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