21 #include <config_features.h>
23 #include <strings.hrc>
28 #include <rtl/uri.hxx>
29 #include <osl/file.hxx>
36 #if HAVE_FEATURE_XMLHELP
40 #include <com/sun/star/deployment/DeploymentException.hpp>
41 #include <com/sun/star/deployment/ExtensionRemovedException.hpp>
42 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
43 #include <com/sun/star/util/XMacroExpander.hpp>
45 #include <string_view>
60 BackendImpl * getMyBackend()
const;
63 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
64 ::osl::ResettableMutexGuard & guard,
67 virtual void processPackage_(
68 ::osl::ResettableMutexGuard & guard,
78 OUString
const & url, OUString
const &
name,
79 Reference<deployment::XPackageTypeInfo>
const & xPackageType,
82 bool extensionContainsCompiledHelp();
85 virtual css::beans::Optional< OUString > SAL_CALL getRegistrationDataURL()
override;
87 friend class PackageImpl;
90 virtual Reference<deployment::XPackage> bindPackage_(
91 OUString
const & url, OUString
const & mediaType,
95 void implProcessHelp( PackageImpl *
package,
bool doRegisterPackage,
96 Reference<ucb::XCommandEnvironment>
const & xCmdEnv);
97 void implCollectXhpFiles(
const OUString& aDir,
98 std::vector< OUString >& o_rXhpFileVector );
100 ::std::optional<HelpBackendDb::Data> readDataFromDb(std::u16string_view url);
101 bool hasActiveEntry(std::u16string_view url);
102 bool activateEntry(std::u16string_view url);
104 Reference< ucb::XSimpleFileAccess3 >
const & getFileAccess();
105 Reference< ucb::XSimpleFileAccess3 >
m_xSFA;
112 BackendImpl( Sequence<Any>
const & args,
121 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
122 getSupportedPackageTypes()
override;
123 virtual void SAL_CALL packageRemoved(OUString
const & url, OUString
const & mediaType)
override;
128 BackendImpl::BackendImpl(
129 Sequence<Any>
const & args,
131 : PackageRegistryBackend( args, xComponentContext ),
141 OUString dbFile =
makeURL(getCachePath(),
"backenddb.xml");
150 std::vector<OUString> folders =
m_backendDb->getAllDataUrls();
151 deleteUnusedFolders(folders);
155 OUString BackendImpl::getImplementationName()
157 return "com.sun.star.comp.deployment.help.PackageRegistryBackend";
160 sal_Bool BackendImpl::supportsService(
const OUString& ServiceName )
165 css::uno::Sequence< OUString > BackendImpl::getSupportedServiceNames()
172 Sequence< Reference<deployment::XPackageTypeInfo> >
173 BackendImpl::getSupportedPackageTypes()
178 void BackendImpl::packageRemoved(OUString
const & url, OUString
const & )
186 Reference<deployment::XPackage> BackendImpl::bindPackage_(
187 OUString
const & url, OUString
const & mediaType_,
188 bool bRemoved, OUString
const & identifier,
192 if (mediaType_.isEmpty())
193 throw lang::IllegalArgumentException(
194 StrCannotDetectMediaType() + url,
195 static_cast<OWeakObject *
>(
this), static_cast<sal_Int16>(-1) );
197 OUString
type, subType;
201 if (type.equalsIgnoreAsciiCase(
"application"))
208 name = StrTitle::getTitle( ucbContent );
211 if (subType.equalsIgnoreAsciiCase(
"vnd.sun.star.help"))
213 return new PackageImpl(
219 throw lang::IllegalArgumentException(
220 StrUnsupportedMediaType() + mediaType_,
221 static_cast<OWeakObject *>(
this),
222 static_cast<sal_Int16>(-1) );
225 ::std::optional<HelpBackendDb::Data> BackendImpl::readDataFromDb(
226 std::u16string_view url)
228 ::std::optional<HelpBackendDb::Data>
data;
234 bool BackendImpl::hasActiveEntry(std::u16string_view url)
241 bool BackendImpl::activateEntry(std::u16string_view url)
249 BackendImpl::PackageImpl::PackageImpl(
251 OUString
const & url, OUString
const & name,
252 Reference<deployment::XPackageTypeInfo>
const & xPackageType,
253 bool bRemoved, OUString
const & identifier)
254 :
Package( myBackend, url, name, name, xPackageType, bRemoved,
260 BackendImpl * BackendImpl::PackageImpl::getMyBackend()
const
262 BackendImpl * pBackend =
static_cast<BackendImpl *
>(m_myBackend.get());
263 if (
nullptr == pBackend)
269 static_cast<OWeakObject*>(const_cast<PackageImpl *>(
this)));
274 bool BackendImpl::PackageImpl::extensionContainsCompiledHelp()
276 bool bCompiled =
true;
279 ::osl::Directory helpFolder(aExpandedHelpURL);
280 if ( helpFolder.open() == ::osl::File::E_None)
286 ::osl::DirectoryItem item;
287 ::osl::File::RC errorNext = ::osl::File::E_None;
288 while ((errorNext = helpFolder.getNextItem(item)) == ::osl::File::E_None)
291 ::osl::FileStatus stat(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName |osl_FileStatus_Mask_FileURL);
292 if (item.getFileStatus(stat) == ::osl::File::E_None)
294 if (stat.getFileType() != ::osl::FileStatus::Directory)
298 OUString compUrl(stat.getFileURL() +
"/help.idxl");
299 ::osl::Directory compiledFolder(compUrl);
300 if (compiledFolder.open() != ::osl::File::E_None)
314 if (errorNext != ::osl::File::E_NOENT
315 && errorNext != ::osl::File::E_None)
326 beans::Optional< beans::Ambiguous<sal_Bool> >
327 BackendImpl::PackageImpl::isRegistered_(
328 ::osl::ResettableMutexGuard &,
332 BackendImpl * that = getMyBackend();
335 if (that->hasActiveEntry(getURL()))
338 return beans::Optional< beans::Ambiguous<sal_Bool> >(
true, beans::Ambiguous<sal_Bool>( bReg,
false ) );
342 void BackendImpl::PackageImpl::processPackage_(
343 ::osl::ResettableMutexGuard &,
344 bool doRegisterPackage,
349 BackendImpl* that = getMyBackend();
350 that->implProcessHelp(
this, doRegisterPackage, xCmdEnv);
353 beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL()
356 throw deployment::ExtensionRemovedException();
358 ::std::optional<HelpBackendDb::Data> data =
359 getMyBackend()->readDataFromDb(getURL());
361 if (data && getMyBackend()->hasActiveEntry(getURL()))
362 return beans::Optional<OUString>(
true, data->dataUrl);
364 return beans::Optional<OUString>(
true, OUString());
367 void BackendImpl::implProcessHelp(
368 PackageImpl *
package,
bool doRegisterPackage,
369 Reference<ucb::XCommandEnvironment>
const & xCmdEnv)
371 Reference< deployment::XPackage > xPackage(package);
372 OSL_ASSERT(xPackage.is());
373 if (doRegisterPackage)
376 if ( !activateEntry(xPackage->getURL()))
378 HelpBackendDb::Data data;
379 data.dataUrl = xPackage->getURL();
380 if (!package->extensionContainsCompiledHelp())
382 #if HAVE_FEATURE_XMLHELP
383 const OUString sHelpFolder = createFolder(xCmdEnv);
384 data.dataUrl = sHelpFolder;
386 Reference< ucb::XSimpleFileAccess3 > xSFA = getFileAccess();
387 OUString aHelpURL = xPackage->getURL();
389 if( !xSFA->isFolder( aExpandedHelpURL ) )
391 OUString aErrStr =
DpResId( RID_STR_HELPPROCESSING_GENERAL_ERROR ) +
393 OWeakObject* oWeakThis =
this;
394 throw deployment::DeploymentException( OUString(), oWeakThis,
395 Any( uno::Exception( aErrStr, oWeakThis ) ) );
400 sal_Int32 nLangCount = aLanguageFolderSeq.getLength();
401 const OUString* pSeq = aLanguageFolderSeq.getConstArray();
402 for( sal_Int32 iLang = 0 ; iLang < nLangCount ; ++iLang )
404 OUString aLangURL = pSeq[iLang];
405 if( xSFA->isFolder( aLangURL ) )
407 std::vector< OUString > aXhpFileVector;
410 sal_Int32 indexStartSegment = aLangURL.lastIndexOf(
'/');
412 OUString langFolderURLSegment(
414 indexStartSegment + 1, aLangURL.getLength() - indexStartSegment - 1));
418 const OUString langFolderDest =
makeURL(sHelpFolder, langFolderURLSegment);
422 langFolderDest, xCmdEnv);
424 static const OUStringLiteral aHelpStr(u
"help");
427 makeURL(sHelpFolder, langFolderURLSegment +
"/" + aHelpStr +
".jar"));
430 OUString aEncodedJarFilePath = rtl::Uri::encode(
431 aJarFile, rtl_UriCharClassPchar,
432 rtl_UriEncodeIgnoreEscapes,
433 RTL_TEXTENCODING_UTF8 );
434 OUString aDestBasePath =
"vnd.sun.star.zip://" +
435 aEncodedJarFilePath +
"/" ;
437 sal_Int32 nLenLangFolderURL = aLangURL.getLength() + 1;
440 sal_Int32 nSubLangCount = aSubLangSeq.getLength();
441 const OUString* pSubLangSeq = aSubLangSeq.getConstArray();
442 for( sal_Int32 iSubLang = 0 ; iSubLang < nSubLangCount ; ++iSubLang )
444 OUString aSubFolderURL = pSubLangSeq[iSubLang];
445 if( !xSFA->isFolder( aSubFolderURL ) )
448 implCollectXhpFiles( aSubFolderURL, aXhpFileVector );
451 std::u16string_view aPureFolderName = aSubFolderURL.subView( nLenLangFolderURL );
452 OUString aDestPath = aDestBasePath + aPureFolderName;
453 xSFA->copy( aSubFolderURL, aDestPath );
457 sal_Int32 nXhpFileCount = aXhpFileVector.size();
458 std::unique_ptr<OUString[]> pXhpFiles(
new OUString[nXhpFileCount]);
459 for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp )
461 OUString aXhpFile = aXhpFileVector[iXhp];
462 OUString aXhpRelFile = aXhpFile.copy( nLenLangFolderURL );
463 pXhpFiles[iXhp] = aXhpRelFile;
467 OUString aOfficeHelpPathFileURL;
468 ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL );
472 aOfficeHelpPathFileURL, aHelpStr, aLangURL,
473 nXhpFileCount, pXhpFiles.get(),
474 langFolderDestExpanded, aErrorInfo );
481 sal_Int32 nLastSlash = aLangURL.lastIndexOf(
'/' );
482 if( nLastSlash != -1 )
483 aLang = aLangURL.copy( nLastSlash + 1 );
487 HelpIndexer aIndexer(aLang,
"help", langFolderDestExpanded, langFolderDestExpanded);
488 aIndexer.indexDocuments();
496 case HelpProcessingErrorClass::General: pErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR;
break;
497 case HelpProcessingErrorClass::XmlParsing: pErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR;
break;
509 sal_Int32 nSearchCR = aErrMsg.indexOf( nCR );
510 sal_Int32 nSearchLF = aErrMsg.indexOf( nLF );
511 if( nSearchCR != -1 || nSearchLF != -1 )
514 if( nSearchCR == -1 )
516 else if( nSearchLF == -1 )
519 nCopy = ( nSearchCR < nSearchLF ) ? nSearchCR : nSearchLF;
521 aErrMsg = aErrMsg.copy( 0, nCopy );
524 if (pErrStrId != RID_STR_HELPPROCESSING_XMLPARSING_ERROR && !aErrorInfo.
m_aXMLParsingFile.isEmpty() )
529 rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
530 aErrStr += aDecodedFile;
533 aErrStr +=
", line " +
539 OWeakObject* oWeakThis =
this;
540 throw deployment::DeploymentException( OUString(), oWeakThis,
541 Any( uno::Exception( aErrStr, oWeakThis ) ) );
562 void BackendImpl::implCollectXhpFiles(
const OUString& aDir,
563 std::vector< OUString >& o_rXhpFileVector )
565 Reference< ucb::XSimpleFileAccess3 > xSFA = getFileAccess();
569 sal_Int32
nCount = aSeq.getLength();
570 const OUString* pSeq = aSeq.getConstArray();
571 for( sal_Int32 i = 0 ;
i < nCount ; ++
i )
573 OUString
aURL = pSeq[
i];
574 if( xSFA->isFolder( aURL ) )
576 implCollectXhpFiles( aURL, o_rXhpFileVector );
580 sal_Int32 nLastDot = aURL.lastIndexOf(
'.' );
583 std::u16string_view aExt = aURL.subView( nLastDot + 1 );
585 o_rXhpFileVector.push_back( aURL );
591 Reference< ucb::XSimpleFileAccess3 >
const & BackendImpl::getFileAccess()
603 "dp_registry::backend::help::BackendImpl::getFileAccess(), "
604 "could not instantiate SimpleFileAccess." );
614 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
616 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const& args)
618 return cppu::acquire(
new dp_registry::backend::help::BackendImpl(args, context));
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_deployment_help_PackageRegistryBackend_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &args)
Reference< ucb::XSimpleFileAccess3 > m_xSFA
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
OUString makeURL(OUString const &baseURL, OUString const &relPath_)
appends a relative path to a url.
HELPLINKER_DLLPUBLIC bool compileExtensionHelp(const OUString &aOfficeHelpPath, std::u16string_view aExtensionName, std::u16string_view aExtensionLanguageRoot, sal_Int32 nXhpFileCount, const OUString *pXhpFiles, std::u16string_view aDestination, HelpProcessingErrorInfo &o_rHelpProcessingErrorInfo)
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
static bool parse(OUString const &rMediaType, OUString &rType, OUString &rSubType, INetContentTypeParameterList *pParameters=nullptr)
std::unique_ptr< HelpBackendDb > m_backendDb
HelpProcessingErrorClass m_eErrorClass
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Sequence< Reference< deployment::XPackageTypeInfo > > m_typeInfos
const Reference< deployment::XPackageTypeInfo > m_xHelpTypeInfo
Reference< XComponentContext > getComponentContext(Reference< XMultiServiceFactory > const &factory)
exports com.sun.star.chart2. data
sal_Int32 m_nXMLParsingLine
OUString expandUnoRcUrl(OUString const &url)
::boost::spirit::classic::rule< ScannerT > identifier
static uno::Reference< css::uno::XComponentContext > xContext
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
Sequence< sal_Int8 > aSeq
std::unordered_map< OString, INetContentTypeParameter > INetContentTypeParameterList
constexpr OUStringLiteral BACKEND_SERVICE_NAME
OUString DpResId(TranslateId aId)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_folder(::ucbhelper::Content *ucb_content, OUString const &url, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv, bool throw_exc=true)
OUString m_aXMLParsingFile
bool m_bDetectedRangeSegmentation false