1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/diagnose.h>
21 #include <com/sun/star/util/DateTime.hpp>
22 #include "SerfUri.hxx"
23 #include "DAVResource.hxx"
24 #include "DAVProperties.hxx"
25 #include "DateTimeHelper.hxx"
26 #include "webdavprovider.hxx"
27 #include "ContentProperties.hxx"
29 using namespace com::sun::star
;
30 using namespace http_dav_ucp
;
33 =============================================================================
37 =============================================================================
38 HTTP (entity header) WebDAV (property) UCB (property)
39 =============================================================================
43 Content-Language getcontentlanguage
44 Content-Length getcontentlength Size
48 Content-Type getcontenttype MediaType
50 Last-Modified getlastmodified DateModified
51 creationdate DateCreated
52 resourcetype IsFolder,IsDocument,ContentType
54 ETag (actually getetag
59 Title (always taken from URI)
61 =============================================================================
63 Important: HTTP headers will not be mapped to DAV properties; only to UCB
64 properties. (Content-Length,Content-Type,Last-Modified)
70 // ContentProperties Implementation.
76 uno::Any
ContentProperties::m_aEmptyAny
;
78 ContentProperties::ContentProperties( const DAVResource
& rResource
)
79 : m_xProps( new PropertyValueMap
),
80 m_bTrailingSlash( false )
82 SAL_WARN_IF( !rResource
.uri
.getLength(), "ucb.ucp.webdav",
83 "ContentProperties ctor - Empty resource URI!" );
88 SerfUri
aURI( rResource
.uri
);
89 m_aEscapedTitle
= aURI
.GetPathBaseName();
91 (*m_xProps
)[ OUString( "Title" ) ]
93 uno::makeAny( aURI
.GetPathBaseNameUnescaped() ), true );
95 catch ( DAVException
const & )
97 (*m_xProps
)[ OUString( "Title" ) ]
100 OUString( "*** unknown ***" ) ),
104 std::vector
< DAVPropertyValue
>::const_iterator it
105 = rResource
.properties
.begin();
106 std::vector
< DAVPropertyValue
>::const_iterator end
107 = rResource
.properties
.end();
111 addProperty( (*it
) );
115 if ( rResource
.uri
.endsWith("/") )
116 m_bTrailingSlash
= true;
120 ContentProperties::ContentProperties(
121 const OUString
& rTitle
, bool bFolder
)
122 : m_xProps( new PropertyValueMap
),
123 m_bTrailingSlash( false )
125 (*m_xProps
)[ OUString( "Title" ) ]
126 = PropertyValue( uno::makeAny( rTitle
), true );
127 (*m_xProps
)[ OUString( "IsFolder" ) ]
128 = PropertyValue( uno::makeAny( bFolder
), true );
129 (*m_xProps
)[ OUString( "IsDocument" ) ]
130 = PropertyValue( uno::makeAny( bool( !bFolder
) ), true );
134 ContentProperties::ContentProperties( const OUString
& rTitle
)
135 : m_xProps( new PropertyValueMap
),
136 m_bTrailingSlash( false )
138 (*m_xProps
)[ OUString( "Title" ) ]
139 = PropertyValue( uno::makeAny( rTitle
), true );
143 ContentProperties::ContentProperties()
144 : m_xProps( new PropertyValueMap
),
145 m_bTrailingSlash( false )
150 ContentProperties::ContentProperties( const ContentProperties
& rOther
)
151 : m_aEscapedTitle( rOther
.m_aEscapedTitle
),
152 m_xProps( rOther
.m_xProps
.get()
153 ? new PropertyValueMap( *rOther
.m_xProps
)
154 : new PropertyValueMap
),
155 m_bTrailingSlash( rOther
.m_bTrailingSlash
)
160 bool ContentProperties::contains( const OUString
& rName
) const
169 const uno::Any
& ContentProperties::getValue(
170 const OUString
& rName
) const
172 const PropertyValue
* pProp
= get( rName
);
174 return pProp
->value();
180 const PropertyValue
* ContentProperties::get(
181 const OUString
& rName
) const
183 PropertyValueMap::const_iterator it
= m_xProps
->find( rName
);
184 const PropertyValueMap::const_iterator end
= m_xProps
->end();
188 it
= m_xProps
->begin();
191 if ( (*it
).first
.equalsIgnoreAsciiCase( rName
) )
192 return &(*it
).second
;
199 return &(*it
).second
;
204 void ContentProperties::UCBNamesToDAVNames(
205 const uno::Sequence
< beans::Property
> & rProps
,
206 std::vector
< OUString
> & propertyNames
,
207 bool bIncludeUnmatched
/* = true */ )
210 // Assemble list of DAV properties to obtain from server.
211 // Append DAV properties needed to obtain requested UCB props.
215 // creationdate <- DateCreated
216 // getlastmodified <- DateModified
217 // getcontenttype <- MediaType
218 // getcontentlength <- Size
219 // resourcetype <- IsFolder, IsDocument, ContentType
220 // (taken from URI) <- Title
222 bool bCreationDate
= false;
223 bool bLastModified
= false;
224 bool bContentType
= false;
225 bool bContentLength
= false;
226 bool bResourceType
= false;
228 sal_Int32 nCount
= rProps
.getLength();
229 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
231 const beans::Property
& rProp
= rProps
[ n
];
233 if ( rProp
.Name
== "Title" )
235 // Title is always obtained from resource's URI.
238 else if ( rProp
.Name
== "DateCreated" ||
239 ( rProp
.Name
== DAVProperties::CREATIONDATE
) )
241 if ( !bCreationDate
)
243 propertyNames
.push_back( DAVProperties::CREATIONDATE
);
244 bCreationDate
= true;
247 else if ( rProp
.Name
== "DateModified" ||
248 ( rProp
.Name
== DAVProperties::GETLASTMODIFIED
) )
250 if ( !bLastModified
)
252 propertyNames
.push_back(
253 DAVProperties::GETLASTMODIFIED
);
254 bLastModified
= true;
257 else if ( rProp
.Name
== "MediaType" ||
258 ( rProp
.Name
== DAVProperties::GETCONTENTTYPE
) )
262 propertyNames
.push_back(
263 DAVProperties::GETCONTENTTYPE
);
267 else if ( rProp
.Name
== "Size" ||
268 ( rProp
.Name
== DAVProperties::GETCONTENTLENGTH
) )
270 if ( !bContentLength
)
272 propertyNames
.push_back(
273 DAVProperties::GETCONTENTLENGTH
);
274 bContentLength
= true;
277 else if ( rProp
.Name
== "ContentType" ||
278 rProp
.Name
== "IsDocument" ||
279 rProp
.Name
== "IsFolder" ||
280 ( rProp
.Name
== DAVProperties::RESOURCETYPE
) )
282 if ( !bResourceType
)
284 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
285 bResourceType
= true;
290 if ( bIncludeUnmatched
)
291 propertyNames
.push_back( rProp
.Name
);
298 void ContentProperties::UCBNamesToHTTPNames(
299 const uno::Sequence
< beans::Property
> & rProps
,
300 std::vector
< OUString
> & propertyNames
,
301 bool bIncludeUnmatched
/* = true */ )
304 // Assemble list of HTTP header names to obtain from server.
305 // Append HTTP headers needed to obtain requested UCB props.
309 // Last-Modified <- DateModified
310 // Content-Type <- MediaType
311 // Content-Length <- Size
313 sal_Int32 nCount
= rProps
.getLength();
314 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
316 const beans::Property
& rProp
= rProps
[ n
];
318 if ( rProp
.Name
== "DateModified" )
320 propertyNames
.push_back( OUString( "Last-Modified" ) );
322 else if ( rProp
.Name
== "MediaType" )
324 propertyNames
.push_back( OUString( "Content-Type" ) );
326 else if ( rProp
.Name
== "Size" )
328 propertyNames
.push_back( OUString( "Content-Length" ) );
332 if ( bIncludeUnmatched
)
333 propertyNames
.push_back( rProp
.Name
);
339 bool ContentProperties::containsAllNames(
340 const uno::Sequence
< beans::Property
>& rProps
,
341 std::vector
< OUString
> & rNamesNotContained
) const
343 rNamesNotContained
.clear();
345 sal_Int32 nCount
= rProps
.getLength();
346 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
348 const OUString
& rName
= rProps
[ n
].Name
;
349 if ( !contains( rName
) )
352 rNamesNotContained
.push_back( rName
);
356 return ( rNamesNotContained
.size() == 0 );
360 void ContentProperties::addProperties(
361 const std::vector
< OUString
> & rProps
,
362 const ContentProperties
& rContentProps
)
364 std::vector
< OUString
>::const_iterator it
= rProps
.begin();
365 std::vector
< OUString
>::const_iterator end
= rProps
.end();
369 const OUString
& rName
= (*it
);
371 if ( !contains( rName
) ) // ignore duplicates
373 const PropertyValue
* pProp
= rContentProps
.get( rName
);
377 addProperty( rName
, pProp
->value(), pProp
->isCaseSensitive() );
381 addProperty( rName
, uno::Any(), false );
389 void ContentProperties::addProperties( const ContentProperties
& rProps
)
391 PropertyValueMap::const_iterator it
= rProps
.m_xProps
->begin();
392 const PropertyValueMap::const_iterator end
= rProps
.m_xProps
->end();
397 (*it
).first
, (*it
).second
.value(), (*it
).second
.isCaseSensitive() );
403 void ContentProperties::addProperties(
404 const std::vector
< DAVPropertyValue
> & rProps
)
406 std::vector
< DAVPropertyValue
>::const_iterator it
= rProps
.begin();
407 const std::vector
< DAVPropertyValue
>::const_iterator end
= rProps
.end();
411 addProperty( (*it
) );
417 void ContentProperties::addProperty( const DAVPropertyValue
& rProp
)
419 addProperty( rProp
.Name
, rProp
.Value
, rProp
.IsCaseSensitive
);
423 void ContentProperties::addProperty( const OUString
& rName
,
424 const com::sun::star::uno::Any
& rValue
,
425 bool bIsCaseSensitive
)
427 if ( rName
== DAVProperties::CREATIONDATE
)
429 // Map DAV:creationdate to UCP:DateCreated
432 util::DateTime aDate
;
433 DateTimeHelper::convert( aValue
, aDate
);
435 (*m_xProps
)[ OUString( "DateCreated" ) ]
436 = PropertyValue( uno::makeAny( aDate
), true );
438 // else if ( rName.equals( DAVProperties::DISPLAYNAME ) )
441 // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) )
444 else if ( rName
== DAVProperties::GETCONTENTLENGTH
)
446 // Map DAV:getcontentlength to UCP:Size
450 (*m_xProps
)[ OUString( "Size" ) ]
451 = PropertyValue( uno::makeAny( aValue
.toInt64() ), true );
453 else if ( rName
== "Content-Length" )
455 // Do NOT map Content-Length entity header to DAV:getcontentlength!
456 // Only DAV resources have this property.
458 // Map Content-Length entity header to UCP:Size
462 (*m_xProps
)[ OUString( "Size" ) ]
463 = PropertyValue( uno::makeAny( aValue
.toInt64() ), true );
465 else if ( rName
== DAVProperties::GETCONTENTTYPE
)
467 // Map DAV:getcontenttype to UCP:MediaType (1:1)
468 (*m_xProps
)[ OUString( "MediaType" ) ]
469 = PropertyValue( rValue
, true );
471 else if ( rName
== "Content-Type" )
473 // Do NOT map Content-Type entity header to DAV:getcontenttype!
474 // Only DAV resources have this property.
476 // Map DAV:getcontenttype to UCP:MediaType (1:1)
477 (*m_xProps
)[ OUString( "MediaType" ) ]
478 = PropertyValue( rValue
, true );
480 // else if ( rName.equals( DAVProperties::GETETAG ) )
483 else if ( rName
== DAVProperties::GETLASTMODIFIED
)
485 // Map the DAV:getlastmodified entity header to UCP:DateModified
488 util::DateTime aDate
;
489 DateTimeHelper::convert( aValue
, aDate
);
491 (*m_xProps
)[ OUString( "DateModified" ) ]
492 = PropertyValue( uno::makeAny( aDate
), true );
494 else if ( rName
== "Last-Modified" )
496 // Do not map Last-Modified entity header to DAV:getlastmodified!
497 // Only DAV resources have this property.
499 // Map the Last-Modified entity header to UCP:DateModified
502 util::DateTime aDate
;
503 DateTimeHelper::convert( aValue
, aDate
);
505 (*m_xProps
)[ OUString( "DateModified" ) ]
506 = PropertyValue( uno::makeAny( aDate
), true );
508 // else if ( rName.equals( DAVProperties::LOCKDISCOVERY ) )
511 else if ( rName
== DAVProperties::RESOURCETYPE
)
516 // Map DAV:resourceype to UCP:IsFolder, UCP:IsDocument, UCP:ContentType
518 aValue
.equalsIgnoreAsciiCase( "collection" );
520 (*m_xProps
)[ OUString( "IsFolder" ) ]
521 = PropertyValue( uno::makeAny( bFolder
), true );
522 (*m_xProps
)[ OUString( "IsDocument" ) ]
523 = PropertyValue( uno::makeAny( bool( !bFolder
) ), true );
524 (*m_xProps
)[ OUString( "ContentType" ) ]
525 = PropertyValue( uno::makeAny( bFolder
526 ? OUString( WEBDAV_COLLECTION_TYPE
)
527 : OUString( WEBDAV_CONTENT_TYPE
) ), true );
529 // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) )
534 (*m_xProps
)[ rName
] = PropertyValue( rValue
, bIsCaseSensitive
);
540 // CachableContentProperties Implementation.
547 bool isCachable( OUString
const & rName
,
548 bool isCaseSensitive
)
550 static const OUString aNonCachableProps
[] =
552 DAVProperties::LOCKDISCOVERY
,
554 DAVProperties::GETETAG
,
557 OUString( "DateModified" ),
558 OUString( "Last-Modified" ),
559 DAVProperties::GETLASTMODIFIED
,
562 OUString( "Content-Length" ),
563 DAVProperties::GETCONTENTLENGTH
,
568 for ( sal_uInt32 n
= 0;
569 n
< ( sizeof( aNonCachableProps
)
570 / sizeof( aNonCachableProps
[ 0 ] ) );
573 if ( isCaseSensitive
)
575 if ( rName
.equals( aNonCachableProps
[ n
] ) )
579 if ( rName
.equalsIgnoreAsciiCase( aNonCachableProps
[ n
] ) )
588 CachableContentProperties::CachableContentProperties(
589 const ContentProperties
& rProps
)
591 addProperties( rProps
);
595 void CachableContentProperties::addProperties(
596 const ContentProperties
& rProps
)
598 const boost::scoped_ptr
< PropertyValueMap
> & props
= rProps
.getProperties();
600 PropertyValueMap::const_iterator it
= props
->begin();
601 const PropertyValueMap::const_iterator end
= props
->end();
605 if ( isCachable( (*it
).first
, (*it
).second
.isCaseSensitive() ) )
606 m_aProps
.addProperty( (*it
).first
,
607 (*it
).second
.value(),
608 (*it
).second
.isCaseSensitive() );
615 void CachableContentProperties::addProperties(
616 const std::vector
< DAVPropertyValue
> & rProps
)
618 std::vector
< DAVPropertyValue
>::const_iterator it
= rProps
.begin();
619 const std::vector
< DAVPropertyValue
>::const_iterator end
= rProps
.end();
623 if ( isCachable( (*it
).Name
, (*it
).IsCaseSensitive
) )
624 m_aProps
.addProperty( (*it
) );
630 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */