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