Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
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.
15 : *
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).
21 : *
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.
26 : *
27 : ************************************************************************/
28 :
29 : /**************************************************************************
30 : TODO
31 : **************************************************************************
32 :
33 : *************************************************************************/
34 :
35 : #include <set>
36 : #include <com/sun/star/beans/Property.hpp>
37 : #include <com/sun/star/beans/PropertyAttribute.hpp>
38 : #include <com/sun/star/beans/PropertyValue.hpp>
39 : #include <com/sun/star/ucb/CommandInfo.hpp>
40 : #include <com/sun/star/ucb/ContentInfo.hpp>
41 : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
42 : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
43 : #include <com/sun/star/ucb/PostCommandArgument2.hpp>
44 : #include <com/sun/star/ucb/PropertyCommandArgument.hpp>
45 : #include <com/sun/star/ucb/TransferInfo.hpp>
46 : #include <com/sun/star/uno/Sequence.hxx>
47 : #include <com/sun/star/util/DateTime.hpp>
48 : #include <com/sun/star/ucb/Link.hpp>
49 : #include <com/sun/star/ucb/Lock.hpp>
50 : #include <com/sun/star/ucb/LockEntry.hpp>
51 : #include "webdavcontent.hxx"
52 : #include "webdavprovider.hxx"
53 : #include "DAVSession.hxx"
54 : #include "ContentProperties.hxx"
55 :
56 : using namespace com::sun::star;
57 : using namespace webdav_ucp;
58 :
59 :
60 :
61 : // ContentProvider implementation.
62 :
63 :
64 :
65 0 : bool ContentProvider::getProperty(
66 : const OUString & rPropName, beans::Property & rProp, bool bStrict )
67 : {
68 0 : if ( !m_pProps )
69 : {
70 0 : osl::MutexGuard aGuard( m_aMutex );
71 0 : if ( !m_pProps )
72 : {
73 0 : m_pProps = new PropertyMap;
74 :
75 :
76 : // Fill map of known properties...
77 :
78 :
79 : // Mandatory UCB properties.
80 : m_pProps->insert(
81 : beans::Property(
82 : OUString( "ContentType" ),
83 : -1,
84 0 : cppu::UnoType<OUString>::get(),
85 : beans::PropertyAttribute::BOUND
86 0 : | beans::PropertyAttribute::READONLY ) );
87 :
88 : m_pProps->insert(
89 : beans::Property(
90 : OUString( "IsDocument" ),
91 : -1,
92 0 : cppu::UnoType<bool>::get(),
93 : beans::PropertyAttribute::BOUND
94 0 : | beans::PropertyAttribute::READONLY ) );
95 :
96 : m_pProps->insert(
97 : beans::Property(
98 : OUString( "IsFolder" ),
99 : -1,
100 0 : cppu::UnoType<bool>::get(),
101 : beans::PropertyAttribute::BOUND
102 0 : | beans::PropertyAttribute::READONLY ) );
103 :
104 : m_pProps->insert(
105 : beans::Property(
106 : OUString( "Title" ),
107 : -1,
108 0 : cppu::UnoType<OUString>::get(),
109 0 : beans::PropertyAttribute::BOUND ) );
110 :
111 : // Optional UCB properties.
112 :
113 : m_pProps->insert(
114 : beans::Property(
115 : OUString( "DateCreated" ),
116 : -1,
117 0 : cppu::UnoType<util::DateTime>::get(),
118 : beans::PropertyAttribute::BOUND
119 0 : | beans::PropertyAttribute::READONLY ) );
120 :
121 : m_pProps->insert(
122 : beans::Property(
123 : OUString( "DateModified" ),
124 : -1,
125 0 : cppu::UnoType<util::DateTime>::get(),
126 : beans::PropertyAttribute::BOUND
127 0 : | beans::PropertyAttribute::READONLY ) );
128 :
129 : m_pProps->insert(
130 : beans::Property(
131 : OUString( "MediaType" ),
132 : -1,
133 0 : cppu::UnoType<OUString>::get(),
134 : beans::PropertyAttribute::BOUND
135 0 : | beans::PropertyAttribute::READONLY ) );
136 :
137 : m_pProps->insert(
138 : beans::Property(
139 : OUString( "Size" ),
140 : -1,
141 0 : cppu::UnoType<sal_Int64>::get(),
142 : beans::PropertyAttribute::BOUND
143 0 : | beans::PropertyAttribute::READONLY ) );
144 :
145 : m_pProps->insert(
146 : beans::Property(
147 : OUString( "BaseURI" ),
148 : -1,
149 0 : cppu::UnoType<OUString>::get(),
150 : beans::PropertyAttribute::BOUND
151 0 : | beans::PropertyAttribute::READONLY ) );
152 :
153 : m_pProps->insert(
154 : beans::Property(
155 : OUString(
156 : "CreatableContentsInfo" ),
157 : -1,
158 : cppu::UnoType<
159 0 : uno::Sequence< ucb::ContentInfo >>::get(),
160 : beans::PropertyAttribute::BOUND
161 0 : | beans::PropertyAttribute::READONLY ) );
162 :
163 : // Standard DAV properties.
164 :
165 : m_pProps->insert(
166 : beans::Property(
167 : DAVProperties::CREATIONDATE,
168 : -1,
169 0 : cppu::UnoType<OUString>::get(),
170 : beans::PropertyAttribute::BOUND
171 0 : | beans::PropertyAttribute::READONLY ) );
172 :
173 : m_pProps->insert(
174 : beans::Property(
175 : DAVProperties::DISPLAYNAME,
176 : -1,
177 0 : cppu::UnoType<OUString>::get(),
178 0 : beans::PropertyAttribute::BOUND ) );
179 :
180 : m_pProps->insert(
181 : beans::Property(
182 : DAVProperties::GETCONTENTLANGUAGE,
183 : -1,
184 0 : cppu::UnoType<OUString>::get(),
185 : beans::PropertyAttribute::BOUND
186 0 : | beans::PropertyAttribute::READONLY ) );
187 :
188 : m_pProps->insert(
189 : beans::Property(
190 : DAVProperties::GETCONTENTLENGTH,
191 : -1,
192 0 : cppu::UnoType<OUString>::get(),
193 : beans::PropertyAttribute::BOUND
194 0 : | beans::PropertyAttribute::READONLY ) );
195 :
196 : m_pProps->insert(
197 : beans::Property(
198 : DAVProperties::GETCONTENTTYPE ,
199 : -1,
200 0 : cppu::UnoType<OUString>::get(),
201 : beans::PropertyAttribute::BOUND
202 0 : | beans::PropertyAttribute::READONLY ) );
203 :
204 : m_pProps->insert(
205 : beans::Property(
206 : DAVProperties::GETETAG,
207 : -1,
208 0 : cppu::UnoType<OUString>::get(),
209 : beans::PropertyAttribute::BOUND
210 0 : | beans::PropertyAttribute::READONLY ) );
211 :
212 : m_pProps->insert(
213 : beans::Property(
214 : DAVProperties::GETLASTMODIFIED,
215 : -1,
216 0 : cppu::UnoType<OUString>::get(),
217 : beans::PropertyAttribute::BOUND
218 0 : | beans::PropertyAttribute::READONLY ) );
219 :
220 : m_pProps->insert(
221 : beans::Property(
222 : DAVProperties::LOCKDISCOVERY,
223 : -1,
224 : cppu::UnoType<
225 0 : uno::Sequence< ucb::Lock >>::get(),
226 : beans::PropertyAttribute::BOUND
227 0 : | beans::PropertyAttribute::READONLY ) );
228 :
229 : m_pProps->insert(
230 : beans::Property(
231 : DAVProperties::RESOURCETYPE,
232 : -1,
233 0 : cppu::UnoType<OUString>::get(),
234 : beans::PropertyAttribute::BOUND
235 0 : | beans::PropertyAttribute::READONLY ) );
236 :
237 : m_pProps->insert(
238 : beans::Property(
239 : DAVProperties::SOURCE,
240 : -1,
241 0 : cppu::UnoType<uno::Sequence< ucb::Link >>::get(),
242 0 : beans::PropertyAttribute::BOUND ) );
243 :
244 : m_pProps->insert(
245 : beans::Property(
246 : DAVProperties::SUPPORTEDLOCK,
247 : -1,
248 0 : cppu::UnoType<uno::Sequence< ucb::LockEntry >>::get(),
249 : beans::PropertyAttribute::BOUND
250 0 : | beans::PropertyAttribute::READONLY ) );
251 :
252 : m_pProps->insert(
253 : beans::Property(
254 : DAVProperties::EXECUTABLE,
255 : -1,
256 0 : cppu::UnoType<OUString>::get(),
257 0 : beans::PropertyAttribute::BOUND ) );
258 0 : }
259 : }
260 :
261 :
262 : // Lookup property.
263 :
264 :
265 0 : beans::Property aProp;
266 0 : aProp.Name = rPropName;
267 0 : const PropertyMap::const_iterator it = m_pProps->find( aProp );
268 0 : if ( it != m_pProps->end() )
269 : {
270 0 : rProp = (*it);
271 : }
272 : else
273 : {
274 0 : if ( bStrict )
275 0 : return false;
276 :
277 : // All unknown props are treated as:
278 0 : rProp = beans::Property(
279 : rPropName,
280 : - 1,
281 0 : cppu::UnoType<OUString>::get(),
282 0 : beans::PropertyAttribute::BOUND );
283 : }
284 :
285 0 : return true;
286 : }
287 :
288 :
289 :
290 : // Content implementation.
291 :
292 :
293 :
294 : // virtual
295 0 : uno::Sequence< beans::Property > Content::getProperties(
296 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
297 : {
298 : bool bTransient;
299 0 : std::unique_ptr< DAVResourceAccess > xResAccess;
300 0 : std::unique_ptr< ContentProperties > xCachedProps;
301 0 : rtl::Reference< ContentProvider > xProvider;
302 :
303 : {
304 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
305 :
306 0 : bTransient = m_bTransient;
307 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
308 0 : if ( m_xCachedProps.get() )
309 : xCachedProps.reset(
310 0 : new ContentProperties( *m_xCachedProps.get() ) );
311 0 : xProvider.set( m_pProvider );
312 : }
313 :
314 : typedef std::set< OUString > StringSet;
315 0 : StringSet aPropSet;
316 :
317 : // No server access for just created (not yet committed) objects.
318 : // Only a minimal set of properties supported at this stage.
319 0 : if ( !bTransient )
320 : {
321 : // Obtain all properties supported for this resource from server.
322 : try
323 : {
324 0 : std::vector< DAVResourceInfo > props;
325 0 : xResAccess->PROPFIND( DAVZERO, props, xEnv );
326 :
327 : // Note: vector always contains exactly one resource info, because
328 : // we used a depth of DAVZERO for PROPFIND.
329 0 : aPropSet.insert( (*props.begin()).properties.begin(),
330 0 : (*props.begin()).properties.end() );
331 : }
332 0 : catch ( DAVException const & )
333 : {
334 : }
335 : }
336 :
337 : // Add DAV properties, map DAV properties to UCB properties.
338 0 : bool bHasCreationDate = false; // creationdate <-> DateCreated
339 0 : bool bHasGetLastModified = false; // getlastmodified <-> DateModified
340 0 : bool bHasGetContentType = false; // getcontenttype <-> MediaType
341 0 : bool bHasGetContentLength = false; // getcontentlength <-> Size
342 :
343 0 : bool bHasContentType = false;
344 0 : bool bHasIsDocument = false;
345 0 : bool bHasIsFolder = false;
346 0 : bool bHasTitle = false;
347 0 : bool bHasBaseURI = false;
348 0 : bool bHasDateCreated = false;
349 0 : bool bHasDateModified = false;
350 0 : bool bHasMediaType = false;
351 0 : bool bHasSize = false;
352 0 : bool bHasCreatableInfos = false;
353 :
354 : {
355 0 : std::set< OUString >::const_iterator it = aPropSet.begin();
356 0 : std::set< OUString >::const_iterator end = aPropSet.end();
357 0 : while ( it != end )
358 : {
359 0 : if ( !bHasCreationDate &&
360 0 : ( (*it) == DAVProperties::CREATIONDATE ) )
361 : {
362 0 : bHasCreationDate = true;
363 : }
364 0 : else if ( !bHasGetLastModified &&
365 0 : ( (*it) == DAVProperties::GETLASTMODIFIED ) )
366 : {
367 0 : bHasGetLastModified = true;
368 : }
369 0 : else if ( !bHasGetContentType &&
370 0 : ( (*it) == DAVProperties::GETCONTENTTYPE ) )
371 : {
372 0 : bHasGetContentType = true;
373 : }
374 0 : else if ( !bHasGetContentLength &&
375 0 : ( (*it) == DAVProperties::GETCONTENTLENGTH ) )
376 : {
377 0 : bHasGetContentLength = true;
378 : }
379 0 : else if ( !bHasContentType && (*it) == "ContentType" )
380 : {
381 0 : bHasContentType = true;
382 : }
383 0 : else if ( !bHasIsDocument && (*it) == "IsDocument" )
384 : {
385 0 : bHasIsDocument = true;
386 : }
387 0 : else if ( !bHasIsFolder && (*it) == "IsFolder" )
388 : {
389 0 : bHasIsFolder = true;
390 : }
391 0 : else if ( !bHasTitle && (*it) == "Title" )
392 : {
393 0 : bHasTitle = true;
394 : }
395 0 : else if ( !bHasBaseURI && (*it) == "BaseURI" )
396 : {
397 0 : bHasBaseURI = true;
398 : }
399 0 : else if ( !bHasDateCreated && (*it) == "DateCreated" )
400 : {
401 0 : bHasDateCreated = true;
402 : }
403 0 : else if ( !bHasDateModified && (*it) == "DateModified" )
404 : {
405 0 : bHasDateModified = true;
406 : }
407 0 : else if ( !bHasMediaType && (*it) == "MediaType" )
408 : {
409 0 : bHasMediaType = true;
410 : }
411 0 : else if ( !bHasSize && (*it) == "Size" )
412 : {
413 0 : bHasSize = true;
414 : }
415 0 : else if ( !bHasCreatableInfos && (*it) == "CreatableContentsInfo" )
416 : {
417 0 : bHasCreatableInfos = true;
418 : }
419 0 : ++it;
420 : }
421 : }
422 :
423 : // Add mandatory properties.
424 0 : if ( !bHasContentType )
425 : aPropSet.insert(
426 0 : OUString( "ContentType" ) );
427 :
428 0 : if ( !bHasIsDocument )
429 : aPropSet.insert(
430 0 : OUString( "IsDocument" ) );
431 :
432 0 : if ( !bHasIsFolder )
433 : aPropSet.insert(
434 0 : OUString( "IsFolder" ) );
435 :
436 0 : if ( !bHasTitle )
437 : {
438 : // Always present since it can be calculated from content's URI.
439 : aPropSet.insert(
440 0 : OUString( "Title" ) );
441 : }
442 :
443 : // Add optional properties.
444 :
445 0 : if ( !bHasBaseURI )
446 : {
447 : // Always present since it can be calculated from content's URI.
448 : aPropSet.insert(
449 0 : OUString( "BaseURI" ) );
450 : }
451 :
452 0 : if ( !bHasDateCreated && bHasCreationDate )
453 : aPropSet.insert(
454 0 : OUString( "DateCreated" ) );
455 :
456 0 : if ( !bHasDateModified && bHasGetLastModified )
457 : aPropSet.insert(
458 0 : OUString( "DateModified" ) );
459 :
460 0 : if ( !bHasMediaType && bHasGetContentType )
461 : aPropSet.insert(
462 0 : OUString( "MediaType" ) );
463 :
464 0 : if ( !bHasSize && bHasGetContentLength )
465 : aPropSet.insert(
466 0 : OUString( "Size" ) );
467 :
468 0 : if ( !bHasCreatableInfos )
469 : aPropSet.insert(
470 : OUString(
471 0 : "CreatableContentsInfo" ) );
472 :
473 : // Add cached properties, if present and still missing.
474 0 : if ( xCachedProps.get() )
475 : {
476 : const std::set< OUString >::const_iterator set_end
477 0 : = aPropSet.end();
478 :
479 : const std::unique_ptr< PropertyValueMap > & xProps
480 0 : = xCachedProps->getProperties();
481 :
482 0 : PropertyValueMap::const_iterator map_it = xProps->begin();
483 0 : const PropertyValueMap::const_iterator map_end = xProps->end();
484 :
485 0 : while ( map_it != map_end )
486 : {
487 0 : if ( aPropSet.find( (*map_it).first ) == set_end )
488 0 : aPropSet.insert( (*map_it).first );
489 :
490 0 : ++map_it;
491 : }
492 : }
493 :
494 : // std::set -> uno::Sequence
495 0 : sal_Int32 nCount = aPropSet.size();
496 0 : uno::Sequence< beans::Property > aProperties( nCount );
497 :
498 0 : std::set< OUString >::const_iterator it = aPropSet.begin();
499 0 : beans::Property aProp;
500 :
501 0 : for ( sal_Int32 n = 0; n < nCount; ++n, ++it )
502 : {
503 0 : xProvider->getProperty( (*it), aProp );
504 0 : aProperties[ n ] = aProp;
505 : }
506 :
507 0 : return aProperties;
508 : }
509 :
510 :
511 : // virtual
512 0 : uno::Sequence< ucb::CommandInfo > Content::getCommands(
513 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
514 : {
515 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
516 :
517 0 : uno::Sequence< ucb::CommandInfo > aCmdInfo( 10 );
518 :
519 :
520 : // Mandatory commands
521 :
522 :
523 0 : aCmdInfo[ 0 ] =
524 : ucb::CommandInfo(
525 : OUString( "getCommandInfo" ),
526 : -1,
527 0 : cppu::UnoType<void>::get() );
528 0 : aCmdInfo[ 1 ] =
529 : ucb::CommandInfo(
530 : OUString( "getPropertySetInfo" ),
531 : -1,
532 0 : cppu::UnoType<void>::get() );
533 0 : aCmdInfo[ 2 ] =
534 : ucb::CommandInfo(
535 : OUString( "getPropertyValues" ),
536 : -1,
537 0 : cppu::UnoType<uno::Sequence< beans::Property >>::get() );
538 0 : aCmdInfo[ 3 ] =
539 : ucb::CommandInfo(
540 : OUString( "setPropertyValues" ),
541 : -1,
542 0 : cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get() );
543 :
544 :
545 : // Optional standard commands
546 :
547 :
548 0 : aCmdInfo[ 4 ] =
549 : ucb::CommandInfo(
550 : OUString( "delete" ),
551 : -1,
552 0 : cppu::UnoType<bool>::get() );
553 0 : aCmdInfo[ 5 ] =
554 : ucb::CommandInfo(
555 : OUString( "insert" ),
556 : -1,
557 0 : cppu::UnoType<ucb::InsertCommandArgument>::get() );
558 0 : aCmdInfo[ 6 ] =
559 : ucb::CommandInfo(
560 : OUString( "open" ),
561 : -1,
562 0 : cppu::UnoType<ucb::OpenCommandArgument2>::get() );
563 :
564 :
565 : // New commands
566 :
567 :
568 0 : aCmdInfo[ 7 ] =
569 : ucb::CommandInfo(
570 : OUString( "post" ),
571 : -1,
572 0 : cppu::UnoType<ucb::PostCommandArgument2>::get() );
573 0 : aCmdInfo[ 8 ] =
574 : ucb::CommandInfo(
575 : OUString( "addProperty" ),
576 : -1,
577 0 : cppu::UnoType<ucb::PropertyCommandArgument>::get() );
578 0 : aCmdInfo[ 9 ] =
579 : ucb::CommandInfo(
580 : OUString( "removeProperty" ),
581 : -1,
582 0 : cppu::UnoType<rtl::OUString>::get() );
583 :
584 0 : bool bFolder = false;
585 :
586 : try
587 : {
588 0 : bFolder = isFolder( xEnv );
589 : }
590 0 : catch ( uno::Exception const & )
591 : {
592 0 : return aCmdInfo;
593 : }
594 :
595 0 : bool bSupportsLocking = supportsExclusiveWriteLock( xEnv );
596 :
597 0 : sal_Int32 nPos = aCmdInfo.getLength();
598 0 : sal_Int32 nMoreCmds = ( bFolder ? 2 : 0 ) + ( bSupportsLocking ? 2 : 0 );
599 0 : if ( nMoreCmds )
600 0 : aCmdInfo.realloc( nPos + nMoreCmds );
601 : else
602 0 : return aCmdInfo;
603 :
604 0 : if ( bFolder )
605 : {
606 :
607 : // Optional standard commands
608 :
609 :
610 0 : aCmdInfo[ nPos ] =
611 : ucb::CommandInfo(
612 : OUString( "transfer" ),
613 : -1,
614 0 : cppu::UnoType<ucb::TransferInfo>::get() );
615 0 : nPos++;
616 0 : aCmdInfo[ nPos ] =
617 : ucb::CommandInfo(
618 : OUString(
619 : "createNewContent" ),
620 : -1,
621 0 : cppu::UnoType<ucb::ContentInfo>::get() );
622 0 : nPos++;
623 : }
624 : else
625 : {
626 : // no document-only commands at the moment.
627 : }
628 :
629 0 : if ( bSupportsLocking )
630 : {
631 0 : aCmdInfo[ nPos ] =
632 : ucb::CommandInfo(
633 : OUString( "lock" ),
634 : -1,
635 0 : cppu::UnoType<void>::get() );
636 0 : nPos++;
637 0 : aCmdInfo[ nPos ] =
638 : ucb::CommandInfo(
639 : OUString( "unlock" ),
640 : -1,
641 0 : cppu::UnoType<void>::get() );
642 0 : nPos++;
643 : }
644 0 : return aCmdInfo;
645 : }
646 :
647 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|