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 33 #include <stdio.h> 34 #include <osl/file.hxx> 35 #ifndef _VOS_DIAGNOSE_HXX_ 36 #include <vos/diagnose.hxx> 37 #endif 38 #include <ucbhelper/contentidentifier.hxx> 39 #include <com/sun/star/frame/XConfigManager.hpp> 40 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ 41 #include <com/sun/star/beans/PropertyAttribute.hpp> 42 #endif 43 #include <com/sun/star/beans/PropertyValue.hpp> 44 #include <com/sun/star/container/XContainer.hpp> 45 #include <com/sun/star/container/XNameAccess.hpp> 46 #include <com/sun/star/container/XNameReplace.hpp> 47 #include <com/sun/star/uno/XComponentContext.hpp> 48 #include <com/sun/star/beans/XPropertySet.hpp> 49 #include <rtl/bootstrap.hxx> 50 51 #include "databases.hxx" 52 #include "provider.hxx" 53 #include "content.hxx" 54 #include "databases.hxx" 55 56 using namespace com::sun::star; 57 using namespace chelp; 58 59 //========================================================================= 60 //========================================================================= 61 // 62 // ContentProvider Implementation. 63 // 64 //========================================================================= 65 //========================================================================= 66 67 ContentProvider::ContentProvider( 68 const uno::Reference< lang::XMultiServiceFactory >& rSMgr ) 69 : ::ucbhelper::ContentProviderImplHelper( rSMgr ), 70 isInitialized( false ), 71 m_aScheme( rtl::OUString::createFromAscii( MYUCP_URL_SCHEME ) ), 72 m_pDatabases( 0 ) 73 { 74 } 75 76 //========================================================================= 77 // virtual 78 ContentProvider::~ContentProvider() 79 { 80 delete m_pDatabases; 81 } 82 83 //========================================================================= 84 // 85 // XInterface methods. 86 // 87 //========================================================================= 88 89 XINTERFACE_IMPL_6( ContentProvider, 90 lang::XTypeProvider, 91 lang::XServiceInfo, 92 ucb::XContentProvider, 93 lang::XComponent, 94 lang::XEventListener, /* base of XContainerListener */ 95 container::XContainerListener); 96 97 //========================================================================= 98 // 99 // XTypeProvider methods. 100 // 101 //========================================================================= 102 103 XTYPEPROVIDER_IMPL_5( ContentProvider, 104 lang::XTypeProvider, 105 lang::XServiceInfo, 106 ucb::XContentProvider, 107 lang::XComponent, 108 container::XContainerListener); 109 110 //========================================================================= 111 // 112 // XServiceInfo methods. 113 // 114 //========================================================================= 115 116 rtl::OUString SAL_CALL ContentProvider::getImplementationName() 117 throw( uno::RuntimeException ) 118 { 119 return getImplementationName_Static(); 120 } 121 122 rtl::OUString ContentProvider::getImplementationName_Static() 123 { 124 return rtl::OUString::createFromAscii("CHelpContentProvider" ); 125 } 126 127 sal_Bool SAL_CALL 128 ContentProvider::supportsService(const rtl::OUString& ServiceName ) 129 throw( uno::RuntimeException ) 130 { 131 uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames(); 132 const rtl::OUString* pArray = aSNL.getArray(); 133 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 134 { 135 if( pArray[ i ] == ServiceName ) 136 return sal_True; 137 } 138 139 return sal_False; 140 } 141 142 uno::Sequence< rtl::OUString > SAL_CALL 143 ContentProvider::getSupportedServiceNames() 144 throw( uno::RuntimeException ) 145 { 146 return getSupportedServiceNames_Static(); 147 } 148 149 static uno::Reference< uno::XInterface > SAL_CALL 150 ContentProvider_CreateInstance( 151 const uno::Reference< lang::XMultiServiceFactory> & rSMgr ) 152 throw( uno::Exception ) 153 { 154 lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >( 155 new ContentProvider( rSMgr ) ); 156 return uno::Reference< uno::XInterface >::query( pX ); 157 } 158 159 uno::Sequence< rtl::OUString > 160 ContentProvider::getSupportedServiceNames_Static() 161 { 162 uno::Sequence< rtl::OUString > aSNS( 2 ); 163 aSNS.getArray()[ 0 ] = 164 rtl::OUString::createFromAscii( 165 MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 ); 166 aSNS.getArray()[ 1 ] = 167 rtl::OUString::createFromAscii( 168 MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 ); 169 170 return aSNS; 171 } 172 173 //========================================================================= 174 // 175 // Service factory implementation. 176 // 177 //========================================================================= 178 179 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider ); 180 181 //========================================================================= 182 // 183 // XContentProvider methods. 184 // 185 //========================================================================= 186 187 // virtual 188 uno::Reference< ucb::XContent > SAL_CALL 189 ContentProvider::queryContent( 190 const uno::Reference< ucb::XContentIdentifier >& xCanonicId ) 191 throw( ucb::IllegalIdentifierException, uno::RuntimeException ) 192 { 193 if ( !xCanonicId->getContentProviderScheme() 194 .equalsIgnoreAsciiCase( m_aScheme ) ) 195 { // Wrong URL-scheme 196 throw ucb::IllegalIdentifierException(); 197 } 198 199 { 200 osl::MutexGuard aGuard( m_aMutex ); 201 if( !isInitialized ) 202 init(); 203 } 204 205 if( !m_pDatabases ) 206 throw uno::RuntimeException(); 207 208 rtl::OUString aOUString( m_pDatabases->getInstallPathAsURL() ); 209 rtl::OString aOString( aOUString.getStr(), 210 aOUString.getLength(), 211 RTL_TEXTENCODING_UTF8 ); 212 213 // Check, if a content with given id already exists... 214 uno::Reference< ucb::XContent > xContent 215 = queryExistingContent( xCanonicId ).get(); 216 if ( xContent.is() ) 217 return xContent; 218 219 xContent = new Content( m_xSMgr, this, xCanonicId, m_pDatabases ); 220 221 // register new content 222 registerNewContent( xContent ); 223 224 // Further checks 225 226 if ( !xContent->getIdentifier().is() ) 227 throw ucb::IllegalIdentifierException(); 228 229 return xContent; 230 } 231 232 void SAL_CALL 233 ContentProvider::dispose() 234 throw ( uno::RuntimeException) 235 { 236 if(m_xContainer.is()) 237 { 238 m_xContainer->removeContainerListener(this); 239 m_xContainer.clear(); 240 } 241 } 242 243 void SAL_CALL 244 ContentProvider::elementReplaced(const container::ContainerEvent& Event) 245 throw (uno::RuntimeException) 246 { 247 if(!m_pDatabases) 248 return; 249 250 rtl::OUString accessor; 251 Event.Accessor >>= accessor; 252 if(accessor.compareToAscii("HelpStyleSheet")) 253 return; 254 255 rtl::OUString replacedElement,element; 256 Event.ReplacedElement >>= replacedElement; 257 Event.Element >>= element; 258 259 if(replacedElement == element) 260 return; 261 262 m_pDatabases->changeCSS(element); 263 } 264 265 void ContentProvider::init() 266 { 267 osl::MutexGuard aGuard( m_aMutex ); 268 269 isInitialized = true; 270 uno::Reference< lang::XMultiServiceFactory > sProvider( 271 getConfiguration() ); 272 uno::Reference< container::XHierarchicalNameAccess > xHierAccess( 273 getHierAccess( sProvider, 274 "org.openoffice.Office.Common" ) ); 275 276 rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) ); 277 if( ! instPath.getLength() ) 278 // try to determine path from default 279 instPath = rtl::OUString::createFromAscii( "$(instpath)/help" ); 280 // replace anything like $(instpath); 281 subst( instPath ); 282 283 rtl::OUString stylesheet( getKey( xHierAccess,"Help/HelpStyleSheet" ) ); 284 try 285 { 286 // now adding as configuration change listener for the stylesheet 287 uno::Reference< container::XNameAccess> xAccess( 288 xHierAccess, uno::UNO_QUERY ); 289 if( xAccess.is() ) 290 { 291 uno::Any aAny = 292 xAccess->getByName( rtl::OUString::createFromAscii( "Help" ) ); 293 aAny >>= m_xContainer; 294 if( m_xContainer.is() ) 295 m_xContainer->addContainerListener( this ); 296 } 297 } 298 catch( uno::Exception const & ) 299 { 300 } 301 302 /** 303 * now determing 304 * productname, 305 * productversion, 306 */ 307 308 xHierAccess = getHierAccess( sProvider, "org.openoffice.Setup" ); 309 rtl::OUString productname( 310 getKey( xHierAccess,"Product/ooName" ) ); 311 312 rtl::OUString setupversion( 313 getKey( xHierAccess,"Product/ooSetupVersion" ) ); 314 rtl::OUString setupextension; 315 316 try 317 { 318 uno::Reference< lang::XMultiServiceFactory > xConfigProvider( 319 m_xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW); 320 321 uno::Sequence < uno::Any > lParams(1); 322 beans::PropertyValue aParam ; 323 aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); 324 aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product"); 325 lParams[0] = uno::makeAny(aParam); 326 327 // open it 328 uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( 329 ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), 330 lParams) ); 331 332 uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY); 333 uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension")); 334 335 aRet >>= setupextension; 336 } 337 catch ( uno::Exception& ) 338 { 339 } 340 341 rtl::OUString productversion( 342 setupversion + 343 rtl::OUString::createFromAscii( " " ) + 344 setupextension ); 345 346 uno::Sequence< rtl::OUString > aImagesZipPaths( 2 ); 347 xHierAccess = getHierAccess( sProvider, "org.openoffice.Office.Common" ); 348 349 rtl::OUString aPath( getKey( xHierAccess, "Path/Current/UserConfig" ) ); 350 subst( aPath ); 351 aImagesZipPaths[ 0 ] = aPath; 352 353 aPath = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/config")); 354 rtl::Bootstrap::expandMacros(aPath); 355 aImagesZipPaths[ 1 ] = aPath; 356 357 uno::Reference< uno::XComponentContext > xContext; 358 uno::Reference< beans::XPropertySet > xProps( m_xSMgr, uno::UNO_QUERY ); 359 OSL_ASSERT( xProps.is() ); 360 if (xProps.is()) 361 { 362 xProps->getPropertyValue( 363 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext; 364 OSL_ASSERT( xContext.is() ); 365 } 366 367 sal_Bool showBasic = getBooleanKey(xHierAccess,"Help/ShowBasic"); 368 m_pDatabases = new Databases( showBasic, 369 instPath, 370 aImagesZipPaths, 371 productname, 372 productversion, 373 stylesheet, 374 xContext ); 375 } 376 377 uno::Reference< lang::XMultiServiceFactory > 378 ContentProvider::getConfiguration() const 379 { 380 uno::Reference< lang::XMultiServiceFactory > sProvider; 381 if( m_xSMgr.is() ) 382 { 383 try 384 { 385 rtl::OUString sProviderService = 386 rtl::OUString::createFromAscii( 387 "com.sun.star.configuration.ConfigurationProvider" ); 388 sProvider = 389 uno::Reference< lang::XMultiServiceFactory >( 390 m_xSMgr->createInstance( sProviderService ), 391 uno::UNO_QUERY ); 392 } 393 catch( const uno::Exception& ) 394 { 395 OSL_ENSURE( sProvider.is(), "cant instantiate configuration" ); 396 } 397 } 398 399 return sProvider; 400 } 401 402 uno::Reference< container::XHierarchicalNameAccess > 403 ContentProvider::getHierAccess( 404 const uno::Reference< lang::XMultiServiceFactory >& sProvider, 405 const char* file ) const 406 { 407 uno::Reference< container::XHierarchicalNameAccess > xHierAccess; 408 409 if( sProvider.is() ) 410 { 411 uno::Sequence< uno::Any > seq( 1 ); 412 rtl::OUString sReaderService( 413 rtl::OUString::createFromAscii( 414 "com.sun.star.configuration.ConfigurationAccess" ) ); 415 416 seq[ 0 ] <<= rtl::OUString::createFromAscii( file ); 417 418 try 419 { 420 xHierAccess = 421 uno::Reference< container::XHierarchicalNameAccess >( 422 sProvider->createInstanceWithArguments( 423 sReaderService, seq ), 424 uno::UNO_QUERY ); 425 } 426 catch( const uno::Exception& ) 427 { 428 } 429 } 430 return xHierAccess; 431 } 432 433 434 435 rtl::OUString 436 ContentProvider::getKey( 437 const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess, 438 const char* key ) const 439 { 440 rtl::OUString instPath; 441 if( xHierAccess.is() ) 442 { 443 uno::Any aAny; 444 try 445 { 446 aAny = 447 xHierAccess->getByHierarchicalName( 448 rtl::OUString::createFromAscii( key ) ); 449 } 450 catch( const container::NoSuchElementException& ) 451 { 452 } 453 aAny >>= instPath; 454 } 455 return instPath; 456 } 457 458 sal_Bool 459 ContentProvider::getBooleanKey( 460 const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess, 461 const char* key ) const 462 { 463 sal_Bool ret = sal_False; 464 if( xHierAccess.is() ) 465 { 466 uno::Any aAny; 467 try 468 { 469 aAny = 470 xHierAccess->getByHierarchicalName( 471 rtl::OUString::createFromAscii( key ) ); 472 } 473 catch( const container::NoSuchElementException& ) 474 { 475 } 476 aAny >>= ret; 477 } 478 return ret; 479 } 480 481 void ContentProvider::subst( rtl::OUString& instpath ) const 482 { 483 uno::Reference< frame::XConfigManager > xCfgMgr; 484 if( m_xSMgr.is() ) 485 { 486 try 487 { 488 xCfgMgr = 489 uno::Reference< frame::XConfigManager >( 490 m_xSMgr->createInstance( 491 rtl::OUString::createFromAscii( 492 "com.sun.star.config.SpecialConfigManager" ) ), 493 uno::UNO_QUERY ); 494 } 495 catch( const uno::Exception&) 496 { 497 OSL_ENSURE( xCfgMgr.is(), 498 "cant instantiate the special config manager " ); 499 } 500 } 501 502 OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" ); 503 504 if( xCfgMgr.is() ) 505 instpath = xCfgMgr->substituteVariables( instpath ); 506 } 507