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