diff options
Diffstat (limited to 'desktop/source/deployment/registry/help/dp_help.cxx')
-rw-r--r-- | desktop/source/deployment/registry/help/dp_help.cxx | 318 |
1 files changed, 161 insertions, 157 deletions
diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx index ca94a30221..60dd5c414e 100644 --- a/desktop/source/deployment/registry/help/dp_help.cxx +++ b/desktop/source/deployment/registry/help/dp_help.cxx @@ -30,9 +30,11 @@ #include "dp_help.hrc" #include "dp_backend.h" +#include "dp_helpbackenddb.hxx" #include "dp_ucb.h" #include "rtl/uri.hxx" #include "osl/file.hxx" +#include "rtl/bootstrap.hxx" #include "ucbhelper/content.hxx" #include "comphelper/servicedecl.hxx" #include "svl/inettype.hxx" @@ -44,6 +46,7 @@ #include <com/sun/star/uri/XUriReferenceFactory.hpp> #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> #include <com/sun/star/script/XInvocation.hpp> +#include "boost/optional.hpp" using namespace ::dp_misc; using namespace ::com::sun::star; @@ -62,6 +65,8 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend class PackageImpl : public ::dp_registry::backend::Package { BackendImpl * getMyBackend() const; + +// HelpBackendDb::Data m_dbData; // Package virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( @@ -71,36 +76,44 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend virtual void processPackage_( ::osl::ResettableMutexGuard & guard, bool registerPackage, + bool startup, ::rtl::Reference<AbortChannel> const & abortChannel, Reference<XCommandEnvironment> const & xCmdEnv ); public: - inline PackageImpl( + PackageImpl( ::rtl::Reference<PackageRegistryBackend> const & myBackend, OUString const & url, OUString const & name, - Reference<deployment::XPackageTypeInfo> const & xPackageType ) - : Package( myBackend, url, name, name, xPackageType ) - {} + Reference<deployment::XPackageTypeInfo> const & xPackageType, + bool bRemoved, OUString const & identifier); + + //XPackage + virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getRegistrationDataURL() + throw (deployment::ExtensionRemovedException, css::uno::RuntimeException); }; friend class PackageImpl; // PackageRegistryBackend virtual Reference<deployment::XPackage> bindPackage_( OUString const & url, OUString const & mediaType, + sal_Bool bRemoved, OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ); - void implProcessHelp( Reference< deployment::XPackage > xPackage, bool doRegisterPackage ); + void implProcessHelp( Reference< deployment::XPackage > xPackage, bool doRegisterPackage, + Reference<ucb::XCommandEnvironment> const & xCmdEnv); void implCollectXhpFiles( const rtl::OUString& aDir, std::vector< rtl::OUString >& o_rXhpFileVector ); - rtl::OUString getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr ); - rtl::OUString getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage ); - rtl::OUString getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage ); - rtl::OUString expandURL( const rtl::OUString& aURL ); + + void addDataToDb(OUString const & url, HelpBackendDb::Data const & data); + ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url); + void deleteDataFromDb(OUString const & url); + Reference< ucb::XSimpleFileAccess > getFileAccess( void ); Reference< ucb::XSimpleFileAccess > m_xSFA; const Reference<deployment::XPackageTypeInfo> m_xHelpTypeInfo; Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos; + std::auto_ptr<HelpBackendDb> m_backendDb; public: BackendImpl( Sequence<Any> const & args, @@ -124,6 +137,20 @@ BackendImpl::BackendImpl( m_typeInfos( 1 ) { m_typeInfos[ 0 ] = m_xHelpTypeInfo; + if (!transientMode()) + { + OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml")); + m_backendDb.reset( + new HelpBackendDb(getComponentContext(), dbFile)); + + //clean up data folders which are no longer used. + //This must not be done in the same process where the help files + //are still registers. Only after revoking and restarting OOo the folders + //can be removed. This works now, because the extension manager is a singleton + //and the backends are only create once per process. + ::std::list<OUString> folders = m_backendDb->getAllDataUrls(); + deleteUnusedFolders(OUString(), folders); + } } // XPackageRegistry @@ -138,6 +165,7 @@ BackendImpl::getSupportedPackageTypes() throw (RuntimeException) //______________________________________________________________________________ Reference<deployment::XPackage> BackendImpl::bindPackage_( OUString const & url, OUString const & mediaType_, + sal_Bool bRemoved, OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ) { // we don't support auto detection: @@ -152,12 +180,20 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( { if (type.EqualsIgnoreCaseAscii("application")) { - ::ucbhelper::Content ucbContent( url, xCmdEnv ); + OUString name; + if (!bRemoved) + { + ::ucbhelper::Content ucbContent( url, xCmdEnv ); + name = ucbContent.getPropertyValue( + StrTitle::get() ).get<OUString>(); + } + if (subType.EqualsIgnoreCaseAscii( "vnd.sun.star.help")) { - return new PackageImpl( this, url, - ucbContent.getPropertyValue( StrTitle::get() ).get<OUString>(), m_xHelpTypeInfo ); + return new PackageImpl( + this, url, name, m_xHelpTypeInfo, bRemoved, + identifier); } } } @@ -167,8 +203,45 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( static_cast<sal_Int16>(-1) ); } +void BackendImpl::addDataToDb( + OUString const & url, HelpBackendDb::Data const & data) +{ + if (m_backendDb.get()) + m_backendDb->addEntry(url, data); +} + +::boost::optional<HelpBackendDb::Data> BackendImpl::readDataFromDb( + OUString const & url) +{ + ::boost::optional<HelpBackendDb::Data> data; + if (m_backendDb.get()) + data = m_backendDb->getEntry(url); + return data; +} + +void BackendImpl::deleteDataFromDb(OUString const & url) +{ + if (m_backendDb.get()) + m_backendDb->removeEntry(url); +} //############################################################################## +BackendImpl::PackageImpl::PackageImpl( + ::rtl::Reference<PackageRegistryBackend> const & myBackend, + OUString const & url, OUString const & name, + Reference<deployment::XPackageTypeInfo> const & xPackageType, + bool bRemoved, OUString const & identifier) + : Package( myBackend, url, name, name, xPackageType, bRemoved, + identifier) +{ +// if (bRemoved) +// { +// ::boost::optional<HelpBackendDb::Data> opt = +// getMyBackend()->readDataFromDb(url); +// if (opt) +// m_dbData = *opt; +// } +} // Package BackendImpl * BackendImpl::PackageImpl::getMyBackend() const @@ -194,11 +267,10 @@ BackendImpl::PackageImpl::isRegistered_( Reference<XCommandEnvironment> const & ) { BackendImpl * that = getMyBackend(); - Reference< deployment::XPackage > xThisPackage( this ); - rtl::OUString aRegisteredFlagFile = that->getRegisteredFlagFileURL( xThisPackage ); - Reference< ucb::XSimpleFileAccess > xSFA = that->getFileAccess(); - bool bReg = xSFA->exists( aRegisteredFlagFile ); + bool bReg = false; + if (that->readDataFromDb(getURL())) + bReg = true; return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) ); } @@ -207,6 +279,7 @@ BackendImpl::PackageImpl::isRegistered_( void BackendImpl::PackageImpl::processPackage_( ::osl::ResettableMutexGuard &, bool doRegisterPackage, + bool /* startup */, ::rtl::Reference<AbortChannel> const & abortChannel, Reference<XCommandEnvironment> const & xCmdEnv ) { @@ -216,39 +289,46 @@ void BackendImpl::PackageImpl::processPackage_( BackendImpl* that = getMyBackend(); Reference< deployment::XPackage > xThisPackage( this ); - that->implProcessHelp( xThisPackage, doRegisterPackage ); + that->implProcessHelp( xThisPackage, doRegisterPackage, xCmdEnv); } +beans::Optional< OUString > BackendImpl::PackageImpl::getRegistrationDataURL() + throw (deployment::ExtensionRemovedException, + css::uno::RuntimeException) +{ + if (m_bRemoved) + throw deployment::ExtensionRemovedException(); + + ::boost::optional<HelpBackendDb::Data> data = + getMyBackend()->readDataFromDb(getURL()); + + if (data) + return beans::Optional<OUString>(true, data->dataUrl); + + return beans::Optional<OUString>(true, OUString()); +} + + //############################################################################## static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); static rtl::OUString aHelpStr( rtl::OUString::createFromAscii( "help" ) ); + void BackendImpl::implProcessHelp - ( Reference< deployment::XPackage > xPackage, bool doRegisterPackage ) +( Reference< deployment::XPackage > xPackage, bool doRegisterPackage, + Reference<ucb::XCommandEnvironment> const & xCmdEnv) { - if( !xPackage.is() ) - return; - - Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess(); - - rtl::OUString aRegisteredFlagFile = getRegisteredFlagFileURL( xPackage ); - if( !doRegisterPackage ) + OSL_ASSERT(xPackage.is()); + if (doRegisterPackage) { - if( xSFA->exists( aRegisteredFlagFile ) ) - xSFA->kill( aRegisteredFlagFile ); - return; - } - - bool bCompile = true; - rtl::OUString aCompiledFlagFile = getCompiledFlagFileURL( xPackage ); - if( xSFA->exists( aCompiledFlagFile ) ) - bCompile = false; + HelpBackendDb::Data data; + const OUString sHelpFolder = createFolder(OUString(), xCmdEnv); + data.dataUrl = sHelpFolder; - if( bCompile ) - { + Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess(); rtl::OUString aHelpURL = xPackage->getURL(); - rtl::OUString aExpandedHelpURL = expandURL( aHelpURL ); + rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl( aHelpURL ); rtl::OUString aName = xPackage->getName(); if( !xSFA->isFolder( aExpandedHelpURL ) ) { @@ -256,7 +336,7 @@ void BackendImpl::implProcessHelp aErrStr += rtl::OUString::createFromAscii( "No help folder" ); OWeakObject* oWeakThis = static_cast<OWeakObject *>(this); throw deployment::DeploymentException( rtl::OUString(), oWeakThis, - makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); + makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); } Reference<XComponentContext> const & xContext = getComponentContext(); @@ -267,7 +347,7 @@ void BackendImpl::implProcessHelp { xInvocation = Reference< script::XInvocation >( xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( - "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY ); + "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY ); } catch (Exception &) { @@ -286,34 +366,30 @@ void BackendImpl::implProcessHelp { std::vector< rtl::OUString > aXhpFileVector; - // Delete (old) files in any case to allow compiler to be started every time - rtl::OUString aLangWithPureNameURL( aLangURL ); - aLangWithPureNameURL += aSlash; - aLangWithPureNameURL += aHelpStr; - rtl::OUString aDbFile( aLangWithPureNameURL ); - aDbFile += rtl::OUString::createFromAscii( ".db" ); - if( xSFA->exists( aDbFile ) ) - xSFA->kill( aDbFile ); - rtl::OUString aHtFile( aLangWithPureNameURL ); - aHtFile += rtl::OUString::createFromAscii( ".ht" ); - if( xSFA->exists( aHtFile ) ) - xSFA->kill( aHtFile ); - rtl::OUString aKeyFile( aLangWithPureNameURL ); - aKeyFile += rtl::OUString::createFromAscii( ".key" ); - if( xSFA->exists( aKeyFile ) ) - xSFA->kill( aKeyFile ); - // calculate jar file URL - rtl::OUString aJarFile( aLangURL ); - aJarFile += aSlash; - aJarFile += aHelpStr; - aJarFile += rtl::OUString::createFromAscii( ".jar" ); - // remove in any case to clean up - if( xSFA->exists( aJarFile ) ) - xSFA->kill( aJarFile ); - - rtl::OUString aEncodedJarFilePath = rtl::Uri::encode( aJarFile, - rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 ); + sal_Int32 indexStartSegment = aLangURL.lastIndexOf('/'); + // for example "/en" + OUString langFolderURLSegment( + aLangURL.copy( + indexStartSegment + 1, aLangURL.getLength() - indexStartSegment - 1)); + + //create the folder in the "temporary folder" + ::ucbhelper::Content langFolderContent; + const OUString langFolderDest = makeURL(sHelpFolder, langFolderURLSegment); + const OUString langFolderDestExpanded = ::dp_misc::expandUnoRcUrl(langFolderDest); + ::dp_misc::create_folder( + &langFolderContent, + langFolderDest, xCmdEnv); + + rtl::OUString aJarFile( + makeURL(sHelpFolder, langFolderURLSegment + aSlash + aHelpStr + + OUSTR(".jar"))); + aJarFile = ::dp_misc::expandUnoRcUrl(aJarFile); + + rtl::OUString aEncodedJarFilePath = rtl::Uri::encode( + aJarFile, rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ); rtl::OUString aDestBasePath = rtl::OUString::createFromAscii( "vnd.sun.star.pkg://" ); aDestBasePath += aEncodedJarFilePath; aDestBasePath += rtl::OUString::createFromAscii( "/" ); @@ -353,8 +429,10 @@ void BackendImpl::implProcessHelp ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL ); HelpProcessingErrorInfo aErrorInfo; - bool bSuccess = compileExtensionHelp( aOfficeHelpPathFileURL, aHelpStr, aLangURL, - nXhpFileCount, pXhpFiles, aErrorInfo ); + bool bSuccess = compileExtensionHelp( + aOfficeHelpPathFileURL, aHelpStr, aLangURL, + nXhpFileCount, pXhpFiles, + langFolderDestExpanded, aErrorInfo ); if( bSuccess && xInvocation.is() ) { @@ -375,13 +453,14 @@ void BackendImpl::implProcessHelp aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); rtl::OUString aSystemPath; - osl::FileBase::getSystemPathFromFileURL( aLangURL, aSystemPath ); + osl::FileBase::getSystemPathFromFileURL( + langFolderDestExpanded, aSystemPath ); aParamsSeq[5] = uno::makeAny( aSystemPath ); Sequence< sal_Int16 > aOutParamIndex; Sequence< uno::Any > aOutParam; uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ), - aParamsSeq, aOutParamIndex, aOutParam ); + aParamsSeq, aOutParamIndex, aOutParam ); } if( !bSuccess ) @@ -389,10 +468,10 @@ void BackendImpl::implProcessHelp USHORT nErrStrId = 0; switch( aErrorInfo.m_eErrorClass ) { - case HELPPROCESSING_GENERAL_ERROR: - case HELPPROCESSING_INTERNAL_ERROR: nErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR; break; - case HELPPROCESSING_XMLPARSING_ERROR: nErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR; break; - default: ; + case HELPPROCESSING_GENERAL_ERROR: + case HELPPROCESSING_INTERNAL_ERROR: nErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR; break; + case HELPPROCESSING_XMLPARSING_ERROR: nErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR; break; + default: ; }; rtl::OUString aErrStr; @@ -423,7 +502,7 @@ void BackendImpl::implProcessHelp aErrStr += rtl::OUString::createFromAscii( " in " ); rtl::OUString aDecodedFile = rtl::Uri::decode( aErrorInfo.m_aXMLParsingFile, - rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); + rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); aErrStr += aDecodedFile; if( aErrorInfo.m_nXMLParsingLine != -1 ) { @@ -435,96 +514,21 @@ void BackendImpl::implProcessHelp OWeakObject* oWeakThis = static_cast<OWeakObject *>(this); throw deployment::DeploymentException( rtl::OUString(), oWeakThis, - makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); + makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); } } } - // Write compiled flag file (this code is only reached in case of success) - Reference< io::XOutputStream > xOutputStream = xSFA->openFileWrite( aCompiledFlagFile ); - if( xOutputStream.is() ) - xOutputStream->closeOutput(); - - } // if( bCompile ) - - // Write registered flag file (this code is only reached in case of success) - if( !xSFA->exists( aRegisteredFlagFile ) ) + //Writing the data entry replaces writing the flag file. If we got to this + //point the registration was successful. + addDataToDb(xPackage->getURL(), data); + } + else { - Reference< io::XOutputStream > xOutputStream = xSFA->openFileWrite( aRegisteredFlagFile ); - if( xOutputStream.is() ) - xOutputStream->closeOutput(); + deleteDataFromDb(xPackage->getURL()); } } -rtl::OUString BackendImpl::getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr ) -{ - rtl::OUString aRetURL; - if( !xPackage.is() ) - return aRetURL; - rtl::OUString aHelpURL = xPackage->getURL(); - aRetURL = expandURL( aHelpURL ); - aRetURL += rtl::OUString::createFromAscii( pFlagStr ); - return aRetURL; -} - -rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage ) -{ - return getFlagFileURL( xPackage, "/RegisteredFlag" ); -} - -rtl::OUString BackendImpl::getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage ) -{ - return getFlagFileURL( xPackage, "/CompiledFlag" ); -} - -rtl::OUString BackendImpl::expandURL( const rtl::OUString& aURL ) -{ - static Reference< util::XMacroExpander > xMacroExpander; - static Reference< uri::XUriReferenceFactory > xFac; - - if( !xMacroExpander.is() || !xFac.is() ) - { - Reference<XComponentContext> const & xContext = getComponentContext(); - if( xContext.is() ) - { - xFac = Reference< uri::XUriReferenceFactory >( - xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( - "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY ); - } - if( !xFac.is() ) - { - throw RuntimeException( - ::rtl::OUString::createFromAscii( - "dp_registry::backend::help::BackendImpl::expandURL(), " - "could not instatiate UriReferenceFactory." ), - Reference< XInterface >() ); - } - - xMacroExpander = Reference< util::XMacroExpander >( - xContext->getValueByName( - ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), - UNO_QUERY_THROW ); - } - - rtl::OUString aRetURL = aURL; - if( xMacroExpander.is() ) - { - Reference< uri::XUriReference > uriRef; - for (;;) - { - uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY ); - if ( uriRef.is() ) - { - Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); - if( !sxUri.is() ) - break; - - aRetURL = sxUri->expand( xMacroExpander ); - } - } - } - return aRetURL; -} void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir, std::vector< rtl::OUString >& o_rXhpFileVector ) |