| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_desktop.hxx" |
| |
| #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" |
| #include "unotools/pathoptions.hxx" |
| |
| #include <l10ntools/compilehelp.hxx> |
| #include <com/sun/star/ucb/XSimpleFileAccess.hpp> |
| #include <com/sun/star/util/XMacroExpander.hpp> |
| #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; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::ucb; |
| using ::rtl::OUString; |
| |
| namespace dp_registry { |
| namespace backend { |
| namespace help { |
| namespace { |
| |
| //============================================================================== |
| 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_( |
| ::osl::ResettableMutexGuard & guard, |
| ::rtl::Reference<AbortChannel> const & abortChannel, |
| Reference<XCommandEnvironment> const & xCmdEnv ); |
| virtual void processPackage_( |
| ::osl::ResettableMutexGuard & guard, |
| bool registerPackage, |
| bool startup, |
| ::rtl::Reference<AbortChannel> const & abortChannel, |
| Reference<XCommandEnvironment> const & xCmdEnv ); |
| |
| |
| public: |
| PackageImpl( |
| ::rtl::Reference<PackageRegistryBackend> const & myBackend, |
| OUString const & url, OUString const & name, |
| Reference<deployment::XPackageTypeInfo> const & xPackageType, |
| bool bRemoved, OUString const & identifier); |
| |
| bool extensionContainsCompiledHelp(); |
| |
| //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( PackageImpl * package, bool doRegisterPackage, |
| Reference<ucb::XCommandEnvironment> const & xCmdEnv); |
| void implCollectXhpFiles( const rtl::OUString& aDir, |
| std::vector< rtl::OUString >& o_rXhpFileVector ); |
| |
| void addDataToDb(OUString const & url, HelpBackendDb::Data const & data); |
| ::boost::optional<HelpBackendDb::Data> readDataFromDb(OUString const & url); |
| bool hasActiveEntry(OUString const & url); |
| void revokeEntryFromDb(OUString const & url); |
| bool activateEntry(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, |
| Reference<XComponentContext> const & xComponentContext ); |
| |
| // XPackageRegistry |
| virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL |
| getSupportedPackageTypes() throw (RuntimeException); |
| virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) |
| throw (deployment::DeploymentException, |
| uno::RuntimeException); |
| |
| }; |
| |
| //______________________________________________________________________________ |
| BackendImpl::BackendImpl( |
| Sequence<Any> const & args, |
| Reference<XComponentContext> const & xComponentContext ) |
| : PackageRegistryBackend( args, xComponentContext ), |
| m_xHelpTypeInfo( new Package::TypeInfo( |
| OUSTR("application/vnd.sun.star.help"), |
| rtl::OUString(), |
| getResourceString(RID_STR_HELP), |
| RID_IMG_HELP, RID_IMG_HELP_HC ) ), |
| 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 |
| //______________________________________________________________________________ |
| Sequence< Reference<deployment::XPackageTypeInfo> > |
| BackendImpl::getSupportedPackageTypes() throw (RuntimeException) |
| { |
| return m_typeInfos; |
| } |
| |
| void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/) |
| throw (deployment::DeploymentException, |
| uno::RuntimeException) |
| { |
| if (m_backendDb.get()) |
| m_backendDb->removeEntry(url); |
| } |
| |
| // PackageRegistryBackend |
| //______________________________________________________________________________ |
| 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: |
| if (mediaType_.getLength() == 0) |
| throw lang::IllegalArgumentException( |
| StrCannotDetectMediaType::get() + url, |
| static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) ); |
| |
| String type, subType; |
| INetContentTypeParameterList params; |
| if (INetContentTypes::parse( mediaType_, type, subType, ¶ms )) |
| { |
| if (type.EqualsIgnoreCaseAscii("application")) |
| { |
| 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, name, m_xHelpTypeInfo, bRemoved, |
| identifier); |
| } |
| } |
| } |
| throw lang::IllegalArgumentException( |
| StrUnsupportedMediaType::get() + mediaType_, |
| static_cast<OWeakObject *>(this), |
| 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; |
| } |
| |
| bool BackendImpl::hasActiveEntry(OUString const & url) |
| { |
| if (m_backendDb.get()) |
| return m_backendDb->hasActiveEntry(url); |
| return false; |
| } |
| |
| void BackendImpl::revokeEntryFromDb(OUString const & url) |
| { |
| if (m_backendDb.get()) |
| m_backendDb->revokeEntry(url); |
| } |
| |
| bool BackendImpl::activateEntry(OUString const & url) |
| { |
| if (m_backendDb.get()) |
| return m_backendDb->activateEntry(url); |
| return false; |
| } |
| |
| |
| //############################################################################## |
| 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) |
| { |
| } |
| |
| // Package |
| BackendImpl * BackendImpl::PackageImpl::getMyBackend() const |
| { |
| BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); |
| if (NULL == pBackend) |
| { |
| //May throw a DisposedException |
| check(); |
| //We should never get here... |
| throw RuntimeException( |
| OUSTR("Failed to get the BackendImpl"), |
| static_cast<OWeakObject*>(const_cast<PackageImpl *>(this))); |
| } |
| return pBackend; |
| } |
| |
| bool BackendImpl::PackageImpl::extensionContainsCompiledHelp() |
| { |
| bool bCompiled = true; |
| rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl(getURL()); |
| |
| ::osl::Directory helpFolder(aExpandedHelpURL); |
| if ( helpFolder.open() == ::osl::File::E_None) |
| { |
| //iterate over the contents of the help folder |
| //We assume that all folders withing the help folder contain language specific |
| //help files. If just one of them does not contain compiled help then this |
| //function returns false. |
| ::osl::DirectoryItem item; |
| ::osl::File::RC errorNext = ::osl::File::E_None; |
| while ((errorNext = helpFolder.getNextItem(item)) == ::osl::File::E_None) |
| { |
| //No find the language folders |
| ::osl::FileStatus stat(FileStatusMask_Type | FileStatusMask_FileName |FileStatusMask_FileURL); |
| if (item.getFileStatus(stat) == ::osl::File::E_None) |
| { |
| if (stat.getFileType() != ::osl::FileStatus::Directory) |
| continue; |
| |
| //look if there is the folder help.idxl in the language folder |
| OUString compUrl(stat.getFileURL() + OUSTR("/help.idxl")); |
| ::osl::Directory compiledFolder(compUrl); |
| if (compiledFolder.open() != ::osl::File::E_None) |
| { |
| bCompiled = false; |
| break; |
| } |
| } |
| else |
| { |
| //Error |
| OSL_ASSERT(0); |
| bCompiled = false; |
| break; |
| } |
| } |
| if (errorNext != ::osl::File::E_NOENT |
| && errorNext != ::osl::File::E_None) |
| { |
| //Error |
| OSL_ASSERT(0); |
| bCompiled = false; |
| } |
| } |
| return bCompiled; |
| } |
| |
| //______________________________________________________________________________ |
| beans::Optional< beans::Ambiguous<sal_Bool> > |
| BackendImpl::PackageImpl::isRegistered_( |
| ::osl::ResettableMutexGuard &, |
| ::rtl::Reference<AbortChannel> const &, |
| Reference<XCommandEnvironment> const & ) |
| { |
| BackendImpl * that = getMyBackend(); |
| |
| bool bReg = false; |
| if (that->hasActiveEntry(getURL())) |
| bReg = true; |
| |
| return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) ); |
| } |
| |
| //______________________________________________________________________________ |
| void BackendImpl::PackageImpl::processPackage_( |
| ::osl::ResettableMutexGuard &, |
| bool doRegisterPackage, |
| bool /* startup */, |
| ::rtl::Reference<AbortChannel> const & abortChannel, |
| Reference<XCommandEnvironment> const & xCmdEnv ) |
| { |
| (void)doRegisterPackage; |
| (void)abortChannel; |
| (void)xCmdEnv; |
| |
| BackendImpl* that = getMyBackend(); |
| that->implProcessHelp( this, 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 && getMyBackend()->hasActiveEntry(getURL())) |
| 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( |
| PackageImpl * package, bool doRegisterPackage, |
| Reference<ucb::XCommandEnvironment> const & xCmdEnv) |
| { |
| Reference< deployment::XPackage > xPackage(package); |
| OSL_ASSERT(xPackage.is()); |
| if (doRegisterPackage) |
| { |
| //revive already processed help if possible |
| if ( !activateEntry(xPackage->getURL())) |
| { |
| HelpBackendDb::Data data; |
| data.dataUrl = xPackage->getURL(); |
| if (!package->extensionContainsCompiledHelp()) |
| { |
| const OUString sHelpFolder = createFolder(OUString(), xCmdEnv); |
| data.dataUrl = sHelpFolder; |
| |
| Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess(); |
| rtl::OUString aHelpURL = xPackage->getURL(); |
| rtl::OUString aExpandedHelpURL = dp_misc::expandUnoRcUrl( aHelpURL ); |
| rtl::OUString aName = xPackage->getName(); |
| if( !xSFA->isFolder( aExpandedHelpURL ) ) |
| { |
| rtl::OUString aErrStr = getResourceString( RID_STR_HELPPROCESSING_GENERAL_ERROR ); |
| aErrStr += rtl::OUString::createFromAscii( "No help folder" ); |
| OWeakObject* oWeakThis = static_cast<OWeakObject *>(this); |
| throw deployment::DeploymentException( rtl::OUString(), oWeakThis, |
| makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); |
| } |
| |
| Reference<XComponentContext> const & xContext = getComponentContext(); |
| Reference< script::XInvocation > xInvocation; |
| if( xContext.is() ) |
| { |
| try |
| { |
| xInvocation = Reference< script::XInvocation >( |
| xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( |
| "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY ); |
| } |
| catch (Exception &) |
| { |
| // i98680: Survive missing lucene |
| } |
| } |
| |
| // Scan languages |
| Sequence< rtl::OUString > aLanguageFolderSeq = xSFA->getFolderContents( aExpandedHelpURL, true ); |
| sal_Int32 nLangCount = aLanguageFolderSeq.getLength(); |
| const rtl::OUString* pSeq = aLanguageFolderSeq.getConstArray(); |
| for( sal_Int32 iLang = 0 ; iLang < nLangCount ; ++iLang ) |
| { |
| rtl::OUString aLangURL = pSeq[iLang]; |
| if( xSFA->isFolder( aLangURL ) ) |
| { |
| std::vector< rtl::OUString > aXhpFileVector; |
| |
| // calculate jar file URL |
| 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.zip://" ); |
| aDestBasePath += aEncodedJarFilePath; |
| aDestBasePath += rtl::OUString::createFromAscii( "/" ); |
| |
| sal_Int32 nLenLangFolderURL = aLangURL.getLength() + 1; |
| |
| Sequence< rtl::OUString > aSubLangSeq = xSFA->getFolderContents( aLangURL, true ); |
| sal_Int32 nSubLangCount = aSubLangSeq.getLength(); |
| const rtl::OUString* pSubLangSeq = aSubLangSeq.getConstArray(); |
| for( sal_Int32 iSubLang = 0 ; iSubLang < nSubLangCount ; ++iSubLang ) |
| { |
| rtl::OUString aSubFolderURL = pSubLangSeq[iSubLang]; |
| if( !xSFA->isFolder( aSubFolderURL ) ) |
| continue; |
| |
| implCollectXhpFiles( aSubFolderURL, aXhpFileVector ); |
| |
| // Copy to package (later: move?) |
| rtl::OUString aDestPath = aDestBasePath; |
| rtl::OUString aPureFolderName = aSubFolderURL.copy( nLenLangFolderURL ); |
| aDestPath += aPureFolderName; |
| xSFA->copy( aSubFolderURL, aDestPath ); |
| } |
| |
| // Call compiler |
| sal_Int32 nXhpFileCount = aXhpFileVector.size(); |
| rtl::OUString* pXhpFiles = new rtl::OUString[nXhpFileCount]; |
| for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp ) |
| { |
| rtl::OUString aXhpFile = aXhpFileVector[iXhp]; |
| rtl::OUString aXhpRelFile = aXhpFile.copy( nLenLangFolderURL ); |
| pXhpFiles[iXhp] = aXhpRelFile; |
| } |
| |
| rtl::OUString aOfficeHelpPath( SvtPathOptions().GetHelpPath() ); |
| rtl::OUString aOfficeHelpPathFileURL; |
| ::osl::File::getFileURLFromSystemPath( aOfficeHelpPath, aOfficeHelpPathFileURL ); |
| |
| HelpProcessingErrorInfo aErrorInfo; |
| bool bSuccess = compileExtensionHelp( |
| aOfficeHelpPathFileURL, aHelpStr, aLangURL, |
| nXhpFileCount, pXhpFiles, |
| langFolderDestExpanded, aErrorInfo ); |
| |
| if( bSuccess && xInvocation.is() ) |
| { |
| Sequence<uno::Any> aParamsSeq( 6 ); |
| |
| aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) ); |
| |
| rtl::OUString aLang; |
| sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' ); |
| if( nLastSlash != -1 ) |
| aLang = aLangURL.copy( nLastSlash + 1 ); |
| else |
| aLang = rtl::OUString::createFromAscii( "en" ); |
| aParamsSeq[1] = uno::makeAny( aLang ); |
| |
| aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) ); |
| aParamsSeq[3] = uno::makeAny( rtl::OUString::createFromAscii( "help" ) ); |
| |
| aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); |
| rtl::OUString 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 ); |
| } |
| |
| if( !bSuccess ) |
| { |
| sal_uInt16 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: ; |
| }; |
| |
| rtl::OUString aErrStr; |
| if( nErrStrId != 0 ) |
| { |
| aErrStr = getResourceString( nErrStrId ); |
| |
| // Remoce CR/LF |
| rtl::OUString aErrMsg( aErrorInfo.m_aErrorMsg ); |
| sal_Unicode nCR = 13, nLF = 10; |
| sal_Int32 nSearchCR = aErrMsg.indexOf( nCR ); |
| sal_Int32 nSearchLF = aErrMsg.indexOf( nLF ); |
| sal_Int32 nCopy; |
| if( nSearchCR != -1 || nSearchLF != -1 ) |
| { |
| if( nSearchCR == -1 ) |
| nCopy = nSearchLF; |
| else if( nSearchLF == -1 ) |
| nCopy = nSearchCR; |
| else |
| nCopy = ( nSearchCR < nSearchLF ) ? nSearchCR : nSearchLF; |
| |
| aErrMsg = aErrMsg.copy( 0, nCopy ); |
| } |
| aErrStr += aErrMsg; |
| if( nErrStrId == RID_STR_HELPPROCESSING_XMLPARSING_ERROR && aErrorInfo.m_aXMLParsingFile.getLength() ) |
| { |
| aErrStr += rtl::OUString::createFromAscii( " in " ); |
| |
| rtl::OUString aDecodedFile = rtl::Uri::decode( aErrorInfo.m_aXMLParsingFile, |
| rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); |
| aErrStr += aDecodedFile; |
| if( aErrorInfo.m_nXMLParsingLine != -1 ) |
| { |
| aErrStr += rtl::OUString::createFromAscii( ", line " ); |
| aErrStr += ::rtl::OUString::valueOf( aErrorInfo.m_nXMLParsingLine ); |
| } |
| } |
| } |
| |
| OWeakObject* oWeakThis = static_cast<OWeakObject *>(this); |
| throw deployment::DeploymentException( rtl::OUString(), oWeakThis, |
| makeAny( uno::Exception( aErrStr, oWeakThis ) ) ); |
| } |
| } |
| } |
| } |
| //Writing the data entry replaces writing the flag file. If we got to this |
| //point the registration was successful. |
| addDataToDb(xPackage->getURL(), data); |
| } |
| } //if (doRegisterPackage) |
| else |
| { |
| revokeEntryFromDb(xPackage->getURL()); |
| } |
| } |
| |
| |
| void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir, |
| std::vector< rtl::OUString >& o_rXhpFileVector ) |
| { |
| Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess(); |
| |
| // Scan xhp files recursively |
| Sequence< rtl::OUString > aSeq = xSFA->getFolderContents( aDir, true ); |
| sal_Int32 nCount = aSeq.getLength(); |
| const rtl::OUString* pSeq = aSeq.getConstArray(); |
| for( sal_Int32 i = 0 ; i < nCount ; ++i ) |
| { |
| rtl::OUString aURL = pSeq[i]; |
| if( xSFA->isFolder( aURL ) ) |
| { |
| implCollectXhpFiles( aURL, o_rXhpFileVector ); |
| } |
| else |
| { |
| sal_Int32 nLastDot = aURL.lastIndexOf( '.' ); |
| if( nLastDot != -1 ) |
| { |
| rtl::OUString aExt = aURL.copy( nLastDot + 1 ); |
| if( aExt.equalsIgnoreAsciiCase( rtl::OUString::createFromAscii( "xhp" ) ) ) |
| o_rXhpFileVector.push_back( aURL ); |
| } |
| } |
| } |
| } |
| |
| Reference< ucb::XSimpleFileAccess > BackendImpl::getFileAccess( void ) |
| { |
| if( !m_xSFA.is() ) |
| { |
| Reference<XComponentContext> const & xContext = getComponentContext(); |
| if( xContext.is() ) |
| { |
| m_xSFA = Reference< ucb::XSimpleFileAccess >( |
| xContext->getServiceManager()->createInstanceWithContext( |
| rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), |
| xContext ), UNO_QUERY ); |
| } |
| if( !m_xSFA.is() ) |
| { |
| throw RuntimeException( |
| ::rtl::OUString::createFromAscii( |
| "dp_registry::backend::help::BackendImpl::getFileAccess(), " |
| "could not instatiate SimpleFileAccess." ), |
| Reference< XInterface >() ); |
| } |
| } |
| return m_xSFA; |
| } |
| |
| } // anon namespace |
| |
| namespace sdecl = comphelper::service_decl; |
| sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI; |
| extern sdecl::ServiceDecl const serviceDecl( |
| serviceBI, |
| "com.sun.star.comp.deployment.help.PackageRegistryBackend", |
| BACKEND_SERVICE_NAME ); |
| |
| } // namespace help |
| } // namespace backend |
| } // namespace dp_registry |
| |