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 /**************************************************************************
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 =============================================================================
52 =============================================================================
53 HTTP (entity header) WebDAV (property) UCB (property)
54 =============================================================================
58 Content-Language getcontentlanguage
59 Content-Length getcontentlength Size
63 Content-Type getcontenttype MediaType
65 Last-Modified getlastmodified DateModified
66 creationdate DateCreated
67 resourcetype IsFolder,IsDocument,ContentType
69 ETag (actually getetag
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.
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!" );
103 NeonUri
aURI( rResource
.uri
);
104 m_aEscapedTitle
= aURI
.GetPathBaseName();
106 (*m_xProps
)[ OUString("Title") ]
108 uno::makeAny( aURI
.GetPathBaseNameUnescaped() ), true );
110 catch ( DAVException
const & )
112 (*m_xProps
)[ OUString("Title") ]
116 "*** unknown ***" ) ),
120 std::vector
< DAVPropertyValue
>::const_iterator it
121 = rResource
.properties
.begin();
122 std::vector
< DAVPropertyValue
>::const_iterator end
123 = rResource
.properties
.end();
127 addProperty( (*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
185 const uno::Any
& ContentProperties::getValue(
186 const OUString
& rName
) const
188 const PropertyValue
* pProp
= get( rName
);
190 return pProp
->value();
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();
204 it
= m_xProps
->begin();
207 if ( (*it
).first
.equalsIgnoreAsciiCase( rName
) )
208 return &(*it
).second
;
215 return &(*it
).second
;
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.
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.
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
)
275 propertyNames
.push_back(
276 DAVProperties::GETCONTENTTYPE
);
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;
299 if ( bIncludeUnmatched
)
300 propertyNames
.push_back( rProp
.Name
);
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.
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") );
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
) )
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();
381 const OUString
& rName
= (*it
);
383 if ( !contains( rName
) ) // ignore duplicates
385 const PropertyValue
* pProp
= rContentProps
.get( rName
);
389 addProperty( rName
, pProp
->value(), pProp
->isCaseSensitive() );
393 addProperty( rName
, uno::Any(), false );
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
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 ) )
425 // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) )
428 else if ( rName
.equals( DAVProperties::GETCONTENTLENGTH
) )
430 // Map DAV:getcontentlength to UCP:Size
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
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 ) )
467 else if ( rName
.equals( DAVProperties::GETLASTMODIFIED
) )
469 // Map the DAV:getlastmodified entity header to UCP:DateModified
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
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 ) )
495 else if ( rName
.equals( DAVProperties::RESOURCETYPE
) )
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 ) )
515 // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) )
520 (*m_xProps
)[ rName
] = PropertyValue( rValue
, bIsCaseSensitive
);
526 // CachableContentProperties Implementation.
533 bool isCachable( OUString
const & rName
,
534 bool isCaseSensitive
)
536 static const OUString aNonCachableProps
[] =
538 DAVProperties::LOCKDISCOVERY
,
540 DAVProperties::GETETAG
,
543 OUString( "DateModified" ),
544 OUString( "Last-Modified" ),
545 DAVProperties::GETLASTMODIFIED
,
548 OUString( "Content-Length" ),
549 DAVProperties::GETCONTENTLENGTH
,
554 for ( sal_uInt32 n
= 0;
555 n
< ( sizeof( aNonCachableProps
)
556 / sizeof( aNonCachableProps
[ 0 ] ) );
559 if ( isCaseSensitive
)
561 if ( rName
.equals( aNonCachableProps
[ n
] ) )
565 if ( rName
.equalsIgnoreAsciiCase( aNonCachableProps
[ n
] ) )
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();
591 if ( isCachable( (*it
).first
, (*it
).second
.isCaseSensitive() ) )
592 m_aProps
.addProperty( (*it
).first
,
593 (*it
).second
.value(),
594 (*it
).second
.isCaseSensitive() );
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();
609 if ( isCachable( (*it
).Name
, (*it
).IsCaseSensitive
) )
610 m_aProps
.addProperty( (*it
) );
616 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */