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_xmlhelp.hxx" 30 31 /************************************************************************** 32 TODO 33 ************************************************************************** 34 35 *************************************************************************/ 36 #include <com/sun/star/beans/PropertyAttribute.hpp> 37 #include <com/sun/star/beans/XPropertyAccess.hpp> 38 #include <com/sun/star/sdbc/XRow.hpp> 39 #include <com/sun/star/ucb/OpenCommandArgument2.hpp> 40 #include <com/sun/star/ucb/OpenMode.hpp> 41 #include <com/sun/star/ucb/XCommandInfo.hpp> 42 #include <com/sun/star/io/XActiveDataSink.hpp> 43 #include <com/sun/star/io/XOutputStream.hpp> 44 #include <com/sun/star/lang/IllegalAccessException.hpp> 45 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> 46 #include <com/sun/star/io/XActiveDataStreamer.hpp> 47 #include <com/sun/star/ucb/XPersistentPropertySet.hpp> 48 #ifndef _VOS_DIAGNOSE_HXX_ 49 #include <vos/diagnose.hxx> 50 #endif 51 #include <ucbhelper/contentidentifier.hxx> 52 #include <ucbhelper/propertyvalueset.hxx> 53 #ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX 54 #include <ucbhelper/cancelcommandexecution.hxx> 55 #endif 56 #include "content.hxx" 57 #include "provider.hxx" 58 #include "resultset.hxx" 59 #include "databases.hxx" 60 #include "resultsetfactory.hxx" 61 #include "resultsetbase.hxx" 62 #include "resultsetforroot.hxx" 63 #include "resultsetforquery.hxx" 64 65 using namespace com::sun::star; 66 using namespace chelp; 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 >& 79 Identifier, 80 Databases* pDatabases ) 81 : ContentImplHelper( rxSMgr, pProvider, Identifier ), 82 m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ), 83 m_pDatabases( pDatabases ) // not owner 84 { 85 } 86 87 //========================================================================= 88 // virtual 89 Content::~Content() 90 { 91 } 92 93 //========================================================================= 94 // 95 // XInterface methods. 96 // 97 //========================================================================= 98 99 // virtual 100 void SAL_CALL Content::acquire() 101 throw( ) 102 { 103 ContentImplHelper::acquire(); 104 } 105 106 //========================================================================= 107 // virtual 108 void SAL_CALL Content::release() 109 throw( ) 110 { 111 ContentImplHelper::release(); 112 } 113 114 //========================================================================= 115 // virtual 116 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) 117 throw ( uno::RuntimeException ) 118 { 119 uno::Any aRet; 120 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); 121 } 122 123 //========================================================================= 124 // 125 // XTypeProvider methods. 126 // 127 //========================================================================= 128 129 XTYPEPROVIDER_COMMON_IMPL( Content ); 130 131 //========================================================================= 132 // virtual 133 uno::Sequence< uno::Type > SAL_CALL Content::getTypes() 134 throw( uno::RuntimeException ) 135 { 136 static cppu::OTypeCollection* pCollection = NULL; 137 138 if ( !pCollection ) 139 { 140 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ); 141 if ( !pCollection ) 142 { 143 static cppu::OTypeCollection aCollection( 144 CPPU_TYPE_REF( lang::XTypeProvider ), 145 CPPU_TYPE_REF( lang::XServiceInfo ), 146 CPPU_TYPE_REF( lang::XComponent ), 147 CPPU_TYPE_REF( ucb::XContent ), 148 CPPU_TYPE_REF( ucb::XCommandProcessor ), 149 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), 150 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), 151 CPPU_TYPE_REF( beans::XPropertyContainer ), 152 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), 153 CPPU_TYPE_REF( container::XChild ) ); 154 pCollection = &aCollection; 155 } 156 } 157 158 return (*pCollection).getTypes(); 159 } 160 161 //========================================================================= 162 // 163 // XServiceInfo methods. 164 // 165 //========================================================================= 166 167 // virtual 168 rtl::OUString SAL_CALL Content::getImplementationName() 169 throw( uno::RuntimeException ) 170 { 171 return rtl::OUString::createFromAscii( "CHelpContent" ); 172 } 173 174 //========================================================================= 175 // virtual 176 uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() 177 throw( uno::RuntimeException ) 178 { 179 uno::Sequence< rtl::OUString > aSNS( 1 ); 180 aSNS.getArray()[ 0 ] 181 = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME ); 182 return aSNS; 183 } 184 185 //========================================================================= 186 // 187 // XContent methods. 188 // 189 //========================================================================= 190 191 // virtual 192 rtl::OUString SAL_CALL Content::getContentType() 193 throw( uno::RuntimeException ) 194 { 195 return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE ); 196 } 197 198 //========================================================================= 199 // 200 // XCommandProcessor methods. 201 // 202 //========================================================================= 203 204 //virtual 205 void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) 206 throw( uno::RuntimeException ) 207 { 208 } 209 210 211 212 class ResultSetForRootFactory 213 : public ResultSetFactory 214 { 215 private: 216 217 uno::Reference< lang::XMultiServiceFactory > m_xSMgr; 218 uno::Reference< ucb::XContentProvider > m_xProvider; 219 sal_Int32 m_nOpenMode; 220 uno::Sequence< beans::Property > m_seq; 221 uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; 222 URLParameter m_aURLParameter; 223 Databases* m_pDatabases; 224 225 226 public: 227 228 ResultSetForRootFactory( 229 const uno::Reference< lang::XMultiServiceFactory >& xSMgr, 230 const uno::Reference< ucb::XContentProvider >& xProvider, 231 sal_Int32 nOpenMode, 232 const uno::Sequence< beans::Property >& seq, 233 const uno::Sequence< ucb::NumberedSortingInfo >& seqSort, 234 URLParameter aURLParameter, 235 Databases* pDatabases ) 236 : m_xSMgr( xSMgr ), 237 m_xProvider( xProvider ), 238 m_nOpenMode( nOpenMode ), 239 m_seq( seq ), 240 m_seqSort( seqSort ), 241 m_aURLParameter( aURLParameter ), 242 m_pDatabases( pDatabases ) 243 { 244 } 245 246 ResultSetBase* createResultSet() 247 { 248 return new ResultSetForRoot( m_xSMgr, 249 m_xProvider, 250 m_nOpenMode, 251 m_seq, 252 m_seqSort, 253 m_aURLParameter, 254 m_pDatabases ); 255 } 256 }; 257 258 259 260 class ResultSetForQueryFactory 261 : public ResultSetFactory 262 { 263 private: 264 265 uno::Reference< lang::XMultiServiceFactory > m_xSMgr; 266 uno::Reference< ucb::XContentProvider > m_xProvider; 267 sal_Int32 m_nOpenMode; 268 uno::Sequence< beans::Property > m_seq; 269 uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; 270 URLParameter m_aURLParameter; 271 Databases* m_pDatabases; 272 273 274 public: 275 276 ResultSetForQueryFactory( 277 const uno::Reference< lang::XMultiServiceFactory >& xSMgr, 278 const uno::Reference< ucb::XContentProvider >& xProvider, 279 sal_Int32 nOpenMode, 280 const uno::Sequence< beans::Property >& seq, 281 const uno::Sequence< ucb::NumberedSortingInfo >& seqSort, 282 URLParameter aURLParameter, 283 Databases* pDatabases ) 284 : m_xSMgr( xSMgr ), 285 m_xProvider( xProvider ), 286 m_nOpenMode( nOpenMode ), 287 m_seq( seq ), 288 m_seqSort( seqSort ), 289 m_aURLParameter( aURLParameter ), 290 m_pDatabases( pDatabases ) 291 { 292 } 293 294 ResultSetBase* createResultSet() 295 { 296 return new ResultSetForQuery( m_xSMgr, 297 m_xProvider, 298 m_nOpenMode, 299 m_seq, 300 m_seqSort, 301 m_aURLParameter, 302 m_pDatabases ); 303 } 304 }; 305 306 307 308 // virtual 309 uno::Any SAL_CALL Content::execute( 310 const ucb::Command& aCommand, 311 sal_Int32 CommandId, 312 const uno::Reference< ucb::XCommandEnvironment >& Environment ) 313 throw( uno::Exception, 314 ucb::CommandAbortedException, 315 uno::RuntimeException ) 316 { 317 uno::Any aRet; 318 319 if ( aCommand.Name.compareToAscii( "getPropertyValues" ) == 0 ) 320 { 321 uno::Sequence< beans::Property > Properties; 322 if ( !( aCommand.Argument >>= Properties ) ) 323 { 324 aRet <<= lang::IllegalArgumentException(); 325 ucbhelper::cancelCommandExecution(aRet,Environment); 326 } 327 328 aRet <<= getPropertyValues( Properties ); 329 } 330 else if ( aCommand.Name.compareToAscii( "setPropertyValues" ) == 0 ) 331 { 332 uno::Sequence<beans::PropertyValue> propertyValues; 333 334 if( ! ( aCommand.Argument >>= propertyValues ) ) { 335 aRet <<= lang::IllegalArgumentException(); 336 ucbhelper::cancelCommandExecution(aRet,Environment); 337 } 338 339 uno::Sequence< uno::Any > ret(propertyValues.getLength()); 340 uno::Sequence< beans::Property > props(getProperties(Environment)); 341 // No properties can be set 342 for(sal_Int32 i = 0; i < ret.getLength(); ++i) { 343 ret[i] <<= beans::UnknownPropertyException(); 344 for(sal_Int32 j = 0; j < props.getLength(); ++j) 345 if(props[j].Name == propertyValues[i].Name) { 346 ret[i] <<= lang::IllegalAccessException(); 347 break; 348 } 349 } 350 351 aRet <<= ret; 352 } 353 else if ( aCommand.Name.compareToAscii( "getPropertySetInfo" ) == 0 ) 354 { 355 // Note: Implemented by base class. 356 aRet <<= getPropertySetInfo( Environment ); 357 } 358 else if ( aCommand.Name.compareToAscii( "getCommandInfo" ) == 0 ) 359 { 360 // Note: Implemented by base class. 361 aRet <<= getCommandInfo( Environment ); 362 } 363 else if ( aCommand.Name.compareToAscii( "open" ) == 0 ) 364 { 365 ucb::OpenCommandArgument2 aOpenCommand; 366 if ( !( aCommand.Argument >>= aOpenCommand ) ) 367 { 368 aRet <<= lang::IllegalArgumentException(); 369 ucbhelper::cancelCommandExecution(aRet,Environment); 370 } 371 372 uno::Reference< io::XActiveDataSink > xActiveDataSink( 373 aOpenCommand.Sink, uno::UNO_QUERY); 374 375 if(xActiveDataSink.is()) 376 m_aURLParameter.open(m_xSMgr, 377 aCommand, 378 CommandId, 379 Environment, 380 xActiveDataSink); 381 382 uno::Reference< io::XActiveDataStreamer > xActiveDataStreamer( 383 aOpenCommand.Sink, uno::UNO_QUERY); 384 385 if(xActiveDataStreamer.is()) { 386 aRet <<= ucb::UnsupportedDataSinkException(); 387 ucbhelper::cancelCommandExecution(aRet,Environment); 388 } 389 390 uno::Reference< io::XOutputStream > xOutputStream( 391 aOpenCommand.Sink, uno::UNO_QUERY); 392 393 if(xOutputStream.is() ) 394 m_aURLParameter.open(m_xSMgr, 395 aCommand, 396 CommandId, 397 Environment, 398 xOutputStream); 399 400 if( m_aURLParameter.isRoot() ) 401 { 402 uno::Reference< ucb::XDynamicResultSet > xSet 403 = new DynamicResultSet( 404 m_xSMgr, 405 this, 406 aOpenCommand, 407 Environment, 408 new ResultSetForRootFactory( 409 m_xSMgr, 410 m_xProvider.get(), 411 aOpenCommand.Mode, 412 aOpenCommand.Properties, 413 aOpenCommand.SortingInfo, 414 m_aURLParameter, 415 m_pDatabases)); 416 aRet <<= xSet; 417 } 418 else if( m_aURLParameter.isQuery() ) 419 { 420 uno::Reference< ucb::XDynamicResultSet > xSet 421 = new DynamicResultSet( 422 m_xSMgr, 423 this, 424 aOpenCommand, 425 Environment, 426 new ResultSetForQueryFactory( 427 m_xSMgr, 428 m_xProvider.get(), 429 aOpenCommand.Mode, 430 aOpenCommand.Properties, 431 aOpenCommand.SortingInfo, 432 m_aURLParameter, 433 m_pDatabases ) ); 434 aRet <<= xSet; 435 } 436 } 437 else 438 { 439 ////////////////////////////////////////////////////////////////// 440 // Unsupported command 441 ////////////////////////////////////////////////////////////////// 442 aRet <<= ucb::UnsupportedCommandException(); 443 ucbhelper::cancelCommandExecution(aRet,Environment); 444 } 445 446 return aRet; 447 } 448 449 450 451 452 //========================================================================= 453 uno::Reference< sdbc::XRow > Content::getPropertyValues( 454 const uno::Sequence< beans::Property >& rProperties ) 455 { 456 osl::MutexGuard aGuard( m_aMutex ); 457 458 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = 459 new ::ucbhelper::PropertyValueSet( m_xSMgr ); 460 461 for ( sal_Int32 n = 0; n < rProperties.getLength(); ++n ) 462 { 463 const beans::Property& rProp = rProperties[n]; 464 465 if ( rProp.Name.compareToAscii( "ContentType" ) == 0 ) 466 xRow->appendString( 467 rProp, 468 rtl::OUString::createFromAscii( 469 "application/vnd.sun.star.help" ) ); 470 else if( rProp.Name.compareToAscii( "Title" ) == 0 ) 471 xRow->appendString ( rProp,m_aURLParameter.get_title() ); 472 else if( rProp.Name.compareToAscii( "IsReadOnly" ) == 0 ) 473 xRow->appendBoolean( rProp,true ); 474 else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 ) 475 xRow->appendBoolean( 476 rProp, 477 m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); 478 else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 ) 479 xRow->appendBoolean( 480 rProp, 481 ! m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); 482 else if( rProp.Name.compareToAscii( "IsErrorDocument" ) == 0 ) 483 xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() ); 484 else if( rProp.Name.compareToAscii( "MediaType" ) == 0 ) 485 if( m_aURLParameter.isPicture() ) 486 xRow->appendString( 487 rProp, 488 rtl::OUString::createFromAscii( "image/gif" ) ); 489 else if( m_aURLParameter.isActive() ) 490 xRow->appendString( 491 rProp, 492 rtl::OUString::createFromAscii( "text/plain" ) ); 493 else if( m_aURLParameter.isFile() ) 494 xRow->appendString( 495 rProp,rtl::OUString::createFromAscii( "text/html" ) ); 496 else if( m_aURLParameter.isRoot() ) 497 xRow->appendString( 498 rProp, 499 rtl::OUString::createFromAscii( "text/css" ) ); 500 else 501 xRow->appendVoid( rProp ); 502 else if( m_aURLParameter.isModule() ) 503 if( rProp.Name.compareToAscii( "KeywordList" ) == 0 ) 504 { 505 KeywordInfo *inf = 506 m_pDatabases->getKeyword( m_aURLParameter.get_module(), 507 m_aURLParameter.get_language() ); 508 509 uno::Any aAny; 510 if( inf ) 511 aAny <<= inf->getKeywordList(); 512 xRow->appendObject( rProp,aAny ); 513 } 514 else if( rProp.Name.compareToAscii( "KeywordRef" ) == 0 ) 515 { 516 KeywordInfo *inf = 517 m_pDatabases->getKeyword( m_aURLParameter.get_module(), 518 m_aURLParameter.get_language() ); 519 520 uno::Any aAny; 521 if( inf ) 522 aAny <<= inf->getIdList(); 523 xRow->appendObject( rProp,aAny ); 524 } 525 else if( rProp.Name.compareToAscii( "KeywordAnchorForRef" ) == 0 ) 526 { 527 KeywordInfo *inf = 528 m_pDatabases->getKeyword( m_aURLParameter.get_module(), 529 m_aURLParameter.get_language() ); 530 531 uno::Any aAny; 532 if( inf ) 533 aAny <<= inf->getAnchorList(); 534 xRow->appendObject( rProp,aAny ); 535 } 536 else if( rProp.Name.compareToAscii( "KeywordTitleForRef" ) == 0 ) 537 { 538 KeywordInfo *inf = 539 m_pDatabases->getKeyword( m_aURLParameter.get_module(), 540 m_aURLParameter.get_language() ); 541 542 uno::Any aAny; 543 if( inf ) 544 aAny <<= inf->getTitleList(); 545 xRow->appendObject( rProp,aAny ); 546 } 547 else if( rProp.Name.compareToAscii( "SearchScopes" ) == 0 ) 548 { 549 uno::Sequence< rtl::OUString > seq( 2 ); 550 seq[0] = rtl::OUString::createFromAscii( "Heading" ); 551 seq[1] = rtl::OUString::createFromAscii( "FullText" ); 552 uno::Any aAny; 553 aAny <<= seq; 554 xRow->appendObject( rProp,aAny ); 555 } 556 else if( rProp.Name.compareToAscii( "Order" ) == 0 ) 557 { 558 StaticModuleInformation *inf = 559 m_pDatabases->getStaticInformationForModule( 560 m_aURLParameter.get_module(), 561 m_aURLParameter.get_language() ); 562 563 uno::Any aAny; 564 if( inf ) 565 aAny <<= sal_Int32( inf->get_order() ); 566 xRow->appendObject( rProp,aAny ); 567 } 568 else 569 xRow->appendVoid( rProp ); 570 else if( rProp.Name.compareToAscii( "AnchorName" ) == 0 && 571 m_aURLParameter.isFile() ) 572 xRow->appendString( rProp,m_aURLParameter.get_tag() ); 573 else 574 xRow->appendVoid( rProp ); 575 } 576 577 return uno::Reference< sdbc::XRow >( xRow.get() ); 578 } 579