bump product version to 5.0.4.1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / ContentProperties.cxx
blobde70572f925818f6560232c11484dbe26749d515
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 /**************************************************************************
31 TODO
32 **************************************************************************
34 *************************************************************************/
35 #include <osl/diagnose.h>
36 #include <com/sun/star/util/DateTime.hpp>
37 #include "NeonUri.hxx"
38 #include "DAVResource.hxx"
39 #include "DAVProperties.hxx"
40 #include "DateTimeHelper.hxx"
41 #include "webdavprovider.hxx"
42 #include "ContentProperties.hxx"
44 using namespace com::sun::star;
45 using namespace webdav_ucp;
48 =============================================================================
50 Property Mapping
52 =============================================================================
53 HTTP (entity header) WebDAV (property) UCB (property)
54 =============================================================================
56 Allow
57 Content-Encoding
58 Content-Language getcontentlanguage
59 Content-Length getcontentlength Size
60 Content-Location
61 Content-MD5
62 Content-Range
63 Content-Type getcontenttype MediaType
64 Expires
65 Last-Modified getlastmodified DateModified
66 creationdate DateCreated
67 resourcetype IsFolder,IsDocument,ContentType
68 displayname
69 ETag (actually getetag
70 a response header )
71 lockdiscovery
72 supportedlock
73 source
74 Title (always taken from URI)
76 =============================================================================
78 Important: HTTP headers will not be mapped to DAV properties; only to UCB
79 properties. (Content-Length,Content-Type,Last-Modified)
85 // ContentProperties Implementation.
90 // static member!
91 uno::Any ContentProperties::m_aEmptyAny;
93 ContentProperties::ContentProperties( const DAVResource& rResource )
94 : m_xProps( new PropertyValueMap ),
95 m_bTrailingSlash( false )
97 OSL_ENSURE( !rResource.uri.isEmpty(),
98 "ContentProperties ctor - Empty resource URI!" );
100 // Title
103 NeonUri aURI( rResource.uri );
104 m_aEscapedTitle = aURI.GetPathBaseName();
106 (*m_xProps)[ OUString("Title") ]
107 = PropertyValue(
108 uno::makeAny( aURI.GetPathBaseNameUnescaped() ), true );
110 catch ( DAVException const & )
112 (*m_xProps)[ OUString("Title") ]
113 = PropertyValue(
114 uno::makeAny(
115 OUString(
116 "*** unknown ***" ) ),
117 true );
120 std::vector< DAVPropertyValue >::const_iterator it
121 = rResource.properties.begin();
122 std::vector< DAVPropertyValue >::const_iterator end
123 = rResource.properties.end();
125 while ( it != end )
127 addProperty( (*it) );
128 ++it;
131 if ( rResource.uri.endsWith("/") )
132 m_bTrailingSlash = true;
136 ContentProperties::ContentProperties(
137 const OUString & rTitle, bool bFolder )
138 : m_xProps( new PropertyValueMap ),
139 m_bTrailingSlash( false )
141 (*m_xProps)[ OUString("Title") ]
142 = PropertyValue( uno::makeAny( rTitle ), true );
143 (*m_xProps)[ OUString("IsFolder") ]
144 = PropertyValue( uno::makeAny( bFolder ), true );
145 (*m_xProps)[ OUString("IsDocument") ]
146 = PropertyValue( uno::makeAny( !bFolder ), true );
150 ContentProperties::ContentProperties( const OUString & rTitle )
151 : m_xProps( new PropertyValueMap ),
152 m_bTrailingSlash( false )
154 (*m_xProps)[ OUString("Title") ]
155 = PropertyValue( uno::makeAny( rTitle ), true );
159 ContentProperties::ContentProperties()
160 : m_xProps( new PropertyValueMap ),
161 m_bTrailingSlash( false )
166 ContentProperties::ContentProperties( const ContentProperties & rOther )
167 : m_aEscapedTitle( rOther.m_aEscapedTitle ),
168 m_xProps( rOther.m_xProps.get()
169 ? new PropertyValueMap( *rOther.m_xProps )
170 : new PropertyValueMap ),
171 m_bTrailingSlash( rOther.m_bTrailingSlash )
176 bool ContentProperties::contains( const OUString & rName ) const
178 if ( get( rName ) )
179 return true;
180 else
181 return false;
185 const uno::Any & ContentProperties::getValue(
186 const OUString & rName ) const
188 const PropertyValue * pProp = get( rName );
189 if ( pProp )
190 return pProp->value();
191 else
192 return m_aEmptyAny;
196 const PropertyValue * ContentProperties::get(
197 const OUString & rName ) const
199 PropertyValueMap::const_iterator it = m_xProps->find( rName );
200 const PropertyValueMap::const_iterator end = m_xProps->end();
202 if ( it == end )
204 it = m_xProps->begin();
205 while ( it != end )
207 if ( (*it).first.equalsIgnoreAsciiCase( rName ) )
208 return &(*it).second;
210 ++it;
212 return 0;
214 else
215 return &(*it).second;
219 // static
220 void ContentProperties::UCBNamesToDAVNames(
221 const uno::Sequence< beans::Property > & rProps,
222 std::vector< OUString > & propertyNames,
223 bool bIncludeUnmatched /* = true */ )
226 // Assemble list of DAV properties to obtain from server.
227 // Append DAV properties needed to obtain requested UCB props.
230 // DAV UCB
231 // creationdate <- DateCreated
232 // getlastmodified <- DateModified
233 // getcontenttype <- MediaType
234 // getcontentlength <- Size
235 // resourcetype <- IsFolder, IsDocument, ContentType
236 // (taken from URI) <- Title
238 bool bCreationDate = false;
239 bool bLastModified = false;
240 bool bContentType = false;
241 bool bContentLength = false;
242 bool bResourceType = false;
244 sal_Int32 nCount = rProps.getLength();
245 for ( sal_Int32 n = 0; n < nCount; ++n )
247 const beans::Property & rProp = rProps[ n ];
249 if ( rProp.Name == "Title" )
251 // Title is always obtained from resource's URI.
252 continue;
254 else if ( rProp.Name == "DateCreated" || rProp.Name == DAVProperties::CREATIONDATE )
256 if ( !bCreationDate )
258 propertyNames.push_back( DAVProperties::CREATIONDATE );
259 bCreationDate = true;
262 else if ( rProp.Name == "DateModified" || rProp.Name == DAVProperties::GETLASTMODIFIED )
264 if ( !bLastModified )
266 propertyNames.push_back(
267 DAVProperties::GETLASTMODIFIED );
268 bLastModified = true;
271 else if ( rProp.Name == "MediaType" || rProp.Name == DAVProperties::GETCONTENTTYPE )
273 if ( !bContentType )
275 propertyNames.push_back(
276 DAVProperties::GETCONTENTTYPE );
277 bContentType = true;
280 else if ( rProp.Name == "Size" || rProp.Name == DAVProperties::GETCONTENTLENGTH )
282 if ( !bContentLength )
284 propertyNames.push_back(
285 DAVProperties::GETCONTENTLENGTH );
286 bContentLength = true;
289 else if ( rProp.Name == "ContentType" || rProp.Name == "IsDocument" || rProp.Name == "IsFolder" || rProp.Name == DAVProperties::RESOURCETYPE )
291 if ( !bResourceType )
293 propertyNames.push_back( DAVProperties::RESOURCETYPE );
294 bResourceType = true;
297 else
299 if ( bIncludeUnmatched )
300 propertyNames.push_back( rProp.Name );
306 // static
307 void ContentProperties::UCBNamesToHTTPNames(
308 const uno::Sequence< beans::Property > & rProps,
309 std::vector< OUString > & propertyNames,
310 bool bIncludeUnmatched /* = true */ )
313 // Assemble list of HTTP header names to obtain from server.
314 // Append HTTP headers needed to obtain requested UCB props.
317 // HTTP UCB
318 // Last-Modified <- DateModified
319 // Content-Type <- MediaType
320 // Content-Length <- Size
322 sal_Int32 nCount = rProps.getLength();
323 for ( sal_Int32 n = 0; n < nCount; ++n )
325 const beans::Property & rProp = rProps[ n ];
327 if ( rProp.Name == "DateModified" )
329 propertyNames.push_back(
330 OUString("Last-Modified") );
332 else if ( rProp.Name == "MediaType" )
334 propertyNames.push_back(
335 OUString("Content-Type") );
337 else if ( rProp.Name == "Size" )
339 propertyNames.push_back(
340 OUString("Content-Length") );
342 else
344 if ( bIncludeUnmatched )
345 propertyNames.push_back( rProp.Name );
351 bool ContentProperties::containsAllNames(
352 const uno::Sequence< beans::Property >& rProps,
353 std::vector< OUString > & rNamesNotContained ) const
355 rNamesNotContained.clear();
357 sal_Int32 nCount = rProps.getLength();
358 for ( sal_Int32 n = 0; n < nCount; ++n )
360 const OUString & rName = rProps[ n ].Name;
361 if ( !contains( rName ) )
363 // Not found.
364 rNamesNotContained.push_back( rName );
368 return ( rNamesNotContained.empty() );
372 void ContentProperties::addProperties(
373 const std::vector< OUString > & rProps,
374 const ContentProperties & rContentProps )
376 std::vector< OUString >::const_iterator it = rProps.begin();
377 std::vector< OUString >::const_iterator end = rProps.end();
379 while ( it != end )
381 const OUString & rName = (*it);
383 if ( !contains( rName ) ) // ignore duplicates
385 const PropertyValue * pProp = rContentProps.get( rName );
386 if ( pProp )
388 // Add it.
389 addProperty( rName, pProp->value(), pProp->isCaseSensitive() );
391 else
393 addProperty( rName, uno::Any(), false );
396 ++it;
401 void ContentProperties::addProperty( const DAVPropertyValue & rProp )
403 addProperty( rProp.Name, rProp.Value, rProp.IsCaseSensitive );
407 void ContentProperties::addProperty( const OUString & rName,
408 const com::sun::star::uno::Any & rValue,
409 bool bIsCaseSensitive )
411 if ( rName.equals( DAVProperties::CREATIONDATE ) )
413 // Map DAV:creationdate to UCP:DateCreated
414 OUString aValue;
415 rValue >>= aValue;
416 util::DateTime aDate;
417 DateTimeHelper::convert( aValue, aDate );
419 (*m_xProps)[ OUString("DateCreated") ]
420 = PropertyValue( uno::makeAny( aDate ), true );
422 // else if ( rName.equals( DAVProperties::DISPLAYNAME ) )
423 // {
424 // }
425 // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) )
426 // {
427 // }
428 else if ( rName.equals( DAVProperties::GETCONTENTLENGTH ) )
430 // Map DAV:getcontentlength to UCP:Size
431 OUString aValue;
432 rValue >>= aValue;
434 (*m_xProps)[ OUString("Size") ]
435 = PropertyValue( uno::makeAny( aValue.toInt64() ), true );
437 else if ( rName == "Content-Length" )
439 // Do NOT map Content-length entity header to DAV:getcontentlength!
440 // Only DAV resources have this property.
442 // Map Content-Length entity header to UCP:Size
443 OUString aValue;
444 rValue >>= aValue;
446 (*m_xProps)[ OUString("Size") ]
447 = PropertyValue( uno::makeAny( aValue.toInt64() ), true );
449 else if ( rName.equals( DAVProperties::GETCONTENTTYPE ) )
451 // Map DAV:getcontenttype to UCP:MediaType (1:1)
452 (*m_xProps)[ OUString("MediaType") ]
453 = PropertyValue( rValue, true );
455 else if ( rName == "Content-Type" )
457 // Do NOT map Content-Type entity header to DAV:getcontenttype!
458 // Only DAV resources have this property.
460 // Map DAV:getcontenttype to UCP:MediaType (1:1)
461 (*m_xProps)[ OUString("MediaType") ]
462 = PropertyValue( rValue, true );
464 // else if ( rName.equals( DAVProperties::GETETAG ) )
465 // {
466 // }
467 else if ( rName.equals( DAVProperties::GETLASTMODIFIED ) )
469 // Map the DAV:getlastmodified entity header to UCP:DateModified
470 OUString aValue;
471 rValue >>= aValue;
472 util::DateTime aDate;
473 DateTimeHelper::convert( aValue, aDate );
475 (*m_xProps)[ OUString("DateModified") ]
476 = PropertyValue( uno::makeAny( aDate ), true );
478 else if ( rName == "Last-Modified" )
480 // Do not map Last-Modified entity header to DAV:getlastmodified!
481 // Only DAV resources have this property.
483 // Map the Last-Modified entity header to UCP:DateModified
484 OUString aValue;
485 rValue >>= aValue;
486 util::DateTime aDate;
487 DateTimeHelper::convert( aValue, aDate );
489 (*m_xProps)[ OUString("DateModified") ]
490 = PropertyValue( uno::makeAny( aDate ), true );
492 // else if ( rName.equals( DAVProperties::LOCKDISCOVERY ) )
493 // {
494 // }
495 else if ( rName.equals( DAVProperties::RESOURCETYPE ) )
497 OUString aValue;
498 rValue >>= aValue;
500 // Map DAV:resourceype to UCP:IsFolder, UCP:IsDocument, UCP:ContentType
501 bool bFolder = aValue.equalsIgnoreAsciiCase( "collection" );
503 (*m_xProps)[ OUString("IsFolder") ]
504 = PropertyValue( uno::makeAny( bFolder ), true );
505 (*m_xProps)[ OUString("IsDocument") ]
506 = PropertyValue( uno::makeAny( !bFolder ), true );
507 (*m_xProps)[ OUString("ContentType") ]
508 = PropertyValue( uno::makeAny( bFolder
509 ? OUString( WEBDAV_COLLECTION_TYPE )
510 : OUString( WEBDAV_CONTENT_TYPE ) ), true );
512 // else if ( rName.equals( DAVProperties::SOURCE ) )
513 // {
514 // }
515 // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) )
516 // {
517 // }
519 // Save property.
520 (*m_xProps)[ rName ] = PropertyValue( rValue, bIsCaseSensitive );
526 // CachableContentProperties Implementation.
531 namespace
533 bool isCachable( OUString const & rName,
534 bool isCaseSensitive )
536 static const OUString aNonCachableProps [] =
538 DAVProperties::LOCKDISCOVERY,
540 DAVProperties::GETETAG,
541 OUString( "ETag" ),
543 OUString( "DateModified" ),
544 OUString( "Last-Modified" ),
545 DAVProperties::GETLASTMODIFIED,
547 OUString( "Size" ),
548 OUString( "Content-Length" ),
549 DAVProperties::GETCONTENTLENGTH,
551 OUString( "Date" )
554 for ( sal_uInt32 n = 0;
555 n < ( sizeof( aNonCachableProps )
556 / sizeof( aNonCachableProps[ 0 ] ) );
557 ++n )
559 if ( isCaseSensitive )
561 if ( rName.equals( aNonCachableProps[ n ] ) )
562 return false;
564 else
565 if ( rName.equalsIgnoreAsciiCase( aNonCachableProps[ n ] ) )
566 return false;
568 return true;
571 } // namespace
574 CachableContentProperties::CachableContentProperties(
575 const ContentProperties & rProps )
577 addProperties( rProps );
581 void CachableContentProperties::addProperties(
582 const ContentProperties & rProps )
584 const std::unique_ptr< PropertyValueMap > & props = rProps.getProperties();
586 PropertyValueMap::const_iterator it = props->begin();
587 const PropertyValueMap::const_iterator end = props->end();
589 while ( it != end )
591 if ( isCachable( (*it).first, (*it).second.isCaseSensitive() ) )
592 m_aProps.addProperty( (*it).first,
593 (*it).second.value(),
594 (*it).second.isCaseSensitive() );
596 ++it;
601 void CachableContentProperties::addProperties(
602 const std::vector< DAVPropertyValue > & rProps )
604 std::vector< DAVPropertyValue >::const_iterator it = rProps.begin();
605 const std::vector< DAVPropertyValue >::const_iterator end = rProps.end();
607 while ( it != end )
609 if ( isCachable( (*it).Name, (*it).IsCaseSensitive ) )
610 m_aProps.addProperty( (*it) );
612 ++it;
616 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */