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