Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / ucb / source / ucp / webdav / webdavcontentcaps.cxx
blobf26ebb01d21f601d1fc4b5e1757c249874dddde1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
21 #include <set>
22 #include <com/sun/star/beans/Property.hpp>
23 #include <com/sun/star/beans/PropertyAttribute.hpp>
24 #include <com/sun/star/beans/PropertyValue.hpp>
25 #include <com/sun/star/ucb/CommandInfo.hpp>
26 #include <com/sun/star/ucb/ContentInfo.hpp>
27 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
28 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
29 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
30 #include <com/sun/star/ucb/PropertyCommandArgument.hpp>
31 #include <com/sun/star/ucb/TransferInfo.hpp>
32 #include <com/sun/star/uno/Sequence.hxx>
33 #include <com/sun/star/util/DateTime.hpp>
34 #include <com/sun/star/ucb/Lock.hpp>
35 #include <com/sun/star/ucb/LockEntry.hpp>
36 #include "webdavcontent.hxx"
37 #include "webdavprovider.hxx"
38 #include "DAVProperties.hxx"
39 #include "ContentProperties.hxx"
41 using namespace com::sun::star;
42 using namespace http_dav_ucp;
45 // ContentProvider implementation.
48 bool ContentProvider::getProperty(
49 const OUString & rPropName, beans::Property & rProp, bool bStrict )
51 if ( !m_pProps )
53 osl::MutexGuard aGuard( m_aMutex );
54 if ( !m_pProps )
56 m_pProps = std::make_unique<PropertyMap>();
59 // Fill map of known properties...
62 // Mandatory UCB properties.
63 m_pProps->insert(
64 beans::Property(
65 "ContentType",
66 -1,
67 cppu::UnoType<OUString>::get(),
68 beans::PropertyAttribute::BOUND
69 | beans::PropertyAttribute::READONLY ) );
71 m_pProps->insert(
72 beans::Property(
73 "IsDocument",
74 -1,
75 cppu::UnoType<bool>::get(),
76 beans::PropertyAttribute::BOUND
77 | beans::PropertyAttribute::READONLY ) );
79 m_pProps->insert(
80 beans::Property(
81 "IsFolder",
82 -1,
83 cppu::UnoType<bool>::get(),
84 beans::PropertyAttribute::BOUND
85 | beans::PropertyAttribute::READONLY ) );
87 m_pProps->insert(
88 beans::Property(
89 "Title",
90 -1,
91 cppu::UnoType<OUString>::get(),
92 beans::PropertyAttribute::BOUND ) );
94 // Optional UCB properties.
96 m_pProps->insert(
97 beans::Property(
98 "DateCreated",
99 -1,
100 cppu::UnoType<util::DateTime>::get(),
101 beans::PropertyAttribute::BOUND
102 | beans::PropertyAttribute::READONLY ) );
104 m_pProps->insert(
105 beans::Property(
106 "DateModified",
108 cppu::UnoType<util::DateTime>::get(),
109 beans::PropertyAttribute::BOUND
110 | beans::PropertyAttribute::READONLY ) );
112 m_pProps->insert(
113 beans::Property(
114 "MediaType",
116 cppu::UnoType<OUString>::get(),
117 beans::PropertyAttribute::BOUND
118 | beans::PropertyAttribute::READONLY ) );
120 m_pProps->insert(
121 beans::Property(
122 "Size",
124 cppu::UnoType<sal_Int64>::get(),
125 beans::PropertyAttribute::BOUND
126 | beans::PropertyAttribute::READONLY ) );
128 m_pProps->insert(
129 beans::Property(
130 "BaseURI",
132 cppu::UnoType<OUString>::get(),
133 beans::PropertyAttribute::BOUND
134 | beans::PropertyAttribute::READONLY ) );
136 m_pProps->insert(
137 beans::Property(
138 "CreatableContentsInfo",
140 cppu::UnoType<uno::Sequence< ucb::ContentInfo >>::get(),
141 beans::PropertyAttribute::BOUND
142 | beans::PropertyAttribute::READONLY ) );
144 // Standard DAV properties.
146 m_pProps->insert(
147 beans::Property(
148 DAVProperties::CREATIONDATE,
150 cppu::UnoType<OUString>::get(),
151 beans::PropertyAttribute::BOUND
152 | beans::PropertyAttribute::READONLY ) );
154 m_pProps->insert(
155 beans::Property(
156 DAVProperties::DISPLAYNAME,
158 cppu::UnoType<OUString>::get(),
159 beans::PropertyAttribute::BOUND ) );
161 m_pProps->insert(
162 beans::Property(
163 DAVProperties::GETCONTENTLANGUAGE,
165 cppu::UnoType<OUString>::get(),
166 beans::PropertyAttribute::BOUND
167 | beans::PropertyAttribute::READONLY ) );
169 m_pProps->insert(
170 beans::Property(
171 DAVProperties::GETCONTENTLENGTH,
173 cppu::UnoType<OUString>::get(),
174 beans::PropertyAttribute::BOUND
175 | beans::PropertyAttribute::READONLY ) );
177 m_pProps->insert(
178 beans::Property(
179 DAVProperties::GETCONTENTTYPE ,
181 cppu::UnoType<OUString>::get(),
182 beans::PropertyAttribute::BOUND
183 | beans::PropertyAttribute::READONLY ) );
185 m_pProps->insert(
186 beans::Property(
187 DAVProperties::GETETAG,
189 cppu::UnoType<OUString>::get(),
190 beans::PropertyAttribute::BOUND
191 | beans::PropertyAttribute::READONLY ) );
193 m_pProps->insert(
194 beans::Property(
195 DAVProperties::GETLASTMODIFIED,
197 cppu::UnoType<OUString>::get(),
198 beans::PropertyAttribute::BOUND
199 | beans::PropertyAttribute::READONLY ) );
201 m_pProps->insert(
202 beans::Property(
203 DAVProperties::LOCKDISCOVERY,
205 cppu::UnoType<uno::Sequence< ucb::Lock >>::get(),
206 beans::PropertyAttribute::BOUND
207 | beans::PropertyAttribute::READONLY ) );
209 m_pProps->insert(
210 beans::Property(
211 DAVProperties::RESOURCETYPE,
213 cppu::UnoType<OUString>::get(),
214 beans::PropertyAttribute::BOUND
215 | beans::PropertyAttribute::READONLY ) );
217 m_pProps->insert(
218 beans::Property(
219 DAVProperties::SUPPORTEDLOCK,
221 cppu::UnoType<uno::Sequence< ucb::LockEntry >>::get(),
222 beans::PropertyAttribute::BOUND
223 | beans::PropertyAttribute::READONLY ) );
225 m_pProps->insert(
226 beans::Property(
227 DAVProperties::EXECUTABLE,
229 cppu::UnoType<OUString>::get(),
230 beans::PropertyAttribute::BOUND ) );
235 // Lookup property.
238 beans::Property aProp;
239 aProp.Name = rPropName;
240 const PropertyMap::const_iterator it = m_pProps->find( aProp );
241 if ( it != m_pProps->end() )
243 rProp = *it;
245 else
247 if ( bStrict )
248 return false;
250 // All unknown props are treated as:
251 rProp = beans::Property(
252 rPropName,
253 - 1,
254 cppu::UnoType<OUString>::get(),
255 beans::PropertyAttribute::BOUND );
258 return true;
262 // Content implementation.
265 // virtual
266 uno::Sequence< beans::Property > Content::getProperties(
267 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
269 bool bTransient;
270 std::unique_ptr< DAVResourceAccess > xResAccess;
271 std::unique_ptr< ContentProperties > xCachedProps;
272 rtl::Reference< ContentProvider > xProvider;
275 osl::Guard< osl::Mutex > aGuard( m_aMutex );
277 bTransient = m_bTransient;
278 xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
279 if ( m_xCachedProps.get() )
280 xCachedProps.reset(
281 new ContentProperties( *m_xCachedProps.get() ) );
282 xProvider.set( m_pProvider );
285 std::set< OUString > aPropSet;
287 // No server access for just created (not yet committed) objects.
288 // Only a minimal set of properties supported at this stage.
289 if ( !bTransient )
291 // Obtain all properties supported for this resource from server.
294 std::vector< DAVResourceInfo > props;
295 xResAccess->PROPFIND( DAVZERO, props, xEnv );
297 // Note: vector always contains exactly one resource info, because
298 // we used a depth of DAVZERO for PROPFIND.
299 aPropSet.insert( (*props.begin()).properties.begin(),
300 (*props.begin()).properties.end() );
302 catch ( DAVException const & )
307 // Add DAV properties, map DAV properties to UCB properties.
308 bool bHasCreationDate = false; // creationdate <-> DateCreated
309 bool bHasGetLastModified = false; // getlastmodified <-> DateModified
310 bool bHasGetContentType = false; // getcontenttype <-> MediaType
311 bool bHasGetContentLength = false; // getcontentlength <-> Size
313 bool bHasContentType = false;
314 bool bHasIsDocument = false;
315 bool bHasIsFolder = false;
316 bool bHasTitle = false;
317 bool bHasBaseURI = false;
318 bool bHasDateCreated = false;
319 bool bHasDateModified = false;
320 bool bHasMediaType = false;
321 bool bHasSize = false;
322 bool bHasCreatableInfos = false;
325 for ( const auto& rProp : aPropSet )
327 if ( !bHasCreationDate &&
328 ( rProp == DAVProperties::CREATIONDATE ) )
330 bHasCreationDate = true;
332 else if ( !bHasGetLastModified &&
333 ( rProp == DAVProperties::GETLASTMODIFIED ) )
335 bHasGetLastModified = true;
337 else if ( !bHasGetContentType &&
338 ( rProp == DAVProperties::GETCONTENTTYPE ) )
340 bHasGetContentType = true;
342 else if ( !bHasGetContentLength &&
343 ( rProp == DAVProperties::GETCONTENTLENGTH ) )
345 bHasGetContentLength = true;
347 else if ( !bHasContentType && rProp == "ContentType" )
349 bHasContentType = true;
351 else if ( !bHasIsDocument && rProp == "IsDocument" )
353 bHasIsDocument = true;
355 else if ( !bHasIsFolder && rProp == "IsFolder" )
357 bHasIsFolder = true;
359 else if ( !bHasTitle && rProp == "Title" )
361 bHasTitle = true;
363 else if ( !bHasBaseURI && rProp == "BaseURI" )
365 bHasBaseURI = true;
367 else if ( !bHasDateCreated && rProp == "DateCreated" )
369 bHasDateCreated = true;
371 else if ( !bHasDateModified && rProp == "DateModified" )
373 bHasDateModified = true;
375 else if ( !bHasMediaType && rProp == "MediaType" )
377 bHasMediaType = true;
379 else if ( !bHasSize && rProp == "Size" )
381 bHasSize = true;
383 else if ( !bHasCreatableInfos && rProp == "CreatableContentsInfo" )
385 bHasCreatableInfos = true;
390 // Add mandatory properties.
391 if ( !bHasContentType )
392 aPropSet.insert(
393 OUString( "ContentType" ) );
395 if ( !bHasIsDocument )
396 aPropSet.insert(
397 OUString( "IsDocument" ) );
399 if ( !bHasIsFolder )
400 aPropSet.insert(
401 OUString( "IsFolder" ) );
403 if ( !bHasTitle )
405 // Always present since it can be calculated from content's URI.
406 aPropSet.insert(
407 OUString( "Title" ) );
410 // Add optional properties.
412 if ( !bHasBaseURI )
414 // Always present since it can be calculated from content's URI.
415 aPropSet.insert(
416 OUString( "BaseURI" ) );
419 if ( !bHasDateCreated && bHasCreationDate )
420 aPropSet.insert(
421 OUString( "DateCreated" ) );
423 if ( !bHasDateModified && bHasGetLastModified )
424 aPropSet.insert(
425 OUString( "DateModified" ) );
427 if ( !bHasMediaType && bHasGetContentType )
428 aPropSet.insert(
429 OUString( "MediaType" ) );
431 if ( !bHasSize && bHasGetContentLength )
432 aPropSet.insert(
433 OUString( "Size" ) );
435 if ( !bHasCreatableInfos )
436 aPropSet.insert(
437 OUString(
438 "CreatableContentsInfo" ) );
440 // Add cached properties, if present and still missing.
441 if ( xCachedProps.get() )
443 const std::unique_ptr< PropertyValueMap > & xProps
444 = xCachedProps->getProperties();
446 for ( const auto& rEntry : *xProps )
447 aPropSet.insert( rEntry.first );
450 // std::set -> uno::Sequence
451 sal_Int32 nCount = aPropSet.size();
452 uno::Sequence< beans::Property > aProperties( nCount );
454 beans::Property aProp;
455 sal_Int32 n = 0;
457 for ( const auto& rProp : aPropSet )
459 xProvider->getProperty( rProp, aProp );
460 aProperties[ n++ ] = aProp;
463 return aProperties;
467 // virtual
468 uno::Sequence< ucb::CommandInfo > Content::getCommands(
469 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
471 osl::Guard< osl::Mutex > aGuard( m_aMutex );
473 uno::Sequence< ucb::CommandInfo > aCmdInfo( 10 );
476 // Mandatory commands
479 aCmdInfo[ 0 ] =
480 ucb::CommandInfo(
481 "getCommandInfo",
483 cppu::UnoType<void>::get() );
484 aCmdInfo[ 1 ] =
485 ucb::CommandInfo(
486 "getPropertySetInfo",
488 cppu::UnoType<void>::get() );
489 aCmdInfo[ 2 ] =
490 ucb::CommandInfo(
491 "getPropertyValues",
493 cppu::UnoType<uno::Sequence< beans::Property >>::get());
494 aCmdInfo[ 3 ] =
495 ucb::CommandInfo(
496 "setPropertyValues",
498 cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get());
501 // Optional standard commands
504 aCmdInfo[ 4 ] =
505 ucb::CommandInfo(
506 "delete",
508 cppu::UnoType<bool>::get() );
509 aCmdInfo[ 5 ] =
510 ucb::CommandInfo(
511 "insert",
513 cppu::UnoType<ucb::InsertCommandArgument>::get() );
514 aCmdInfo[ 6 ] =
515 ucb::CommandInfo(
516 "open",
518 cppu::UnoType<ucb::OpenCommandArgument2>::get() );
521 // New commands
524 aCmdInfo[ 7 ] =
525 ucb::CommandInfo(
526 "post",
528 cppu::UnoType<ucb::PostCommandArgument2>::get() );
529 aCmdInfo[ 8 ] =
530 ucb::CommandInfo(
531 "addProperty",
533 cppu::UnoType<ucb::PropertyCommandArgument>::get() );
534 aCmdInfo[ 9 ] =
535 ucb::CommandInfo(
536 "removeProperty",
538 cppu::UnoType<OUString>::get() );
540 bool bFolder = false;
544 bFolder = isFolder( xEnv );
546 catch ( uno::Exception const & )
548 return aCmdInfo;
551 bool bSupportsLocking = supportsExclusiveWriteLock( xEnv );
553 sal_Int32 nPos = aCmdInfo.getLength();
554 sal_Int32 nMoreCmds = ( bFolder ? 2 : 0 ) + ( bSupportsLocking ? 2 : 0 );
555 if ( nMoreCmds )
556 aCmdInfo.realloc( nPos + nMoreCmds );
557 else
558 return aCmdInfo;
560 if ( bFolder )
563 // Optional standard commands
566 aCmdInfo[ nPos ] =
567 ucb::CommandInfo(
568 "transfer",
570 cppu::UnoType<ucb::TransferInfo>::get() );
571 nPos++;
572 aCmdInfo[ nPos ] =
573 ucb::CommandInfo(
574 "createNewContent",
576 cppu::UnoType<ucb::ContentInfo>::get() );
577 nPos++;
579 else
581 // no document-only commands at the moment.
584 if ( bSupportsLocking )
586 aCmdInfo[ nPos ] =
587 ucb::CommandInfo(
588 "lock",
590 cppu::UnoType<void>::get() );
591 nPos++;
592 aCmdInfo[ nPos ] =
593 ucb::CommandInfo(
594 "unlock",
596 cppu::UnoType<void>::get() );
597 nPos++;
599 return aCmdInfo;
602 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */