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_ucbhelper.hxx" 26 27 /************************************************************************** 28 TODO 29 ************************************************************************** 30 31 *************************************************************************/ 32 33 #include "osl/diagnose.h" 34 35 #include "com/sun/star/beans/PropertyAttribute.hpp" 36 #include "com/sun/star/beans/XPropertyAccess.hpp" 37 #include "com/sun/star/lang/IllegalAccessException.hpp" 38 #include "com/sun/star/sdbc/XRow.hpp" 39 #include "com/sun/star/ucb/XCommandInfo.hpp" 40 #include "com/sun/star/ucb/XPersistentPropertySet.hpp" 41 #include "ucbhelper/contentidentifier.hxx" 42 #include "ucbhelper/propertyvalueset.hxx" 43 #include "ucbhelper/cancelcommandexecution.hxx" 44 45 #include "myucp_content.hxx" 46 #include "myucp_provider.hxx" 47 48 #ifdef IMPLEMENT_COMMAND_INSERT 49 #include "com/sun/star/ucb/InsertCommandArgument.hpp" 50 #include "com/sun/star/ucb/MissingInputStreamException.hpp" 51 #include "com/sun/star/ucb/MissingPropertiesException.hpp" 52 #endif 53 #ifdef IMPLEMENT_COMMAND_OPEN 54 #include "com/sun/star/io/XOutputStream.hpp" 55 #include "com/sun/star/io/XActiveDataSink.hpp" 56 #include "com/sun/star/ucb/OpenCommandArgument2.hpp" 57 #include "com/sun/star/ucb/OpenMode.hpp" 58 #include "com/sun/star/ucb/UnsupportedDataSinkException.hpp" 59 #include "com/sun/star/ucb/UnsupportedOpenModeException.hpp" 60 #include "myucp_resultset.hxx" 61 #endif 62 63 using namespace com::sun::star; 64 65 // @@@ Adjust namespace name. 66 using namespace myucp; 67 68 //========================================================================= 69 //========================================================================= 70 // 71 // Content Implementation. 72 // 73 //========================================================================= 74 //========================================================================= 75 76 Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, 77 ::ucbhelper::ContentProviderImplHelper* pProvider, 78 const uno::Reference< ucb::XContentIdentifier >& Identifier ) 79 : ContentImplHelper( rxSMgr, pProvider, Identifier ) 80 { 81 // @@@ Fill m_aProps here or implement lazy evaluation logic for this. 82 // m_aProps.aTitle = 83 // m_aprops.aContentType = 84 // m_aProps.bIsDocument = 85 // m_aProps.bIsFolder = 86 } 87 88 //========================================================================= 89 // virtual 90 Content::~Content() 91 { 92 } 93 94 //========================================================================= 95 // 96 // XInterface methods. 97 // 98 //========================================================================= 99 100 // virtual 101 void SAL_CALL Content::acquire() 102 throw() 103 { 104 ContentImplHelper::acquire(); 105 } 106 107 //========================================================================= 108 // virtual 109 void SAL_CALL Content::release() 110 throw() 111 { 112 ContentImplHelper::release(); 113 } 114 115 //========================================================================= 116 // virtual 117 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) 118 { 119 uno::Any aRet; 120 121 // @@@ Add support for additional interfaces. 122 #if 0 123 aRet = cppu::queryInterface( rType, 124 static_cast< yyy::Xxxxxxxxx * >( this ) ); 125 #endif 126 127 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); 128 } 129 130 //========================================================================= 131 // 132 // XTypeProvider methods. 133 // 134 //========================================================================= 135 136 XTYPEPROVIDER_COMMON_IMPL( Content ); 137 138 //========================================================================= 139 // virtual 140 uno::Sequence< uno::Type > SAL_CALL Content::getTypes() 141 { 142 // @@@ Add own interfaces. 143 144 static cppu::OTypeCollection* pCollection = 0; 145 146 if ( !pCollection ) 147 { 148 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 149 if ( !pCollection ) 150 { 151 static cppu::OTypeCollection aCollection( 152 CPPU_TYPE_REF( lang::XTypeProvider ), 153 CPPU_TYPE_REF( lang::XServiceInfo ), 154 CPPU_TYPE_REF( lang::XComponent ), 155 CPPU_TYPE_REF( ucb::XContent ), 156 CPPU_TYPE_REF( ucb::XCommandProcessor ), 157 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), 158 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), 159 CPPU_TYPE_REF( beans::XPropertyContainer ), 160 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), 161 CPPU_TYPE_REF( container::XChild ) ); 162 pCollection = &aCollection; 163 } 164 } 165 166 return (*pCollection).getTypes(); 167 } 168 169 //========================================================================= 170 // 171 // XServiceInfo methods. 172 // 173 //========================================================================= 174 175 // virtual 176 rtl::OUString SAL_CALL Content::getImplementationName() 177 { 178 // @@@ Adjust implementation name. 179 // Prefix with reversed company domain name. 180 return rtl::OUString::createFromAscii( "com.sun.star.comp.myucp.Content" ); 181 } 182 183 //========================================================================= 184 // virtual 185 uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() 186 { 187 // @@@ Adjust macro name. 188 uno::Sequence< rtl::OUString > aSNS( 1 ); 189 aSNS.getArray()[ 0 ] 190 = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME ); 191 return aSNS; 192 } 193 194 //========================================================================= 195 // 196 // XContent methods. 197 // 198 //========================================================================= 199 200 // virtual 201 rtl::OUString SAL_CALL Content::getContentType() 202 { 203 // @@@ Adjust macro name ( def in myucp_provider.hxx ). 204 return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE ); 205 } 206 207 //========================================================================= 208 // 209 // XCommandProcessor methods. 210 // 211 //========================================================================= 212 213 // virtual 214 uno::Any SAL_CALL Content::execute( 215 const ucb::Command& aCommand, 216 sal_Int32 /* CommandId */, 217 const uno::Reference< ucb::XCommandEnvironment >& Environment ) 218 { 219 uno::Any aRet; 220 221 if ( aCommand.Name.equalsAsciiL( 222 RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) ) 223 { 224 ////////////////////////////////////////////////////////////////// 225 // getPropertyValues 226 ////////////////////////////////////////////////////////////////// 227 228 uno::Sequence< beans::Property > Properties; 229 if ( !( aCommand.Argument >>= Properties ) ) 230 { 231 OSL_ENSURE( sal_False, "Wrong argument type!" ); 232 ::ucbhelper::cancelCommandExecution( 233 uno::makeAny( lang::IllegalArgumentException( 234 rtl::OUString(), 235 static_cast< cppu::OWeakObject * >( this ), 236 -1 ) ), 237 Environment ); 238 // Unreachable 239 } 240 241 aRet <<= getPropertyValues( Properties, Environment ); 242 } 243 else if ( aCommand.Name.equalsAsciiL( 244 RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) ) 245 { 246 ////////////////////////////////////////////////////////////////// 247 // setPropertyValues 248 ////////////////////////////////////////////////////////////////// 249 250 uno::Sequence< beans::PropertyValue > aProperties; 251 if ( !( aCommand.Argument >>= aProperties ) ) 252 { 253 OSL_ENSURE( sal_False, "Wrong argument type!" ); 254 ::ucbhelper::cancelCommandExecution( 255 uno::makeAny( lang::IllegalArgumentException( 256 rtl::OUString(), 257 static_cast< cppu::OWeakObject * >( this ), 258 -1 ) ), 259 Environment ); 260 // Unreachable 261 } 262 263 if ( !aProperties.getLength() ) 264 { 265 OSL_ENSURE( sal_False, "No properties!" ); 266 ::ucbhelper::cancelCommandExecution( 267 uno::makeAny( lang::IllegalArgumentException( 268 rtl::OUString(), 269 static_cast< cppu::OWeakObject * >( this ), 270 -1 ) ), 271 Environment ); 272 // Unreachable 273 } 274 275 aRet <<= setPropertyValues( aProperties, Environment ); 276 } 277 else if ( aCommand.Name.equalsAsciiL( 278 RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) ) 279 { 280 ////////////////////////////////////////////////////////////////// 281 // getPropertySetInfo 282 ////////////////////////////////////////////////////////////////// 283 284 // Note: Implemented by base class. 285 aRet <<= getPropertySetInfo( Environment ); 286 } 287 else if ( aCommand.Name.equalsAsciiL( 288 RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) ) 289 { 290 ////////////////////////////////////////////////////////////////// 291 // getCommandInfo 292 ////////////////////////////////////////////////////////////////// 293 294 // Note: Implemented by base class. 295 aRet <<= getCommandInfo( Environment ); 296 } 297 #ifdef IMPLEMENT_COMMAND_OPEN 298 else if ( aCommand.Name.equalsAsciiL( 299 RTL_CONSTASCII_STRINGPARAM( "open" ) ) ) 300 { 301 ucb::OpenCommandArgument2 aOpenCommand; 302 if ( !( aCommand.Argument >>= aOpenCommand ) ) 303 { 304 OSL_ENSURE( sal_False, "Wrong argument type!" ); 305 ::ucbhelper::cancelCommandExecution( 306 uno::makeAny( lang::IllegalArgumentException( 307 rtl::OUString(), 308 static_cast< cppu::OWeakObject * >( this ), 309 -1 ) ), 310 Environment ); 311 // Unreachable 312 } 313 314 sal_Bool bOpenFolder = 315 ( ( aOpenCommand.Mode == ucb::OpenMode::ALL ) || 316 ( aOpenCommand.Mode == ucb::OpenMode::FOLDERS ) || 317 ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) ); 318 319 if ( bOpenFolder /*&& isFolder( Environment )*/ ) 320 { 321 // open as folder - return result set 322 323 uno::Reference< ucb::XDynamicResultSet > xSet 324 = new DynamicResultSet( m_xSMgr, 325 this, 326 aOpenCommand, 327 Environment ); 328 aRet <<= xSet; 329 } 330 331 if ( aOpenCommand.Sink.is() ) 332 { 333 // Open document - supply document data stream. 334 335 // Check open mode 336 if ( ( aOpenCommand.Mode 337 == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) || 338 ( aOpenCommand.Mode 339 == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) ) 340 { 341 // Unsupported. 342 ::ucbhelper::cancelCommandExecution( 343 uno::makeAny( ucb::UnsupportedOpenModeException( 344 rtl::OUString(), 345 static_cast< cppu::OWeakObject * >( this ), 346 sal_Int16( aOpenCommand.Mode ) ) ), 347 Environment ); 348 // Unreachable 349 } 350 351 352 rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); 353 uno::Reference< io::XOutputStream > xOut 354 = uno::Reference< io::XOutputStream >( 355 aOpenCommand.Sink, uno::UNO_QUERY ); 356 if ( xOut.is() ) 357 { 358 // @@@ write data into xOut 359 } 360 else 361 { 362 uno::Reference< io::XActiveDataSink > xDataSink( 363 aOpenCommand.Sink, uno::UNO_QUERY ); 364 if ( xDataSink.is() ) 365 { 366 uno::Reference< io::XInputStream > xIn 367 /* @@@ your XInputStream + XSeekable impl. object */; 368 xDataSink->setInputStream( xIn ); 369 } 370 else 371 { 372 // Note: aOpenCommand.Sink may contain an XStream 373 // implementation. Support for this type of 374 // sink is optional... 375 ::ucbhelper::cancelCommandExecution( 376 uno::makeAny( ucb::UnsupportedDataSinkException( 377 rtl::OUString(), 378 static_cast< cppu::OWeakObject * >( this ), 379 aOpenCommand.Sink ) ), 380 Environment ); 381 // Unreachable 382 } 383 } 384 } 385 } 386 #endif // IMPLEMENT_COMMAND_OPEN 387 388 #ifdef IMPLEMENT_COMMAND_INSERT 389 else if ( aCommand.Name.equalsAsciiL( 390 RTL_CONSTASCII_STRINGPARAM( "insert" ) ) ) 391 { 392 ////////////////////////////////////////////////////////////////// 393 // insert 394 ////////////////////////////////////////////////////////////////// 395 396 ucb::InsertCommandArgument arg; 397 if ( !( aCommand.Argument >>= arg ) ) 398 { 399 OSL_ENSURE( sal_False, "Wrong argument type!" ); 400 ::ucbhelper::cancelCommandExecution( 401 uno::makeAny( lang::IllegalArgumentException( 402 rtl::OUString(), 403 static_cast< cppu::OWeakObject * >( this ), 404 -1 ) ), 405 Environment ); 406 // Unreachable 407 } 408 409 insert( arg.Data, arg.ReplaceExisting, Environment ); 410 } 411 #endif // IMPLEMENT_COMMAND_INSERT 412 413 #ifdef IMPLEMENT_COMMAND_DELETE 414 else if ( aCommand.Name.equalsAsciiL( 415 RTL_CONSTASCII_STRINGPARAM( "delete" ) ) ) 416 { 417 ////////////////////////////////////////////////////////////////// 418 // delete 419 ////////////////////////////////////////////////////////////////// 420 421 sal_Bool bDeletePhysical = sal_False; 422 aCommand.Argument >>= bDeletePhysical; 423 destroy( bDeletePhysical ); 424 425 // Remove own and all children's Additional Core Properties. 426 removeAdditionalPropertySet( sal_True ); 427 428 // Remove own and all childrens(!) persistent data. 429 // removeData(); 430 } 431 #endif // IMPLEMENT_COMMAND_DELETE 432 else 433 { 434 ////////////////////////////////////////////////////////////////// 435 // Unsupported command 436 ////////////////////////////////////////////////////////////////// 437 438 OSL_ENSURE( sal_False, "Content::execute - unsupported command!" ); 439 440 ::ucbhelper::cancelCommandExecution( 441 uno::makeAny( ucb::UnsupportedCommandException( 442 rtl::OUString(), 443 static_cast< cppu::OWeakObject * >( this ) ) ), 444 Environment ); 445 // Unreachable 446 } 447 448 return aRet; 449 } 450 451 //========================================================================= 452 // virtual 453 void SAL_CALL Content::abort( sal_Int32 ) 454 { 455 // @@@ Implement logic to abort running commands, if this makes 456 // sense for your content. 457 } 458 459 //========================================================================= 460 // 461 // Non-interface methods. 462 // 463 //========================================================================= 464 465 // virtual 466 rtl::OUString Content::getParentURL() 467 { 468 rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); 469 470 // @@@ Extract URL of parent from aURL and return it... 471 472 return rtl::OUString(); 473 } 474 475 //========================================================================= 476 // static 477 uno::Reference< sdbc::XRow > Content::getPropertyValues( 478 const uno::Reference< lang::XMultiServiceFactory >& rSMgr, 479 const uno::Sequence< beans::Property >& rProperties, 480 const ContentProperties& rData, 481 const rtl::Reference< 482 ::ucbhelper::ContentProviderImplHelper >& rProvider, 483 const rtl::OUString& rContentId ) 484 { 485 // Note: Empty sequence means "get values of all supported properties". 486 487 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow 488 = new ::ucbhelper::PropertyValueSet( rSMgr ); 489 490 sal_Int32 nCount = rProperties.getLength(); 491 if ( nCount ) 492 { 493 uno::Reference< beans::XPropertySet > xAdditionalPropSet; 494 sal_Bool bTriedToGetAdditonalPropSet = sal_False; 495 496 const beans::Property* pProps = rProperties.getConstArray(); 497 for ( sal_Int32 n = 0; n < nCount; ++n ) 498 { 499 const beans::Property& rProp = pProps[ n ]; 500 501 // Process Core properties. 502 503 if ( rProp.Name.equalsAsciiL( 504 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) 505 { 506 xRow->appendString ( rProp, rData.aContentType ); 507 } 508 else if ( rProp.Name.equalsAsciiL( 509 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 510 { 511 xRow->appendString ( rProp, rData.aTitle ); 512 } 513 else if ( rProp.Name.equalsAsciiL( 514 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) 515 { 516 xRow->appendBoolean( rProp, rData.bIsDocument ); 517 } 518 else if ( rProp.Name.equalsAsciiL( 519 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) 520 { 521 xRow->appendBoolean( rProp, rData.bIsFolder ); 522 } 523 524 // @@@ Process other properties supported directly. 525 #if 0 526 else if ( rProp.Name.equalsAsciiL( 527 RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) ) 528 { 529 } 530 #endif 531 else 532 { 533 // @@@ Note: If your data source supports adding/removing 534 // properties, you should implement the interface 535 // XPropertyContainer by yourself and supply your own 536 // logic here. The base class uses the service 537 // "com.sun.star.ucb.Store" to maintain Additional Core 538 // properties. But using server functionality is preferred! 539 540 // Not a Core Property! Maybe it's an Additional Core Property?! 541 542 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) 543 { 544 xAdditionalPropSet 545 = uno::Reference< beans::XPropertySet >( 546 rProvider->getAdditionalPropertySet( rContentId, 547 sal_False ), 548 uno::UNO_QUERY ); 549 bTriedToGetAdditonalPropSet = sal_True; 550 } 551 552 if ( xAdditionalPropSet.is() ) 553 { 554 if ( !xRow->appendPropertySetValue( 555 xAdditionalPropSet, 556 rProp ) ) 557 { 558 // Append empty entry. 559 xRow->appendVoid( rProp ); 560 } 561 } 562 else 563 { 564 // Append empty entry. 565 xRow->appendVoid( rProp ); 566 } 567 } 568 } 569 } 570 else 571 { 572 // Append all Core Properties. 573 xRow->appendString ( 574 beans::Property( rtl::OUString::createFromAscii( "ContentType" ), 575 -1, 576 getCppuType( static_cast< const rtl::OUString * >( 0 ) ), 577 beans::PropertyAttribute::BOUND 578 | beans::PropertyAttribute::READONLY ), 579 rData.aContentType ); 580 xRow->appendString ( 581 beans::Property( rtl::OUString::createFromAscii( "Title" ), 582 -1, 583 getCppuType( static_cast< const rtl::OUString * >( 0 ) ), 584 beans::PropertyAttribute::BOUND ), 585 rData.aTitle ); 586 xRow->appendBoolean( 587 beans::Property( rtl::OUString::createFromAscii( "IsDocument" ), 588 -1, 589 getCppuBooleanType(), 590 beans::PropertyAttribute::BOUND 591 | beans::PropertyAttribute::READONLY ), 592 rData.bIsDocument ); 593 xRow->appendBoolean( 594 beans::Property( rtl::OUString::createFromAscii( "IsFolder" ), 595 -1, 596 getCppuBooleanType(), 597 beans::PropertyAttribute::BOUND 598 | beans::PropertyAttribute::READONLY ), 599 rData.bIsFolder ); 600 601 // @@@ Append other properties supported directly. 602 603 // @@@ Note: If your data source supports adding/removing 604 // properties, you should implement the interface 605 // XPropertyContainer by yourself and supply your own 606 // logic here. The base class uses the service 607 // "com.sun.star.ucb.Store" to maintain Additional Core 608 // properties. But using server functionality is preferred! 609 610 // Append all Additional Core Properties. 611 612 uno::Reference< beans::XPropertySet > xSet( 613 rProvider->getAdditionalPropertySet( rContentId, sal_False ), 614 uno::UNO_QUERY ); 615 xRow->appendPropertySet( xSet ); 616 } 617 618 return uno::Reference< sdbc::XRow >( xRow.get() ); 619 } 620 621 //========================================================================= 622 uno::Reference< sdbc::XRow > Content::getPropertyValues( 623 const uno::Sequence< beans::Property >& rProperties, 624 const uno::Reference< ucb::XCommandEnvironment >& /* xEnv */) 625 { 626 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 627 return getPropertyValues( m_xSMgr, 628 rProperties, 629 m_aProps, 630 rtl::Reference< 631 ::ucbhelper::ContentProviderImplHelper >( 632 m_xProvider.get() ), 633 m_xIdentifier->getContentIdentifier() ); 634 } 635 636 //========================================================================= 637 uno::Sequence< uno::Any > Content::setPropertyValues( 638 const uno::Sequence< beans::PropertyValue >& rValues, 639 const uno::Reference< ucb::XCommandEnvironment >& /* xEnv */) 640 { 641 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 642 643 uno::Sequence< uno::Any > aRet( rValues.getLength() ); 644 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() ); 645 sal_Int32 nChanged = 0; 646 647 beans::PropertyChangeEvent aEvent; 648 aEvent.Source = static_cast< cppu::OWeakObject * >( this ); 649 aEvent.Further = sal_False; 650 // aEvent.PropertyName = 651 aEvent.PropertyHandle = -1; 652 // aEvent.OldValue = 653 // aEvent.NewValue = 654 655 const beans::PropertyValue* pValues = rValues.getConstArray(); 656 sal_Int32 nCount = rValues.getLength(); 657 658 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet; 659 sal_Bool bTriedToGetAdditonalPropSet = sal_False; 660 661 for ( sal_Int32 n = 0; n < nCount; ++n ) 662 { 663 const beans::PropertyValue& rValue = pValues[ n ]; 664 665 if ( rValue.Name.equalsAsciiL( 666 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ) 667 { 668 // Read-only property! 669 aRet[ n ] <<= lang::IllegalAccessException( 670 rtl::OUString::createFromAscii( 671 "Property is read-only!" ), 672 static_cast< cppu::OWeakObject * >( this ) ); 673 } 674 else if ( rValue.Name.equalsAsciiL( 675 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ) 676 { 677 // Read-only property! 678 aRet[ n ] <<= lang::IllegalAccessException( 679 rtl::OUString::createFromAscii( 680 "Property is read-only!" ), 681 static_cast< cppu::OWeakObject * >( this ) ); 682 } 683 else if ( rValue.Name.equalsAsciiL( 684 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ) 685 { 686 // Read-only property! 687 aRet[ n ] <<= lang::IllegalAccessException( 688 rtl::OUString::createFromAscii( 689 "Property is read-only!" ), 690 static_cast< cppu::OWeakObject * >( this ) ); 691 } 692 else if ( rValue.Name.equalsAsciiL( 693 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 694 { 695 rtl::OUString aNewValue; 696 if ( rValue.Value >>= aNewValue ) 697 { 698 if ( aNewValue != m_aProps.aTitle ) 699 { 700 aEvent.PropertyName = rValue.Name; 701 aEvent.OldValue = uno::makeAny( m_aProps.aTitle ); 702 aEvent.NewValue = uno::makeAny( aNewValue ); 703 704 aChanges.getArray()[ nChanged ] = aEvent; 705 706 m_aProps.aTitle = aNewValue; 707 nChanged++; 708 } 709 else 710 { 711 // Old value equals new value. No error! 712 } 713 } 714 else 715 { 716 aRet[ n ] <<= beans::IllegalTypeException( 717 rtl::OUString::createFromAscii( 718 "Property value has wrong type!" ), 719 static_cast< cppu::OWeakObject * >( this ) ); 720 } 721 } 722 723 // @@@ Process other properties supported directly. 724 #if 0 725 else if ( rValue.Name.equalsAsciiL( 726 RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) ) 727 { 728 } 729 #endif 730 else 731 { 732 // @@@ Note: If your data source supports adding/removing 733 // properties, you should implement the interface 734 // XPropertyContainer by yourself and supply your own 735 // logic here. The base class uses the service 736 // "com.sun.star.ucb.Store" to maintain Additional Core 737 // properties. But using server functionality is preferred! 738 739 // Not a Core Property! Maybe it's an Additional Core Property?! 740 741 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() ) 742 { 743 xAdditionalPropSet = getAdditionalPropertySet( sal_False ); 744 bTriedToGetAdditonalPropSet = sal_True; 745 } 746 747 if ( xAdditionalPropSet.is() ) 748 { 749 try 750 { 751 uno::Any aOldValue 752 = xAdditionalPropSet->getPropertyValue( rValue.Name ); 753 if ( aOldValue != rValue.Value ) 754 { 755 xAdditionalPropSet->setPropertyValue( 756 rValue.Name, rValue.Value ); 757 758 aEvent.PropertyName = rValue.Name; 759 aEvent.OldValue = aOldValue; 760 aEvent.NewValue = rValue.Value; 761 762 aChanges.getArray()[ nChanged ] = aEvent; 763 nChanged++; 764 } 765 else 766 { 767 // Old value equals new value. No error! 768 } 769 } 770 catch ( beans::UnknownPropertyException const & e ) 771 { 772 aRet[ n ] <<= e; 773 } 774 catch ( lang::WrappedTargetException const & e ) 775 { 776 aRet[ n ] <<= e; 777 } 778 catch ( beans::PropertyVetoException const & e ) 779 { 780 aRet[ n ] <<= e; 781 } 782 catch ( lang::IllegalArgumentException const & e ) 783 { 784 aRet[ n ] <<= e; 785 } 786 } 787 else 788 { 789 aRet[ n ] <<= uno::Exception( 790 rtl::OUString::createFromAscii( 791 "No property set for storing the value!" ), 792 static_cast< cppu::OWeakObject * >( this ) ); 793 } 794 } 795 } 796 797 if ( nChanged > 0 ) 798 { 799 // @@@ Save changes. 800 // storeData(); 801 802 aGuard.clear(); 803 aChanges.realloc( nChanged ); 804 notifyPropertiesChange( aChanges ); 805 } 806 807 return aRet; 808 } 809 810 #ifdef IMPLEMENT_COMMAND_INSERT 811 812 //========================================================================= 813 void Content::queryChildren( ContentRefList& rChildren ) 814 { 815 // @@@ Adapt method to your URL scheme... 816 817 // Obtain a list with a snapshot of all currently instantiated contents 818 // from provider and extract the contents which are direct children 819 // of this content. 820 821 ::ucbhelper::ContentRefList aAllContents; 822 m_xProvider->queryExistingContents( aAllContents ); 823 824 ::rtl::OUString aURL = m_xIdentifier->getContentIdentifier(); 825 sal_Int32 nPos = aURL.lastIndexOf( '/' ); 826 827 if ( nPos != ( aURL.getLength() - 1 ) ) 828 { 829 // No trailing slash found. Append. 830 aURL += ::rtl::OUString::createFromAscii( "/" ); 831 } 832 833 sal_Int32 nLen = aURL.getLength(); 834 835 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin(); 836 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end(); 837 838 while ( it != end ) 839 { 840 ::ucbhelper::ContentImplHelperRef xChild = (*it); 841 ::rtl::OUString aChildURL 842 = xChild->getIdentifier()->getContentIdentifier(); 843 844 // Is aURL a prefix of aChildURL? 845 if ( ( aChildURL.getLength() > nLen ) && 846 ( aChildURL.compareTo( aURL, nLen ) == 0 ) ) 847 { 848 nPos = aChildURL.indexOf( '/', nLen ); 849 850 if ( ( nPos == -1 ) || 851 ( nPos == ( aChildURL.getLength() - 1 ) ) ) 852 { 853 // No further slashes / only a final slash. It's a child! 854 rChildren.push_back( 855 ContentRef( 856 static_cast< Content * >( xChild.get() ) ) ); 857 } 858 } 859 ++it; 860 } 861 } 862 863 //========================================================================= 864 void Content::insert( 865 const uno::Reference< io::XInputStream > & xInputStream, 866 sal_Bool bReplaceExisting, 867 const uno::Reference< ucb::XCommandEnvironment >& Environment ) 868 { 869 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex ); 870 871 // Check, if all required properties were set. 872 873 #if 0 874 // @@@ add checks for property presence 875 if ( m_aProps.xxxx == yyyyy ) 876 { 877 OSL_ENSURE( sal_False, "Content::insert - property value missing!" ); 878 879 uno::Sequence< rtl::OUString > aProps( 1 ); 880 aProps[ 0 ] = rtl::OUString::createFromAscii( "zzzz" ); 881 ::ucbhelper::cancelCommandExecution( 882 uno::makeAny( ucb::MissingPropertiesException( 883 rtl::OUString(), 884 static_cast< cppu::OWeakObject * >( this ), 885 aProps ) ), 886 Environment ); 887 // Unreachable 888 } 889 #endif 890 891 bool bNeedInputStream = true; // @@@ adjust to real requirements 892 if ( bNeedInputStream && !xInputStream.is() ) 893 { 894 OSL_ENSURE( sal_False, "Content::insert - No data stream!" ); 895 896 ::ucbhelper::cancelCommandExecution( 897 uno::makeAny( ucb::MissingInputStreamException( 898 rtl::OUString(), 899 static_cast< cppu::OWeakObject * >( this ) ) ), 900 Environment ); 901 // Unreachable 902 } 903 904 // Assemble new content identifier... 905 906 uno::Reference< ucb::XContentIdentifier > xId /* @@@ create content identifier */; 907 908 // Fail, if a resource with given id already exists. 909 if ( !bReplaceExisting /*&& hasData( xId ) @@@ impl for hasData() */ ) 910 { 911 uno::Any aProps 912 = uno::makeAny( beans::PropertyValue( 913 rtl::OUString( 914 RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), 915 -1, 916 uno::makeAny( xId->getContentIdentifier() ), 917 beans::PropertyState_DIRECT_VALUE ) ); 918 ucbhelper::cancelCommandExecution( 919 ucb::IOErrorCode_ALREADY_EXISTING, 920 uno::Sequence< uno::Any >(&aProps, 1), 921 Environment, 922 rtl::OUString::createFromAscii( "content already existing!!" ), 923 this ); 924 // Unreachable 925 } 926 927 m_xIdentifier = xId; 928 929 // @@@ 930 // storeData(); 931 932 aGuard.clear(); 933 inserted(); 934 } 935 936 #endif // IMPLEMENT_COMMAND_INSERT 937 938 #ifdef IMPLEMENT_COMMAND_DELETE 939 940 //========================================================================= 941 void Content::destroy( sal_Bool bDeletePhysical ) 942 { 943 // @@@ take care about bDeletePhysical -> trashcan support 944 945 uno::Reference< ucb::XContent > xThis = this; 946 947 deleted(); 948 949 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 950 951 // Process instantiated children... 952 953 ContentRefList aChildren; 954 queryChildren( aChildren ); 955 956 ContentRefList::const_iterator it = aChildren.begin(); 957 ContentRefList::const_iterator end = aChildren.end(); 958 959 while ( it != end ) 960 { 961 (*it)->destroy( bDeletePhysical ); 962 ++it; 963 } 964 } 965 966 #endif // IMPLEMENT_COMMAND_DELETE 967