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_desktop.hxx" 26 27 #include "dp_help.hrc" 28 #include "dp_backend.h" 29 #include "dp_helpbackenddb.hxx" 30 #include "dp_ucb.h" 31 #include "rtl/uri.hxx" 32 #include "osl/file.hxx" 33 #include "rtl/bootstrap.hxx" 34 #include "ucbhelper/content.hxx" 35 #include "comphelper/servicedecl.hxx" 36 #include "svl/inettype.hxx" 37 #include "unotools/pathoptions.hxx" 38 39 #include <l10ntools/compilehelp.hxx> 40 #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 41 #include <com/sun/star/util/XMacroExpander.hpp> 42 #include <com/sun/star/uri/XUriReferenceFactory.hpp> 43 #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> 44 #include <com/sun/star/script/XInvocation.hpp> 45 #include "boost/optional.hpp" 46 47 using namespace ::dp_misc; 48 using namespace ::com::sun::star; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::ucb; 51 using ::rtl::OUString; 52 53 namespace dp_registry { 54 namespace backend { 55 namespace help { 56 namespace { 57 58 //============================================================================== 59 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend 60 { 61 class PackageImpl : public ::dp_registry::backend::Package 62 { 63 BackendImpl * getMyBackend() const; 64 65 // HelpBackendDb::Data m_dbData; 66 67 // Package 68 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( 69 ::osl::ResettableMutexGuard & guard, 70 ::rtl::Reference<AbortChannel> const & abortChannel, 71 Reference<XCommandEnvironment> const & xCmdEnv ); 72 virtual void processPackage_( 73 ::osl::ResettableMutexGuard & guard, 74 bool registerPackage, 75 bool startup, 76 ::rtl::Reference<AbortChannel> const & abortChannel, 77 Reference<XCommandEnvironment> const & xCmdEnv ); 78 79 80 public: 81 PackageImpl( 82 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 83 OUString const & url, OUString const & name, 84 Reference<deployment::XPackageTypeInfo> const & xPackageType, 85 bool bRemoved, OUString const & identifier); 86 87 bool extensionContainsCompiledHelp(); 88 89 //XPackage 90 virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL(); 91 }; 92 friend class PackageImpl; 93 94 // PackageRegistryBackend 95 virtual Reference<deployment::XPackage> bindPackage_( 96 OUString const & url, OUString const & mediaType, 97 sal_Bool bRemoved, OUString const & identifier, 98 Reference<XCommandEnvironment> const & xCmdEnv ); 99 100 void implProcessHelp( PackageImpl * package, bool doRegisterPackage, 101 Reference<ucb::XCommandEnvironment> const & xCmdEnv); 102 void implCollectXhpFiles( const rtl::OUString& aDir, 103 std::vector< rtl::OUString >& o_rXhpFileVector ); 104 105 void addDataToDb(OUString const & url, HelpBackendDb::Data const & data); 106 ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url); 107 bool hasActiveEntry(OUString const & url); 108 void revokeEntryFromDb(OUString const & url); 109 bool activateEntry(OUString const & url); 110 111 Reference< ucb::XSimpleFileAccess > getFileAccess( void ); 112 Reference< ucb::XSimpleFileAccess > m_xSFA; 113 114 const Reference<deployment::XPackageTypeInfo> m_xHelpTypeInfo; 115 Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos; 116 std::auto_ptr<HelpBackendDb> m_backendDb; 117 118 public: 119 BackendImpl( Sequence<Any> const & args, 120 Reference<XComponentContext> const & xComponentContext ); 121 122 // XPackageRegistry 123 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL 124 getSupportedPackageTypes(); 125 virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType); 126 127 }; 128 129 //______________________________________________________________________________ 130 BackendImpl::BackendImpl( 131 Sequence<Any> const & args, 132 Reference<XComponentContext> const & xComponentContext ) 133 : PackageRegistryBackend( args, xComponentContext ), 134 m_xHelpTypeInfo( new Package::TypeInfo( 135 OUSTR("application/vnd.sun.star.help"), 136 rtl::OUString(), 137 getResourceString(RID_STR_HELP), 138 RID_IMG_HELP, RID_IMG_HELP_HC ) ), 139 m_typeInfos( 1 ) 140 { 141 m_typeInfos[ 0 ] = m_xHelpTypeInfo; 142 if (!transientMode()) 143 { 144 OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml")); 145 m_backendDb.reset( 146 new HelpBackendDb(getComponentContext(), dbFile)); 147 148 //clean up data folders which are no longer used. 149 //This must not be done in the same process where the help files 150 //are still registers. Only after revoking and restarting OOo the folders 151 //can be removed. This works now, because the extension manager is a singleton 152 //and the backends are only create once per process. 153 ::std::list<OUString> folders = m_backendDb->getAllDataUrls(); 154 deleteUnusedFolders(OUString(), folders); 155 } 156 } 157 158 // XPackageRegistry 159 //______________________________________________________________________________ 160 Sequence< Reference<deployment::XPackageTypeInfo> > 161 BackendImpl::getSupportedPackageTypes() 162 { 163 return m_typeInfos; 164 } 165 166 void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/) 167 { 168 if (m_backendDb.get()) 169 m_backendDb->removeEntry(url); 170 } 171 172 // PackageRegistryBackend 173 //______________________________________________________________________________ 174 Reference<deployment::XPackage> BackendImpl::bindPackage_( 175 OUString const & url, OUString const & mediaType_, 176 sal_Bool bRemoved, OUString const & identifier, 177 Reference<XCommandEnvironment> const & xCmdEnv ) 178 { 179 // we don't support auto detection: 180 if (mediaType_.getLength() == 0) 181 throw lang::IllegalArgumentException( 182 StrCannotDetectMediaType::get() + url, 183 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) ); 184 185 String type, subType; 186 INetContentTypeParameterList params; 187 if (INetContentTypes::parse( mediaType_, type, subType, ¶ms )) 188 { 189 if (type.EqualsIgnoreCaseAscii("application")) 190 { 191 OUString name; 192 if (!bRemoved) 193 { 194 ::ucbhelper::Content ucbContent( url, xCmdEnv ); 195 name = ucbContent.getPropertyValue( 196 StrTitle::get() ).get<OUString>(); 197 } 198 199 if (subType.EqualsIgnoreCaseAscii( 200 "vnd.sun.star.help")) 201 { 202 return new PackageImpl( 203 this, url, name, m_xHelpTypeInfo, bRemoved, 204 identifier); 205 } 206 } 207 } 208 throw lang::IllegalArgumentException( 209 StrUnsupportedMediaType::get() + mediaType_, 210 static_cast<OWeakObject *>(this), 211 static_cast<sal_Int16>(-1) ); 212 } 213 214 void BackendImpl::addDataToDb( 215 OUString const & url, HelpBackendDb::Data const & data) 216 { 217 if (m_backendDb.get()) 218 m_backendDb->addEntry(url, data); 219 } 220 221 ::boost::optional<HelpBackendDb::Data> BackendImpl::readDataFromDb( 222 OUString const & url) 223 { 224 ::boost::optional<HelpBackendDb::Data> data; 225 if (m_backendDb.get()) 226 data = m_backendDb->getEntry(url); 227 return data; 228 } 229 230 bool BackendImpl::hasActiveEntry(OUString const & url) 231 { 232 if (m_backendDb.get()) 233 return m_backendDb->hasActiveEntry(url); 234 return false; 235 } 236 237 void BackendImpl::revokeEntryFromDb(OUString const & url) 238 { 239 if (m_backendDb.get()) 240 m_backendDb->revokeEntry(url); 241 } 242 243 bool BackendImpl::activateEntry(OUString const & url) 244 { 245 if (m_backendDb.get()) 246 return m_backendDb->activateEntry(url); 247 return false; 248 } 249 250 251 //############################################################################## 252 BackendImpl::PackageImpl::PackageImpl( 253 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 254 OUString const & url, OUString const & name, 255 Reference<deployment::XPackageTypeInfo> const & xPackageType, 256 bool bRemoved, OUString const & identifier) 257 : Package( myBackend, url, name, name, xPackageType, bRemoved, 258 identifier) 259 { 260 } 261 262 // Package 263 BackendImpl * BackendImpl::PackageImpl::getMyBackend() const 264 { 265 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); 266 if (NULL == pBackend) 267 { 268 //May throw a DisposedException 269 check(); 270 //We should never get here... 271 throw RuntimeException( 272 OUSTR("Failed to get the BackendImpl"), 273 static_cast<OWeakObject*>(const_cast<PackageImpl *>(this))); 274 } 275 return pBackend; 276 } 277 278 bool BackendImpl::PackageImpl::extensionContainsCompiledHelp() 279 { 280 bool bCompiled = true; 281 rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl(getURL()); 282 283 ::osl::Directory helpFolder(aExpandedHelpURL); 284 if ( helpFolder.open() == ::osl::File::E_None) 285 { 286 //iterate over the contents of the help folder 287 //We assume that all folders within the help folder contain language specific 288 //help files. If just one of them does not contain compiled help then this 289 //function returns false. 290 ::osl::DirectoryItem item; 291 ::osl::File::RC errorNext = ::osl::File::E_None; 292 while ((errorNext = helpFolder.getNextItem(item)) == ::osl::File::E_None) 293 { 294 //No find the language folders 295 ::osl::FileStatus stat(FileStatusMask_Type | FileStatusMask_FileName |FileStatusMask_FileURL); 296 if (item.getFileStatus(stat) == ::osl::File::E_None) 297 { 298 if (stat.getFileType() != ::osl::FileStatus::Directory) 299 continue; 300 301 //look if there is the folder help.idxl in the language folder 302 OUString compUrl(stat.getFileURL() + OUSTR("/help.idxl")); 303 ::osl::Directory compiledFolder(compUrl); 304 if (compiledFolder.open() != ::osl::File::E_None) 305 { 306 bCompiled = false; 307 break; 308 } 309 } 310 else 311 { 312 //Error 313 OSL_ASSERT(0); 314 bCompiled = false; 315 break; 316 } 317 } 318 if (errorNext != ::osl::File::E_NOENT 319 && errorNext != ::osl::File::E_None) 320 { 321 //Error 322 OSL_ASSERT(0); 323 bCompiled = false; 324 } 325 } 326 return bCompiled; 327 } 328 329 //______________________________________________________________________________ 330 beans::Optional< beans::Ambiguous<sal_Bool> > 331 BackendImpl::PackageImpl::isRegistered_( 332 ::osl::ResettableMutexGuard &, 333 ::rtl::Reference<AbortChannel> const &, 334 Reference<XCommandEnvironment> const & ) 335 { 336 BackendImpl * that = getMyBackend(); 337 338 bool bReg = false; 339 if (that->hasActiveEntry(getURL())) 340 bReg = true; 341 342 return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) ); 343 } 344 345 //______________________________________________________________________________ 346 void BackendImpl::PackageImpl::processPackage_( 347 ::osl::ResettableMutexGuard &, 348 bool doRegisterPackage, 349 bool /* startup */, 350 ::rtl::Reference<AbortChannel> const & abortChannel, 351 Reference<XCommandEnvironment> const & xCmdEnv ) 352 { 353 (void)doRegisterPackage; 354 (void)abortChannel; 355 (void)xCmdEnv; 356 357 BackendImpl* that = getMyBackend(); 358 that->implProcessHelp( this, doRegisterPackage, xCmdEnv); 359 } 360 361 beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL() 362 { 363 if (m_bRemoved) 364 throw deployment::ExtensionRemovedException(); 365 366 ::boost::optional<HelpBackendDb::Data> data = 367 getMyBackend()->readDataFromDb(getURL()); 368 369 if (data && getMyBackend()->hasActiveEntry(getURL())) 370 return beans::Optional<OUString>(true, data->dataUrl); 371 372 return beans::Optional<OUString>(true, OUString()); 373 } 374 375 376 //############################################################################## 377 378 static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); 379 static rtl::OUString aHelpStr( rtl::OUString::createFromAscii( "help" ) ); 380 381 382 void BackendImpl::implProcessHelp( 383 PackageImpl * package, bool doRegisterPackage, 384 Reference<ucb::XCommandEnvironment> const & xCmdEnv) 385 { 386 Reference< deployment::XPackage > xPackage(package); 387 OSL_ASSERT(xPackage.is()); 388 if (doRegisterPackage) 389 { 390 //revive already processed help if possible 391 if ( !activateEntry(xPackage->getURL())) 392 { 393 HelpBackendDb::Data data; 394 data.dataUrl = xPackage->getURL(); 395 if (!package->extensionContainsCompiledHelp()) 396 { 397 const OUString sHelpFolder = createFolder(OUString(), xCmdEnv); 398 data.dataUrl = sHelpFolder; 399 400 Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess(); 401 rtl::OUString aHelpURL = xPackage->getURL(); 402 rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl( aHelpURL ); 403 rtl::OUString aName = xPackage->getName(); 404 if( !xSFA->isFolder( aExpandedHelpURL ) ) 405 { 406 rtl::OUString aErrStr = getResourceString( RID_STR_HELPPROCESSING_GENERAL_ERROR ); 407 aErrStr += rtl::OUString::createFromAscii( "No help folder" ); 408 OWeakObject* oWeakThis = static_cast<OWeakObject *>(this); 409 throw deployment::DeploymentException( rtl::OUString(), oWeakThis, 410 makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); 411 } 412 413 Reference<XComponentContext> const & xContext = getComponentContext(); 414 Reference< script::XInvocation > xInvocation; 415 if( xContext.is() ) 416 { 417 try 418 { 419 xInvocation = Reference< script::XInvocation >( 420 xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( 421 "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY ); 422 } 423 catch (Exception &) 424 { 425 // i98680: Survive missing lucene 426 } 427 } 428 429 // Scan languages 430 Sequence< rtl::OUString > aLanguageFolderSeq = xSFA->getFolderContents( aExpandedHelpURL, true ); 431 sal_Int32 nLangCount = aLanguageFolderSeq.getLength(); 432 const rtl::OUString* pSeq = aLanguageFolderSeq.getConstArray(); 433 for( sal_Int32 iLang = 0 ; iLang < nLangCount ; ++iLang ) 434 { 435 rtl::OUString aLangURL = pSeq[iLang]; 436 if( xSFA->isFolder( aLangURL ) ) 437 { 438 std::vector< rtl::OUString > aXhpFileVector; 439 440 // calculate jar file URL 441 sal_Int32 indexStartSegment = aLangURL.lastIndexOf('/'); 442 // for example "/en" 443 OUString langFolderURLSegment( 444 aLangURL.copy( 445 indexStartSegment + 1, aLangURL.getLength() - indexStartSegment - 1)); 446 447 //create the folder in the "temporary folder" 448 ::ucbhelper::Content langFolderContent; 449 const OUString langFolderDest = makeURL(sHelpFolder, langFolderURLSegment); 450 const OUString langFolderDestExpanded = ::dp_misc::expandUnoRcUrl(langFolderDest); 451 ::dp_misc::create_folder( 452 &langFolderContent, 453 langFolderDest, xCmdEnv); 454 455 rtl::OUString aJarFile( 456 makeURL(sHelpFolder, langFolderURLSegment + aSlash + aHelpStr + 457 OUSTR(".jar"))); 458 aJarFile = ::dp_misc::expandUnoRcUrl(aJarFile); 459 460 rtl::OUString aEncodedJarFilePath = rtl::Uri::encode( 461 aJarFile, rtl_UriCharClassPchar, 462 rtl_UriEncodeIgnoreEscapes, 463 RTL_TEXTENCODING_UTF8 ); 464 rtl::OUString aDestBasePath = rtl::OUString::createFromAscii( "vnd.sun.star.zip://" ); 465 aDestBasePath += aEncodedJarFilePath; 466 aDestBasePath += rtl::OUString::createFromAscii( "/" ); 467 468 sal_Int32 nLenLangFolderURL = aLangURL.getLength() + 1; 469 470 Sequence< rtl::OUString > aSubLangSeq = xSFA->getFolderContents( aLangURL, true ); 471 sal_Int32 nSubLangCount = aSubLangSeq.getLength(); 472 const rtl::OUString* pSubLangSeq = aSubLangSeq.getConstArray(); 473 for( sal_Int32 iSubLang = 0 ; iSubLang < nSubLangCount ; ++iSubLang ) 474 { 475 rtl::OUString aSubFolderURL = pSubLangSeq[iSubLang]; 476 if( !xSFA->isFolder( aSubFolderURL ) ) 477 continue; 478 479 implCollectXhpFiles( aSubFolderURL, aXhpFileVector ); 480 481 // Copy to package (later: move?) 482 rtl::OUString aDestPath = aDestBasePath; 483 rtl::OUString aPureFolderName = aSubFolderURL.copy( nLenLangFolderURL ); 484 aDestPath += aPureFolderName; 485 xSFA->copy( aSubFolderURL, aDestPath ); 486 } 487 488 // Call compiler 489 sal_Int32 nXhpFileCount = aXhpFileVector.size(); 490 rtl::OUString* pXhpFiles = new rtl::OUString[nXhpFileCount]; 491 for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp ) 492 { 493 rtl::OUString aXhpFile = aXhpFileVector[iXhp]; 494 rtl::OUString aXhpRelFile = aXhpFile.copy( nLenLangFolderURL ); 495 pXhpFiles[iXhp] = aXhpRelFile; 496 } 497 498 rtl::OUString aOfficeHelpPath( SvtPathOptions().GetHelpPath() ); 499 rtl::OUString aOfficeHelpPathFileURL; 500 ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL ); 501 502 HelpProcessingErrorInfo aErrorInfo; 503 bool bSuccess = compileExtensionHelp( 504 aOfficeHelpPathFileURL, aHelpStr, aLangURL, 505 nXhpFileCount, pXhpFiles, 506 langFolderDestExpanded, aErrorInfo ); 507 508 if( bSuccess && xInvocation.is() ) 509 { 510 Sequence<uno::Any> aParamsSeq( 6 ); 511 512 aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) ); 513 514 rtl::OUString aLang; 515 sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' ); 516 if( nLastSlash != -1 ) 517 aLang = aLangURL.copy( nLastSlash + 1 ); 518 else 519 aLang = rtl::OUString::createFromAscii( "en" ); 520 aParamsSeq[1] = uno::makeAny( aLang ); 521 522 aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) ); 523 aParamsSeq[3] = uno::makeAny( rtl::OUString::createFromAscii( "help" ) ); 524 525 aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); 526 rtl::OUString aSystemPath; 527 osl::FileBase::getSystemPathFromFileURL( 528 langFolderDestExpanded, aSystemPath ); 529 aParamsSeq[5] = uno::makeAny( aSystemPath ); 530 531 Sequence< sal_Int16 > aOutParamIndex; 532 Sequence< uno::Any > aOutParam; 533 uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ), 534 aParamsSeq, aOutParamIndex, aOutParam ); 535 } 536 537 if( !bSuccess ) 538 { 539 sal_uInt16 nErrStrId = 0; 540 switch( aErrorInfo.m_eErrorClass ) 541 { 542 case HELPPROCESSING_GENERAL_ERROR: 543 case HELPPROCESSING_INTERNAL_ERROR: nErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR; break; 544 case HELPPROCESSING_XMLPARSING_ERROR: nErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR; break; 545 default: ; 546 }; 547 548 rtl::OUString aErrStr; 549 if( nErrStrId != 0 ) 550 { 551 aErrStr = getResourceString( nErrStrId ); 552 553 // Remoce CR/LF 554 rtl::OUString aErrMsg( aErrorInfo.m_aErrorMsg ); 555 sal_Unicode nCR = 13, nLF = 10; 556 sal_Int32 nSearchCR = aErrMsg.indexOf( nCR ); 557 sal_Int32 nSearchLF = aErrMsg.indexOf( nLF ); 558 sal_Int32 nCopy; 559 if( nSearchCR != -1 || nSearchLF != -1 ) 560 { 561 if( nSearchCR == -1 ) 562 nCopy = nSearchLF; 563 else if( nSearchLF == -1 ) 564 nCopy = nSearchCR; 565 else 566 nCopy = ( nSearchCR < nSearchLF ) ? nSearchCR : nSearchLF; 567 568 aErrMsg = aErrMsg.copy( 0, nCopy ); 569 } 570 aErrStr += aErrMsg; 571 if( nErrStrId == RID_STR_HELPPROCESSING_XMLPARSING_ERROR && aErrorInfo.m_aXMLParsingFile.getLength() ) 572 { 573 aErrStr += rtl::OUString::createFromAscii( " in " ); 574 575 rtl::OUString aDecodedFile = rtl::Uri::decode( aErrorInfo.m_aXMLParsingFile, 576 rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 577 aErrStr += aDecodedFile; 578 if( aErrorInfo.m_nXMLParsingLine != -1 ) 579 { 580 aErrStr += rtl::OUString::createFromAscii( ", line " ); 581 aErrStr += ::rtl::OUString::valueOf( aErrorInfo.m_nXMLParsingLine ); 582 } 583 } 584 } 585 586 OWeakObject* oWeakThis = static_cast<OWeakObject *>(this); 587 throw deployment::DeploymentException( rtl::OUString(), oWeakThis, 588 makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); 589 } 590 } 591 } 592 } 593 //Writing the data entry replaces writing the flag file. If we got to this 594 //point the registration was successful. 595 addDataToDb(xPackage->getURL(), data); 596 } 597 } //if (doRegisterPackage) 598 else 599 { 600 revokeEntryFromDb(xPackage->getURL()); 601 } 602 } 603 604 605 void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir, 606 std::vector< rtl::OUString >& o_rXhpFileVector ) 607 { 608 Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess(); 609 610 // Scan xhp files recursively 611 Sequence< rtl::OUString > aSeq = xSFA->getFolderContents( aDir, true ); 612 sal_Int32 nCount = aSeq.getLength(); 613 const rtl::OUString* pSeq = aSeq.getConstArray(); 614 for( sal_Int32 i = 0 ; i < nCount ; ++i ) 615 { 616 rtl::OUString aURL = pSeq[i]; 617 if( xSFA->isFolder( aURL ) ) 618 { 619 implCollectXhpFiles( aURL, o_rXhpFileVector ); 620 } 621 else 622 { 623 sal_Int32 nLastDot = aURL.lastIndexOf( '.' ); 624 if( nLastDot != -1 ) 625 { 626 rtl::OUString aExt = aURL.copy( nLastDot + 1 ); 627 if( aExt.equalsIgnoreAsciiCase( rtl::OUString::createFromAscii( "xhp" ) ) ) 628 o_rXhpFileVector.push_back( aURL ); 629 } 630 } 631 } 632 } 633 634 Reference< ucb::XSimpleFileAccess > BackendImpl::getFileAccess( void ) 635 { 636 if( !m_xSFA.is() ) 637 { 638 Reference<XComponentContext> const & xContext = getComponentContext(); 639 if( xContext.is() ) 640 { 641 m_xSFA = Reference< ucb::XSimpleFileAccess >( 642 xContext->getServiceManager()->createInstanceWithContext( 643 rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), 644 xContext ), UNO_QUERY ); 645 } 646 if( !m_xSFA.is() ) 647 { 648 throw RuntimeException( 649 ::rtl::OUString::createFromAscii( 650 "dp_registry::backend::help::BackendImpl::getFileAccess(), " 651 "could not instantiate SimpleFileAccess." ), 652 Reference< XInterface >() ); 653 } 654 } 655 return m_xSFA; 656 } 657 658 } // anon namespace 659 660 namespace sdecl = comphelper::service_decl; 661 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI; 662 extern sdecl::ServiceDecl const serviceDecl( 663 serviceBI, 664 "com.sun.star.comp.deployment.help.PackageRegistryBackend", 665 BACKEND_SERVICE_NAME ); 666 667 } // namespace help 668 } // namespace backend 669 } // namespace dp_registry 670