1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ContentProperties.cxx,v $
10 * $Revision: 1.12.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 /**************************************************************************
36 **************************************************************************
38 *************************************************************************/
39 #include <osl/diagnose.h>
40 #include <com/sun/star/util/DateTime.hpp>
41 #include "NeonUri.hxx"
42 #include "DAVResource.hxx"
43 #include "DAVProperties.hxx"
44 #include "DateTimeHelper.hxx"
45 #include "webdavprovider.hxx"
46 #include "ContentProperties.hxx"
48 using namespace com::sun::star
;
49 using namespace webdav_ucp
;
52 =============================================================================
56 =============================================================================
57 HTTP (entity header) WebDAV (property) UCB (property)
58 =============================================================================
62 Content-Language getcontentlanguage
63 Content-Length getcontentlength Size
67 Content-Type getcontenttype MediaType
69 Last-Modified getlastmodified DateModified
70 creationdate DateCreated
71 resourcetype IsFolder,IsDocument,ContentType
73 ETag (actually getetag
78 Title (always taken from URI)
80 =============================================================================
82 Important: HTTP headers will not be mapped to DAV properties; only to UCB
83 properties. (Content-Length,Content-Type,Last-Modified)
86 //=========================================================================
87 //=========================================================================
89 // ContentProperties Implementation.
91 //=========================================================================
92 //=========================================================================
95 uno::Any
ContentProperties::m_aEmptyAny
;
97 ContentProperties::ContentProperties( const DAVResource
& rResource
)
98 : m_xProps( new PropertyValueMap
),
99 m_bTrailingSlash( false )
101 OSL_ENSURE( rResource
.uri
.getLength(),
102 "ContentProperties ctor - Empty resource URI!" );
107 NeonUri
aURI( rResource
.uri
);
108 m_aEscapedTitle
= aURI
.GetPathBaseName();
110 (*m_xProps
)[ rtl::OUString::createFromAscii( "Title" ) ]
112 uno::makeAny( aURI
.GetPathBaseNameUnescaped() ), true );
114 catch ( DAVException
const & )
116 (*m_xProps
)[ rtl::OUString::createFromAscii( "Title" ) ]
120 RTL_CONSTASCII_USTRINGPARAM( "*** unknown ***" ) ) ),
124 std::vector
< DAVPropertyValue
>::const_iterator it
125 = rResource
.properties
.begin();
126 std::vector
< DAVPropertyValue
>::const_iterator end
127 = rResource
.properties
.end();
131 addProperty( (*it
) );
135 if ( rResource
.uri
.getStr()[ rResource
.uri
.getLength() - 1 ]
136 == sal_Unicode( '/' ) )
137 m_bTrailingSlash
= sal_True
;
140 //=========================================================================
141 ContentProperties::ContentProperties(
142 const rtl::OUString
& rTitle
, sal_Bool bFolder
)
143 : m_xProps( new PropertyValueMap
),
144 m_bTrailingSlash( sal_False
)
146 (*m_xProps
)[ rtl::OUString::createFromAscii( "Title" ) ]
147 = PropertyValue( uno::makeAny( rTitle
), true );
148 (*m_xProps
)[ rtl::OUString::createFromAscii( "IsFolder" ) ]
149 = PropertyValue( uno::makeAny( bFolder
), true );
150 (*m_xProps
)[ rtl::OUString::createFromAscii( "IsDocument" ) ]
151 = PropertyValue( uno::makeAny( sal_Bool( !bFolder
) ), true );
154 //=========================================================================
155 ContentProperties::ContentProperties( const rtl::OUString
& rTitle
)
156 : m_xProps( new PropertyValueMap
),
157 m_bTrailingSlash( sal_False
)
159 (*m_xProps
)[ rtl::OUString::createFromAscii( "Title" ) ]
160 = PropertyValue( uno::makeAny( rTitle
), true );
163 //=========================================================================
164 ContentProperties::ContentProperties( const ContentProperties
& rOther
)
165 : m_aEscapedTitle( rOther
.m_aEscapedTitle
),
166 m_xProps( rOther
.m_xProps
.get()
167 ? new PropertyValueMap( *rOther
.m_xProps
)
168 : new PropertyValueMap
),
169 m_bTrailingSlash( rOther
.m_bTrailingSlash
)
173 //=========================================================================
174 bool ContentProperties::contains( const rtl::OUString
& rName
) const
182 //=========================================================================
183 const uno::Any
& ContentProperties::getValue(
184 const rtl::OUString
& rName
) const
186 const PropertyValue
* pProp
= get( rName
);
188 return pProp
->value();
193 //=========================================================================
194 const PropertyValue
* ContentProperties::get(
195 const rtl::OUString
& rName
) const
197 PropertyValueMap::const_iterator it
= m_xProps
->find( rName
);
198 const PropertyValueMap::const_iterator end
= m_xProps
->end();
202 it
= m_xProps
->begin();
205 if ( (*it
).first
.equalsIgnoreAsciiCase( rName
) )
206 return &(*it
).second
;
213 return &(*it
).second
;
216 //=========================================================================
218 void ContentProperties::UCBNamesToDAVNames(
219 const uno::Sequence
< beans::Property
> & rProps
,
220 std::vector
< rtl::OUString
> & propertyNames
,
221 bool bIncludeUnmatched
/* = true */ )
223 //////////////////////////////////////////////////////////////
224 // Assemble list of DAV properties to obtain from server.
225 // Append DAV properties needed to obtain requested UCB props.
226 //////////////////////////////////////////////////////////////
229 // creationdate <- DateCreated
230 // getlastmodified <- DateModified
231 // getcontenttype <- MediaType
232 // getcontentlength <- Size
233 // resourcetype <- IsFolder, IsDocument, ContentType
234 // (taken from URI) <- Title
236 sal_Bool bCreationDate
= sal_False
;
237 sal_Bool bLastModified
= sal_False
;
238 sal_Bool bContentType
= sal_False
;
239 sal_Bool bContentLength
= sal_False
;
240 sal_Bool bResourceType
= sal_False
;
242 sal_Int32 nCount
= rProps
.getLength();
243 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
245 const beans::Property
& rProp
= rProps
[ n
];
247 if ( rProp
.Name
.equalsAsciiL(
248 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
250 // Title is always obtained from resource's URI.
253 else if ( rProp
.Name
.equalsAsciiL(
254 RTL_CONSTASCII_STRINGPARAM( "DateCreated" ) )
256 ( rProp
.Name
== DAVProperties::CREATIONDATE
) )
258 if ( !bCreationDate
)
260 propertyNames
.push_back( DAVProperties::CREATIONDATE
);
261 bCreationDate
= sal_True
;
264 else if ( rProp
.Name
.equalsAsciiL(
265 RTL_CONSTASCII_STRINGPARAM( "DateModified" ) )
267 ( rProp
.Name
== DAVProperties::GETLASTMODIFIED
) )
269 if ( !bLastModified
)
271 propertyNames
.push_back(
272 DAVProperties::GETLASTMODIFIED
);
273 bLastModified
= sal_True
;
276 else if ( rProp
.Name
.equalsAsciiL(
277 RTL_CONSTASCII_STRINGPARAM( "MediaType" ) )
279 ( rProp
.Name
== DAVProperties::GETCONTENTTYPE
) )
283 propertyNames
.push_back(
284 DAVProperties::GETCONTENTTYPE
);
285 bContentType
= sal_True
;
288 else if ( rProp
.Name
.equalsAsciiL(
289 RTL_CONSTASCII_STRINGPARAM( "Size" ) )
291 ( rProp
.Name
== DAVProperties::GETCONTENTLENGTH
) )
293 if ( !bContentLength
)
295 propertyNames
.push_back(
296 DAVProperties::GETCONTENTLENGTH
);
297 bContentLength
= sal_True
;
300 else if ( rProp
.Name
.equalsAsciiL(
301 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) )
303 rProp
.Name
.equalsAsciiL(
304 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) )
306 rProp
.Name
.equalsAsciiL(
307 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) )
309 ( rProp
.Name
== DAVProperties::RESOURCETYPE
) )
311 if ( !bResourceType
)
313 propertyNames
.push_back( DAVProperties::RESOURCETYPE
);
314 bResourceType
= sal_True
;
319 if ( bIncludeUnmatched
)
320 propertyNames
.push_back( rProp
.Name
);
325 //=========================================================================
327 void ContentProperties::UCBNamesToHTTPNames(
328 const uno::Sequence
< beans::Property
> & rProps
,
329 std::vector
< rtl::OUString
> & propertyNames
,
330 bool bIncludeUnmatched
/* = true */ )
332 //////////////////////////////////////////////////////////////
333 // Assemble list of HTTP header names to obtain from server.
334 // Append HTTP headers needed to obtain requested UCB props.
335 //////////////////////////////////////////////////////////////
338 // Last-Modified <- DateModified
339 // Content-Type <- MediaType
340 // Content-Length <- Size
342 sal_Int32 nCount
= rProps
.getLength();
343 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
345 const beans::Property
& rProp
= rProps
[ n
];
347 if ( rProp
.Name
.equalsAsciiL(
348 RTL_CONSTASCII_STRINGPARAM( "DateModified" ) ) )
350 propertyNames
.push_back(
351 rtl::OUString::createFromAscii( "Last-Modified" ) );
353 else if ( rProp
.Name
.equalsAsciiL(
354 RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) )
356 propertyNames
.push_back(
357 rtl::OUString::createFromAscii( "Content-Type" ) );
359 else if ( rProp
.Name
.equalsAsciiL(
360 RTL_CONSTASCII_STRINGPARAM( "Size" ) ) )
362 propertyNames
.push_back(
363 rtl::OUString::createFromAscii( "Content-Length" ) );
367 if ( bIncludeUnmatched
)
368 propertyNames
.push_back( rProp
.Name
);
373 //=========================================================================
374 bool ContentProperties::containsAllNames(
375 const uno::Sequence
< beans::Property
>& rProps
,
376 std::vector
< rtl::OUString
> & rNamesNotContained
) const
378 rNamesNotContained
.clear();
380 sal_Int32 nCount
= rProps
.getLength();
381 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
383 const rtl::OUString
& rName
= rProps
[ n
].Name
;
384 if ( !contains( rName
) )
387 rNamesNotContained
.push_back( rName
);
391 return ( rNamesNotContained
.size() == 0 );
394 //=========================================================================
395 void ContentProperties::addProperties(
396 const std::vector
< rtl::OUString
> & rProps
,
397 const ContentProperties
& rContentProps
)
399 std::vector
< rtl::OUString
>::const_iterator it
= rProps
.begin();
400 std::vector
< rtl::OUString
>::const_iterator end
= rProps
.end();
404 const rtl::OUString
& rName
= (*it
);
406 if ( !contains( rName
) ) // ignore duplicates
408 const PropertyValue
* pProp
= rContentProps
.get( rName
);
412 addProperty( rName
, pProp
->value(), pProp
->isCaseSensitive() );
416 addProperty( rName
, uno::Any(), false );
423 //=========================================================================
424 void ContentProperties::addProperties( const ContentProperties
& rProps
)
426 PropertyValueMap::const_iterator it
= rProps
.m_xProps
->begin();
427 const PropertyValueMap::const_iterator end
= rProps
.m_xProps
->end();
432 (*it
).first
, (*it
).second
.value(), (*it
).second
.isCaseSensitive() );
437 //=========================================================================
438 void ContentProperties::addProperties(
439 const std::vector
< DAVPropertyValue
> & rProps
)
441 std::vector
< DAVPropertyValue
>::const_iterator it
= rProps
.begin();
442 std::vector
< DAVPropertyValue
>::const_iterator end
= rProps
.end();
446 addProperty( (*it
) );
451 //=========================================================================
452 void ContentProperties::addProperty( const DAVPropertyValue
& rProp
)
454 addProperty( rProp
.Name
, rProp
.Value
, rProp
.IsCaseSensitive
);
457 //=========================================================================
458 void ContentProperties::addProperty( const rtl::OUString
& rName
,
459 const com::sun::star::uno::Any
& rValue
,
460 bool bIsCaseSensitive
)
462 if ( rName
.equals( DAVProperties::CREATIONDATE
) )
464 // Map DAV:creationdate to UCP:DateCreated
465 rtl::OUString aValue
;
467 util::DateTime aDate
;
468 DateTimeHelper::convert( aValue
, aDate
);
470 (*m_xProps
)[ rtl::OUString::createFromAscii( "DateCreated" ) ]
471 = PropertyValue( uno::makeAny( aDate
), true );
473 // else if ( rName.equals( DAVProperties::DISPLAYNAME ) )
476 // else if ( rName.equals( DAVProperties::GETCONTENTLANGUAGE ) )
479 else if ( rName
.equals( DAVProperties::GETCONTENTLENGTH
) )
481 // Map DAV:getcontentlength to UCP:Size
482 rtl::OUString aValue
;
485 (*m_xProps
)[ rtl::OUString::createFromAscii( "Size" ) ]
486 = PropertyValue( uno::makeAny( aValue
.toInt64() ), true );
488 else if ( rName
.equalsAsciiL(
489 RTL_CONSTASCII_STRINGPARAM( "Content-Length" ) ) )
491 // Do NOT map Content-Lenght entity header to DAV:getcontentlength!
492 // Only DAV resources have this property.
494 // Map Content-Length entity header to UCP:Size
495 rtl::OUString aValue
;
498 (*m_xProps
)[ rtl::OUString::createFromAscii( "Size" ) ]
499 = PropertyValue( uno::makeAny( aValue
.toInt64() ), true );
501 else if ( rName
.equals( DAVProperties::GETCONTENTTYPE
) )
503 // Map DAV:getcontenttype to UCP:MediaType (1:1)
504 (*m_xProps
)[ rtl::OUString::createFromAscii( "MediaType" ) ]
505 = PropertyValue( rValue
, true );
507 else if ( rName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Content-Type" ) ) )
509 // Do NOT map Content-Type entity header to DAV:getcontenttype!
510 // Only DAV resources have this property.
512 // Map DAV:getcontenttype to UCP:MediaType (1:1)
513 (*m_xProps
)[ rtl::OUString::createFromAscii( "MediaType" ) ]
514 = PropertyValue( rValue
, true );
516 // else if ( rName.equals( DAVProperties::GETETAG ) )
519 else if ( rName
.equals( DAVProperties::GETLASTMODIFIED
) )
521 // Map the DAV:getlastmodified entity header to UCP:DateModified
522 rtl::OUString aValue
;
524 util::DateTime aDate
;
525 DateTimeHelper::convert( aValue
, aDate
);
527 (*m_xProps
)[ rtl::OUString::createFromAscii( "DateModified" ) ]
528 = PropertyValue( uno::makeAny( aDate
), true );
530 else if ( rName
.equalsAsciiL(
531 RTL_CONSTASCII_STRINGPARAM( "Last-Modified" ) ) )
533 // Do not map Last-Modified entity header to DAV:getlastmodified!
534 // Only DAV resources have this property.
536 // Map the Last-Modified entity header to UCP:DateModified
537 rtl::OUString aValue
;
539 util::DateTime aDate
;
540 DateTimeHelper::convert( aValue
, aDate
);
542 (*m_xProps
)[ rtl::OUString::createFromAscii( "DateModified" ) ]
543 = PropertyValue( uno::makeAny( aDate
), true );
545 // else if ( rName.equals( DAVProperties::LOCKDISCOVERY ) )
548 else if ( rName
.equals( DAVProperties::RESOURCETYPE
) )
550 rtl::OUString aValue
;
553 // Map DAV:resourceype to UCP:IsFolder, UCP:IsDocument, UCP:ContentType
555 aValue
.equalsIgnoreAsciiCaseAsciiL(
556 RTL_CONSTASCII_STRINGPARAM( "collection" ) );
558 (*m_xProps
)[ rtl::OUString::createFromAscii( "IsFolder" ) ]
559 = PropertyValue( uno::makeAny( bFolder
), true );
560 (*m_xProps
)[ rtl::OUString::createFromAscii( "IsDocument" ) ]
561 = PropertyValue( uno::makeAny( sal_Bool( !bFolder
) ), true );
562 (*m_xProps
)[ rtl::OUString::createFromAscii( "ContentType" ) ]
563 = PropertyValue( uno::makeAny( bFolder
564 ? rtl::OUString::createFromAscii( WEBDAV_COLLECTION_TYPE
)
565 : rtl::OUString::createFromAscii( WEBDAV_CONTENT_TYPE
) ), true );
567 // else if ( rName.equals( DAVProperties::SOURCE ) )
570 // else if ( rName.equals( DAVProperties::SUPPORTEDLOCK ) )
575 (*m_xProps
)[ rName
] = PropertyValue( rValue
, bIsCaseSensitive
);