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 /************************************************************************** 32 TODO 33 ************************************************************************** 34 35 *************************************************************************/ 36 #include <osl/diagnose.h> 37 #include <cppuhelper/implbase1.hxx> 38 #include <cppuhelper/exc_hlp.hxx> 39 #include <rtl/ustring.h> 40 #include <rtl/ustring.hxx> 41 #include <com/sun/star/uno/XInterface.hpp> 42 #include <com/sun/star/beans/PropertyState.hpp> 43 #include <com/sun/star/beans/PropertyValue.hpp> 44 #include <com/sun/star/beans/XPropertySet.hpp> 45 #include <com/sun/star/container/XChild.hpp> 46 #include <com/sun/star/beans/XPropertySetInfo.hpp> 47 #include <com/sun/star/io/XActiveDataSink.hpp> 48 #include <com/sun/star/io/XOutputStream.hpp> 49 #include <com/sun/star/io/XSeekable.hpp> 50 #include <com/sun/star/sdbc/XRow.hpp> 51 #include <com/sun/star/task/XInteractionHandler.hpp> 52 #include <com/sun/star/ucb/CommandEnvironment.hpp> 53 #include <com/sun/star/ucb/CommandFailedException.hpp> 54 #include <com/sun/star/ucb/ContentInfoAttribute.hpp> 55 #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp> 56 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 57 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp> 58 #include <com/sun/star/ucb/NameClash.hpp> 59 #include <com/sun/star/ucb/NameClashException.hpp> 60 #include <com/sun/star/ucb/OpenCommandArgument2.hpp> 61 #include <com/sun/star/ucb/OpenMode.hpp> 62 #include <com/sun/star/ucb/TransferInfo.hpp> 63 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp> 64 #include <com/sun/star/ucb/XCommandInfo.hpp> 65 #include <com/sun/star/ucb/XContentAccess.hpp> 66 #include <com/sun/star/ucb/XContentCreator.hpp> 67 #include <com/sun/star/ucb/XDynamicResultSet.hpp> 68 #include <com/sun/star/uno/Any.hxx> 69 #include <com/sun/star/uno/Sequence.hxx> 70 #include <ucbhelper/cancelcommandexecution.hxx> 71 #include <ucbhelper/simplenameclashresolverequest.hxx> 72 #include "ucbcmds.hxx" 73 #include "ucb.hxx" 74 75 using namespace com::sun::star; 76 77 namespace 78 { 79 80 //========================================================================= 81 // 82 // struct TransferCommandContext. 83 // 84 //========================================================================= 85 86 struct TransferCommandContext 87 { 88 uno::Reference< lang::XMultiServiceFactory > xSMgr; 89 uno::Reference< ucb::XCommandProcessor > xProcessor; 90 uno::Reference< ucb::XCommandEnvironment > xEnv; 91 uno::Reference< ucb::XCommandEnvironment > xOrigEnv; 92 ucb::GlobalTransferCommandArgument aArg; 93 94 TransferCommandContext( 95 const uno::Reference< lang::XMultiServiceFactory > & rxSMgr, 96 const uno::Reference< ucb::XCommandProcessor > & rxProcessor, 97 const uno::Reference< ucb::XCommandEnvironment > & rxEnv, 98 const uno::Reference< ucb::XCommandEnvironment > & rxOrigEnv, 99 const ucb::GlobalTransferCommandArgument & rArg ) 100 : xSMgr( rxSMgr ), xProcessor( rxProcessor ), xEnv( rxEnv ), 101 xOrigEnv( rxOrigEnv ), aArg( rArg ) {} 102 }; 103 104 //========================================================================= 105 // 106 // class InteractionHandlerProxy. 107 // 108 //========================================================================= 109 110 class InteractionHandlerProxy : 111 public cppu::WeakImplHelper1< task::XInteractionHandler > 112 { 113 uno::Reference< task::XInteractionHandler > m_xOrig; 114 115 public: 116 InteractionHandlerProxy( 117 const uno::Reference< task::XInteractionHandler > & xOrig ) 118 : m_xOrig( xOrig ) {} 119 120 // XInteractionHandler methods. 121 virtual void SAL_CALL handle( 122 const uno::Reference< task::XInteractionRequest >& Request ) 123 throw ( uno::RuntimeException ); 124 }; 125 126 //========================================================================= 127 // virtual 128 void SAL_CALL InteractionHandlerProxy::handle( 129 const uno::Reference< task::XInteractionRequest >& Request ) 130 throw ( uno::RuntimeException ) 131 { 132 if ( !m_xOrig.is() ) 133 return; 134 135 // Filter unwanted requests by just not handling them. 136 uno::Any aRequest = Request->getRequest(); 137 138 // "transfer" 139 ucb::InteractiveBadTransferURLException aBadTransferURLEx; 140 if ( aRequest >>= aBadTransferURLEx ) 141 { 142 return; 143 } 144 else 145 { 146 // "transfer" 147 ucb::UnsupportedNameClashException aUnsupportedNameClashEx; 148 if ( aRequest >>= aUnsupportedNameClashEx ) 149 { 150 if ( aUnsupportedNameClashEx.NameClash 151 != ucb::NameClash::ERROR ) 152 return; 153 } 154 else 155 { 156 // "insert" 157 ucb::NameClashException aNameClashEx; 158 if ( aRequest >>= aNameClashEx ) 159 { 160 return; 161 } 162 else 163 { 164 // "transfer" 165 ucb::UnsupportedCommandException aUnsupportedCommandEx; 166 if ( aRequest >>= aUnsupportedCommandEx ) 167 { 168 return; 169 } 170 } 171 } 172 } 173 174 // not filtered; let the original handler do the work. 175 m_xOrig->handle( Request ); 176 } 177 178 //========================================================================= 179 // 180 // class ActiveDataSink. 181 // 182 //========================================================================= 183 184 class ActiveDataSink : public cppu::WeakImplHelper1< io::XActiveDataSink > 185 { 186 uno::Reference< io::XInputStream > m_xStream; 187 188 public: 189 // XActiveDataSink methods. 190 virtual void SAL_CALL setInputStream( 191 const uno::Reference< io::XInputStream >& aStream ) 192 throw( uno::RuntimeException ); 193 virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream() 194 throw( uno::RuntimeException ); 195 }; 196 197 //========================================================================= 198 // virtual 199 void SAL_CALL ActiveDataSink::setInputStream( 200 const uno::Reference< io::XInputStream >& aStream ) 201 throw( uno::RuntimeException ) 202 { 203 m_xStream = aStream; 204 } 205 206 //========================================================================= 207 // virtual 208 uno::Reference< io::XInputStream > SAL_CALL ActiveDataSink::getInputStream() 209 throw( uno::RuntimeException ) 210 { 211 return m_xStream; 212 } 213 214 //========================================================================= 215 // 216 // class CommandProcessorInfo. 217 // 218 //========================================================================= 219 220 class CommandProcessorInfo : 221 public cppu::WeakImplHelper1< ucb::XCommandInfo > 222 { 223 uno::Sequence< ucb::CommandInfo > * m_pInfo; 224 225 public: 226 CommandProcessorInfo(); 227 virtual ~CommandProcessorInfo(); 228 229 // XCommandInfo methods 230 virtual uno::Sequence< ucb::CommandInfo > SAL_CALL getCommands() 231 throw( uno::RuntimeException ); 232 virtual ucb::CommandInfo SAL_CALL 233 getCommandInfoByName( const rtl::OUString& Name ) 234 throw( ucb::UnsupportedCommandException, uno::RuntimeException ); 235 virtual ucb::CommandInfo SAL_CALL 236 getCommandInfoByHandle( sal_Int32 Handle ) 237 throw( ucb::UnsupportedCommandException, uno::RuntimeException ); 238 virtual sal_Bool SAL_CALL hasCommandByName( const rtl::OUString& Name ) 239 throw( uno::RuntimeException ); 240 virtual sal_Bool SAL_CALL hasCommandByHandle( sal_Int32 Handle ) 241 throw( uno::RuntimeException ); 242 }; 243 244 //========================================================================= 245 CommandProcessorInfo::CommandProcessorInfo() 246 { 247 m_pInfo = new uno::Sequence< ucb::CommandInfo >( 2 ); 248 249 (*m_pInfo)[ 0 ] 250 = ucb::CommandInfo( 251 rtl::OUString::createFromAscii( GETCOMMANDINFO_NAME ), // Name 252 GETCOMMANDINFO_HANDLE, // Handle 253 getCppuVoidType() ); // ArgType 254 (*m_pInfo)[ 1 ] 255 = ucb::CommandInfo( 256 rtl::OUString::createFromAscii( GLOBALTRANSFER_NAME ), // Name 257 GLOBALTRANSFER_HANDLE, // Handle 258 getCppuType( 259 static_cast< 260 ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType 261 } 262 263 //========================================================================= 264 // virtual 265 CommandProcessorInfo::~CommandProcessorInfo() 266 { 267 delete m_pInfo; 268 } 269 270 //========================================================================= 271 // virtual 272 uno::Sequence< ucb::CommandInfo > SAL_CALL 273 CommandProcessorInfo::getCommands() 274 throw( uno::RuntimeException ) 275 { 276 return uno::Sequence< ucb::CommandInfo >( *m_pInfo ); 277 } 278 279 //========================================================================= 280 // virtual 281 ucb::CommandInfo SAL_CALL 282 CommandProcessorInfo::getCommandInfoByName( const rtl::OUString& Name ) 283 throw( ucb::UnsupportedCommandException, uno::RuntimeException ) 284 { 285 for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) 286 { 287 if ( (*m_pInfo)[ n ].Name == Name ) 288 return ucb::CommandInfo( (*m_pInfo)[ n ] ); 289 } 290 291 throw ucb::UnsupportedCommandException(); 292 } 293 294 //========================================================================= 295 // virtual 296 ucb::CommandInfo SAL_CALL 297 CommandProcessorInfo::getCommandInfoByHandle( sal_Int32 Handle ) 298 throw( ucb::UnsupportedCommandException, uno::RuntimeException ) 299 { 300 for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) 301 { 302 if ( (*m_pInfo)[ n ].Handle == Handle ) 303 return ucb::CommandInfo( (*m_pInfo)[ n ] ); 304 } 305 306 throw ucb::UnsupportedCommandException(); 307 } 308 309 //========================================================================= 310 // virtual 311 sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByName( 312 const rtl::OUString& Name ) 313 throw( uno::RuntimeException ) 314 { 315 for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) 316 { 317 if ( (*m_pInfo)[ n ].Name == Name ) 318 return sal_True; 319 } 320 321 return sal_False; 322 } 323 324 //========================================================================= 325 // virtual 326 sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByHandle( sal_Int32 Handle ) 327 throw( uno::RuntimeException ) 328 { 329 for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n ) 330 { 331 if ( (*m_pInfo)[ n ].Handle == Handle ) 332 return sal_True; 333 } 334 335 return sal_False; 336 } 337 338 //========================================================================= 339 //========================================================================= 340 //========================================================================= 341 342 rtl::OUString createDesiredName( 343 const rtl::OUString & rSourceURL, const rtl::OUString & rNewTitle ) 344 { 345 rtl::OUString aName( rNewTitle ); 346 if ( aName.getLength() == 0 ) 347 { 348 // calculate name using source URL 349 350 // @@@ It's not guaranteed that slashes contained in the URL are 351 // actually path separators. This depends on the fact whether the 352 // URL is hierarchical. Only then the slashes are path separators. 353 // Therefore this algorithm is not guaranteed to work! But, ATM 354 // I don't know a better solution. It would have been better to 355 // have a member for the clashing name in 356 // UnsupportedNameClashException... 357 358 sal_Int32 nLastSlash = rSourceURL.lastIndexOf( '/' ); 359 bool bTrailingSlash = false; 360 if ( nLastSlash == rSourceURL.getLength() - 1 ) 361 { 362 nLastSlash = rSourceURL.lastIndexOf( '/', nLastSlash ); 363 bTrailingSlash = true; 364 } 365 366 if ( nLastSlash != -1 ) 367 { 368 if ( bTrailingSlash ) 369 aName = rSourceURL.copy( 370 nLastSlash + 1, 371 rSourceURL.getLength() - nLastSlash - 2 ); 372 else 373 aName = rSourceURL.copy( nLastSlash + 1 ); 374 } 375 else 376 { 377 aName = rSourceURL; 378 } 379 380 // query, fragment present? 381 sal_Int32 nPos = aName.indexOf( '?' ); 382 if ( nPos == -1 ) 383 nPos = aName.indexOf( '#' ); 384 385 if ( nPos != -1 ) 386 aName = aName.copy( 0, nPos ); 387 } 388 return rtl::OUString( aName ); 389 } 390 391 rtl::OUString createDesiredName( 392 const ucb::GlobalTransferCommandArgument & rArg ) 393 { 394 return createDesiredName( rArg.SourceURL, rArg.NewTitle ); 395 } 396 397 rtl::OUString createDesiredName( 398 const ucb::TransferInfo & rArg ) 399 { 400 return createDesiredName( rArg.SourceURL, rArg.NewTitle ); 401 } 402 403 //========================================================================= 404 enum NameClashContinuation { NOT_HANDLED, ABORT, OVERWRITE, NEW_NAME, UNKNOWN }; 405 406 NameClashContinuation interactiveNameClashResolve( 407 const uno::Reference< ucb::XCommandEnvironment > & xEnv, 408 const rtl::OUString & rTargetURL, 409 const rtl::OUString & rClashingName, 410 /* [out] */ uno::Any & rException, 411 /* [out] */ rtl::OUString & rNewName ) 412 { 413 rtl::Reference< ucbhelper::SimpleNameClashResolveRequest > xRequest( 414 new ucbhelper::SimpleNameClashResolveRequest( 415 rTargetURL, // target folder URL 416 rClashingName, // clashing name 417 rtl::OUString(), // no proposal for new name 418 sal_True /* bSupportsOverwriteData */ ) ); 419 420 rException = xRequest->getRequest(); 421 if ( xEnv.is() ) 422 { 423 uno::Reference< task::XInteractionHandler > xIH 424 = xEnv->getInteractionHandler(); 425 if ( xIH.is() ) 426 { 427 428 xIH->handle( xRequest.get() ); 429 430 rtl::Reference< ucbhelper::InteractionContinuation > 431 xSelection( xRequest->getSelection() ); 432 433 if ( xSelection.is() ) 434 { 435 // Handler handled the request. 436 uno::Reference< task::XInteractionAbort > xAbort( 437 xSelection.get(), uno::UNO_QUERY ); 438 if ( xAbort.is() ) 439 { 440 // Abort. 441 return ABORT; 442 } 443 else 444 { 445 uno::Reference< 446 ucb::XInteractionReplaceExistingData > 447 xReplace( 448 xSelection.get(), uno::UNO_QUERY ); 449 if ( xReplace.is() ) 450 { 451 // Try again: Replace existing data. 452 return OVERWRITE; 453 } 454 else 455 { 456 uno::Reference< 457 ucb::XInteractionSupplyName > 458 xSupplyName( 459 xSelection.get(), uno::UNO_QUERY ); 460 if ( xSupplyName.is() ) 461 { 462 // Try again: Use new name. 463 rNewName = xRequest->getNewName(); 464 return NEW_NAME; 465 } 466 else 467 { 468 OSL_ENSURE( sal_False, 469 "Unknown interaction continuation!" ); 470 return UNKNOWN; 471 } 472 } 473 } 474 } 475 } 476 } 477 return NOT_HANDLED; 478 } 479 480 //========================================================================= 481 bool setTitle( 482 const uno::Reference< ucb::XCommandProcessor > & xCommandProcessor, 483 const uno::Reference< ucb::XCommandEnvironment > & xEnv, 484 const rtl::OUString & rNewTitle ) 485 throw( uno::RuntimeException ) 486 { 487 try 488 { 489 uno::Sequence< beans::PropertyValue > aPropValues( 1 ); 490 aPropValues[ 0 ].Name 491 = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 492 aPropValues[ 0 ].Handle = -1; 493 aPropValues[ 0 ].Value = uno::makeAny( rNewTitle ); 494 495 ucb::Command aSetPropsCommand( 496 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ), 497 -1, 498 uno::makeAny( aPropValues ) ); 499 500 uno::Any aResult 501 = xCommandProcessor->execute( aSetPropsCommand, 0, xEnv ); 502 503 uno::Sequence< uno::Any > aErrors; 504 aResult >>= aErrors; 505 506 OSL_ENSURE( aErrors.getLength() == 1, 507 "getPropertyValues return value invalid!" ); 508 509 if ( aErrors[ 0 ].hasValue() ) 510 { 511 // error occured. 512 OSL_ENSURE( sal_False, "error setting Title property!" ); 513 return false; 514 } 515 } 516 catch ( uno::RuntimeException const & ) 517 { 518 throw; 519 } 520 catch ( uno::Exception const & ) 521 { 522 return false; 523 } 524 525 return true; 526 } 527 528 //========================================================================= 529 uno::Reference< ucb::XContent > createNew( 530 const TransferCommandContext & rContext, 531 const uno::Reference< ucb::XContent > & xTarget, 532 sal_Bool bSourceIsFolder, 533 sal_Bool bSourceIsDocument, 534 sal_Bool bSourceIsLink ) 535 throw( uno::Exception ) 536 { 537 ////////////////////////////////////////////////////////////////////// 538 // 539 // (1) Obtain creatable types from target. 540 // 541 ////////////////////////////////////////////////////////////////////// 542 543 // First, try it using "CreatabeleContentsInfo" property and 544 // "createNewContent" command -> the "new" way. 545 546 uno::Reference< ucb::XCommandProcessor > xCommandProcessorT( 547 xTarget, uno::UNO_QUERY ); 548 if ( !xCommandProcessorT.is() ) 549 { 550 uno::Any aProps 551 = uno::makeAny(beans::PropertyValue( 552 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 553 "Folder")), 554 -1, 555 uno::makeAny(rContext.aArg.TargetURL), 556 beans::PropertyState_DIRECT_VALUE)); 557 ucbhelper::cancelCommandExecution( 558 ucb::IOErrorCode_CANT_CREATE, 559 uno::Sequence< uno::Any >(&aProps, 1), 560 rContext.xOrigEnv, 561 rtl::OUString::createFromAscii( "Target is no XCommandProcessor!" ), 562 rContext.xProcessor ); 563 // Unreachable 564 } 565 566 uno::Sequence< beans::Property > aPropsToObtain( 1 ); 567 aPropsToObtain[ 0 ].Name 568 = rtl::OUString::createFromAscii( "CreatableContentsInfo" ); 569 aPropsToObtain[ 0 ].Handle 570 = -1; 571 572 ucb::Command aGetPropsCommand( 573 rtl::OUString::createFromAscii( "getPropertyValues" ), 574 -1, 575 uno::makeAny( aPropsToObtain ) ); 576 577 uno::Reference< sdbc::XRow > xRow; 578 xCommandProcessorT->execute( aGetPropsCommand, 0, rContext.xEnv ) >>= xRow; 579 580 uno::Sequence< ucb::ContentInfo > aTypesInfo; 581 bool bGotTypesInfo = false; 582 583 if ( xRow.is() ) 584 { 585 uno::Any aValue = xRow->getObject( 586 1, uno::Reference< container::XNameAccess >() ); 587 if ( aValue.hasValue() && ( aValue >>= aTypesInfo ) ) 588 { 589 bGotTypesInfo = true; 590 } 591 } 592 593 uno::Reference< ucb::XContentCreator > xCreator; 594 595 if ( !bGotTypesInfo ) 596 { 597 // Second, try it using XContentCreator interface -> the "old" way (not 598 // providing the chance to supply an XCommandEnvironment. 599 600 xCreator.set( xTarget, uno::UNO_QUERY ); 601 602 if ( !xCreator.is() ) 603 { 604 uno::Any aProps 605 = uno::makeAny(beans::PropertyValue( 606 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 607 "Folder")), 608 -1, 609 uno::makeAny(rContext.aArg.TargetURL), 610 beans::PropertyState_DIRECT_VALUE)); 611 ucbhelper::cancelCommandExecution( 612 ucb::IOErrorCode_CANT_CREATE, 613 uno::Sequence< uno::Any >(&aProps, 1), 614 rContext.xOrigEnv, 615 rtl::OUString::createFromAscii( "Target is no XContentCreator!" ), 616 rContext.xProcessor ); 617 // Unreachable 618 } 619 620 aTypesInfo = xCreator->queryCreatableContentsInfo(); 621 } 622 623 sal_Int32 nCount = aTypesInfo.getLength(); 624 if ( !nCount ) 625 { 626 uno::Any aProps 627 = uno::makeAny(beans::PropertyValue( 628 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Folder")), 629 -1, 630 uno::makeAny(rContext.aArg.TargetURL), 631 beans::PropertyState_DIRECT_VALUE)); 632 ucbhelper::cancelCommandExecution( 633 ucb::IOErrorCode_CANT_CREATE, 634 uno::Sequence< uno::Any >(&aProps, 1), 635 rContext.xOrigEnv, 636 rtl::OUString::createFromAscii( "No types creatable!" ), 637 rContext.xProcessor ); 638 // Unreachable 639 } 640 641 ////////////////////////////////////////////////////////////////////// 642 // 643 // (2) Try to find a matching target type for the source object. 644 // 645 ////////////////////////////////////////////////////////////////////// 646 647 uno::Reference< ucb::XContent > xNew; 648 for ( sal_Int32 n = 0; n < nCount; ++n ) 649 { 650 sal_Int32 nAttribs = aTypesInfo[ n ].Attributes; 651 sal_Bool bMatch = sal_False; 652 653 if ( rContext.aArg.Operation == ucb::TransferCommandOperation_LINK ) 654 { 655 // Create link 656 657 if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK ) 658 { 659 // Match! 660 bMatch = sal_True; 661 } 662 } 663 else if ( ( rContext.aArg.Operation 664 == ucb::TransferCommandOperation_COPY ) || 665 ( rContext.aArg.Operation 666 == ucb::TransferCommandOperation_MOVE ) ) 667 { 668 // Copy / Move 669 670 // Is source a link? Create link in target folder then. 671 if ( bSourceIsLink ) 672 { 673 if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK ) 674 { 675 // Match! 676 bMatch = sal_True; 677 } 678 } 679 else 680 { 681 // (not a and not b) or (a and b) 682 // not( a or b) or (a and b) 683 // 684 if ( ( !!bSourceIsFolder == 685 !!( nAttribs 686 & ucb::ContentInfoAttribute::KIND_FOLDER ) ) 687 && 688 ( !!bSourceIsDocument == 689 !!( nAttribs 690 & ucb::ContentInfoAttribute::KIND_DOCUMENT ) ) 691 ) 692 { 693 // Match! 694 bMatch = sal_True; 695 } 696 } 697 } 698 else 699 { 700 ucbhelper::cancelCommandExecution( 701 uno::makeAny( lang::IllegalArgumentException( 702 rtl::OUString::createFromAscii( 703 "Unknown transfer operation!" ), 704 rContext.xProcessor, 705 -1 ) ), 706 rContext.xOrigEnv ); 707 // Unreachable 708 } 709 710 if ( bMatch ) 711 { 712 ////////////////////////////////////////////////////////////// 713 // 714 // (3) Create a new, empty object of matched type. 715 // 716 ////////////////////////////////////////////////////////////// 717 718 if ( !xCreator.is() ) 719 { 720 // First, try it using "CreatabeleContentsInfo" property and 721 // "createNewContent" command -> the "new" way. 722 ucb::Command aCreateNewCommand( 723 rtl::OUString::createFromAscii( "createNewContent" ), 724 -1, 725 uno::makeAny( aTypesInfo[ n ] ) ); 726 727 xCommandProcessorT->execute( aCreateNewCommand, 0, rContext.xEnv ) 728 >>= xNew; 729 } 730 else 731 { 732 // Second, try it using XContentCreator interface -> the "old" 733 // way (not providing the chance to supply an XCommandEnvironment. 734 735 xNew = xCreator->createNewContent( aTypesInfo[ n ] ); 736 } 737 738 if ( !xNew.is() ) 739 { 740 uno::Any aProps 741 = uno::makeAny( 742 beans::PropertyValue( 743 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 744 "Folder")), 745 -1, 746 uno::makeAny(rContext.aArg.TargetURL), 747 beans::PropertyState_DIRECT_VALUE)); 748 ucbhelper::cancelCommandExecution( 749 ucb::IOErrorCode_CANT_CREATE, 750 uno::Sequence< uno::Any >(&aProps, 1), 751 rContext.xOrigEnv, 752 rtl::OUString::createFromAscii( 753 "createNewContent failed!" ), 754 rContext.xProcessor ); 755 // Unreachable 756 } 757 break; // escape from 'for' loop 758 } 759 } // for 760 761 return xNew; 762 } 763 764 //========================================================================= 765 void transferProperties( 766 const TransferCommandContext & rContext, 767 const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS, 768 const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorN ) 769 throw( uno::Exception ) 770 { 771 ucb::Command aGetPropertySetInfoCommand( 772 rtl::OUString::createFromAscii( "getPropertySetInfo" ), 773 -1, 774 uno::Any() ); 775 776 uno::Reference< beans::XPropertySetInfo > xInfo; 777 xCommandProcessorS->execute( aGetPropertySetInfoCommand, 0, rContext.xEnv ) 778 >>= xInfo; 779 780 if ( !xInfo.is() ) 781 { 782 uno::Any aProps 783 = uno::makeAny(beans::PropertyValue( 784 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 785 "Uri")), 786 -1, 787 uno::makeAny(rContext.aArg.SourceURL), 788 beans::PropertyState_DIRECT_VALUE)); 789 ucbhelper::cancelCommandExecution( 790 ucb::IOErrorCode_CANT_READ, 791 uno::Sequence< uno::Any >(&aProps, 1), 792 rContext.xOrigEnv, 793 rtl::OUString::createFromAscii( 794 "Unable to get propertyset info from source object!" ), 795 rContext.xProcessor ); 796 // Unreachable 797 } 798 799 uno::Sequence< beans::Property > aAllProps = xInfo->getProperties(); 800 801 ucb::Command aGetPropsCommand1( 802 rtl::OUString::createFromAscii( "getPropertyValues" ), 803 -1, 804 uno::makeAny( aAllProps ) ); 805 806 uno::Reference< sdbc::XRow > xRow1; 807 xCommandProcessorS->execute( 808 aGetPropsCommand1, 0, rContext.xEnv ) >>= xRow1; 809 810 if ( !xRow1.is() ) 811 { 812 uno::Any aProps 813 = uno::makeAny(beans::PropertyValue( 814 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 815 "Uri")), 816 -1, 817 uno::makeAny(rContext.aArg.SourceURL), 818 beans::PropertyState_DIRECT_VALUE)); 819 ucbhelper::cancelCommandExecution( 820 ucb::IOErrorCode_CANT_READ, 821 uno::Sequence< uno::Any >(&aProps, 1), 822 rContext.xOrigEnv, 823 rtl::OUString::createFromAscii( 824 "Unable to get properties from source object!" ), 825 rContext.xProcessor ); 826 // Unreachable 827 } 828 829 // Assemble data structure for setPropertyValues command. 830 831 // Note: Make room for additional Title and TargetURL too. -> + 2 832 uno::Sequence< beans::PropertyValue > aPropValues( 833 aAllProps.getLength() + 2 ); 834 835 sal_Bool bHasTitle = ( rContext.aArg.NewTitle.getLength() == 0 ); 836 sal_Bool bHasTargetURL = ( rContext.aArg.Operation 837 != ucb::TransferCommandOperation_LINK ); 838 839 sal_Int32 nWritePos = 0; 840 for ( sal_Int32 m = 0; m < aAllProps.getLength(); ++m ) 841 { 842 const beans::Property & rCurrProp = aAllProps[ m ]; 843 beans::PropertyValue & rCurrValue = aPropValues[ nWritePos ]; 844 845 uno::Any aValue; 846 847 if ( rCurrProp.Name.compareToAscii( "Title" ) == 0 ) 848 { 849 // Supply new title, if given. 850 if ( !bHasTitle ) 851 { 852 bHasTitle = sal_True; 853 aValue <<= rContext.aArg.NewTitle; 854 } 855 } 856 else if ( rCurrProp.Name.compareToAscii( "TargetURL" ) == 0 ) 857 { 858 // Supply source URL as link target for the new link to create. 859 if ( !bHasTargetURL ) 860 { 861 bHasTargetURL = sal_True; 862 aValue <<= rContext.aArg.SourceURL; 863 } 864 } 865 866 if ( !aValue.hasValue() ) 867 { 868 try 869 { 870 aValue = xRow1->getObject( 871 m + 1, uno::Reference< container::XNameAccess >() ); 872 } 873 catch ( sdbc::SQLException const & ) 874 { 875 // Argh! But try to bring things to an end. Perhaps the 876 // mad property is not really important... 877 } 878 } 879 880 if ( aValue.hasValue() ) 881 { 882 rCurrValue.Name = rCurrProp.Name; 883 rCurrValue.Handle = rCurrProp.Handle; 884 rCurrValue.Value = aValue; 885 // rCurrValue.State = 886 887 nWritePos++; 888 } 889 } 890 891 // Title needed, but not set yet? 892 if ( !bHasTitle && ( rContext.aArg.NewTitle.getLength() > 0 ) ) 893 { 894 aPropValues[ nWritePos ].Name 895 = rtl::OUString::createFromAscii( "Title" ); 896 aPropValues[ nWritePos ].Handle = -1; 897 aPropValues[ nWritePos ].Value <<= rContext.aArg.NewTitle; 898 899 nWritePos++; 900 } 901 902 // TargetURL needed, but not set yet? 903 if ( !bHasTargetURL && ( rContext.aArg.Operation 904 == ucb::TransferCommandOperation_LINK ) ) 905 { 906 aPropValues[ nWritePos ].Name 907 = rtl::OUString::createFromAscii( "TargetURL" ); 908 aPropValues[ nWritePos ].Handle = -1; 909 aPropValues[ nWritePos ].Value <<= rContext.aArg.SourceURL; 910 911 nWritePos++; 912 } 913 914 aPropValues.realloc( nWritePos ); 915 916 // Set properties at new object. 917 918 ucb::Command aSetPropsCommand( 919 rtl::OUString::createFromAscii( "setPropertyValues" ), 920 -1, 921 uno::makeAny( aPropValues ) ); 922 923 xCommandProcessorN->execute( aSetPropsCommand, 0, rContext.xEnv ); 924 925 // @@@ What to do with source props that are not supported by the 926 // new object? addProperty ??? 927 } 928 929 //========================================================================= 930 uno::Reference< io::XInputStream > getInputStream( 931 const TransferCommandContext & rContext, 932 const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS ) 933 throw( uno::Exception ) 934 { 935 uno::Reference< io::XInputStream > xInputStream; 936 937 ////////////////////////////////////////////////////////////////////// 938 // 939 // (1) Try to get data as XInputStream via XActiveDataSink. 940 // 941 ////////////////////////////////////////////////////////////////////// 942 943 try 944 { 945 uno::Reference< io::XActiveDataSink > xSink = new ActiveDataSink; 946 947 ucb::OpenCommandArgument2 aArg; 948 aArg.Mode = ucb::OpenMode::DOCUMENT; 949 aArg.Priority = 0; // unused 950 aArg.Sink = xSink; 951 aArg.Properties = uno::Sequence< beans::Property >( 0 ); // unused 952 953 ucb::Command aOpenCommand( 954 rtl::OUString::createFromAscii( "open" ), 955 -1, 956 uno::makeAny( aArg ) ); 957 958 xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ); 959 xInputStream = xSink->getInputStream(); 960 } 961 catch ( uno::RuntimeException const & ) 962 { 963 throw; 964 } 965 catch ( uno::Exception const & ) 966 { 967 // will be handled below. 968 } 969 970 if ( !xInputStream.is() ) 971 { 972 ////////////////////////////////////////////////////////////////// 973 // 974 // (2) Try to get data via XOutputStream. 975 // 976 ////////////////////////////////////////////////////////////////// 977 978 try 979 { 980 uno::Reference< io::XOutputStream > xOutputStream( 981 rContext.xSMgr->createInstance( 982 rtl::OUString::createFromAscii( "com.sun.star.io.Pipe" ) ), 983 uno::UNO_QUERY ); 984 985 if ( xOutputStream.is() ) 986 { 987 ucb::OpenCommandArgument2 aArg; 988 aArg.Mode = ucb::OpenMode::DOCUMENT; 989 aArg.Priority = 0; // unused 990 aArg.Sink = xOutputStream; 991 aArg.Properties = uno::Sequence< beans::Property >( 0 ); 992 993 ucb::Command aOpenCommand( 994 rtl::OUString::createFromAscii( "open" ), 995 -1, 996 uno::makeAny( aArg ) ); 997 998 xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ); 999 1000 xInputStream = uno::Reference< io::XInputStream >( 1001 xOutputStream, uno::UNO_QUERY ); 1002 } 1003 } 1004 catch ( uno::RuntimeException const & ) 1005 { 1006 throw; 1007 } 1008 catch ( uno::Exception const & ) 1009 { 1010 OSL_ENSURE( sal_False, "unable to get input stream from document!" ); 1011 } 1012 } 1013 1014 return xInputStream; 1015 } 1016 1017 //========================================================================= 1018 uno::Reference< sdbc::XResultSet > getResultSet( 1019 const TransferCommandContext & rContext, 1020 const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS ) 1021 throw( uno::Exception ) 1022 { 1023 uno::Reference< sdbc::XResultSet > xResultSet; 1024 1025 uno::Sequence< beans::Property > aProps( 3 ); 1026 1027 aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" ); 1028 aProps[ 0 ].Handle = -1; /* unknown */ 1029 aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" ); 1030 aProps[ 1 ].Handle = -1; /* unknown */ 1031 aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" ); 1032 aProps[ 2 ].Handle = -1; /* unknown */ 1033 1034 ucb::OpenCommandArgument2 aArg; 1035 aArg.Mode = ucb::OpenMode::ALL; 1036 aArg.Priority = 0; // unused 1037 aArg.Sink = 0; 1038 aArg.Properties = aProps; 1039 1040 ucb::Command aOpenCommand( rtl::OUString::createFromAscii( "open" ), 1041 -1, 1042 uno::makeAny( aArg ) ); 1043 try 1044 { 1045 uno::Reference< ucb::XDynamicResultSet > xSet; 1046 xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ) >>= xSet; 1047 1048 if ( xSet.is() ) 1049 xResultSet = xSet->getStaticResultSet(); 1050 } 1051 catch ( uno::RuntimeException const & ) 1052 { 1053 throw; 1054 } 1055 catch ( uno::Exception const & ) 1056 { 1057 OSL_ENSURE( sal_False, "unable to get result set from folder!" ); 1058 } 1059 1060 return xResultSet; 1061 } 1062 1063 //========================================================================= 1064 void handleNameClashRename( 1065 const TransferCommandContext & rContext, 1066 const uno::Reference< ucb::XContent > & xNew, 1067 const uno::Reference< 1068 ucb::XCommandProcessor > & xCommandProcessorN, 1069 const uno::Reference< 1070 ucb::XCommandProcessor > & xCommandProcessorS, 1071 /* [inout] */ uno::Reference< io::XInputStream > & xInputStream ) 1072 throw( uno::Exception ) 1073 { 1074 sal_Int32 nTry = 0; 1075 1076 // Obtain old title. 1077 uno::Sequence< beans::Property > aProps( 1 ); 1078 aProps[ 0 ].Name = rtl::OUString::createFromAscii( "Title" ); 1079 aProps[ 0 ].Handle = -1; 1080 1081 ucb::Command aGetPropsCommand( 1082 rtl::OUString::createFromAscii( "getPropertyValues" ), 1083 -1, 1084 uno::makeAny( aProps ) ); 1085 1086 uno::Reference< sdbc::XRow > xRow; 1087 xCommandProcessorN->execute( aGetPropsCommand, 0, rContext.xEnv ) >>= xRow; 1088 1089 if ( !xRow.is() ) 1090 { 1091 uno::Any aProps2 1092 = uno::makeAny( 1093 beans::PropertyValue( 1094 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), 1095 -1, 1096 uno::makeAny( 1097 xNew->getIdentifier()->getContentIdentifier() ), 1098 beans::PropertyState_DIRECT_VALUE ) ); 1099 ucbhelper::cancelCommandExecution( 1100 ucb::IOErrorCode_CANT_READ, 1101 uno::Sequence< uno::Any >( &aProps2, 1 ), 1102 rContext.xOrigEnv, 1103 rtl::OUString::createFromAscii( 1104 "Unable to get properties from new object!" ), 1105 rContext.xProcessor ); 1106 // Unreachable 1107 } 1108 1109 rtl::OUString aOldTitle = xRow->getString( 1 ); 1110 if ( !aOldTitle.getLength() ) 1111 { 1112 ucbhelper::cancelCommandExecution( 1113 uno::makeAny( beans::UnknownPropertyException( 1114 rtl::OUString::createFromAscii( 1115 "Unable to get property 'Title' " 1116 "from new object!" ), 1117 rContext.xProcessor ) ), 1118 rContext.xOrigEnv ); 1119 // Unreachable 1120 } 1121 1122 // Some pseudo-intelligence for not destroying file extensions. 1123 rtl::OUString aOldTitlePre; 1124 rtl::OUString aOldTitlePost; 1125 sal_Int32 nPos = aOldTitle.lastIndexOf( '.' ); 1126 if ( nPos != -1 ) 1127 { 1128 aOldTitlePre = aOldTitle.copy( 0, nPos ); 1129 aOldTitlePost = aOldTitle.copy( nPos ); 1130 } 1131 else 1132 aOldTitlePre = aOldTitle; 1133 1134 if ( nPos > 0 ) 1135 aOldTitlePre += rtl::OUString::createFromAscii( "_" ); 1136 1137 sal_Bool bContinue = sal_True; 1138 do 1139 { 1140 nTry++; 1141 1142 rtl::OUString aNewTitle = aOldTitlePre; 1143 aNewTitle += rtl::OUString::valueOf( nTry ); 1144 aNewTitle += aOldTitlePost; 1145 1146 // Set new title 1147 setTitle( xCommandProcessorN, rContext.xEnv, aNewTitle ); 1148 1149 // Retry inserting the content. 1150 try 1151 { 1152 // Previous try may have read from stream. Seek to begin (if 1153 // optional interface XSeekable is supported) or get a new stream. 1154 if ( xInputStream.is() ) 1155 { 1156 uno::Reference< io::XSeekable > xSeekable( 1157 xInputStream, uno::UNO_QUERY ); 1158 if ( xSeekable.is() ) 1159 { 1160 try 1161 { 1162 xSeekable->seek( 0 ); 1163 } 1164 catch ( lang::IllegalArgumentException const & ) 1165 { 1166 xInputStream.clear(); 1167 } 1168 catch ( io::IOException const & ) 1169 { 1170 xInputStream.clear(); 1171 } 1172 } 1173 else 1174 xInputStream.clear(); 1175 1176 if ( !xInputStream.is() ) 1177 { 1178 xInputStream 1179 = getInputStream( rContext, xCommandProcessorS ); 1180 if ( !xInputStream.is() ) 1181 { 1182 uno::Any aProps2 1183 = uno::makeAny( 1184 beans::PropertyValue( 1185 rtl::OUString( 1186 RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), 1187 -1, 1188 uno::makeAny( 1189 xNew->getIdentifier()-> 1190 getContentIdentifier() ), 1191 beans::PropertyState_DIRECT_VALUE ) ); 1192 ucbhelper::cancelCommandExecution( 1193 ucb::IOErrorCode_CANT_READ, 1194 uno::Sequence< uno::Any >( &aProps2, 1 ), 1195 rContext.xOrigEnv, 1196 rtl::OUString::createFromAscii( 1197 "Got no data stream from source!" ), 1198 rContext.xProcessor ); 1199 // Unreachable 1200 } 1201 } 1202 } 1203 1204 ucb::InsertCommandArgument aArg; 1205 aArg.Data = xInputStream; 1206 aArg.ReplaceExisting = sal_False; 1207 1208 ucb::Command aInsertCommand( 1209 rtl::OUString::createFromAscii( "insert" ), 1210 -1, 1211 uno::makeAny( aArg ) ); 1212 1213 xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv ); 1214 1215 // Success! 1216 bContinue = sal_False; 1217 } 1218 catch ( uno::RuntimeException const & ) 1219 { 1220 throw; 1221 } 1222 catch ( uno::Exception const & ) 1223 { 1224 } 1225 } 1226 while ( bContinue && ( nTry < 50 ) ); 1227 1228 if ( nTry == 50 ) 1229 { 1230 ucbhelper::cancelCommandExecution( 1231 uno::makeAny( 1232 ucb::UnsupportedNameClashException( 1233 rtl::OUString::createFromAscii( 1234 "Unable to resolve name clash!" ), 1235 rContext.xProcessor, 1236 ucb::NameClash::RENAME ) ), 1237 rContext.xOrigEnv ); 1238 // Unreachable 1239 } 1240 } 1241 1242 //========================================================================= 1243 void globalTransfer_( 1244 const TransferCommandContext & rContext, 1245 const uno::Reference< ucb::XContent > & xSource, 1246 const uno::Reference< ucb::XContent > & xTarget, 1247 const uno::Reference< sdbc::XRow > & xSourceProps ) 1248 throw( uno::Exception ) 1249 { 1250 // IsFolder: property is required. 1251 sal_Bool bSourceIsFolder = xSourceProps->getBoolean( 1 ); 1252 if ( !bSourceIsFolder && xSourceProps->wasNull() ) 1253 { 1254 ucbhelper::cancelCommandExecution( 1255 uno::makeAny( beans::UnknownPropertyException( 1256 rtl::OUString::createFromAscii( 1257 "Unable to get property 'IsFolder' " 1258 "from source object!" ), 1259 rContext.xProcessor ) ), 1260 rContext.xOrigEnv ); 1261 // Unreachable 1262 } 1263 1264 // IsDocument: property is required. 1265 sal_Bool bSourceIsDocument = xSourceProps->getBoolean( 2 ); 1266 if ( !bSourceIsDocument && xSourceProps->wasNull() ) 1267 { 1268 ucbhelper::cancelCommandExecution( 1269 uno::makeAny( beans::UnknownPropertyException( 1270 rtl::OUString::createFromAscii( 1271 "Unable to get property 'IsDocument' " 1272 "from source object!" ), 1273 rContext.xProcessor ) ), 1274 rContext.xOrigEnv ); 1275 // Unreachable 1276 } 1277 1278 // TargetURL: property is optional. 1279 sal_Bool bSourceIsLink = ( xSourceProps->getString( 3 ).getLength() > 0 ); 1280 1281 ////////////////////////////////////////////////////////////////////// 1282 // 1283 // (1) Try to find a matching target type for the source object and 1284 // create a new, empty object of that type. 1285 // 1286 ////////////////////////////////////////////////////////////////////// 1287 1288 uno::Reference< ucb::XContent > xNew = createNew( rContext, 1289 xTarget, 1290 bSourceIsFolder, 1291 bSourceIsDocument, 1292 bSourceIsLink ); 1293 if ( !xNew.is() ) 1294 { 1295 uno::Any aProps 1296 = uno::makeAny(beans::PropertyValue( 1297 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1298 "Folder")), 1299 -1, 1300 uno::makeAny(rContext.aArg.TargetURL), 1301 beans::PropertyState_DIRECT_VALUE)); 1302 ucbhelper::cancelCommandExecution( 1303 ucb::IOErrorCode_CANT_CREATE, 1304 uno::Sequence< uno::Any >(&aProps, 1), 1305 rContext.xOrigEnv, 1306 rtl::OUString::createFromAscii( 1307 "No matching content type at target!" ), 1308 rContext.xProcessor ); 1309 // Unreachable 1310 } 1311 1312 ////////////////////////////////////////////////////////////////////// 1313 // 1314 // (2) Transfer property values from source to new object. 1315 // 1316 ////////////////////////////////////////////////////////////////////// 1317 1318 uno::Reference< ucb::XCommandProcessor > xCommandProcessorN( 1319 xNew, uno::UNO_QUERY ); 1320 if ( !xCommandProcessorN.is() ) 1321 { 1322 uno::Any aProps 1323 = uno::makeAny(beans::PropertyValue( 1324 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1325 "Uri")), 1326 -1, 1327 uno::makeAny( 1328 xNew->getIdentifier()-> 1329 getContentIdentifier()), 1330 beans::PropertyState_DIRECT_VALUE)); 1331 ucbhelper::cancelCommandExecution( 1332 ucb::IOErrorCode_CANT_WRITE, 1333 uno::Sequence< uno::Any >(&aProps, 1), 1334 rContext.xOrigEnv, 1335 rtl::OUString::createFromAscii( 1336 "New content is not a XCommandProcessor!" ), 1337 rContext.xProcessor ); 1338 // Unreachable 1339 } 1340 1341 // Obtain all properties from source. 1342 1343 uno::Reference< ucb::XCommandProcessor > xCommandProcessorS( 1344 xSource, uno::UNO_QUERY ); 1345 if ( !xCommandProcessorS.is() ) 1346 { 1347 uno::Any aProps 1348 = uno::makeAny(beans::PropertyValue( 1349 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1350 "Uri")), 1351 -1, 1352 uno::makeAny(rContext.aArg.SourceURL), 1353 beans::PropertyState_DIRECT_VALUE)); 1354 ucbhelper::cancelCommandExecution( 1355 ucb::IOErrorCode_CANT_READ, 1356 uno::Sequence< uno::Any >(&aProps, 1), 1357 rContext.xOrigEnv, 1358 rtl::OUString::createFromAscii( 1359 "Source content is not a XCommandProcessor!" ), 1360 rContext.xProcessor ); 1361 // Unreachable 1362 } 1363 1364 transferProperties( rContext, xCommandProcessorS, xCommandProcessorN ); 1365 1366 ////////////////////////////////////////////////////////////////////// 1367 // 1368 // (3) Try to obtain a data stream from source. 1369 // 1370 ////////////////////////////////////////////////////////////////////// 1371 1372 uno::Reference< io::XInputStream > xInputStream; 1373 1374 if ( bSourceIsDocument && ( rContext.aArg.Operation 1375 != ucb::TransferCommandOperation_LINK ) ) 1376 xInputStream = getInputStream( rContext, xCommandProcessorS ); 1377 1378 ////////////////////////////////////////////////////////////////////// 1379 // 1380 // (4) Try to obtain a resultset (children) from source. 1381 // 1382 ////////////////////////////////////////////////////////////////////// 1383 1384 uno::Reference< sdbc::XResultSet > xResultSet; 1385 1386 if ( bSourceIsFolder && ( rContext.aArg.Operation 1387 != ucb::TransferCommandOperation_LINK ) ) 1388 xResultSet = getResultSet( rContext, xCommandProcessorS ); 1389 1390 ////////////////////////////////////////////////////////////////////// 1391 // 1392 // (5) Insert (store) new content. 1393 // 1394 ////////////////////////////////////////////////////////////////////// 1395 1396 ucb::InsertCommandArgument aArg; 1397 aArg.Data = xInputStream; 1398 1399 switch ( rContext.aArg.NameClash ) 1400 { 1401 case ucb::NameClash::OVERWRITE: 1402 aArg.ReplaceExisting = sal_True; 1403 break; 1404 1405 case ucb::NameClash::ERROR: 1406 case ucb::NameClash::RENAME: 1407 case ucb::NameClash::KEEP: // deprecated 1408 case ucb::NameClash::ASK: 1409 aArg.ReplaceExisting = sal_False; 1410 break; 1411 1412 default: 1413 aArg.ReplaceExisting = sal_False; 1414 OSL_ENSURE( sal_False, "Unknown nameclash directive!" ); 1415 break; 1416 } 1417 1418 rtl::OUString aDesiredName = createDesiredName( rContext.aArg ); 1419 1420 bool bRetry; 1421 do 1422 { 1423 bRetry = false; 1424 1425 try 1426 { 1427 ucb::Command aInsertCommand( 1428 rtl::OUString::createFromAscii( "insert" ), 1429 -1, 1430 uno::makeAny( aArg ) ); 1431 1432 xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv ); 1433 } 1434 catch ( ucb::UnsupportedNameClashException const & exc ) 1435 { 1436 OSL_ENSURE( !aArg.ReplaceExisting, 1437 "BUG: UnsupportedNameClashException not allowed here!" ); 1438 1439 if (exc.NameClash != ucb::NameClash::ERROR) { 1440 OSL_ENSURE( false, "BUG: NameClash::ERROR expected!" ); 1441 } 1442 1443 // No chance to solve name clashes, because I'm not able to detect 1444 // whether there is one. 1445 throw ucb::UnsupportedNameClashException( 1446 rtl::OUString::createFromAscii( 1447 "Unable to resolve name clashes, no chance to detect " 1448 "that there is one!" ), 1449 rContext.xProcessor, 1450 rContext.aArg.NameClash ); 1451 } 1452 catch ( ucb::NameClashException const & ) 1453 { 1454 // The 'insert' command throws a NameClashException if the parameter 1455 // ReplaceExisting of the command's argument was set to false and 1456 // there exists a resource with a clashing name in the target folder 1457 // of the operation. 1458 1459 // 'insert' command has no direct support for name clashes other 1460 // than ERROR ( ReplaceExisting == false ) and OVERWRITE 1461 // ( ReplaceExisting == true ). So we have to implement the 1462 // other name clash handling directives on top of the content. 1463 1464 // @@@ 'insert' command should be extended that it accepts a 1465 // name clash handling directive, exactly like 'transfer' command. 1466 1467 switch ( rContext.aArg.NameClash ) 1468 { 1469 case ucb::NameClash::OVERWRITE: 1470 { 1471 ucbhelper::cancelCommandExecution( 1472 uno::makeAny( 1473 ucb::UnsupportedNameClashException( 1474 rtl::OUString::createFromAscii( 1475 "BUG: insert + replace == true MUST NOT " 1476 "throw NameClashException." ), 1477 rContext.xProcessor, 1478 rContext.aArg.NameClash ) ), 1479 rContext.xOrigEnv ); 1480 // Unreachable 1481 } 1482 1483 case ucb::NameClash::ERROR: 1484 throw; 1485 1486 case ucb::NameClash::RENAME: 1487 { 1488 // "invent" a new valid title. 1489 handleNameClashRename( rContext, 1490 xNew, 1491 xCommandProcessorN, 1492 xCommandProcessorS, 1493 xInputStream ); 1494 break; 1495 } 1496 1497 case ucb::NameClash::ASK: 1498 { 1499 uno::Any aExc; 1500 rtl::OUString aNewTitle; 1501 NameClashContinuation eCont 1502 = interactiveNameClashResolve( 1503 rContext.xOrigEnv, // always use original environment! 1504 rContext.aArg.TargetURL, // target folder URL 1505 aDesiredName, 1506 aExc, 1507 aNewTitle ); 1508 1509 switch ( eCont ) 1510 { 1511 case NOT_HANDLED: 1512 // Not handled. 1513 cppu::throwException( aExc ); 1514 // break; 1515 1516 case UNKNOWN: 1517 // Handled, but not clear, how... 1518 // fall-thru intended. 1519 1520 case ABORT: 1521 throw ucb::CommandFailedException( 1522 rtl::OUString( 1523 RTL_CONSTASCII_USTRINGPARAM( 1524 "abort requested via interaction " 1525 "handler" ) ), 1526 uno::Reference< uno::XInterface >(), 1527 aExc ); 1528 // break; 1529 1530 case OVERWRITE: 1531 OSL_ENSURE( aArg.ReplaceExisting == sal_False, 1532 "Hu? ReplaceExisting already true?" 1533 ); 1534 aArg.ReplaceExisting = sal_True; 1535 bRetry = true; 1536 break; 1537 1538 case NEW_NAME: 1539 { 1540 // set new name -> set "Title" property... 1541 if ( setTitle( xCommandProcessorN, 1542 rContext.xEnv, 1543 aNewTitle ) ) 1544 { 1545 // remember suggested title... 1546 aDesiredName = aNewTitle; 1547 1548 // ... and try again. 1549 bRetry = true; 1550 } 1551 else 1552 { 1553 // error setting title. Abort. 1554 throw ucb::CommandFailedException( 1555 rtl::OUString( 1556 RTL_CONSTASCII_USTRINGPARAM( 1557 "error setting Title property!" 1558 ) ), 1559 uno::Reference< uno::XInterface >(), 1560 aExc ); 1561 } 1562 break; 1563 } 1564 } 1565 1566 OSL_ENSURE( bRetry, "bRetry must be true here!!!" ); 1567 } 1568 break; 1569 1570 case ucb::NameClash::KEEP: // deprecated 1571 default: 1572 { 1573 ucbhelper::cancelCommandExecution( 1574 uno::makeAny( 1575 ucb::UnsupportedNameClashException( 1576 rtl::OUString( 1577 RTL_CONSTASCII_USTRINGPARAM( 1578 "default action, don't know how to " 1579 "handle name clash" ) ), 1580 rContext.xProcessor, 1581 rContext.aArg.NameClash ) ), 1582 rContext.xOrigEnv ); 1583 // Unreachable 1584 } 1585 } 1586 } 1587 } 1588 while ( bRetry ); 1589 1590 ////////////////////////////////////////////////////////////////////// 1591 // 1592 // (6) Process children of source. 1593 // 1594 ////////////////////////////////////////////////////////////////////// 1595 1596 if ( xResultSet.is() ) 1597 { 1598 try 1599 { 1600 // Iterate over children... 1601 1602 uno::Reference< sdbc::XRow > xChildRow( 1603 xResultSet, uno::UNO_QUERY ); 1604 1605 if ( !xChildRow.is() ) 1606 { 1607 uno::Any aProps 1608 = uno::makeAny( 1609 beans::PropertyValue( 1610 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1611 "Uri")), 1612 -1, 1613 uno::makeAny(rContext.aArg.SourceURL), 1614 beans::PropertyState_DIRECT_VALUE)); 1615 ucbhelper::cancelCommandExecution( 1616 ucb::IOErrorCode_CANT_READ, 1617 uno::Sequence< uno::Any >(&aProps, 1), 1618 rContext.xOrigEnv, 1619 rtl::OUString::createFromAscii( 1620 "Unable to get properties from children of source!" ), 1621 rContext.xProcessor ); 1622 // Unreachable 1623 } 1624 1625 uno::Reference< ucb::XContentAccess > xChildAccess( 1626 xResultSet, uno::UNO_QUERY ); 1627 1628 if ( !xChildAccess.is() ) 1629 { 1630 uno::Any aProps 1631 = uno::makeAny( 1632 beans::PropertyValue( 1633 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1634 "Uri")), 1635 -1, 1636 uno::makeAny(rContext.aArg.SourceURL), 1637 beans::PropertyState_DIRECT_VALUE)); 1638 ucbhelper::cancelCommandExecution( 1639 ucb::IOErrorCode_CANT_READ, 1640 uno::Sequence< uno::Any >(&aProps, 1), 1641 rContext.xOrigEnv, 1642 rtl::OUString::createFromAscii( 1643 "Unable to get children of source!" ), 1644 rContext.xProcessor ); 1645 // Unreachable 1646 } 1647 1648 if ( xResultSet->first() ) 1649 { 1650 ucb::GlobalTransferCommandArgument aTransArg( 1651 rContext.aArg.Operation, // Operation 1652 rtl::OUString(), // SourceURL; filled later 1653 xNew->getIdentifier() 1654 ->getContentIdentifier(), // TargetURL 1655 rtl::OUString(), // NewTitle; 1656 rContext.aArg.NameClash ); // NameClash 1657 1658 TransferCommandContext aSubCtx( 1659 rContext.xSMgr, 1660 rContext.xProcessor, 1661 rContext.xEnv, 1662 rContext.xOrigEnv, 1663 aTransArg ); 1664 do 1665 { 1666 uno::Reference< ucb::XContent > xChild 1667 = xChildAccess->queryContent(); 1668 if ( xChild.is() ) 1669 { 1670 // Recursion! 1671 1672 aSubCtx.aArg.SourceURL 1673 = xChild->getIdentifier()->getContentIdentifier(); 1674 1675 globalTransfer_( aSubCtx, 1676 xChild, 1677 xNew, 1678 xChildRow ); 1679 } 1680 } 1681 while ( xResultSet->next() ); 1682 } 1683 } 1684 catch ( sdbc::SQLException const & ) 1685 { 1686 } 1687 } 1688 1689 try { 1690 uno::Reference< ucb::XCommandProcessor > xcp( 1691 xTarget, uno::UNO_QUERY ); 1692 1693 uno::Any aAny; 1694 uno::Reference< ucb::XCommandInfo > xci; 1695 if(xcp.is()) 1696 aAny = 1697 xcp->execute( 1698 ucb::Command( 1699 rtl::OUString::createFromAscii("getCommandInfo"), 1700 -1, 1701 uno::Any()), 1702 0, 1703 rContext.xEnv ); 1704 1705 const rtl::OUString cmdName = 1706 rtl::OUString::createFromAscii("flush"); 1707 if((aAny >>= xci) && xci->hasCommandByName(cmdName)) 1708 xcp->execute( 1709 ucb::Command( 1710 cmdName, 1711 -1, 1712 uno::Any()) , 1713 0, 1714 rContext.xEnv ); 1715 } 1716 catch( uno::Exception const & ) 1717 { 1718 } 1719 } 1720 1721 } /* namescpace */ 1722 1723 //========================================================================= 1724 // 1725 // UniversalContentBroker implementation ( XCommandProcessor commands ). 1726 // 1727 //========================================================================= 1728 1729 uno::Reference< ucb::XCommandInfo > 1730 UniversalContentBroker::getCommandInfo() 1731 { 1732 return uno::Reference< ucb::XCommandInfo >( new CommandProcessorInfo() ); 1733 } 1734 1735 //========================================================================= 1736 void UniversalContentBroker::globalTransfer( 1737 const ucb::GlobalTransferCommandArgument & rArg, 1738 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 1739 throw( uno::Exception ) 1740 { 1741 // Use own command environment with own interaction handler intercepting 1742 // some interaction requests that shall not be handled by the user-supplied 1743 // interaction handler. 1744 uno::Reference< ucb::XCommandEnvironment > xLocalEnv; 1745 if (xEnv.is()) 1746 { 1747 uno::Reference< beans::XPropertySet > const xProps( 1748 m_xSMgr, uno::UNO_QUERY_THROW ); 1749 uno::Reference< uno::XComponentContext > xCtx; 1750 xCtx.set( xProps->getPropertyValue( 1751 rtl::OUString( 1752 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), 1753 uno::UNO_QUERY_THROW ); 1754 1755 xLocalEnv.set( ucb::CommandEnvironment::create( 1756 xCtx, 1757 new InteractionHandlerProxy( xEnv->getInteractionHandler() ), 1758 xEnv->getProgressHandler() ) ); 1759 } 1760 1761 ////////////////////////////////////////////////////////////////////// 1762 // 1763 // (1) Try to transfer the content using 'transfer' command. 1764 // 1765 ////////////////////////////////////////////////////////////////////// 1766 1767 uno::Reference< ucb::XContent > xTarget; 1768 uno::Reference< ucb::XContentIdentifier > xId 1769 = createContentIdentifier( rArg.TargetURL ); 1770 if ( xId.is() ) 1771 { 1772 try 1773 { 1774 xTarget = queryContent( xId ); 1775 } 1776 catch ( ucb::IllegalIdentifierException const & ) 1777 { 1778 } 1779 } 1780 1781 if ( !xTarget.is() ) 1782 { 1783 uno::Any aProps 1784 = uno::makeAny(beans::PropertyValue( 1785 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1786 "Uri")), 1787 -1, 1788 uno::makeAny(rArg.TargetURL), 1789 beans::PropertyState_DIRECT_VALUE)); 1790 ucbhelper::cancelCommandExecution( 1791 ucb::IOErrorCode_CANT_READ, 1792 uno::Sequence< uno::Any >(&aProps, 1), 1793 xEnv, 1794 rtl::OUString::createFromAscii( 1795 "Can't instanciate target object!" ), 1796 this ); 1797 // Unreachable 1798 } 1799 1800 if ( ( rArg.Operation == ucb::TransferCommandOperation_COPY ) || 1801 ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) ) 1802 { 1803 uno::Reference< ucb::XCommandProcessor > xCommandProcessor( 1804 xTarget, uno::UNO_QUERY ); 1805 if ( !xCommandProcessor.is() ) 1806 { 1807 uno::Any aProps 1808 = uno::makeAny( 1809 beans::PropertyValue( 1810 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1811 "Uri")), 1812 -1, 1813 uno::makeAny(rArg.TargetURL), 1814 beans::PropertyState_DIRECT_VALUE)); 1815 ucbhelper::cancelCommandExecution( 1816 ucb::IOErrorCode_CANT_READ, 1817 uno::Sequence< uno::Any >(&aProps, 1), 1818 xEnv, 1819 rtl::OUString::createFromAscii( 1820 "Target content is not a XCommandProcessor!" ), 1821 this ); 1822 // Unreachable 1823 } 1824 1825 ucb::TransferInfo aTransferArg( 1826 ( rArg.Operation 1827 == ucb::TransferCommandOperation_MOVE ), // MoveData 1828 rArg.SourceURL, // SourceURL 1829 rArg.NewTitle, // NewTitle 1830 rArg.NameClash ); // NameClash 1831 1832 bool bRetry; 1833 do 1834 { 1835 bRetry = false; 1836 1837 try 1838 { 1839 ucb::Command aCommand( 1840 rtl::OUString::createFromAscii( "transfer" ), // Name 1841 -1, // Handle 1842 uno::makeAny( aTransferArg ) ); // Argument 1843 1844 xCommandProcessor->execute( aCommand, 0, xLocalEnv ); 1845 1846 // Command succeeded. We're done. 1847 return; 1848 } 1849 catch ( ucb::InteractiveBadTransferURLException const & ) 1850 { 1851 // Source URL is not supported by target. Try to transfer 1852 // the content "manually". 1853 } 1854 catch ( ucb::UnsupportedCommandException const & ) 1855 { 1856 // 'transfer' command is not supported by commandprocessor. 1857 // Try to transfer manually. 1858 } 1859 catch ( ucb::UnsupportedNameClashException const & exc ) 1860 { 1861 OSL_ENSURE( aTransferArg.NameClash == exc.NameClash, 1862 "nameclash mismatch!" ); 1863 if ( exc.NameClash == ucb::NameClash::ASK ) 1864 { 1865 // Try to detect a name clash by invoking "transfer" with 1866 // NameClash::ERROR. 1867 try 1868 { 1869 ucb::TransferInfo aTransferArg1( 1870 aTransferArg.MoveData, 1871 aTransferArg.SourceURL, 1872 aTransferArg.NewTitle, 1873 ucb::NameClash::ERROR ); 1874 1875 ucb::Command aCommand1( 1876 rtl::OUString::createFromAscii( "transfer" ), 1877 -1, 1878 uno::makeAny( aTransferArg1 ) ); 1879 1880 xCommandProcessor->execute( aCommand1, 0, xLocalEnv ); 1881 1882 // Command succeeded. We're done. 1883 return; 1884 } 1885 catch ( ucb::UnsupportedNameClashException const & ) 1886 { 1887 // No chance to solve name clashes, because I'm not 1888 // able to detect whether there is one. 1889 throw exc; // Not just 'throw;'! 1890 } 1891 catch ( ucb::NameClashException const & ) 1892 { 1893 // There's a clash. Use interaction handler to solve it. 1894 1895 uno::Any aExc; 1896 rtl::OUString aNewTitle; 1897 NameClashContinuation eCont 1898 = interactiveNameClashResolve( 1899 xEnv, // always use original environment! 1900 rArg.TargetURL, // target folder URL 1901 createDesiredName( 1902 aTransferArg ), // clashing name 1903 aExc, 1904 aNewTitle ); 1905 1906 switch ( eCont ) 1907 { 1908 case NOT_HANDLED: 1909 // Not handled. 1910 cppu::throwException( aExc ); 1911 // break; 1912 1913 case UNKNOWN: 1914 // Handled, but not clear, how... 1915 // fall-thru intended. 1916 1917 case ABORT: 1918 throw ucb::CommandFailedException( 1919 rtl::OUString( 1920 RTL_CONSTASCII_USTRINGPARAM( 1921 "abort requested via interaction " 1922 "handler" ) ), 1923 uno::Reference< uno::XInterface >(), 1924 aExc ); 1925 // break; 1926 1927 case OVERWRITE: 1928 aTransferArg.NameClash 1929 = ucb::NameClash::OVERWRITE; 1930 bRetry = true; 1931 break; 1932 1933 case NEW_NAME: 1934 aTransferArg.NewTitle = aNewTitle; 1935 bRetry = true; 1936 break; 1937 } 1938 1939 OSL_ENSURE( bRetry, "bRetry must be true here!!!" ); 1940 } 1941 } 1942 else 1943 { 1944 throw; 1945 } 1946 } 1947 } 1948 while ( bRetry ); 1949 } 1950 1951 ////////////////////////////////////////////////////////////////////// 1952 // 1953 // (2) Try to transfer the content "manually". 1954 // 1955 ////////////////////////////////////////////////////////////////////// 1956 1957 uno::Reference< ucb::XContent > xSource; 1958 try 1959 { 1960 uno::Reference< ucb::XContentIdentifier > xId2 1961 = createContentIdentifier( rArg.SourceURL ); 1962 if ( xId2.is() ) 1963 xSource = queryContent( xId2 ); 1964 } 1965 catch ( ucb::IllegalIdentifierException const & ) 1966 { 1967 // Error handling via "if ( !xSource.is() )" below. 1968 } 1969 1970 if ( !xSource.is() ) 1971 { 1972 uno::Any aProps 1973 = uno::makeAny(beans::PropertyValue( 1974 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1975 "Uri")), 1976 -1, 1977 uno::makeAny(rArg.SourceURL), 1978 beans::PropertyState_DIRECT_VALUE)); 1979 ucbhelper::cancelCommandExecution( 1980 ucb::IOErrorCode_CANT_READ, 1981 uno::Sequence< uno::Any >(&aProps, 1), 1982 xEnv, 1983 rtl::OUString::createFromAscii( 1984 "Can't instanciate source object!" ), 1985 this ); 1986 // Unreachable 1987 } 1988 1989 uno::Reference< ucb::XCommandProcessor > xCommandProcessor( 1990 xSource, uno::UNO_QUERY ); 1991 if ( !xCommandProcessor.is() ) 1992 { 1993 uno::Any aProps 1994 = uno::makeAny(beans::PropertyValue( 1995 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 1996 "Uri")), 1997 -1, 1998 uno::makeAny(rArg.SourceURL), 1999 beans::PropertyState_DIRECT_VALUE)); 2000 ucbhelper::cancelCommandExecution( 2001 ucb::IOErrorCode_CANT_READ, 2002 uno::Sequence< uno::Any >(&aProps, 1), 2003 xEnv, 2004 rtl::OUString::createFromAscii( 2005 "Source content is not a XCommandProcessor!" ), 2006 this ); 2007 // Unreachable 2008 } 2009 2010 // Obtain interesting property values from source... 2011 2012 uno::Sequence< beans::Property > aProps( 4 ); 2013 2014 aProps[ 0 ].Name = rtl::OUString::createFromAscii( "IsFolder" ); 2015 aProps[ 0 ].Handle = -1; /* unknown */ 2016 aProps[ 1 ].Name = rtl::OUString::createFromAscii( "IsDocument" ); 2017 aProps[ 1 ].Handle = -1; /* unknown */ 2018 aProps[ 2 ].Name = rtl::OUString::createFromAscii( "TargetURL" ); 2019 aProps[ 2 ].Handle = -1; /* unknown */ 2020 aProps[ 3 ].Name = rtl::OUString::createFromAscii( "BaseURI" ); 2021 aProps[ 3 ].Handle = -1; /* unknown */ 2022 2023 ucb::Command aGetPropsCommand( 2024 rtl::OUString::createFromAscii( "getPropertyValues" ), 2025 -1, 2026 uno::makeAny( aProps ) ); 2027 2028 uno::Reference< sdbc::XRow > xRow; 2029 xCommandProcessor->execute( aGetPropsCommand, 0, xLocalEnv ) >>= xRow; 2030 2031 if ( !xRow.is() ) 2032 { 2033 uno::Any aProps2 2034 = uno::makeAny(beans::PropertyValue( 2035 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 2036 "Uri")), 2037 -1, 2038 uno::makeAny(rArg.SourceURL), 2039 beans::PropertyState_DIRECT_VALUE)); 2040 ucbhelper::cancelCommandExecution( 2041 ucb::IOErrorCode_CANT_READ, 2042 uno::Sequence< uno::Any >(&aProps2, 1), 2043 xEnv, 2044 rtl::OUString::createFromAscii( 2045 "Unable to get properties from source object!" ), 2046 this ); 2047 // Unreachable 2048 } 2049 2050 TransferCommandContext aTransferCtx( 2051 m_xSMgr, this, xLocalEnv, xEnv, rArg ); 2052 2053 if ( rArg.NewTitle.getLength() == 0 ) 2054 { 2055 // BaseURI: property is optional. 2056 rtl::OUString aBaseURI( xRow->getString( 4 ) ); 2057 if ( aBaseURI.getLength() ) 2058 { 2059 aTransferCtx.aArg.NewTitle 2060 = createDesiredName( aBaseURI, rtl::OUString() ); 2061 } 2062 } 2063 2064 // Do it! 2065 globalTransfer_( aTransferCtx, xSource, xTarget, xRow ); 2066 2067 ////////////////////////////////////////////////////////////////////// 2068 // 2069 // (3) Delete source, if operation is MOVE. 2070 // 2071 ////////////////////////////////////////////////////////////////////// 2072 2073 if ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) 2074 { 2075 try 2076 { 2077 ucb::Command aCommand( 2078 rtl::OUString::createFromAscii( "delete" ), // Name 2079 -1, // Handle 2080 uno::makeAny( sal_Bool( sal_True ) ) ); // Argument 2081 2082 xCommandProcessor->execute( aCommand, 0, xLocalEnv ); 2083 } 2084 catch ( uno::Exception const & ) 2085 { 2086 OSL_ENSURE( sal_False, "Cannot delete source object!" ); 2087 throw; 2088 } 2089 } 2090 } 2091