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 : getCppuBooleanType(),
93 : beans::PropertyAttribute::BOUND
94 0 : | beans::PropertyAttribute::READONLY ) );
95 :
96 : m_pProps->insert(
97 : beans::Property(
98 : OUString( "IsFolder" ),
99 : -1,
100 0 : getCppuBooleanType(),
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 : getCppuType( static_cast<
159 0 : const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
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 : getCppuType( static_cast<
225 0 : const uno::Sequence< ucb::Lock > * >( 0 ) ),
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 : getCppuType( static_cast<
242 0 : const uno::Sequence< ucb::Link > * >( 0 ) ),
243 0 : beans::PropertyAttribute::BOUND ) );
244 :
245 : m_pProps->insert(
246 : beans::Property(
247 : DAVProperties::SUPPORTEDLOCK,
248 : -1,
249 : getCppuType( static_cast<
250 : const uno::Sequence<
251 0 : ucb::LockEntry > * >( 0 ) ),
252 : beans::PropertyAttribute::BOUND
253 0 : | beans::PropertyAttribute::READONLY ) );
254 :
255 : m_pProps->insert(
256 : beans::Property(
257 : DAVProperties::EXECUTABLE,
258 : -1,
259 0 : cppu::UnoType<OUString>::get(),
260 0 : beans::PropertyAttribute::BOUND ) );
261 0 : }
262 : }
263 :
264 :
265 : // Lookup property.
266 :
267 :
268 0 : beans::Property aProp;
269 0 : aProp.Name = rPropName;
270 0 : const PropertyMap::const_iterator it = m_pProps->find( aProp );
271 0 : if ( it != m_pProps->end() )
272 : {
273 0 : rProp = (*it);
274 : }
275 : else
276 : {
277 0 : if ( bStrict )
278 0 : return false;
279 :
280 : // All unknown props are treated as:
281 0 : rProp = beans::Property(
282 : rPropName,
283 : - 1,
284 0 : cppu::UnoType<OUString>::get(),
285 0 : beans::PropertyAttribute::BOUND );
286 : }
287 :
288 0 : return true;
289 : }
290 :
291 :
292 :
293 : // Content implementation.
294 :
295 :
296 :
297 : // virtual
298 0 : uno::Sequence< beans::Property > Content::getProperties(
299 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
300 : {
301 : bool bTransient;
302 0 : std::unique_ptr< DAVResourceAccess > xResAccess;
303 0 : std::unique_ptr< ContentProperties > xCachedProps;
304 0 : rtl::Reference< ContentProvider > xProvider;
305 :
306 : {
307 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
308 :
309 0 : bTransient = m_bTransient;
310 0 : xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
311 0 : if ( m_xCachedProps.get() )
312 : xCachedProps.reset(
313 0 : new ContentProperties( *m_xCachedProps.get() ) );
314 0 : xProvider.set( m_pProvider );
315 : }
316 :
317 : typedef std::set< OUString > StringSet;
318 0 : StringSet aPropSet;
319 :
320 : // No server access for just created (not yet committed) objects.
321 : // Only a minimal set of properties supported at this stage.
322 0 : if ( !bTransient )
323 : {
324 : // Obtain all properties supported for this resource from server.
325 : try
326 : {
327 0 : std::vector< DAVResourceInfo > props;
328 0 : xResAccess->PROPFIND( DAVZERO, props, xEnv );
329 :
330 : // Note: vector always contains exactly one resource info, because
331 : // we used a depth of DAVZERO for PROPFIND.
332 0 : aPropSet.insert( (*props.begin()).properties.begin(),
333 0 : (*props.begin()).properties.end() );
334 : }
335 0 : catch ( DAVException const & )
336 : {
337 : }
338 : }
339 :
340 : // Add DAV properties, map DAV properties to UCB properties.
341 0 : bool bHasCreationDate = false; // creationdate <-> DateCreated
342 0 : bool bHasGetLastModified = false; // getlastmodified <-> DateModified
343 0 : bool bHasGetContentType = false; // getcontenttype <-> MediaType
344 0 : bool bHasGetContentLength = false; // getcontentlength <-> Size
345 :
346 0 : bool bHasContentType = false;
347 0 : bool bHasIsDocument = false;
348 0 : bool bHasIsFolder = false;
349 0 : bool bHasTitle = false;
350 0 : bool bHasBaseURI = false;
351 0 : bool bHasDateCreated = false;
352 0 : bool bHasDateModified = false;
353 0 : bool bHasMediaType = false;
354 0 : bool bHasSize = false;
355 0 : bool bHasCreatableInfos = false;
356 :
357 : {
358 0 : std::set< OUString >::const_iterator it = aPropSet.begin();
359 0 : std::set< OUString >::const_iterator end = aPropSet.end();
360 0 : while ( it != end )
361 : {
362 0 : if ( !bHasCreationDate &&
363 0 : ( (*it) == DAVProperties::CREATIONDATE ) )
364 : {
365 0 : bHasCreationDate = true;
366 : }
367 0 : else if ( !bHasGetLastModified &&
368 0 : ( (*it) == DAVProperties::GETLASTMODIFIED ) )
369 : {
370 0 : bHasGetLastModified = true;
371 : }
372 0 : else if ( !bHasGetContentType &&
373 0 : ( (*it) == DAVProperties::GETCONTENTTYPE ) )
374 : {
375 0 : bHasGetContentType = true;
376 : }
377 0 : else if ( !bHasGetContentLength &&
378 0 : ( (*it) == DAVProperties::GETCONTENTLENGTH ) )
379 : {
380 0 : bHasGetContentLength = true;
381 : }
382 0 : else if ( !bHasContentType && (*it) == "ContentType" )
383 : {
384 0 : bHasContentType = true;
385 : }
386 0 : else if ( !bHasIsDocument && (*it) == "IsDocument" )
387 : {
388 0 : bHasIsDocument = true;
389 : }
390 0 : else if ( !bHasIsFolder && (*it) == "IsFolder" )
391 : {
392 0 : bHasIsFolder = true;
393 : }
394 0 : else if ( !bHasTitle && (*it) == "Title" )
395 : {
396 0 : bHasTitle = true;
397 : }
398 0 : else if ( !bHasBaseURI && (*it) == "BaseURI" )
399 : {
400 0 : bHasBaseURI = true;
401 : }
402 0 : else if ( !bHasDateCreated && (*it) == "DateCreated" )
403 : {
404 0 : bHasDateCreated = true;
405 : }
406 0 : else if ( !bHasDateModified && (*it) == "DateModified" )
407 : {
408 0 : bHasDateModified = true;
409 : }
410 0 : else if ( !bHasMediaType && (*it) == "MediaType" )
411 : {
412 0 : bHasMediaType = true;
413 : }
414 0 : else if ( !bHasSize && (*it) == "Size" )
415 : {
416 0 : bHasSize = true;
417 : }
418 0 : else if ( !bHasCreatableInfos && (*it) == "CreatableContentsInfo" )
419 : {
420 0 : bHasCreatableInfos = true;
421 : }
422 0 : ++it;
423 : }
424 : }
425 :
426 : // Add mandatory properties.
427 0 : if ( !bHasContentType )
428 : aPropSet.insert(
429 0 : OUString( "ContentType" ) );
430 :
431 0 : if ( !bHasIsDocument )
432 : aPropSet.insert(
433 0 : OUString( "IsDocument" ) );
434 :
435 0 : if ( !bHasIsFolder )
436 : aPropSet.insert(
437 0 : OUString( "IsFolder" ) );
438 :
439 0 : if ( !bHasTitle )
440 : {
441 : // Always present since it can be calculated from content's URI.
442 : aPropSet.insert(
443 0 : OUString( "Title" ) );
444 : }
445 :
446 : // Add optional properties.
447 :
448 0 : if ( !bHasBaseURI )
449 : {
450 : // Always present since it can be calculated from content's URI.
451 : aPropSet.insert(
452 0 : OUString( "BaseURI" ) );
453 : }
454 :
455 0 : if ( !bHasDateCreated && bHasCreationDate )
456 : aPropSet.insert(
457 0 : OUString( "DateCreated" ) );
458 :
459 0 : if ( !bHasDateModified && bHasGetLastModified )
460 : aPropSet.insert(
461 0 : OUString( "DateModified" ) );
462 :
463 0 : if ( !bHasMediaType && bHasGetContentType )
464 : aPropSet.insert(
465 0 : OUString( "MediaType" ) );
466 :
467 0 : if ( !bHasSize && bHasGetContentLength )
468 : aPropSet.insert(
469 0 : OUString( "Size" ) );
470 :
471 0 : if ( !bHasCreatableInfos )
472 : aPropSet.insert(
473 : OUString(
474 0 : "CreatableContentsInfo" ) );
475 :
476 : // Add cached properties, if present and still missing.
477 0 : if ( xCachedProps.get() )
478 : {
479 : const std::set< OUString >::const_iterator set_end
480 0 : = aPropSet.end();
481 :
482 : const std::unique_ptr< PropertyValueMap > & xProps
483 0 : = xCachedProps->getProperties();
484 :
485 0 : PropertyValueMap::const_iterator map_it = xProps->begin();
486 0 : const PropertyValueMap::const_iterator map_end = xProps->end();
487 :
488 0 : while ( map_it != map_end )
489 : {
490 0 : if ( aPropSet.find( (*map_it).first ) == set_end )
491 0 : aPropSet.insert( (*map_it).first );
492 :
493 0 : ++map_it;
494 : }
495 : }
496 :
497 : // std::set -> uno::Sequence
498 0 : sal_Int32 nCount = aPropSet.size();
499 0 : uno::Sequence< beans::Property > aProperties( nCount );
500 :
501 0 : std::set< OUString >::const_iterator it = aPropSet.begin();
502 0 : beans::Property aProp;
503 :
504 0 : for ( sal_Int32 n = 0; n < nCount; ++n, ++it )
505 : {
506 0 : xProvider->getProperty( (*it), aProp );
507 0 : aProperties[ n ] = aProp;
508 : }
509 :
510 0 : return aProperties;
511 : }
512 :
513 :
514 : // virtual
515 0 : uno::Sequence< ucb::CommandInfo > Content::getCommands(
516 : const uno::Reference< ucb::XCommandEnvironment > & xEnv )
517 : {
518 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
519 :
520 0 : uno::Sequence< ucb::CommandInfo > aCmdInfo( 10 );
521 :
522 :
523 : // Mandatory commands
524 :
525 :
526 0 : aCmdInfo[ 0 ] =
527 : ucb::CommandInfo(
528 : OUString( "getCommandInfo" ),
529 : -1,
530 0 : getCppuVoidType() );
531 0 : aCmdInfo[ 1 ] =
532 : ucb::CommandInfo(
533 : OUString( "getPropertySetInfo" ),
534 : -1,
535 0 : getCppuVoidType() );
536 0 : aCmdInfo[ 2 ] =
537 : ucb::CommandInfo(
538 : OUString( "getPropertyValues" ),
539 : -1,
540 : getCppuType( static_cast<
541 0 : uno::Sequence< beans::Property > * >( 0 ) ) );
542 0 : aCmdInfo[ 3 ] =
543 : ucb::CommandInfo(
544 : OUString( "setPropertyValues" ),
545 : -1,
546 : getCppuType( static_cast<
547 0 : uno::Sequence< beans::PropertyValue > * >( 0 ) ) );
548 :
549 :
550 : // Optional standard commands
551 :
552 :
553 0 : aCmdInfo[ 4 ] =
554 : ucb::CommandInfo(
555 : OUString( "delete" ),
556 : -1,
557 0 : getCppuBooleanType() );
558 0 : aCmdInfo[ 5 ] =
559 : ucb::CommandInfo(
560 : OUString( "insert" ),
561 : -1,
562 0 : cppu::UnoType<ucb::InsertCommandArgument>::get() );
563 0 : aCmdInfo[ 6 ] =
564 : ucb::CommandInfo(
565 : OUString( "open" ),
566 : -1,
567 0 : cppu::UnoType<ucb::OpenCommandArgument2>::get() );
568 :
569 :
570 : // New commands
571 :
572 :
573 0 : aCmdInfo[ 7 ] =
574 : ucb::CommandInfo(
575 : OUString( "post" ),
576 : -1,
577 0 : cppu::UnoType<ucb::PostCommandArgument2>::get() );
578 0 : aCmdInfo[ 8 ] =
579 : ucb::CommandInfo(
580 : OUString( "addProperty" ),
581 : -1,
582 0 : cppu::UnoType<ucb::PropertyCommandArgument>::get() );
583 0 : aCmdInfo[ 9 ] =
584 : ucb::CommandInfo(
585 : OUString( "removeProperty" ),
586 : -1,
587 0 : cppu::UnoType<rtl::OUString>::get() );
588 :
589 0 : bool bFolder = false;
590 :
591 : try
592 : {
593 0 : bFolder = isFolder( xEnv );
594 : }
595 0 : catch ( uno::Exception const & )
596 : {
597 0 : return aCmdInfo;
598 : }
599 :
600 0 : bool bSupportsLocking = supportsExclusiveWriteLock( xEnv );
601 :
602 0 : sal_Int32 nPos = aCmdInfo.getLength();
603 0 : sal_Int32 nMoreCmds = ( bFolder ? 2 : 0 ) + ( bSupportsLocking ? 2 : 0 );
604 0 : if ( nMoreCmds )
605 0 : aCmdInfo.realloc( nPos + nMoreCmds );
606 : else
607 0 : return aCmdInfo;
608 :
609 0 : if ( bFolder )
610 : {
611 :
612 : // Optional standard commands
613 :
614 :
615 0 : aCmdInfo[ nPos ] =
616 : ucb::CommandInfo(
617 : OUString( "transfer" ),
618 : -1,
619 0 : cppu::UnoType<ucb::TransferInfo>::get() );
620 0 : nPos++;
621 0 : aCmdInfo[ nPos ] =
622 : ucb::CommandInfo(
623 : OUString(
624 : "createNewContent" ),
625 : -1,
626 0 : cppu::UnoType<ucb::ContentInfo>::get() );
627 0 : nPos++;
628 : }
629 : else
630 : {
631 : // no document-only commands at the moment.
632 : }
633 :
634 0 : if ( bSupportsLocking )
635 : {
636 0 : aCmdInfo[ nPos ] =
637 : ucb::CommandInfo(
638 : OUString( "lock" ),
639 : -1,
640 0 : getCppuVoidType() );
641 0 : nPos++;
642 0 : aCmdInfo[ nPos ] =
643 : ucb::CommandInfo(
644 : OUString( "unlock" ),
645 : -1,
646 0 : getCppuVoidType() );
647 0 : nPos++;
648 : }
649 0 : return aCmdInfo;
650 : }
651 :
652 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|