diff options
author | Mathias Bauer <mba@openoffice.org> | 2009-09-25 21:47:16 +0200 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2009-09-25 21:47:16 +0200 |
commit | 0a266bd33b8786869cdeab8325f8f1b1900533ad (patch) | |
tree | 137ba378aaae9e8f0765fabbbf5035131f250781 /xmlhelp/source | |
parent | 6a1e797fa4b432841708545272e13e8f6ab4bd39 (diff) | |
parent | ab33e14647ada2a32624fa39ec0ddbbbdc694df5 (diff) |
merge commit
Diffstat (limited to 'xmlhelp/source')
-rw-r--r-- | xmlhelp/source/com/sun/star/help/HelpCompiler.cxx | 593 | ||||
-rw-r--r-- | xmlhelp/source/com/sun/star/help/HelpCompiler.hxx | 320 | ||||
-rw-r--r-- | xmlhelp/source/com/sun/star/help/HelpFileDocument.java | 89 | ||||
-rw-r--r-- | xmlhelp/source/com/sun/star/help/HelpIndexer.java | 299 | ||||
-rw-r--r-- | xmlhelp/source/com/sun/star/help/HelpLinker.cxx | 1157 | ||||
-rw-r--r-- | xmlhelp/source/com/sun/star/help/makefile.mk | 68 | ||||
-rw-r--r-- | xmlhelp/source/cxxhelp/provider/databases.cxx | 4110 | ||||
-rw-r--r-- | xmlhelp/source/cxxhelp/provider/urlparameter.cxx | 14 |
8 files changed, 2108 insertions, 4542 deletions
diff --git a/xmlhelp/source/com/sun/star/help/HelpCompiler.cxx b/xmlhelp/source/com/sun/star/help/HelpCompiler.cxx deleted file mode 100644 index 5001d0907972..000000000000 --- a/xmlhelp/source/com/sun/star/help/HelpCompiler.cxx +++ /dev/null @@ -1,593 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: HelpCompiler.cxx,v $ - * $Revision: 1.9 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - -#include "HelpCompiler.hxx" -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <libxslt/xslt.h> -#include <libxslt/xsltInternals.h> -#include <libxslt/transform.h> -#include <libxslt/xsltutils.h> -#ifdef __MINGW32__ -#include <tools/prewin.h> -#include <tools/postwin.h> -#endif -#include <osl/thread.hxx> - -static void impl_sleep( sal_uInt32 nSec ) -{ - TimeValue aTime; - aTime.Seconds = nSec; - aTime.Nanosec = 0; - - osl::Thread::wait( aTime ); -} - -HelpCompiler::HelpCompiler(StreamTable &in_streamTable, const fs::path &in_inputFile, - const fs::path &in_src, const fs::path &in_resEmbStylesheet, - const std::string &in_module, const std::string &in_lang, bool in_bExtensionMode) - : streamTable(in_streamTable), inputFile(in_inputFile), - src(in_src), module(in_module), lang(in_lang), resEmbStylesheet(in_resEmbStylesheet), - bExtensionMode( in_bExtensionMode ) -{ - xmlKeepBlanksDefaultValue = 0; -} - -xmlDocPtr HelpCompiler::getSourceDocument(const fs::path &filePath) -{ - static const char *params[4 + 1]; - static xsltStylesheetPtr cur = NULL; - - xmlDocPtr res; - if( bExtensionMode ) - { - res = xmlParseFile(filePath.native_file_string().c_str()); - if( !res ){ - impl_sleep( 3 ); - res = xmlParseFile(filePath.native_file_string().c_str()); - } - } - else - { - if (!cur) - { - static std::string fsroot('\'' + src.toUTF8() + '\''); - static std::string esclang('\'' + lang + '\''); - - xmlSubstituteEntitiesDefault(1); - xmlLoadExtDtdDefaultValue = 1; - cur = xsltParseStylesheetFile((const xmlChar *)resEmbStylesheet.native_file_string().c_str()); - - int nbparams = 0; - params[nbparams++] = "Language"; - params[nbparams++] = esclang.c_str(); - params[nbparams++] = "fsroot"; - params[nbparams++] = fsroot.c_str(); - params[nbparams] = NULL; - } - xmlDocPtr doc = xmlParseFile(filePath.native_file_string().c_str()); - if( !doc ) - { - impl_sleep( 3 ); - doc = xmlParseFile(filePath.native_file_string().c_str()); - } - - //???res = xmlParseFile(filePath.native_file_string().c_str()); - - res = xsltApplyStylesheet(cur, doc, params); - xmlFreeDoc(doc); - } - return res; -} - -HashSet HelpCompiler::switchFind(xmlDocPtr doc) -{ - HashSet hs; - xmlChar *xpath = (xmlChar*)"//switchinline"; - - xmlXPathContextPtr context = xmlXPathNewContext(doc); - xmlXPathObjectPtr result = xmlXPathEvalExpression(xpath, context); - xmlXPathFreeContext(context); - if (result) - { - xmlNodeSetPtr nodeset = result->nodesetval; - for (int i = 0; i < nodeset->nodeNr; i++) - { - xmlNodePtr el = nodeset->nodeTab[i]; - xmlChar *select = xmlGetProp(el, (xmlChar*)"select"); - if (select) - { - if (!strcmp((const char*)select, "appl")) - { - xmlNodePtr n1 = el->xmlChildrenNode; - while (n1) - { - if ((!xmlStrcmp(n1->name, (const xmlChar*)"caseinline"))) - { - xmlChar *appl = xmlGetProp(n1, (xmlChar*)"select"); - hs.push_back(std::string((const char*)appl)); - xmlFree(appl); - } - else if ((!xmlStrcmp(n1->name, (const xmlChar*)"defaultinline"))) - hs.push_back(std::string("DEFAULT")); - n1 = n1->next; - } - } - xmlFree(select); - } - } - xmlXPathFreeObject(result); - } - hs.push_back(std::string("DEFAULT")); - return hs; -} - -// returns a node representing the whole stuff compiled for the current -// application. -xmlNodePtr HelpCompiler::clone(xmlNodePtr node, const std::string& appl) -{ - xmlNodePtr parent = xmlCopyNode(node, 2); - xmlNodePtr n = node->xmlChildrenNode; - while (n != NULL) - { - bool isappl = false; - if ( (!strcmp((const char*)n->name, "switchinline")) || - (!strcmp((const char*)n->name, "switch")) ) - { - xmlChar *select = xmlGetProp(n, (xmlChar*)"select"); - if (select) - { - if (!strcmp((const char*)select, "appl")) - isappl = true; - xmlFree(select); - } - } - if (isappl) - { - xmlNodePtr caseNode = n->xmlChildrenNode; - if (appl == "DEFAULT") - { - while (caseNode) - { - if (!strcmp((const char*)caseNode->name, "defaultinline")) - { - xmlNodePtr cnl = caseNode->xmlChildrenNode; - while (cnl) - { - xmlAddChild(parent, clone(cnl, appl)); - cnl = cnl->next; - } - break; - } - caseNode = caseNode->next; - } - } - else - { - while (caseNode) - { - isappl=false; - if (!strcmp((const char*)caseNode->name, "caseinline")) - { - xmlChar *select = xmlGetProp(n, (xmlChar*)"select"); - if (select) - { - if (!strcmp((const char*)select, appl.c_str())) - isappl = true; - xmlFree(select); - } - if (isappl) - { - xmlNodePtr cnl = caseNode->xmlChildrenNode; - while (cnl) - { - xmlAddChild(parent, clone(cnl, appl)); - cnl = cnl->next; - } - break; - } - - } - caseNode = caseNode->next; - } - } - - } - else - xmlAddChild(parent, clone(n, appl)); - - n = n->next; - } - return parent; -} - -class myparser -{ -public: - std::string documentId; - std::string fileName; - std::string title; - HashSet *hidlist; - Hashtable *keywords; - Stringtable *helptexts; -private: - HashSet extendedHelpText; -public: - myparser(const std::string &indocumentId, const std::string &infileName, - const std::string &intitle) : documentId(indocumentId), fileName(infileName), - title(intitle) - { - hidlist = new HashSet; - keywords = new Hashtable; - helptexts = new Stringtable; - } - void traverse( xmlNodePtr parentNode ); -private: - std::string dump(xmlNodePtr node); -}; - -std::string myparser::dump(xmlNodePtr node) -{ - std::string app; - if (node->xmlChildrenNode) - { - xmlNodePtr list = node->xmlChildrenNode; - while (list) - { - app += dump(list); - list = list->next; - } - } - if (xmlNodeIsText(node)) - { - xmlChar *pContent = xmlNodeGetContent(node); - app += std::string((const char*)pContent); - xmlFree(pContent); - // std::cout << app << std::endl; - } - return app; -} - -void trim(std::string& str) -{ - std::string::size_type pos = str.find_last_not_of(' '); - if(pos != std::string::npos) - { - str.erase(pos + 1); - pos = str.find_first_not_of(' '); - if(pos != std::string::npos) - str.erase(0, pos); - } - else - str.erase(str.begin(), str.end()); -} - -void myparser::traverse( xmlNodePtr parentNode ) -{ - // traverse all nodes that belong to the parent - xmlNodePtr test ; - for (test = parentNode->xmlChildrenNode; test; test = test->next) - { - if (fileName.empty() && !strcmp((const char*)test->name, "filename")) - { - xmlNodePtr node = test->xmlChildrenNode; - if (xmlNodeIsText(node)) - { - xmlChar *pContent = xmlNodeGetContent(node); - fileName = std::string((const char*)pContent); - xmlFree(pContent); - } - } - else if (title.empty() && !strcmp((const char*)test->name, "title")) - { - title = dump(test); - if (title.empty()) - title = "<notitle>"; - } - else if (!strcmp((const char*)test->name, "bookmark")) - { - xmlChar *branchxml = xmlGetProp(test, (const xmlChar*)"branch"); - xmlChar *idxml = xmlGetProp(test, (const xmlChar*)"id"); - std::string branch((const char*)branchxml); - std::string anchor((const char*)idxml); - xmlFree (branchxml); - xmlFree (idxml); - - std::string hid; - - if (branch.find("hid") == 0) - { - size_t index = branch.find('/'); - if (index != std::string::npos) - { - hid = branch.substr(1 + index); - // one shall serve as a documentId - if (documentId.empty()) - documentId = hid; - extendedHelpText.push_back(hid); - std::string foo = anchor.empty() ? hid : hid + "#" + anchor; - HCDBG(std::cerr << "hid pushback" << foo << std::endl); - hidlist->push_back( anchor.empty() ? hid : hid + "#" + anchor); - } - else - continue; - } - else if (branch.compare("index") == 0) - { - LinkedList ll; - - for (xmlNodePtr nd = test->xmlChildrenNode; nd; nd = nd->next) - { - if (strcmp((const char*)nd->name, "bookmark_value")) - continue; - - std::string embedded; - xmlChar *embeddedxml = xmlGetProp(nd, (const xmlChar*)"embedded"); - if (embeddedxml) - { - embedded = std::string((const char*)embeddedxml); - xmlFree (embeddedxml); - std::transform (embedded.begin(), embedded.end(), - embedded.begin(), tolower); - } - - bool isEmbedded = !embedded.empty() && embedded.compare("true") == 0; - if (isEmbedded) - continue; - - std::string keyword = dump(nd); - size_t keywordSem = keyword.find(';'); - if (keywordSem != std::string::npos) - { - std::string tmppre = - keyword.substr(0,keywordSem); - trim(tmppre); - std::string tmppos = - keyword.substr(1+keywordSem); - trim(tmppos); - keyword = tmppre + ";" + tmppos; - } - ll.push_back(keyword); - } - if (!ll.empty()) - (*keywords)[anchor] = ll; - } - else if (branch.compare("contents") == 0) - { - // currently not used - } - } - else if (!strcmp((const char*)test->name, "ahelp")) - { - std::string text = dump(test); - trim(text); - std::string name; - - HashSet::const_iterator aEnd = extendedHelpText.end(); - for (HashSet::const_iterator iter = extendedHelpText.begin(); iter != aEnd; - ++iter) - { - name = *iter; - (*helptexts)[name] = text; - } - extendedHelpText.clear(); - } - - // traverse children - traverse(test); - } -} - -bool HelpCompiler::compile( void ) throw( HelpProcessingException ) -{ - // we now have the jaroutputstream, which will contain the document. - // now determine the document as a dom tree in variable docResolved - - xmlDocPtr docResolvedOrg = getSourceDocument(inputFile); - - // now add path to the document - // resolve the dom - if (!docResolvedOrg) - { - impl_sleep( 3 ); - docResolvedOrg = getSourceDocument(inputFile); - if( !docResolvedOrg ) - { - std::stringstream aStrStream; - aStrStream << "ERROR: file not existing: " << inputFile.native_file_string().c_str() << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - } - - // now find all applications for which one has to compile - std::string documentId; - std::string fileName; - std::string title; - // returns all applications for which one has to compile - HashSet applications = switchFind(docResolvedOrg); - - HashSet::const_iterator aEnd = applications.end(); - for (HashSet::const_iterator aI = applications.begin(); aI != aEnd; ++aI) - { - std::string appl = *aI; - std::string modulename = appl; - if (modulename[0] == 'S') - { - modulename = modulename.substr(1); - std::transform(modulename.begin(), modulename.end(), modulename.begin(), tolower); - } - if (modulename != "DEFAULT" && modulename != module) - continue; - - // returns a clone of the document with swich-cases resolved - xmlNodePtr docResolved = clone(xmlDocGetRootElement(docResolvedOrg), appl); - myparser aparser(documentId, fileName, title); - aparser.traverse(docResolved); - - documentId = aparser.documentId; - fileName = aparser.fileName; - title = aparser.title; - - HCDBG(std::cerr << documentId << " : " << fileName << " : " << title << std::endl); - - xmlDocPtr docResolvedDoc = xmlCopyDoc(docResolvedOrg, false); - xmlDocSetRootElement(docResolvedDoc, docResolved); - - if (modulename == "DEFAULT") - { - streamTable.dropdefault(); - streamTable.default_doc = docResolvedDoc; - streamTable.default_hidlist = aparser.hidlist; - streamTable.default_helptexts = aparser.helptexts; - streamTable.default_keywords = aparser.keywords; - } - else if (modulename == module) - { - streamTable.dropappl(); - streamTable.appl_doc = docResolvedDoc; - streamTable.appl_hidlist = aparser.hidlist; - streamTable.appl_helptexts = aparser.helptexts; - streamTable.appl_keywords = aparser.keywords; - } - else - { - std::stringstream aStrStream; - aStrStream << "ERROR: Found unexpected module name \"" << modulename - << "\" in file" << src.native_file_string().c_str() << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - } // end iteration over all applications - - streamTable.document_id = documentId; - streamTable.document_path = fileName; - streamTable.document_title = title; - std::string actMod = module; - if ( !bExtensionMode && !fileName.empty()) - { - if (fileName.find("/text/") == 0) - { - int len = strlen("/text/"); - actMod = fileName.substr(len); - actMod = actMod.substr(0, actMod.find('/')); - } - } - streamTable.document_module = actMod; - - xmlFreeDoc(docResolvedOrg); - return true; -} - -namespace fs -{ - rtl_TextEncoding getThreadTextEncoding( void ) - { - static bool bNeedsInit = true; - static rtl_TextEncoding nThreadTextEncoding; - if( bNeedsInit ) - { - bNeedsInit = false; - nThreadTextEncoding = osl_getThreadTextEncoding(); - } - return nThreadTextEncoding; - } - - void create_directory(const fs::path indexDirName) - { - HCDBG( - std::cerr << "creating " << - rtl::OUStringToOString(indexDirName.data, RTL_TEXTENCODING_UTF8).getStr() - << std::endl - ); - osl::Directory::createPath(indexDirName.data); - } - - void rename(const fs::path &src, const fs::path &dest) - { - osl::File::move(src.data, dest.data); - } - - void copy(const fs::path &src, const fs::path &dest) - { - osl::File::copy(src.data, dest.data); - } - - bool exists(const fs::path &in) - { - osl::File tmp(in.data); - return (tmp.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None); - } - - void remove(const fs::path &in) - { - osl::File::remove(in.data); - } - - void removeRecursive(rtl::OUString const& _suDirURL) - { - { - osl::Directory aDir(_suDirURL); - aDir.open(); - if (aDir.isOpen()) - { - osl::DirectoryItem aItem; - osl::FileStatus aStatus(osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Attributes); - while (aDir.getNextItem(aItem) == ::osl::FileBase::E_None) - { - if (osl::FileBase::E_None == aItem.getFileStatus(aStatus) && - aStatus.isValid(osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Attributes)) - { - rtl::OUString suFilename = aStatus.getFileName(); - rtl::OUString suFullFileURL; - suFullFileURL += _suDirURL; - suFullFileURL += rtl::OUString::createFromAscii("/"); - suFullFileURL += suFilename; - - if (aStatus.getFileType() == osl::FileStatus::Directory) - removeRecursive(suFullFileURL); - else - osl::File::remove(suFullFileURL); - } - } - aDir.close(); - } - } - osl::Directory::remove(_suDirURL); - } - - void remove_all(const fs::path &in) - { - removeRecursive(in.data); - } -} - -/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/xmlhelp/source/com/sun/star/help/HelpCompiler.hxx b/xmlhelp/source/com/sun/star/help/HelpCompiler.hxx deleted file mode 100644 index 768aafd0e120..000000000000 --- a/xmlhelp/source/com/sun/star/help/HelpCompiler.hxx +++ /dev/null @@ -1,320 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: HelpCompiler.hxx,v $ - * $Revision: 1.8 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef HELPCOMPILER_HXX -#define HELPCOMPILER_HXX - -#include <string> -#include <hash_map> -#include <vector> -#include <list> -#include <fstream> -#include <iostream> -#include <sstream> -#include <algorithm> -#include <ctype.h> -#ifdef SYSTEM_DB -#include <db.h> -#else -#include <berkeleydb/db.h> -#endif - -#include <boost/shared_ptr.hpp> - -#include <libxml/xmlmemory.h> -#include <libxml/debugXML.h> -#include <libxml/HTMLtree.h> -#include <libxml/xmlIO.h> -#include <libxml/xinclude.h> -#include <libxml/catalog.h> - -#include <rtl/ustring.hxx> -#include <osl/thread.h> -#include <osl/process.h> -#include <osl/file.hxx> - -#include <xmlhelp/compilehelp.hxx> - -#define EMULATEORIGINAL 1 - -#ifdef CMCDEBUG - #define HCDBG(foo) do { if (1) foo; } while(0) -#else - #define HCDBG(foo) do { if (0) foo; } while(0) -#endif - -namespace fs -{ - rtl_TextEncoding getThreadTextEncoding( void ); - - enum convert { native }; - class path - { - public: - ::rtl::OUString data; - public: - path() {} - path(const path &rOther) : data(rOther.data) {} - path(const std::string &in, convert) - { - rtl::OUString sWorkingDir; - osl_getProcessWorkingDir(&sWorkingDir.pData); - - rtl::OString tmp(in.c_str()); - rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding())); - osl::File::getFileURLFromSystemPath(ustrSystemPath, data); - osl::File::getAbsoluteFileURL(sWorkingDir, data, data); - } - path(const std::string &FileURL) - { - rtl::OString tmp(FileURL.c_str()); - data = rtl::OStringToOUString(tmp, getThreadTextEncoding()); - } - std::string native_file_string() const - { - ::rtl::OUString ustrSystemPath; - osl::File::getSystemPathFromFileURL(data, ustrSystemPath); - rtl::OString tmp(rtl::OUStringToOString(ustrSystemPath, getThreadTextEncoding())); - HCDBG(std::cerr << "native_file_string is " << tmp.getStr() << std::endl); - return std::string(tmp.getStr()); - } - std::string native_directory_string() const { return native_file_string(); } - std::string toUTF8() const - { - rtl::OString tmp(rtl::OUStringToOString(data, RTL_TEXTENCODING_UTF8)); - return std::string(tmp.getStr()); - } - bool empty() const { return data.getLength() == 0; } - path operator/(const std::string &in) const - { - path ret(*this); - HCDBG(std::cerr << "orig was " << - rtl::OUStringToOString(ret.data, RTL_TEXTENCODING_UTF8).getStr() << std::endl); - rtl::OString tmp(in.c_str()); - rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding())); - ret.data += rtl::OUString(sal_Unicode('/')); - ret.data += ustrSystemPath; - HCDBG(std::cerr << "final is " << - rtl::OUStringToOString(ret.data, RTL_TEXTENCODING_UTF8).getStr() << std::endl); - return ret; - } - void append(const char *in) - { - rtl::OString tmp(in); - rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding())); - data = data + ustrSystemPath; - } - void append(const std::string &in) { append(in.c_str()); } - }; - - void create_directory(const fs::path indexDirName); - void rename(const fs::path &src, const fs::path &dest); - void copy(const fs::path &src, const fs::path &dest); - bool exists(const fs::path &in); - void remove_all(const fs::path &in); - void remove(const fs::path &in); -} - -struct joaat_hash -{ - size_t operator()(const std::string &str) const - { - size_t hash = 0; - const char *key = str.data(); - for (size_t i = 0; i < str.size(); i++) - { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; - } -}; - -#define get16bits(d) ((((sal_uInt32)(((const sal_uInt8 *)(d))[1])) << 8)\ - +(sal_uInt32)(((const sal_uInt8 *)(d))[0]) ) - -struct SuperFastHash -{ - size_t operator()(const std::string &str) const - { - const char * data = str.data(); - int len = str.size(); - size_t hash = len, tmp; - if (len <= 0 || data == NULL) return 0; - - int rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) - { - hash += get16bits (data); - tmp = (get16bits (data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof (sal_uInt16); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) - { - case 3: hash += get16bits (data); - hash ^= hash << 16; - hash ^= data[sizeof (sal_uInt16)] << 18; - hash += hash >> 11; - break; - case 2: hash += get16bits (data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += *data; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; - } -}; - -#define pref_hash joaat_hash - -typedef std::hash_map<std::string, std::string, pref_hash> Stringtable; -typedef std::list<std::string> LinkedList; -typedef std::vector<std::string> HashSet; - -typedef std::hash_map<std::string, LinkedList, pref_hash> Hashtable; - -class StreamTable -{ -public: - std::string document_id; - std::string document_path; - std::string document_module; - std::string document_title; - - HashSet *appl_hidlist; - Hashtable *appl_keywords; - Stringtable *appl_helptexts; - xmlDocPtr appl_doc; - - HashSet *default_hidlist; - Hashtable *default_keywords; - Stringtable *default_helptexts; - xmlDocPtr default_doc; - - StreamTable() : - appl_hidlist(NULL), appl_keywords(NULL), appl_helptexts(NULL), appl_doc(NULL), - default_hidlist(NULL), default_keywords(NULL), default_helptexts(NULL), default_doc(NULL) - {} - void dropdefault() - { - delete default_hidlist; - delete default_keywords; - delete default_helptexts; - if (default_doc) xmlFreeDoc(default_doc); - } - void dropappl() - { - delete appl_hidlist; - delete appl_keywords; - delete appl_helptexts; - if (appl_doc) xmlFreeDoc(appl_doc); - } - ~StreamTable() - { - dropappl(); - dropdefault(); - } -}; - -struct HelpProcessingException -{ - HelpProcessingErrorClass m_eErrorClass; - std::string m_aErrorMsg; - std::string m_aXMLParsingFile; - int m_nXMLParsingLine; - - HelpProcessingException( HelpProcessingErrorClass eErrorClass, const std::string& aErrorMsg ) - : m_eErrorClass( eErrorClass ) - , m_aErrorMsg( aErrorMsg ) - {} - HelpProcessingException( const std::string& aErrorMsg, const std::string& aXMLParsingFile, int nXMLParsingLine ) - : m_eErrorClass( HELPPROCESSING_XMLPARSING_ERROR ) - , m_aErrorMsg( aErrorMsg ) - , m_aXMLParsingFile( aXMLParsingFile ) - , m_nXMLParsingLine( nXMLParsingLine ) - {} -}; - -class HelpCompiler -{ -public: - HelpCompiler(StreamTable &streamTable, - const fs::path &in_inputFile, - const fs::path &in_src, - const fs::path &in_resEmbStylesheet, - const std::string &in_module, - const std::string &in_lang, - bool in_bExtensionMode); - bool compile( void ) throw (HelpProcessingException); - void addEntryToJarFile(const std::string &prefix, - const std::string &entryName, const std::string &bytesToAdd); - void addEntryToJarFile(const std::string &prefix, - const std::string &entryName, const HashSet &bytesToAdd); - void addEntryToJarFile(const std::string &prefix, - const std::string &entryName, const Stringtable &bytesToAdd); - void addEntryToJarFile(const std::string &prefix, - const std::string &entryName, const Hashtable &bytesToAdd); -private: - xmlDocPtr getSourceDocument(const fs::path &filePath); - HashSet switchFind(xmlDocPtr doc); - xmlNodePtr clone(xmlNodePtr node, const std::string& appl); - StreamTable &streamTable; - const fs::path inputFile, src; - const std::string module, lang; - const fs::path resEmbStylesheet; - bool bExtensionMode; -}; - -#endif - -/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/xmlhelp/source/com/sun/star/help/HelpFileDocument.java b/xmlhelp/source/com/sun/star/help/HelpFileDocument.java deleted file mode 100644 index 2212db27f251..000000000000 --- a/xmlhelp/source/com/sun/star/help/HelpFileDocument.java +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: HelpFileDocument.java,v $ - * $Revision: 1.2 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -package com.sun.star.help; - -import java.io.File; -import java.io.Reader; -import java.io.FileInputStream; -import java.io.InputStreamReader; -//import java.io.FileReader; -import java.io.StringReader; - -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; - -/** Lucene Document for help files */ -public class HelpFileDocument -{ - /** Creates reader for UTF-8 files - */ - private static Reader getReaderForFile( File aFile ) - throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { - Reader aReader; - if( aFile != null ) { - FileInputStream fis = new FileInputStream( aFile ); - aReader = new InputStreamReader( fis, "UTF-8" ); - } - else { - aReader = new StringReader( "" ); - } - return aReader; - } - - /** Makes a document for a File. - */ - public static Document Document( String aModule, File aCaptionFile, File aContentFile ) - throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { - Document doc = new Document(); - - // Add the path of the file as a field named "path". Use a field that is - // indexed (i.e. searchable), but don't tokenize the field into words. - File aFile = aCaptionFile != null ? aCaptionFile : aContentFile; - if( aFile != null ) - { - String aPath = "#HLP#" + aModule + "/" + aFile.getName(); - doc.add(new Field("path", aPath, Field.Store.YES, Field.Index.UN_TOKENIZED)); - } - - // Add the caption of the file to a field named "caption". Specify a Reader, - // so that the text of the file is tokenized and indexed, but not stored. - doc.add( new Field( "caption", getReaderForFile( aCaptionFile ) ) ); - - // Add the contents of the file to a field named "content". Specify a Reader, - // so that the text of the file is tokenized and indexed, but not stored. - doc.add( new Field( "content", getReaderForFile( aContentFile ) ) ); - - // return the document - return doc; - } - - private HelpFileDocument() {} -} diff --git a/xmlhelp/source/com/sun/star/help/HelpIndexer.java b/xmlhelp/source/com/sun/star/help/HelpIndexer.java index eabf1fdd6e88..abb803289e7e 100644 --- a/xmlhelp/source/com/sun/star/help/HelpIndexer.java +++ b/xmlhelp/source/com/sun/star/help/HelpIndexer.java @@ -37,23 +37,11 @@ import com.sun.star.beans.XIntrospectionAccess; import com.sun.star.uno.AnyConverter; import com.sun.star.uno.XComponentContext; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import java.util.zip.CRC32; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.analysis.cjk.CJKAnalyzer; -import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.index.IndexWriter; - import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Date; +import java.util.zip.ZipOutputStream; public class HelpIndexer extends WeakBase implements XServiceInfo, XInvocation @@ -62,6 +50,8 @@ public class HelpIndexer extends WeakBase "com.sun.star.help.HelpIndexer"; static private final String aCreateIndexMethodName = "createIndex"; + static private com.sun.star.help.HelpIndexerTool helpindexer = new com.sun.star.help.HelpIndexerTool(); + public HelpIndexer() { } @@ -70,292 +60,26 @@ public class HelpIndexer extends WeakBase { } - /** - * @param args the command line arguments - */ - public static void main( String[] args ) + public static void mainImpl( String[] args, boolean bExtensionMode ) { - boolean bExtensionMode = false; - mainImpl( args, bExtensionMode ); - } - - private static void mainImpl( String[] args, boolean bExtensionMode ) - { - String aDirToZipStr = ""; - String aSrcDirStr = ""; - String aLanguageStr = ""; - String aModule = ""; - String aTargetZipFileStr = ""; - - // Scan arguments - boolean bLang = false; - boolean bMod = false; - boolean bZipDir = false; - boolean bSrcDir = false; - boolean bOutput = false; - - int nArgCount = args.length; - for( int i = 0 ; i < nArgCount ; i++ ) - { - if( "-lang".equals(args[i]) ) - { - if( i + 1 < nArgCount ) - { - aLanguageStr = args[i + 1]; - bLang = true; - } - i++; - } - else if( "-mod".equals(args[i]) ) - { - if( i + 1 < nArgCount ) - { - aModule = args[i + 1]; - bMod = true; - } - i++; - } - else if( "-zipdir".equals(args[i]) ) - { - if( i + 1 < nArgCount ) - { - aDirToZipStr = args[i + 1]; - bZipDir = true; - } - i++; - } - else if( "-srcdir".equals(args[i]) ) - { - if( i + 1 < nArgCount ) - { - aSrcDirStr = args[i + 1]; - bSrcDir = true; - } - i++; - } - else if( "-o".equals(args[i]) ) - { - if( i + 1 < nArgCount ) - { - aTargetZipFileStr = args[i + 1]; - bOutput = true; - } - i++; - } - } - - if( !bLang || !bMod || !bZipDir || (!bOutput && !bExtensionMode) ) - { - if( bExtensionMode ) - return; - - System.out.println("Usage: HelpIndexer -lang ISOLangCode -mod HelpModule -zipdir TempZipDir -o OutputZipFile"); - System.exit( -1 ); - } - - String aIndexDirName = aModule + ".idxl"; - File aIndexDir = new File( aDirToZipStr + File.separator + aIndexDirName ); - if( !bSrcDir ) - aSrcDirStr = aDirToZipStr; - File aCaptionFilesDir = new File( aSrcDirStr + File.separator + "caption" ); - File aContentFilesDir = new File( aSrcDirStr + File.separator + "content" ); - - try - { - Date start = new Date(); - Analyzer analyzer = aLanguageStr.equals("ja") ? (Analyzer)new CJKAnalyzer() : (Analyzer)new StandardAnalyzer(); - IndexWriter writer = new IndexWriter( aIndexDir, analyzer, true ); - if( !bExtensionMode ) - System.out.println( "Lucene: Indexing to directory '" + aIndexDir + "'..." ); - int nRet = indexDocs( writer, aModule, bExtensionMode, aCaptionFilesDir, aContentFilesDir ); - if( nRet != -1 ) - { - if( !bExtensionMode ) - { - System.out.println(); - System.out.println( "Optimizing ..." ); - } - writer.optimize(); - } - writer.close(); - - if( bExtensionMode ) - { - if( !bSrcDir ) - { - deleteRecursively( aCaptionFilesDir ); - deleteRecursively( aContentFilesDir ); - } - } - else - { - if( nRet == -1 ) - deleteRecursively( aIndexDir ); - - if( !bExtensionMode ) - System.out.println( "Zipping ..." ); - File aDirToZipFile = new File( aDirToZipStr ); - createZipFile( aDirToZipFile, aTargetZipFileStr ); - deleteRecursively( aDirToZipFile ); - } - - Date end = new Date(); - if( !bExtensionMode ) - System.out.println(end.getTime() - start.getTime() + " total milliseconds"); - } - catch (IOException e) - { - if( bExtensionMode ) - return; - - System.out.println(" caught a " + e.getClass() + - "\n with message: " + e.getMessage()); - System.exit( -1 ); - } - } - - private static int indexDocs(IndexWriter writer, String aModule, boolean bExtensionMode, - File aCaptionFilesDir, File aContentFilesDir) throws IOException - { - if( !aCaptionFilesDir.canRead() || !aCaptionFilesDir.isDirectory() ) - { - if( !bExtensionMode ) - System.out.println( "Not found: " + aCaptionFilesDir ); - return -1; - } - if( !aContentFilesDir.canRead() || !aContentFilesDir.isDirectory() ) - { - if( !bExtensionMode ) - System.out.println( "Not found: " + aContentFilesDir ); - return -1; - } - - String[] aCaptionFiles = aCaptionFilesDir.list(); - List aCaptionFilesList = Arrays.asList( aCaptionFiles ); - HashSet aCaptionFilesHashSet = new HashSet( aCaptionFilesList ); - - String[] aContentFiles = aContentFilesDir.list(); - List aContentFilesList = Arrays.asList( aContentFiles ); - HashSet aContentFilesHashSet = new HashSet( aContentFilesList ); - - // Loop over caption files and find corresponding content file - if( !bExtensionMode ) - System.out.println( "Indexing, adding files" ); - int nCaptionFilesLen = aCaptionFiles.length; - for( int i = 0 ; i < nCaptionFilesLen ; i++ ) - { - String aCaptionFileStr = aCaptionFiles[i]; - File aCaptionFile = new File( aCaptionFilesDir, aCaptionFileStr ); - File aContentFile = null; - if( aContentFilesHashSet.contains( aCaptionFileStr ) ) - aContentFile = new File( aContentFilesDir, aCaptionFileStr ); - - if( !bExtensionMode ) - System.out.print( "." ); - writer.addDocument( HelpFileDocument.Document( aModule, aCaptionFile, aContentFile ) ); - } - - // Loop over content files to find remaining files not mapped to caption files - int nContentFilesLen = aContentFiles.length; - for( int i = 0 ; i < nContentFilesLen ; i++ ) - { - String aContentFileStr = aContentFiles[i]; - if( !aCaptionFilesHashSet.contains( aContentFileStr ) ) - { - // Not already handled in caption files loop - File aCaptionFile = null; - File aContentFile = new File( aContentFilesDir, aContentFileStr ); - if( !bExtensionMode ) - System.out.print( "." ); - writer.addDocument( HelpFileDocument.Document( aModule, aCaptionFile, aContentFile ) ); - } - } - return 0; + helpindexer.mainImpl( args , bExtensionMode ); } public static void createZipFile( File aDirToZip, String aTargetZipFileStr ) throws FileNotFoundException, IOException { - FileOutputStream fos = new FileOutputStream( aTargetZipFileStr ); - ZipOutputStream zos = new ZipOutputStream( fos ); - - File[] aChildrenFiles = aDirToZip.listFiles(); - int nFileCount = aChildrenFiles.length; - for( int i = 0 ; i < nFileCount ; i++ ) - addToZipRecursively( zos, aChildrenFiles[i], null ); - - zos.close(); + helpindexer.createZipFile( aDirToZip , aTargetZipFileStr ); } public static void addToZipRecursively( ZipOutputStream zos, File aFile, String aBasePath ) throws FileNotFoundException, IOException { - if( aFile.isDirectory() ) - { - String aDirName = aFile.getName(); - if( aDirName.equalsIgnoreCase( "caption" ) || aDirName.equalsIgnoreCase( "content" ) ) - return; - - File[] aChildrenFiles = aFile.listFiles(); - String aNewBasePath = ""; - if( aBasePath != null ) - aNewBasePath += aBasePath + File.separator; - aNewBasePath += aDirName; - - int nFileCount = aChildrenFiles.length; - for( int i = 0 ; i < nFileCount ; i++ ) - addToZipRecursively( zos, aChildrenFiles[i], aNewBasePath ); - - return; - } - - // No directory - // read contents of file we are going to put in the zip - int fileLength = (int) aFile.length(); - FileInputStream fis = new FileInputStream( aFile ); - byte[] wholeFile = new byte[fileLength]; - int bytesRead = fis.read( wholeFile, 0, fileLength ); - fis.close(); - - String aFileName = aFile.getName(); - String aEntryName = ""; - if( aBasePath != null ) - aEntryName += aBasePath + "/"; - aEntryName += aFileName; - ZipEntry aZipEntry = new ZipEntry( aEntryName ); - aZipEntry.setTime( aFile.lastModified() ); - aZipEntry.setSize( fileLength ); - - int nMethod = ( aFileName.toLowerCase().endsWith( ".jar" ) ) - ? ZipEntry.STORED : ZipEntry.DEFLATED; - aZipEntry.setMethod( nMethod ); - - CRC32 tempCRC = new CRC32(); - tempCRC.update( wholeFile, 0, wholeFile.length ); - aZipEntry.setCrc( tempCRC.getValue() ); - - // write the contents into the zip element - zos.putNextEntry( aZipEntry ); - zos.write( wholeFile, 0, fileLength ); - zos.closeEntry(); + helpindexer.addToZipRecursively( zos , aFile , aBasePath ); } static public boolean deleteRecursively( File aFile ) { - if( aFile.isDirectory() ) - { - File[] aChildrenFiles = aFile.listFiles(); - int nFileCount = aChildrenFiles.length; - for( int i = 0 ; i < nFileCount ; i++ ) - { - File aChildrenFile = aChildrenFiles[i]; - boolean bSuccess = deleteRecursively( aChildrenFile ); - if( !bSuccess ) - return false; - } - } - - return aFile.delete(); + return helpindexer.deleteRecursively( aFile ); } //=================================================== @@ -371,7 +95,8 @@ public class HelpIndexer extends WeakBase com.sun.star.script.CannotConvertException, com.sun.star.reflection.InvocationTargetException { - if( !aFunctionName.equals( aCreateIndexMethodName ) ) + if( + !aFunctionName.equals( aCreateIndexMethodName ) ) throw new com.sun.star.lang.IllegalArgumentException(); aOutParamIndex[0] = new short[0]; @@ -421,6 +146,7 @@ public class HelpIndexer extends WeakBase } + /** This method returns an array of all supported service names. * @return Array of supported service names. */ @@ -439,6 +165,7 @@ public class HelpIndexer extends WeakBase return sSupportedServiceNames; } + /** This method returns true, if the given service will be * supported by the component. * @param sServiceName Service name. @@ -449,6 +176,7 @@ public class HelpIndexer extends WeakBase return sServiceName.equals( __serviceName ); } + /** Return the class name of the component. * @return Class name of the component. */ @@ -456,5 +184,6 @@ public class HelpIndexer extends WeakBase { return HelpIndexer.class.getName(); } + } diff --git a/xmlhelp/source/com/sun/star/help/HelpLinker.cxx b/xmlhelp/source/com/sun/star/help/HelpLinker.cxx deleted file mode 100644 index 67049df439e1..000000000000 --- a/xmlhelp/source/com/sun/star/help/HelpLinker.cxx +++ /dev/null @@ -1,1157 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: HelpLinker.cxx,v $ - * $Revision: 1.16 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "HelpCompiler.hxx" - -#include <map> - -#include <string.h> -#include <limits.h> - -#include <libxslt/xslt.h> -#include <libxslt/transform.h> -#include <libxslt/xsltutils.h> -#include <libxslt/functions.h> -#include <libxslt/extensions.h> - -#include <sal/types.h> -#include <osl/time.h> -#include <rtl/bootstrap.hxx> - -#ifdef SYSTEM_EXPAT -#include <expat.h> -#else -#include <expat/xmlparse.h> -#endif - -#define DBHELP_ONLY - - -class IndexerPreProcessor -{ -private: - std::string m_aModuleName; - fs::path m_fsIndexBaseDir; - fs::path m_fsCaptionFilesDirName; - fs::path m_fsContentFilesDirName; - - xsltStylesheetPtr m_xsltStylesheetPtrCaption; - xsltStylesheetPtr m_xsltStylesheetPtrContent; - -public: - IndexerPreProcessor( const std::string& aModuleName, const fs::path& fsIndexBaseDir, - const fs::path& idxCaptionStylesheet, const fs::path& idxContentStylesheet ); - ~IndexerPreProcessor(); - - void processDocument( xmlDocPtr doc, const std::string& EncodedDocPath ); -}; - -IndexerPreProcessor::IndexerPreProcessor - ( const std::string& aModuleName, const fs::path& fsIndexBaseDir, - const fs::path& idxCaptionStylesheet, const fs::path& idxContentStylesheet ) - : m_aModuleName( aModuleName ) - , m_fsIndexBaseDir( fsIndexBaseDir ) -{ - m_fsCaptionFilesDirName = fsIndexBaseDir / "caption"; - fs::create_directory( m_fsCaptionFilesDirName ); - - m_fsContentFilesDirName = fsIndexBaseDir / "content"; - fs::create_directory( m_fsContentFilesDirName ); - - m_xsltStylesheetPtrCaption = xsltParseStylesheetFile - ((const xmlChar *)idxCaptionStylesheet.native_file_string().c_str()); - m_xsltStylesheetPtrContent = xsltParseStylesheetFile - ((const xmlChar *)idxContentStylesheet.native_file_string().c_str()); -} - -IndexerPreProcessor::~IndexerPreProcessor() -{ - if( m_xsltStylesheetPtrCaption ) - xsltFreeStylesheet( m_xsltStylesheetPtrCaption ); - if( m_xsltStylesheetPtrContent ) - xsltFreeStylesheet( m_xsltStylesheetPtrContent ); -} - - -std::string getEncodedPath( const std::string& Path ) -{ - rtl::OString aOStr_Path( Path.c_str() ); - rtl::OUString aOUStr_Path( rtl::OStringToOUString - ( aOStr_Path, fs::getThreadTextEncoding() ) ); - rtl::OUString aPathURL; - osl::File::getFileURLFromSystemPath( aOUStr_Path, aPathURL ); - rtl::OString aOStr_PathURL( rtl::OUStringToOString - ( aPathURL, fs::getThreadTextEncoding() ) ); - std::string aStdStr_PathURL( aOStr_PathURL.getStr() ); - return aStdStr_PathURL; -} - -void IndexerPreProcessor::processDocument - ( xmlDocPtr doc, const std::string &EncodedDocPath ) -{ - std::string aStdStr_EncodedDocPathURL = getEncodedPath( EncodedDocPath ); - - xmlDocPtr resCaption = xsltApplyStylesheet( m_xsltStylesheetPtrCaption, doc, NULL ); - xmlNodePtr pResNodeCaption = resCaption->xmlChildrenNode; - if( pResNodeCaption ) - { - fs::path fsCaptionPureTextFile_docURL = m_fsCaptionFilesDirName / aStdStr_EncodedDocPathURL; - std::string aCaptionPureTextFileStr_docURL = fsCaptionPureTextFile_docURL.native_file_string(); - FILE* pFile_docURL = fopen( aCaptionPureTextFileStr_docURL.c_str(), "w" ); - if( pFile_docURL ) - { - fprintf( pFile_docURL, "%s\n", pResNodeCaption->content ); - fclose( pFile_docURL ); - } - } - xmlFreeDoc(resCaption); - - xmlDocPtr resContent = xsltApplyStylesheet( m_xsltStylesheetPtrContent, doc, NULL ); - xmlNodePtr pResNodeContent = resContent->xmlChildrenNode; - if( pResNodeContent ) - { - fs::path fsContentPureTextFile_docURL = m_fsContentFilesDirName / aStdStr_EncodedDocPathURL; - std::string aContentPureTextFileStr_docURL = fsContentPureTextFile_docURL.native_file_string(); - FILE* pFile_docURL = fopen( aContentPureTextFileStr_docURL.c_str(), "w" ); - if( pFile_docURL ) - { - fprintf( pFile_docURL, "%s\n", pResNodeContent->content ); - fclose( pFile_docURL ); - } - } - xmlFreeDoc(resContent); -} - -struct Data -{ - std::vector<std::string> _idList; - typedef std::vector<std::string>::const_iterator cIter; - - void append(const std::string &id) - { - _idList.push_back(id); - } - - std::string getString() const - { - std::string ret; - cIter aEnd = _idList.end(); - for (cIter aIter = _idList.begin(); aIter != aEnd; ++aIter) - ret += *aIter + ";"; - return ret; - } -}; - -void writeKeyValue_DBHelp( FILE* pFile, const std::string& aKeyStr, const std::string& aValueStr ) -{ - if( pFile == NULL ) - return; - char cLF = 10; - int nKeyLen = aKeyStr.length(); - int nValueLen = aValueStr.length(); - fprintf( pFile, "%x ", nKeyLen ); - if( nKeyLen > 0 ) - fwrite( aKeyStr.c_str(), 1, nKeyLen, pFile );
- fprintf( pFile, " %x ", nValueLen ); - if( nValueLen > 0 ) - fwrite( aValueStr.c_str(), 1, nValueLen, pFile );
- fprintf( pFile, "%c", cLF ); -} - -class HelpKeyword -{ -private: - typedef std::hash_map<std::string, Data, pref_hash> DataHashtable; - DataHashtable _hash; - -public: - void insert(const std::string &key, const std::string &id) - { - Data &data = _hash[key]; - data.append(id); - } - - void dump(DB* table) - { - DataHashtable::const_iterator aEnd = _hash.end(); - for (DataHashtable::const_iterator aIter = _hash.begin(); aIter != aEnd; ++aIter) - { - const std::string &keystr = aIter->first; - DBT key; - memset(&key, 0, sizeof(key)); - key.data = const_cast<char*>(keystr.c_str()); - key.size = keystr.length(); - - const Data &data = aIter->second; - std::string str = data.getString(); - DBT value; - memset(&value, 0, sizeof(value)); - value.data = const_cast<char*>(str.c_str()); - value.size = str.length(); - - table->put(table, NULL, &key, &value, 0); - } - } - - void dump_DBHelp( const std::string& rFileName ) - { - FILE* pFile = fopen( rFileName.c_str(), "wb" ); - if( pFile == NULL ) - return; - - DataHashtable::const_iterator aEnd = _hash.end(); - for (DataHashtable::const_iterator aIter = _hash.begin(); aIter != aEnd; ++aIter) - writeKeyValue_DBHelp( pFile, aIter->first, aIter->second.getString() ); - - fclose( pFile ); - } -}; - -class HelpLinker -{ -public: - void main(std::vector<std::string> &args, std::string* pExtensionPath = NULL ) - throw( HelpProcessingException ); - - HelpLinker() - : init(true) - , m_pIndexerPreProcessor(NULL) - {} - ~HelpLinker() - { delete m_pIndexerPreProcessor; } - -private: - int locCount, totCount; - Stringtable additionalFiles; - HashSet helpFiles; - fs::path sourceRoot; - fs::path embeddStylesheet; - fs::path idxCaptionStylesheet; - fs::path idxContentStylesheet; - fs::path zipdir; - fs::path outputFile; - std::string module; - std::string lang; - std::string hid; - std::string extensionPath; - bool bExtensionMode; - fs::path indexDirName; - Stringtable hidlistTranslation; - fs::path indexDirParentName; - bool init; - IndexerPreProcessor* m_pIndexerPreProcessor; - void initIndexerPreProcessor(); - void link() throw( HelpProcessingException ); - void addBookmark( DB* dbBase, FILE* pFile_DBHelp, std::string thishid, - const std::string& fileB, const std::string& anchorB, - const std::string& jarfileB, const std::string& titleB ); -#if 0 - /** - * @param outputFile - * @param module - * @param lang - * @param hid - * @param helpFiles - * @param additionalFiles - */ - - private HelpURLStreamHandlerFactory urlHandler = null; -#endif -}; - -namespace URLEncoder -{ - static std::string encode(const std::string &rIn) - { - const char *good = "!$&'()*+,-.=@_"; - static const char hex[17] = "0123456789ABCDEF"; - - std::string result; - for (size_t i=0; i < rIn.length(); ++i) - { - unsigned char c = rIn[i]; - if (isalnum (c) || strchr (good, c)) - result += c; - else { - result += '%'; - result += hex[c >> 4]; - result += hex[c & 0xf]; - } - } - return result; - } -} - -void HelpLinker::addBookmark( DB* dbBase, FILE* pFile_DBHelp, std::string thishid, - const std::string& fileB, const std::string& anchorB, - const std::string& jarfileB, const std::string& titleB) -{ - HCDBG(std::cerr << "HelpLinker::addBookmark " << thishid << " " << - fileB << " " << anchorB << " " << jarfileB << " " << titleB << std::endl); - - std::string temp = thishid; - std::transform (temp.begin(), temp.end(), temp.begin(), toupper); - std::replace(temp.begin(), temp.end(), ':', '_'); - const std::string& translatedHid = hidlistTranslation[temp]; - if (!translatedHid.empty()) - thishid = translatedHid; - - thishid = URLEncoder::encode(thishid); - - DBT key; - memset(&key, 0, sizeof(key)); - key.data = const_cast<char*>(thishid.c_str()); - key.size = thishid.length(); - - int fileLen = fileB.length(); - if (!anchorB.empty()) - fileLen += (1 + anchorB.length()); - int dataLen = 1 + fileLen + 1 + jarfileB.length() + 1 + titleB.length(); - - std::vector<unsigned char> dataB(dataLen); - size_t i = 0; - dataB[i++] = static_cast<unsigned char>(fileLen); - for (size_t j = 0; j < fileB.length(); ++j) - dataB[i++] = fileB[j]; - if (!anchorB.empty()) - { - dataB[i++] = '#'; - for (size_t j = 0; j < anchorB.length(); ++j) - dataB[i++] = anchorB[j]; - } - dataB[i++] = static_cast<unsigned char>(jarfileB.length()); - for (size_t j = 0; j < jarfileB.length(); ++j) - dataB[i++] = jarfileB[j]; - - dataB[i++] = static_cast<unsigned char>(titleB.length()); - for (size_t j = 0; j < titleB.length(); ++j) - dataB[i++] = titleB[j]; - - DBT data; - memset(&data, 0, sizeof(data)); - data.data = &dataB[0]; - data.size = dataB.size(); - - if( dbBase != NULL ) - dbBase->put(dbBase, NULL, &key, &data, 0); - - if( pFile_DBHelp != NULL ) - { - std::string aValueStr( dataB.begin(), dataB.end() ); - writeKeyValue_DBHelp( pFile_DBHelp, thishid, aValueStr ); - } -} - -void HelpLinker::initIndexerPreProcessor() -{ - if( m_pIndexerPreProcessor ) - delete m_pIndexerPreProcessor; - std::string mod = module; - std::transform (mod.begin(), mod.end(), mod.begin(), tolower); - m_pIndexerPreProcessor = new IndexerPreProcessor( mod, indexDirParentName, - idxCaptionStylesheet, idxContentStylesheet ); -} - -/** -* -*/ -void HelpLinker::link() throw( HelpProcessingException ) -{ - bool bIndexForExtension = true;
-
- if( bExtensionMode ) - { - indexDirParentName = sourceRoot; - } - else - { - indexDirParentName = zipdir; - fs::create_directory(indexDirParentName); - } - -#ifdef CMC_DEBUG - std::cerr << "will not delete tmpdir of " << indexDirParentName.native_file_string().c_str() << std::endl; -#endif - - std::string mod = module; - std::transform (mod.begin(), mod.end(), mod.begin(), tolower); - - // do the work here - // continue with introduction of the overall process thing into the - // here all hzip files will be worked on - std::string appl = mod; - if (appl[0] == 's') - appl = appl.substr(1); - - bool bUse_ = true; -#ifdef DBHELP_ONLY - if( !bExtensionMode ) - bUse_ = false; -#endif - - DB* helpText(0); -#ifndef DBHELP_ONLY - fs::path helpTextFileName(indexDirParentName / (mod + ".ht")); - db_create(&helpText,0,0); - helpText->open(helpText, NULL, helpTextFileName.native_file_string().c_str(), NULL, DB_BTREE, - DB_CREATE | DB_TRUNCATE, 0644); -#endif - - fs::path helpTextFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".ht_" : ".ht"))); - FILE* pFileHelpText_DBHelp = fopen - ( helpTextFileName_DBHelp.native_file_string().c_str(), "wb" ); - - DB* dbBase(0); -#ifndef DBHELP_ONLY - fs::path dbBaseFileName(indexDirParentName / (mod + ".db")); - db_create(&dbBase,0,0); - dbBase->open(dbBase, NULL, dbBaseFileName.native_file_string().c_str(), NULL, DB_BTREE, - DB_CREATE | DB_TRUNCATE, 0644); -#endif - - fs::path dbBaseFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".db_" : ".db"))); - FILE* pFileDbBase_DBHelp = fopen - ( dbBaseFileName_DBHelp.native_file_string().c_str(), "wb" ); - -#ifndef DBHELP_ONLY - DB* keyWord(0); - fs::path keyWordFileName(indexDirParentName / (mod + ".key")); - db_create(&keyWord,0,0); - keyWord->open(keyWord, NULL, keyWordFileName.native_file_string().c_str(), NULL, DB_BTREE, - DB_CREATE | DB_TRUNCATE, 0644); -#endif - - fs::path keyWordFileName_DBHelp(indexDirParentName / (mod + (bUse_ ? ".key_" : ".key"))); - - HelpKeyword helpKeyword; - - // catch HelpProcessingException to avoid locking data bases - try - { - - std::ifstream fileReader(hid.c_str()); - while (fileReader) - { - std::string key; - fileReader >> key; - std::transform (key.begin(), key.end(), key.begin(), toupper); - std::replace(key.begin(), key.end(), ':', '_'); - std::string data; - fileReader >> data; - if (!key.empty() && !data.empty()) - hidlistTranslation[key] = data; - } - fileReader.close(); - - // lastly, initialize the indexBuilder - if ( (!bExtensionMode || bIndexForExtension) && !helpFiles.empty()) - initIndexerPreProcessor(); - - if( !bExtensionMode ) - { - std::cout << "Making " << outputFile.native_file_string() << - " from " << helpFiles.size() << " input files" << std::endl; - } - - // here we start our loop over the hzip files. - HashSet::iterator end = helpFiles.end(); - for (HashSet::iterator iter = helpFiles.begin(); iter != end; ++iter) - { - if( !bExtensionMode ) - { - std::cout << "."; - std::cout.flush(); - } - - // process one file - // streamTable contains the streams in the hzip file - StreamTable streamTable; - const std::string &xhpFileName = *iter; - - if (!bExtensionMode && xhpFileName.rfind(".xhp") != xhpFileName.length()-4) - { - // only work on .xhp - files - std::cerr << - "ERROR: input list entry '" - << xhpFileName - << "' has the wrong extension (only files with extension .xhp " - << "are accepted)"; - continue; - } - - fs::path langsourceRoot(sourceRoot); - fs::path xhpFile; - - if( bExtensionMode ) - { - // langsourceRoot == sourceRoot for extensions - std::string xhpFileNameComplete( extensionPath ); - xhpFileNameComplete.append( '/' + xhpFileName ); - xhpFile = fs::path( xhpFileNameComplete ); - } - else - { - langsourceRoot.append('/' + lang + '/'); - xhpFile = fs::path(xhpFileName, fs::native); - } - - HelpCompiler hc( streamTable, xhpFile, langsourceRoot, - embeddStylesheet, module, lang, bExtensionMode ); - - HCDBG(std::cerr << "before compile of " << xhpFileName << std::endl); - bool success = hc.compile(); - HCDBG(std::cerr << "after compile of " << xhpFileName << std::endl); - - if (!success && !bExtensionMode) - { - std::stringstream aStrStream; - aStrStream << - "\nERROR: compiling help particle '" - << xhpFileName - << "' for language '" - << lang - << "' failed!"; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - const std::string documentBaseId = streamTable.document_id; - std::string documentPath = streamTable.document_path; - if (documentPath.find("/") == 0) - documentPath = documentPath.substr(1); - - std::string documentJarfile = streamTable.document_module + ".jar"; - - std::string documentTitle = streamTable.document_title; - if (documentTitle.empty()) - documentTitle = "<notitle>"; - -#if 0 - std::cout << "for " << xhpFileName << " documentBaseId is " << documentBaseId << "\n"; - std::cout << "for " << xhpFileName << " documentPath is " << documentPath << "\n"; - std::cout << "for " << xhpFileName << " documentJarfile is " << documentJarfile << "\n"; - std::cout << "for " << xhpFileName << " documentPath is " << documentTitle << "\n"; -#endif - - const std::string& fileB = documentPath; - const std::string& jarfileB = documentJarfile; - std::string& titleB = documentTitle; - - // add once this as its own id. - addBookmark(dbBase, pFileDbBase_DBHelp, documentPath, fileB, std::string(), jarfileB, titleB); - - // first the database *.db - // ByteArrayInputStream bais = null; - // ObjectInputStream ois = null; - - const HashSet *hidlist = streamTable.appl_hidlist; - if (!hidlist) - hidlist = streamTable.default_hidlist; - if (hidlist && !hidlist->empty()) - { - // now iterate over all elements of the hidlist - HashSet::const_iterator aEnd = hidlist->end(); - for (HashSet::const_iterator hidListIter = hidlist->begin(); - hidListIter != aEnd; ++hidListIter) - { - std::string thishid = *hidListIter; - - std::string anchorB; - size_t index = thishid.rfind('#'); - if (index != std::string::npos) - { - anchorB = thishid.substr(1 + index); - thishid = thishid.substr(0, index); - } - addBookmark(dbBase, pFileDbBase_DBHelp, thishid, fileB, anchorB, jarfileB, titleB); - } - } - - // now the keywords - const Hashtable *anchorToLL = streamTable.appl_keywords; - if (!anchorToLL) - anchorToLL = streamTable.default_keywords; - if (anchorToLL && !anchorToLL->empty()) - { - std::string fakedHid = URLEncoder::encode(documentPath); - Hashtable::const_iterator aEnd = anchorToLL->end(); - for (Hashtable::const_iterator enumer = anchorToLL->begin(); - enumer != aEnd; ++enumer) - { - const std::string &anchor = enumer->first; - addBookmark(dbBase, pFileDbBase_DBHelp, documentPath, fileB, - anchor, jarfileB, titleB); - std::string totalId = fakedHid + "#" + anchor; - // std::cerr << hzipFileName << std::endl; - const LinkedList& ll = enumer->second; - LinkedList::const_iterator aOtherEnd = ll.end(); - for (LinkedList::const_iterator llIter = ll.begin(); - llIter != aOtherEnd; ++llIter) - { - helpKeyword.insert(*llIter, totalId); - } - } - - } - - // and last the helptexts - const Stringtable *helpTextHash = streamTable.appl_helptexts; - if (!helpTextHash) - helpTextHash = streamTable.default_helptexts; - if (helpTextHash && !helpTextHash->empty()) - { - Stringtable::const_iterator aEnd = helpTextHash->end(); - for (Stringtable::const_iterator helpTextIter = helpTextHash->begin(); - helpTextIter != aEnd; ++helpTextIter) - { - std::string helpTextId = helpTextIter->first; - const std::string& helpTextText = helpTextIter->second; - - std::string temp = helpTextId; - std::transform (temp.begin(), temp.end(), temp.begin(), toupper); - std::replace(temp.begin(), temp.end(), ':', '_'); - - const std::string& tHid = hidlistTranslation[temp]; - if (!tHid.empty()) - helpTextId = tHid; - helpTextId = URLEncoder::encode(helpTextId); - - DBT keyDbt; - memset(&keyDbt, 0, sizeof(keyDbt)); - keyDbt.data = const_cast<char*>(helpTextId.c_str()); - keyDbt.size = helpTextId.length(); - - DBT textDbt; - memset(&textDbt, 0, sizeof(textDbt)); - textDbt.data = const_cast<char*>(helpTextText.c_str()); - textDbt.size = helpTextText.length(); - - if( helpText != NULL ) - helpText->put(helpText, NULL, &keyDbt, &textDbt, 0); - - if( pFileHelpText_DBHelp != NULL ) - writeKeyValue_DBHelp( pFileHelpText_DBHelp, helpTextId, helpTextText ); - } - } - - //IndexerPreProcessor - if( !bExtensionMode || bIndexForExtension ) - { - // now the indexing - xmlDocPtr document = streamTable.appl_doc; - if (!document) - document = streamTable.default_doc; - if (document) - { - std::string temp = module; - std::transform (temp.begin(), temp.end(), temp.begin(), tolower); - m_pIndexerPreProcessor->processDocument(document, URLEncoder::encode(documentPath) ); - } - } - - } // while loop over hzip files ending - if( !bExtensionMode ) - std::cout << std::endl; - - } // try - catch( HelpProcessingException& ) - { - // catch HelpProcessingException to avoid locking data bases -#ifndef DBHELP_ONLY - helpText->close(helpText, 0); - dbBase->close(dbBase, 0); - keyWord->close(keyWord, 0); -#endif - if( pFileHelpText_DBHelp != NULL ) - fclose( pFileHelpText_DBHelp ); - if( pFileDbBase_DBHelp != NULL ) - fclose( pFileDbBase_DBHelp ); - throw; - } - -#ifndef DBHELP_ONLY - helpText->close(helpText, 0); - dbBase->close(dbBase, 0); - helpKeyword.dump(keyWord); - keyWord->close(keyWord, 0); -#endif - if( pFileHelpText_DBHelp != NULL ) - fclose( pFileHelpText_DBHelp ); - if( pFileDbBase_DBHelp != NULL ) - fclose( pFileDbBase_DBHelp ); - - helpKeyword.dump_DBHelp( keyWordFileName_DBHelp.native_file_string() ); - - if( !bExtensionMode ) - { - // New index - Stringtable::iterator aEnd = additionalFiles.end(); - for (Stringtable::iterator enumer = additionalFiles.begin(); enumer != aEnd; - ++enumer) - { - const std::string &additionalFileName = enumer->second; - const std::string &additionalFileKey = enumer->first; - - fs::path fsAdditionalFileName( additionalFileName, fs::native ); - std::string aNativeStr = fsAdditionalFileName.native_file_string(); - const char* pStr = aNativeStr.c_str(); - std::cerr << pStr; - - fs::path fsTargetName( indexDirParentName / additionalFileKey ); - - fs::copy( fsAdditionalFileName, fsTargetName ); - } - } - -/* - ///////////////////////////////////////////////////////////////////////// - /// remove temprary directory for index creation - ///////////////////////////////////////////////////////////////////////// -#ifndef CMC_DEBUG - if( !bExtensionMode ) - fs::remove_all( indexDirParentName ); -#endif -*/ -} - - -void HelpLinker::main(std::vector<std::string> &args, std::string* pExtensionPath) - throw( HelpProcessingException ) -{ - rtl::OUString aOfficeHelpPath; - - bExtensionMode = false; - if( pExtensionPath && pExtensionPath->length() > 0 ) - { - helpFiles.clear(); - bExtensionMode = true; - extensionPath = *pExtensionPath; - sourceRoot = fs::path(extensionPath); - - aOfficeHelpPath = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/help") ); - rtl::Bootstrap::expandMacros( aOfficeHelpPath ); - } - if (args.size() > 0 && args[0][0] == '@') - { - std::vector<std::string> stringList; - std::string strBuf; - std::ifstream fileReader(args[0].substr(1).c_str()); - - while (fileReader) - { - std::string token; - fileReader >> token; - if (!token.empty()) - stringList.push_back(token); - } - fileReader.close(); - - args = stringList; - } - - size_t i = 0; - - while (i < args.size()) - { - if (args[i].compare("-src") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "sourceroot missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - if( !bExtensionMode ) - sourceRoot = fs::path(args[i], fs::native); - } - else if (args[i].compare("-sty") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "embeddingStylesheet missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - embeddStylesheet = fs::path(args[i], fs::native); - } - else if (args[i].compare("-zipdir") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "idxtemp missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - zipdir = fs::path(args[i], fs::native); - } - else if (args[i].compare("-idxcaption") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "idxcaption stylesheet missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - idxCaptionStylesheet = fs::path(args[i], fs::native); - } - else if (args[i].compare("-idxcontent") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "idxcontent stylesheet missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - idxContentStylesheet = fs::path(args[i], fs::native); - } - else if (args[i].compare("-o") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "outputfilename missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - outputFile = fs::path(args[i], fs::native); - } - else if (args[i].compare("-mod") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "module name missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - module = args[i]; - } - else if (args[i].compare("-lang") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "language name missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - lang = args[i]; - } - else if (args[i].compare("-hid") == 0) - { - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "hid list missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - hid = args[i]; - } - else if (args[i].compare("-add") == 0) - { - std::string addFile, addFileUnderPath; - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "pathname missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - addFileUnderPath = args[i]; - ++i; - if (i >= args.size()) - { - std::stringstream aStrStream; - aStrStream << "pathname missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - addFile = args[i]; - if (!addFileUnderPath.empty() && !addFile.empty()) - additionalFiles[addFileUnderPath] = addFile; - } - else - helpFiles.push_back(args[i]); - ++i; - } - - if (!bExtensionMode && zipdir.empty()) - { - std::stringstream aStrStream; - aStrStream << "no index dir given" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - if (!bExtensionMode && idxCaptionStylesheet.empty()) - { - std::stringstream aStrStream; - aStrStream << "no index caption stylesheet given" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - else if ( bExtensionMode )
- {
- rtl::OUString aIdxCaptionPathFileURL( aOfficeHelpPath );
- aIdxCaptionPathFileURL += rtl::OUString::createFromAscii( "/idxcaption.xsl" );
-
- rtl::OString aOStr_IdxCaptionPathFileURL( rtl::OUStringToOString - ( aIdxCaptionPathFileURL, fs::getThreadTextEncoding() ) ); - std::string aStdStr_IdxCaptionPathFileURL( aOStr_IdxCaptionPathFileURL.getStr() ); -
- idxCaptionStylesheet = fs::path( aStdStr_IdxCaptionPathFileURL );
- }
- if (!bExtensionMode && idxContentStylesheet.empty()) - { - std::stringstream aStrStream; - aStrStream << "no index content stylesheet given" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - else if ( bExtensionMode )
- {
- rtl::OUString aIdxContentPathFileURL( aOfficeHelpPath );
- aIdxContentPathFileURL += rtl::OUString::createFromAscii( "/idxcontent.xsl" );
-
- rtl::OString aOStr_IdxContentPathFileURL( rtl::OUStringToOString - ( aIdxContentPathFileURL, fs::getThreadTextEncoding() ) ); - std::string aStdStr_IdxContentPathFileURL( aOStr_IdxContentPathFileURL.getStr() ); -
- idxContentStylesheet = fs::path( aStdStr_IdxContentPathFileURL );
- }
- if (!bExtensionMode && embeddStylesheet.empty()) - { - std::stringstream aStrStream; - aStrStream << "no embedding resolving file given" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - if (sourceRoot.empty()) - { - std::stringstream aStrStream; - aStrStream << "no sourceroot given" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - if (!bExtensionMode && outputFile.empty()) - { - std::stringstream aStrStream; - aStrStream << "no output file given" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - if (module.empty()) - { - std::stringstream aStrStream; - aStrStream << "module missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - if (!bExtensionMode && lang.empty()) - { - std::stringstream aStrStream; - aStrStream << "language missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - if (!bExtensionMode && hid.empty()) - { - std::stringstream aStrStream; - aStrStream << "hid list missing" << std::endl; - throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() ); - } - - link(); -} - -int main(int argc, char**argv) -{ - sal_uInt32 starttime = osl_getGlobalTimer(); - std::vector<std::string> args; - for (int i = 1; i < argc; ++i) - args.push_back(std::string(argv[i])); - try - { - HelpLinker* pHelpLinker = new HelpLinker(); - pHelpLinker->main( args ); - delete pHelpLinker; - } - catch( const HelpProcessingException& e ) - { - std::cerr << e.m_aErrorMsg; - exit(1); - } - sal_uInt32 endtime = osl_getGlobalTimer(); - std::cout << "time taken was " << (endtime-starttime)/1000.0 << " seconds" << std::endl; - return 0; -} - -// Variable to set an exception in "C" StructuredXMLErrorFunction -static const HelpProcessingException* GpXMLParsingException = NULL; - -extern "C" void StructuredXMLErrorFunction(void *userData, xmlErrorPtr error) -{ - (void)userData; - (void)error; - - std::string aErrorMsg = error->message; - std::string aXMLParsingFile; - if( error->file != NULL ) - aXMLParsingFile = error->file; - int nXMLParsingLine = error->line; - HelpProcessingException* pException = new HelpProcessingException( aErrorMsg, aXMLParsingFile, nXMLParsingLine ); - GpXMLParsingException = pException; - - // Reset error handler - xmlSetStructuredErrorFunc( NULL, NULL ); -} - -HelpProcessingErrorInfo& HelpProcessingErrorInfo::operator=( const struct HelpProcessingException& e ) -{ - m_eErrorClass = e.m_eErrorClass; - rtl::OString tmpErrorMsg( e.m_aErrorMsg.c_str() ); - m_aErrorMsg = rtl::OStringToOUString( tmpErrorMsg, fs::getThreadTextEncoding() ); - rtl::OString tmpXMLParsingFile( e.m_aXMLParsingFile.c_str() ); - m_aXMLParsingFile = rtl::OStringToOUString( tmpXMLParsingFile, fs::getThreadTextEncoding() ); - m_nXMLParsingLine = e.m_nXMLParsingLine; - return *this; -} - - -// Returns true in case of success, false in case of error -HELPLINKER_DLLPUBLIC bool compileExtensionHelp -( - const rtl::OUString& aExtensionName, - const rtl::OUString& aExtensionLanguageRoot, - sal_Int32 nXhpFileCount, const rtl::OUString* pXhpFiles, - HelpProcessingErrorInfo& o_rHelpProcessingErrorInfo -) -{ - bool bSuccess = true; - - sal_Int32 argc = nXhpFileCount + 3; - const char** argv = new const char*[argc]; - argv[0] = ""; - argv[1] = "-mod"; - rtl::OString aOExtensionName = rtl::OUStringToOString( aExtensionName, fs::getThreadTextEncoding() ); - argv[2] = aOExtensionName.getStr(); - - for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp ) - { - rtl::OUString aXhpFile = pXhpFiles[iXhp]; - - rtl::OString aOXhpFile = rtl::OUStringToOString( aXhpFile, fs::getThreadTextEncoding() ); - char* pArgStr = new char[aOXhpFile.getLength() + 1]; - strcpy( pArgStr, aOXhpFile.getStr() ); - argv[iXhp + 3] = pArgStr; - } - - std::vector<std::string> args; - for( sal_Int32 i = 1; i < argc; ++i ) - args.push_back(std::string( argv[i]) ); - - for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp ) - delete argv[iXhp + 3]; - delete[] argv; - - rtl::OString aOExtensionLanguageRoot = rtl::OUStringToOString( aExtensionLanguageRoot, fs::getThreadTextEncoding() ); - const char* pExtensionPath = aOExtensionLanguageRoot.getStr(); - std::string aStdStrExtensionPath = pExtensionPath; - - // Set error handler - xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction ); - try - { - HelpLinker* pHelpLinker = new HelpLinker(); - pHelpLinker->main( args,&aStdStrExtensionPath ); - delete pHelpLinker; - } - catch( const HelpProcessingException& e ) - { - if( GpXMLParsingException != NULL ) - { - o_rHelpProcessingErrorInfo = *GpXMLParsingException; - delete GpXMLParsingException; - GpXMLParsingException = NULL; - } - else - { - o_rHelpProcessingErrorInfo = e; - } - bSuccess = false; - } - // Reset error handler - xmlSetStructuredErrorFunc( NULL, NULL ); - - // i83624: Tree files - ::rtl::OUString aTreeFileURL = aExtensionLanguageRoot; - aTreeFileURL += rtl::OUString::createFromAscii( "/help.tree" ); - osl::DirectoryItem aTreeFileItem; - osl::FileBase::RC rcGet = osl::DirectoryItem::get( aTreeFileURL, aTreeFileItem ); - osl::FileStatus aFileStatus( FileStatusMask_FileSize ); - if( rcGet == osl::FileBase::E_None && - aTreeFileItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None && - aFileStatus.isValid( FileStatusMask_FileSize ) ) - { - sal_uInt64 ret, len = aFileStatus.getFileSize(); - char* s = new char[ int(len) ]; // the buffer to hold the installed files - osl::File aFile( aTreeFileURL ); - aFile.open( OpenFlag_Read ); - aFile.read( s, len, ret ); - aFile.close(); - - XML_Parser parser = XML_ParserCreate( 0 ); - int parsed = XML_Parse( parser, s, int( len ), true ); - - if( parsed == 0 ) - { - XML_Error nError = XML_GetErrorCode( parser ); - o_rHelpProcessingErrorInfo.m_eErrorClass = HELPPROCESSING_XMLPARSING_ERROR; - o_rHelpProcessingErrorInfo.m_aErrorMsg = rtl::OUString::createFromAscii( XML_ErrorString( nError ) );; - o_rHelpProcessingErrorInfo.m_aXMLParsingFile = aTreeFileURL; - // CRAHSES!!! o_rHelpProcessingErrorInfo.m_nXMLParsingLine = XML_GetCurrentLineNumber( parser ); - bSuccess = false; - } - - XML_ParserFree( parser ); - delete[] s; - } - - return bSuccess; -} - -// vnd.sun.star.help://swriter/52821?Language=en-US&System=UNIX -/* vi:set tabstop=4 shiftwidth=4 expandtab: */ - diff --git a/xmlhelp/source/com/sun/star/help/makefile.mk b/xmlhelp/source/com/sun/star/help/makefile.mk index c30b36bea8a5..1e1a2c518fa0 100644 --- a/xmlhelp/source/com/sun/star/help/makefile.mk +++ b/xmlhelp/source/com/sun/star/help/makefile.mk @@ -56,62 +56,36 @@ CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES) CFLAGS+=-DSYSTEM_EXPAT .ENDIF -OBJFILES=\ - $(OBJ)$/HelpLinker.obj \ - $(OBJ)$/HelpCompiler.obj -SLOFILES=\ - $(SLO)$/HelpLinker.obj \ - $(SLO)$/HelpCompiler.obj - -EXCEPTIONSFILES=\ - $(OBJ)$/HelpLinker.obj \ - $(OBJ)$/HelpCompiler.obj \ - $(SLO)$/HelpLinker.obj \ - $(SLO)$/HelpCompiler.obj -.IF "$(OS)" == "MACOSX" && "$(CPU)" == "P" && "$(COM)" == "GCC" -# There appears to be a GCC 4.0.1 optimization error causing _file:good() to -# report true right before the call to writeOut at HelpLinker.cxx:1.12 l. 954 -# but out.good() to report false right at the start of writeOut at -# HelpLinker.cxx:1.12 l. 537: -NOOPTFILES=\ - $(OBJ)$/HelpLinker.obj \ - $(SLO)$/HelpLinker.obj -.ENDIF -APP1TARGET= $(TARGET) -APP1OBJS=\ - $(OBJ)$/HelpLinker.obj \ - $(OBJ)$/HelpCompiler.obj -APP1RPATH=NONE +JAVACLASSFILES = \ + $(SOLARBINDIR)$/help$/$(PACKAGE)$/HelpIndexerTool.class \ + $(SOLARBINDIR)$/help$/$(PACKAGE)$/HelpFileDocument.class \ + $(CLASSDIR)$/$(PACKAGE)$/HelpSearch.class \ + $(CLASSDIR)$/$(PACKAGE)$/HelpComponent.class \ + $(CLASSDIR)$/$(PACKAGE)$/HelpIndexer.class -APP1STDLIBS+=$(SALLIB) $(BERKELEYLIB) $(XSLTLIB) $(EXPATASCII3RDLIB) +JAVAFILES = \ + HelpSearch.java \ + HelpComponent.java \ + HelpIndexer.java -SHL1TARGET =$(LIBBASENAME)$(DLLPOSTFIX) -SHL1LIBS= $(SLB)$/$(TARGET).lib -SHL1IMPLIB =i$(LIBBASENAME) -SHL1DEF =$(MISC)$/$(SHL1TARGET).def -SHL1STDLIBS =$(SALLIB) $(BERKELEYLIB) $(XSLTLIB) $(EXPATASCII3RDLIB) -SHL1USE_EXPORTS =ordinal +TRANSEX3FILES = \ + $(SOLARBINDIR)$/help$/$(PACKAGE)$/HelpIndexerTool.class \ + $(SOLARBINDIR)$/help$/$(PACKAGE)$/HelpFileDocument.class -DEF1NAME =$(SHL1TARGET) -DEFLIB1NAME =$(TARGET) +ADDFILES = $(subst,$(SOLARBINDIR)$/help,$(CLASSDIR) $(TRANSEX3FILES)) -JAVACLASSFILES = \ - $(CLASSDIR)$/$(PACKAGE)$/HelpSearch.class \ - $(CLASSDIR)$/$(PACKAGE)$/HelpIndexer.class \ - $(CLASSDIR)$/$(PACKAGE)$/HelpComponent.class \ - $(CLASSDIR)$/$(PACKAGE)$/HelpFileDocument.class +#JAVAFILES = $(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES))) -JARFILES = ridl.jar jurt.jar unoil.jar juh.jar +JARFILES = ridl.jar jurt.jar unoil.jar juh.jar HelpIndexerTool.jar .IF "$(SYSTEM_LUCENE)" == "YES" XCLASSPATH!:=$(XCLASSPATH)$(PATH_SEPERATOR)$(LUCENE_CORE_JAR)$(PATH_SEPERATOR)$(LUCENE_ANALYZERS_JAR) COMP=fix_system_lucene .ELSE JARFILES += lucene-core-2.3.jar lucene-analyzers-2.3.jar .ENDIF -JAVAFILES = $(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES))) -JARTARGET = LuceneHelpWrapper.jar +JARTARGET = LuceneHelpWrapper.jar JARCOMPRESS = TRUE CUSTOMMANIFESTFILE = MANIFEST.MF @@ -119,10 +93,18 @@ CUSTOMMANIFESTFILE = MANIFEST.MF .INCLUDE : target.mk +ALLTAR : $(ADDFILES) + .IF "$(JARTARGETN)"!="" +$(JARTARGETN) : $(ADDFILES) $(JARTARGETN) : $(COMP) .ENDIF +$(CLASSDIR)$/$(PACKAGE)$/%.class : $(SOLARBINDIR)$/help$/$(PACKAGE)$/%.class + $(MKDIRHIER) $(@:d) + $(COPY) $< $@ + + fix_system_lucene: @echo "Fix Java Class-Path entry for Lucene libraries from system." @$(SED) -r -e "s#^(Class-Path:).*#\1 file://$(LUCENE_CORE_JAR) file://$(LUCENE_ANALYZERS_JAR)#" \ diff --git a/xmlhelp/source/cxxhelp/provider/databases.cxx b/xmlhelp/source/cxxhelp/provider/databases.cxx index 618596a11c0b..6245fb430b8e 100644 --- a/xmlhelp/source/cxxhelp/provider/databases.cxx +++ b/xmlhelp/source/cxxhelp/provider/databases.cxx @@ -1,266 +1,268 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: databases.cxx,v $ - * $Revision: 1.54 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_xmlhelp.hxx" -#include "db.hxx" -#ifndef _VOS_DIAGNOSE_HXX_ -#include <vos/diagnose.hxx> -#endif -#include <osl/thread.h> -#include <rtl/uri.hxx> -#include <osl/file.hxx> -#include <rtl/memory.h> -#include <com/sun/star/lang/Locale.hpp> -#include <rtl/ustrbuf.hxx> -#include "inputstream.hxx" -#include <algorithm> -#include <string.h> - -// Extensible help -#include "com/sun/star/deployment/thePackageManagerFactory.hpp" -#include <comphelper/processfactory.hxx> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/ucb/XCommandEnvironment.hpp> -#include <com/sun/star/beans/Optional.hpp> -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/frame/XConfigManager.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 <comphelper/locale.hxx> - -#include <xmlhelp/compilehelp.hxx> - -#include "databases.hxx" -#include "urlparameter.hxx" - -using namespace chelp; -using namespace berkeleydbproxy; -using namespace com::sun::star; -using namespace com::sun::star::uno; -using namespace com::sun::star::io; -using namespace com::sun::star::container; -using namespace com::sun::star::i18n; -using namespace com::sun::star::lang; -using namespace com::sun::star::deployment; -using namespace com::sun::star::beans; - - -static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); -static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) ); -static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) ); - -rtl::OUString Databases::expandURL( const rtl::OUString& aURL ) -{ - osl::MutexGuard aGuard( m_aMutex ); - rtl::OUString aRetURL = expandURL( aURL, m_xContext ); - return aRetURL; -} - -rtl::OUString Databases::expandURL( const rtl::OUString& aURL, Reference< uno::XComponentContext > xContext ) -{ - static Reference< util::XMacroExpander > xMacroExpander; - static Reference< uri::XUriReferenceFactory > xFac; - - if( !xContext.is() ) - return rtl::OUString(); - - if( !xMacroExpander.is() || !xFac.is() ) - { - Reference< XMultiComponentFactory > xSMgr( xContext->getServiceManager(), UNO_QUERY ); - - xFac = Reference< uri::XUriReferenceFactory >( - xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( - "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY ); - if( !xFac.is() ) - { - throw RuntimeException( - ::rtl::OUString::createFromAscii( "Databases::expand(), 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; -} - -Databases::Databases( sal_Bool showBasic, - const rtl::OUString& instPath, - const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths, - const rtl::OUString& productName, - const rtl::OUString& productVersion, - const rtl::OUString& vendorName, - const rtl::OUString& vendorVersion, - const rtl::OUString& vendorShort, - const rtl::OUString& styleSheet, - Reference< uno::XComponentContext > xContext ) - : m_xContext( xContext ), - m_bShowBasic(showBasic), - m_nErrorDocLength( 0 ), - m_pErrorDoc( 0 ), - m_nCustomCSSDocLength( 0 ), - m_pCustomCSSDoc( 0 ), - m_aCSS(styleSheet.toAsciiLowerCase()), - newProdName(rtl::OUString::createFromAscii( "$[officename]" ) ), - newProdVersion(rtl::OUString::createFromAscii( "$[officeversion]" ) ), - prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ), - prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ), - vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ), - vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ), - vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) ), - m_aImagesZipPaths( imagesZipPaths ), - m_nSymbolsStyle( 0 ) -{ - m_xSMgr = Reference< XMultiComponentFactory >( m_xContext->getServiceManager(), UNO_QUERY ); - - m_vAdd[0] = 12; - m_vAdd[1] = 15; - m_vAdd[2] = 11; - m_vAdd[3] = 14; - m_vAdd[4] = 12; - m_vAdd[5] = 13; - m_vAdd[6] = 16; - - m_vReplacement[0] = productName; - m_vReplacement[1] = productVersion; - m_vReplacement[2] = vendorName; - m_vReplacement[3] = vendorVersion; - m_vReplacement[4] = vendorShort; - m_vReplacement[5] = productName; - m_vReplacement[6] = productVersion; - - setInstallPath( instPath ); - - m_xSFA = Reference< ucb::XSimpleFileAccess >( - m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), - m_xContext ), UNO_QUERY_THROW ); -} - -Databases::~Databases() -{ - // release stylesheet - - delete[] m_pCustomCSSDoc; - - // release errorDocument - - delete[] m_pErrorDoc; - - // unload the databases - - { - // DatabasesTable - DatabasesTable::iterator it = m_aDatabases.begin(); - while( it != m_aDatabases.end() ) - { - if( it->second ) - it->second->close( 0 ); - delete it->second; - ++it; - } - } - - { - // ModInfoTable - - ModInfoTable::iterator it = m_aModInfo.begin(); - while( it != m_aModInfo.end() ) - { - delete it->second; - ++it; - } - } - - { - // KeywordInfoTable - - KeywordInfoTable::iterator it = m_aKeywordInfo.begin(); - while( it != m_aKeywordInfo.end() ) - { - delete it->second; - ++it; - } - } - -} - -static bool impl_getZipFile( - Sequence< rtl::OUString > & rImagesZipPaths, - const rtl::OUString & rZipName, - rtl::OUString & rFileName ) -{ - const rtl::OUString *pPathArray = rImagesZipPaths.getArray(); - for ( int i = 0; i < rImagesZipPaths.getLength(); ++i ) - { - rFileName = pPathArray[ i ]; - if ( rFileName.getLength() ) - { - if ( 1 + rFileName.lastIndexOf( '/' ) != rFileName.getLength() ) - { - rFileName += rtl::OUString::createFromAscii( "/" ); - } - rFileName += rZipName; - - // test existence - osl::DirectoryItem aDirItem; - if ( osl::DirectoryItem::get( rFileName, aDirItem ) == osl::FileBase::E_None ) - return true; - } - } - return false; -} - +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: databases.cxx,v $
+ * $Revision: 1.54 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_xmlhelp.hxx"
+#include "db.hxx"
+#ifndef _VOS_DIAGNOSE_HXX_
+#include <vos/diagnose.hxx>
+#endif
+#include <osl/thread.h>
+#include <rtl/uri.hxx>
+#include <osl/file.hxx>
+#include <rtl/memory.h>
+#include <com/sun/star/lang/Locale.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "inputstream.hxx"
+#include <algorithm>
+#include <string.h>
+
+// Extensible help
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/frame/XConfigManager.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 <comphelper/locale.hxx>
+
+#include <transex3/compilehelp.hxx>
+#include <comphelper/storagehelper.hxx>
+
+#include "databases.hxx"
+#include "urlparameter.hxx"
+
+using namespace chelp;
+using namespace berkeleydbproxy;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace com::sun::star::container;
+using namespace com::sun::star::i18n;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::deployment;
+using namespace com::sun::star::beans;
+
+
+static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
+static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) );
+static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) );
+
+rtl::OUString Databases::expandURL( const rtl::OUString& aURL )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ rtl::OUString aRetURL = expandURL( aURL, m_xContext );
+ return aRetURL;
+}
+
+rtl::OUString Databases::expandURL( const rtl::OUString& aURL, Reference< uno::XComponentContext > xContext )
+{
+ static Reference< util::XMacroExpander > xMacroExpander;
+ static Reference< uri::XUriReferenceFactory > xFac;
+
+ if( !xContext.is() )
+ return rtl::OUString();
+
+ if( !xMacroExpander.is() || !xFac.is() )
+ {
+ Reference< XMultiComponentFactory > xSMgr( xContext->getServiceManager(), UNO_QUERY );
+
+ xFac = Reference< uri::XUriReferenceFactory >(
+ xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY );
+ if( !xFac.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii( "Databases::expand(), 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;
+}
+
+Databases::Databases( sal_Bool showBasic,
+ const rtl::OUString& instPath,
+ const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths,
+ const rtl::OUString& productName,
+ const rtl::OUString& productVersion,
+ const rtl::OUString& vendorName,
+ const rtl::OUString& vendorVersion,
+ const rtl::OUString& vendorShort,
+ const rtl::OUString& styleSheet,
+ Reference< uno::XComponentContext > xContext )
+ : m_xContext( xContext ),
+ m_bShowBasic(showBasic),
+ m_nErrorDocLength( 0 ),
+ m_pErrorDoc( 0 ),
+ m_nCustomCSSDocLength( 0 ),
+ m_pCustomCSSDoc( 0 ),
+ m_aCSS(styleSheet.toAsciiLowerCase()),
+ newProdName(rtl::OUString::createFromAscii( "$[officename]" ) ),
+ newProdVersion(rtl::OUString::createFromAscii( "$[officeversion]" ) ),
+ prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ),
+ prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ),
+ vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ),
+ vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ),
+ vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) ),
+ m_aImagesZipPaths( imagesZipPaths ),
+ m_nSymbolsStyle( 0 )
+{
+ m_xSMgr = Reference< XMultiComponentFactory >( m_xContext->getServiceManager(), UNO_QUERY );
+
+ m_vAdd[0] = 12;
+ m_vAdd[1] = 15;
+ m_vAdd[2] = 11;
+ m_vAdd[3] = 14;
+ m_vAdd[4] = 12;
+ m_vAdd[5] = 13;
+ m_vAdd[6] = 16;
+
+ m_vReplacement[0] = productName;
+ m_vReplacement[1] = productVersion;
+ m_vReplacement[2] = vendorName;
+ m_vReplacement[3] = vendorVersion;
+ m_vReplacement[4] = vendorShort;
+ m_vReplacement[5] = productName;
+ m_vReplacement[6] = productVersion;
+
+ setInstallPath( instPath );
+
+ m_xSFA = Reference< ucb::XSimpleFileAccess >(
+ m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
+ m_xContext ), UNO_QUERY_THROW );
+}
+
+Databases::~Databases()
+{
+ // release stylesheet
+
+ delete[] m_pCustomCSSDoc;
+
+ // release errorDocument
+
+ delete[] m_pErrorDoc;
+
+ // unload the databases
+
+ {
+ // DatabasesTable
+ DatabasesTable::iterator it = m_aDatabases.begin();
+ while( it != m_aDatabases.end() )
+ {
+ if( it->second )
+ it->second->close( 0 );
+ delete it->second;
+ ++it;
+ }
+ }
+
+ {
+ // ModInfoTable
+
+ ModInfoTable::iterator it = m_aModInfo.begin();
+ while( it != m_aModInfo.end() )
+ {
+ delete it->second;
+ ++it;
+ }
+ }
+
+ {
+ // KeywordInfoTable
+
+ KeywordInfoTable::iterator it = m_aKeywordInfo.begin();
+ while( it != m_aKeywordInfo.end() )
+ {
+ delete it->second;
+ ++it;
+ }
+ }
+
+}
+
+static bool impl_getZipFile(
+ Sequence< rtl::OUString > & rImagesZipPaths,
+ const rtl::OUString & rZipName,
+ rtl::OUString & rFileName )
+{
+ const rtl::OUString *pPathArray = rImagesZipPaths.getArray();
+ for ( int i = 0; i < rImagesZipPaths.getLength(); ++i )
+ {
+ rFileName = pPathArray[ i ];
+ if ( rFileName.getLength() )
+ {
+ if ( 1 + rFileName.lastIndexOf( '/' ) != rFileName.getLength() )
+ {
+ rFileName += rtl::OUString::createFromAscii( "/" );
+ }
+ rFileName += rZipName;
+
+ // test existence
+ osl::DirectoryItem aDirItem;
+ if ( osl::DirectoryItem::get( rFileName, aDirItem ) == osl::FileBase::E_None )
+ return true;
+ }
+ }
+ return false;
+}
+
rtl::OString Databases::getImagesZipFileURL()
{
//sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle();
@@ -327,1788 +329,1800 @@ rtl::OString Databases::getImagesZipFileURL() return m_aImagesZipFileURL;
}
- -void Databases::replaceName( rtl::OUString& oustring ) const -{ - sal_Int32 idx = -1,idx1 = -1,idx2 = -1,k = 0,off; - bool cap = false; - rtl::OUStringBuffer aStrBuf( 0 ); - - while( true ) - { - ++idx; - idx1 = oustring.indexOf( sal_Unicode('%'),idx); - idx2 = oustring.indexOf( sal_Unicode('$'),idx); - - if(idx1 == -1 && idx2 == -1) - break; - - if(idx1 == -1) - idx = idx2; - else if(idx2 == -1) - idx = idx1; - else { - // no index is zero - if(idx1 < idx2) - idx = idx1; - else if(idx2 < idx1 ) - idx = idx2; - } - - if( oustring.indexOf( prodName,idx ) == idx ) - off = PRODUCTNAME; - else if( oustring.indexOf( prodVersion,idx ) == idx ) - off = PRODUCTVERSION; - else if( oustring.indexOf( vendName,idx ) == idx ) - off = VENDORNAME; - else if( oustring.indexOf( vendVersion,idx ) == idx ) - off = VENDORVERSION; - else if( oustring.indexOf( vendShort,idx ) == idx ) - off = VENDORSHORT; - else if( oustring.indexOf( newProdName,idx ) == idx ) - off = NEWPRODUCTNAME; - else if( oustring.indexOf( newProdVersion,idx ) == idx ) - off = NEWPRODUCTVERSION; - else - off = -1; - - if( off != -1 ) - { - if( ! cap ) - { - cap = true; - aStrBuf.ensureCapacity( 256 ); - } - - aStrBuf.append( &oustring.getStr()[k],idx - k ); - aStrBuf.append( m_vReplacement[off] ); - k = idx + m_vAdd[off]; - } - } - - if( cap ) - { - if( k < oustring.getLength() ) - aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k ); - oustring = aStrBuf.makeStringAndClear(); - } -} - - - - -rtl::OUString Databases::getInstallPathAsSystemPath() -{ - osl::MutexGuard aGuard( m_aMutex ); - - if( ! m_aInstallDirectoryAsSystemPath.getLength() ) - { -#ifdef DBG_UTIL - bool bla = - osl::FileBase::E_None == - osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath ); - VOS_ENSURE( bla,"HelpProvider, no installpath" ); -#else - osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath ); -#endif - } - - return m_aInstallDirectoryAsSystemPath; -} - - - - -rtl::OUString Databases::getInstallPathAsURL() -{ - osl::MutexGuard aGuard( m_aMutex ); - - return m_aInstallDirectory; -} - - -const std::vector< rtl::OUString >& Databases::getModuleList( const rtl::OUString& Language ) -{ - if( m_avModules.size() == 0 ) - { - rtl::OUString fileName,dirName = getInstallPathAsURL() + processLang( Language ); - osl::Directory dirFile( dirName ); - - osl::DirectoryItem aDirItem; - osl::FileStatus aStatus( FileStatusMask_FileName ); - - sal_Int32 idx; - - if( osl::FileBase::E_None != dirFile.open() ) - return m_avModules; - - while( dirFile.getNextItem( aDirItem ) == osl::FileBase::E_None && - aDirItem.getFileStatus( aStatus ) == osl::FileBase::E_None ) - { - if( ! aStatus.isValid( FileStatusMask_FileName ) ) - continue; - - fileName = aStatus.getFileName(); - - // Check, whether fileName is of the form *.cfg - idx = fileName.lastIndexOf( sal_Unicode( '.' ) ); - - if( idx == -1 ) - continue; - - const sal_Unicode* str = fileName.getStr(); - - if( fileName.getLength() == idx + 4 && - ( str[idx + 1] == 'c' || str[idx + 1] == 'C' ) && - ( str[idx + 2] == 'f' || str[idx + 2] == 'F' ) && - ( str[idx + 3] == 'g' || str[idx + 3] == 'G' ) && - ( fileName = fileName.copy(0,idx).toAsciiLowerCase() ).compareToAscii( "picture" ) != 0 ) { - if(! m_bShowBasic && fileName.compareToAscii("sbasic") == 0 ) - continue; - m_avModules.push_back( fileName ); - } - } - } - return m_avModules; -} - - - -StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OUString& Module, - const rtl::OUString& Language ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Module; - - std::pair< ModInfoTable::iterator,bool > aPair = - m_aModInfo.insert( ModInfoTable::value_type( key,0 ) ); - - ModInfoTable::iterator it = aPair.first; - - if( aPair.second && ! it->second ) - { - osl::File cfgFile( getInstallPathAsURL() + - key + - rtl::OUString::createFromAscii( ".cfg" ) ); - - if( osl::FileBase::E_None != cfgFile.open( OpenFlag_Read ) ) - it->second = 0; - else - { - sal_uInt32 pos = 0; - sal_uInt64 nRead; - sal_Char buffer[2048]; - sal_Unicode lineBuffer[1028]; - rtl::OUString fileContent; - - while( osl::FileBase::E_None == cfgFile.read( &buffer,2048,nRead ) && nRead ) - fileContent += rtl::OUString( buffer,sal_Int32( nRead ),RTL_TEXTENCODING_UTF8 ); - - cfgFile.close(); - - const sal_Unicode* str = fileContent.getStr(); - rtl::OUString current,lang_,program,startid,title,heading,fulltext; - rtl::OUString order = rtl::OUString::createFromAscii( "1" ); - - for( sal_Int32 i = 0;i < fileContent.getLength();i++ ) - { - sal_Unicode ch = str[ i ]; - if( ch == sal_Unicode( '\n' ) || ch == sal_Unicode( '\r' ) ) - { - if( pos ) - { - current = rtl::OUString( lineBuffer,pos ); - - if( current.compareToAscii( "Title",5 ) == 0 ) - { - title = current.copy( current.indexOf(sal_Unicode( '=' ) ) + 1 ); - } - else if( current.compareToAscii( "Start",5 ) == 0 ) - { - startid = current.copy( current.indexOf('=') + 1 ); - } - else if( current.compareToAscii( "Language",8 ) == 0 ) - { - lang_ = current.copy( current.indexOf('=') + 1 ); - } - else if( current.compareToAscii( "Program",7 ) == 0 ) - { - program = current.copy( current.indexOf('=') + 1 ); - } - else if( current.compareToAscii( "Heading",7 ) == 0 ) - { - heading = current.copy( current.indexOf('=') + 1 ); - } - else if( current.compareToAscii( "FullText",8 ) == 0 ) - { - fulltext = current.copy( current.indexOf('=') + 1 ); - } - else if( current.compareToAscii( "Order",5 ) == 0 ) - { - order = current.copy( current.indexOf('=') + 1 ); - } - } - pos = 0; - } - else - lineBuffer[ pos++ ] = ch; - } - replaceName( title ); - it->second = new StaticModuleInformation( title, - startid, - program, - heading, - fulltext, - order ); - } - } - - return it->second; -} - - - - -rtl::OUString Databases::processLang( const rtl::OUString& Language ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - rtl::OUString ret; - LangSetTable::iterator it = m_aLangSet.find( Language ); - - if( it == m_aLangSet.end() ) - { - sal_Int32 idx; - osl::DirectoryItem aDirItem; - - if( osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language,aDirItem ) ) - { - ret = Language; - m_aLangSet[ Language ] = ret; - } - else if( ( ( idx = Language.indexOf( '-' ) ) != -1 || - ( idx = Language.indexOf( '_' ) ) != -1 ) && - osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language.copy( 0,idx ), - aDirItem ) ) - { - ret = Language.copy( 0,idx ); - m_aLangSet[ Language ] = ret; - } - } - else - ret = it->second; - - return ret; -} - - -rtl::OUString Databases::country( const rtl::OUString& Language ) -{ - sal_Int32 idx; - if( ( idx = Language.indexOf( '-' ) ) != -1 || - ( idx = Language.indexOf( '_' ) ) != -1 ) - return Language.copy( 1+idx ); - - return rtl::OUString(); -} - - - -Db* Databases::getBerkeley( const rtl::OUString& Database, - const rtl::OUString& Language, bool helpText, - const rtl::OUString* pExtensionPath ) -{ - if( ! Database.getLength() || ! Language.getLength() ) - return 0; - - osl::MutexGuard aGuard( m_aMutex ); - - - rtl::OUString aFileExt( rtl::OUString::createFromAscii( helpText ? ".ht" : ".db" ) ); - rtl::OUString dbFileName = aSlash + Database + aFileExt; - rtl::OUString key; - if( pExtensionPath == NULL ) - key = processLang( Language ) + dbFileName; - else - key = *pExtensionPath + Language + dbFileName; // make unique, don't change language - - std::pair< DatabasesTable::iterator,bool > aPair = - m_aDatabases.insert( DatabasesTable::value_type( key,0 ) ); - - DatabasesTable::iterator it = aPair.first; - - if( aPair.second && ! it->second ) - { - Db* table = new Db(); - - rtl::OUString fileNameOU; - if( pExtensionPath ) - { - rtl::OUString aExpandedURL = expandURL( *pExtensionPath ); - aExpandedURL += Language + dbFileName; - osl::FileBase::getSystemPathFromFileURL( aExpandedURL, fileNameOU ); - } - else - fileNameOU = getInstallPathAsSystemPath() + key; - - - rtl::OString fileName( fileNameOU.getStr(),fileNameOU.getLength(),osl_getThreadTextEncoding() ); - - rtl::OUString fileNameDBHelp( fileNameOU ); - if( pExtensionPath != NULL ) - fileNameDBHelp += rtl::OUString::createFromAscii( "_" ); - if( m_xSFA->exists( fileNameDBHelp ) ) - { - DBHelp* pDBHelp = new DBHelp( fileNameDBHelp, m_xSFA ); - table->setDBHelp( pDBHelp ); - -#ifdef TEST_DBHELP - bool bSuccess; - bool bOldDbAccess = false; - bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess ); - - bOldDbAccess = true; - bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess ); -#endif - } - else if( table->open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) - { - table->close( 0 ); - delete table; - table = 0; - } - - it->second = table; - } - - return it->second; -} - -Reference< XCollator > -Databases::getCollator( const rtl::OUString& Language, - const rtl::OUString& System ) -{ - (void)System; - - rtl::OUString key = Language; - - osl::MutexGuard aGuard( m_aMutex ); - - CollatorTable::iterator it = - m_aCollatorTable.insert( CollatorTable::value_type( key,0 ) ).first; - - if( ! it->second.is() ) - { - it->second = - Reference< XCollator > ( - m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ), - m_xContext ), UNO_QUERY ); - rtl::OUString langStr = processLang(Language); - rtl::OUString countryStr = country(Language); - if( !countryStr.getLength() ) - { - if( langStr.compareToAscii("de") == 0 ) - countryStr = rtl::OUString::createFromAscii("DE"); - else if( langStr.compareToAscii("en") == 0 ) - countryStr = rtl::OUString::createFromAscii("US"); - else if( langStr.compareToAscii("es") == 0 ) - countryStr = rtl::OUString::createFromAscii("ES"); - else if( langStr.compareToAscii("it") == 0 ) - countryStr = rtl::OUString::createFromAscii("IT"); - else if( langStr.compareToAscii("fr") == 0 ) - countryStr = rtl::OUString::createFromAscii("FR"); - else if( langStr.compareToAscii("sv") == 0 ) - countryStr = rtl::OUString::createFromAscii("SE"); - else if( langStr.compareToAscii("ja") == 0 ) - countryStr = rtl::OUString::createFromAscii("JP"); - else if( langStr.compareToAscii("ko") == 0 ) - countryStr = rtl::OUString::createFromAscii("KR"); - } - it->second->loadDefaultCollator( Locale( langStr, - countryStr, - rtl::OUString() ), - 0 ); - } - - return it->second; -} - - - -namespace chelp { - - struct KeywordElementComparator - { - KeywordElementComparator( const Reference< XCollator >& xCollator ) - : m_xCollator( xCollator ) - { } - - bool operator()( const KeywordInfo::KeywordElement& la, - const KeywordInfo::KeywordElement& ra ) const - { - const rtl::OUString& l = la.key; - const rtl::OUString& r = ra.key; - - bool ret; - - if( m_xCollator.is() ) - { - sal_Int32 l1 = l.indexOf( sal_Unicode( ';' ) ); - sal_Int32 l3 = ( l1 == -1 ? l.getLength() : l1 ); - - sal_Int32 r1 = r.indexOf( sal_Unicode( ';' ) ); - sal_Int32 r3 = ( r1 == -1 ? r.getLength() : r1 ); - - sal_Int32 c1 = m_xCollator->compareSubstring( l,0,l3,r,0,r3 ); - - if( c1 == +1 ) - ret = false; - else if( c1 == 0 ) - { - sal_Int32 l2 = l.getLength() - l1 - 1; - sal_Int32 r2 = r.getLength() - r1 - 1; - ret = ( m_xCollator->compareSubstring( l,1+l1,l2,r,1+r1,r2 ) < 0 ); - } - else - ret = true; - } - else - ret = bool( l < r ); - - return ret; - } - - Reference< XCollator > m_xCollator; - }; // end struct KeywordElementComparator - -} - - - -KeywordInfo::KeywordElement::KeywordElement( Databases *pDatabases, - Db* pDb, - rtl::OUString& ky, - rtl::OUString& data ) - : key( ky ) -{ - pDatabases->replaceName( key ); - init( pDatabases,pDb,data ); -} - - - -void KeywordInfo::KeywordElement::init( Databases *pDatabases,Db* pDb,const rtl::OUString& ids ) -{ - const sal_Unicode* idstr = ids.getStr(); - std::vector< rtl::OUString > id,anchor; - int idx = -1,k; - while( ( idx = ids.indexOf( ';',k = ++idx ) ) != -1 ) - { - int h = ids.indexOf( sal_Unicode( '#' ),k ); - if( h < idx ) - { - // found an anchor - id.push_back( rtl::OUString( &idstr[k],h-k ) ); - anchor.push_back( rtl::OUString( &idstr[h+1],idx-h-1 ) ); - } - else - { - id.push_back( rtl::OUString( &idstr[k],idx-k ) ); - anchor.push_back( rtl::OUString() ); - } - } - - listId.realloc( id.size() ); - listAnchor.realloc( id.size() ); - listTitle.realloc( id.size() ); - - int nSize = 0; - const sal_Char* pData = NULL; - const sal_Char pEmpty[] = ""; - - for( sal_uInt32 i = 0; i < id.size(); ++i ) - { - listId[i] = id[i]; - listAnchor[i] = anchor[i]; - - nSize = 0; - pData = pEmpty; - if( pDb ) - { - rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 ); - DBHelp* pDBHelp = pDb->getDBHelp(); - if( pDBHelp != NULL ) - { - DBData aDBData; - bool bSuccess = pDBHelp->getValueForKey( idi, aDBData ); - if( bSuccess ) - { - nSize = aDBData.getSize(); - pData = aDBData.getData(); - } - } - else - { - Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ), - idi.getLength() ); - Dbt data; - pDb->get( 0,&key_,&data,0 ); - nSize = data.get_size(); - pData = static_cast<sal_Char*>( data.get_data() ); - } - } - - DbtToStringConverter converter( pData, nSize ); - - rtl::OUString title = converter.getTitle(); - pDatabases->replaceName( title ); - listTitle[i] = title; - } -} - - - -KeywordInfo::KeywordInfo( const std::vector< KeywordElement >& aVec ) - : listKey( aVec.size() ), - listId( aVec.size() ), - listAnchor( aVec.size() ), - listTitle( aVec.size() ) -{ - for( unsigned int i = 0; i < aVec.size(); ++i ) - { - listKey[i] = aVec[i].key; - listId[i] = aVec[i].listId; - listAnchor[i] = aVec[i].listAnchor; - listTitle[i] = aVec[i].listTitle; - } -} - -bool Databases::checkModuleMatchForExtension - ( const rtl::OUString& Database, const rtl::OUString& doclist ) -{ - bool bBelongsToDatabase = true; - - // Analyse doclist string to find module assignments - bool bFoundAtLeastOneModule = false; - bool bModuleMatch = false; - sal_Int32 nLen = doclist.getLength(); - sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') ); - if( nLastFound == -1 ) - nLastFound = nLen; - const sal_Unicode* pStr = doclist.getStr(); - sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') ); - while( nFound != -1 ) - { - // Simple optimization, stop if '_' is followed by "id" - if( nLen - nFound > 2 ) - { - if( pStr[ nFound + 1 ] == sal_Unicode('i') && - pStr[ nFound + 2 ] == sal_Unicode('d') ) - break; - } - - rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 ); - std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule ); - if( result != m_avModules.end() ) - { - bFoundAtLeastOneModule = true; - if( Database == aModule ) - { - bModuleMatch = true; - break; - } - } - - nLastFound = nFound; - if( nLastFound == 0 ) - break; - nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 ); - } - - if( bFoundAtLeastOneModule && !bModuleMatch ) - bBelongsToDatabase = false; - - return bBelongsToDatabase; -} - - -KeywordInfo* Databases::getKeyword( const rtl::OUString& Database, - const rtl::OUString& Language ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Database; - - std::pair< KeywordInfoTable::iterator,bool > aPair = - m_aKeywordInfo.insert( KeywordInfoTable::value_type( key,0 ) ); - - KeywordInfoTable::iterator it = aPair.first; - - if( aPair.second && ! it->second ) - { - std::vector<KeywordInfo::KeywordElement> aVector; - - KeyDataBaseFileIterator aDbFileIt( m_xContext, *this, Database, Language ); - rtl::OUString fileNameOU; - bool bExtension = false; - while( (fileNameOU = aDbFileIt.nextDbFile( bExtension )).getLength() > 0 ) - { - rtl::OString fileName( fileNameOU.getStr(), - fileNameOU.getLength(), - osl_getThreadTextEncoding() ); - - Db table; - - rtl::OUString fileNameDBHelp( fileNameOU ); - if( bExtension ) - fileNameDBHelp += rtl::OUString::createFromAscii( "_" ); - if( m_xSFA->exists( fileNameDBHelp ) ) - { - DBHelp aDBHelp( fileNameDBHelp, m_xSFA ); - - DBData aKey; - DBData aValue; - if( aDBHelp.startIteration() ) - { - Db* idmap = getBerkeley( Database,Language ); - - DBHelp* pDBHelp = idmap->getDBHelp(); - if( pDBHelp != NULL ) - { - bool bOptimizeForPerformance = true; - pDBHelp->releaseHashMap(); - pDBHelp->createHashMap( bOptimizeForPerformance ); - } - - while( aDBHelp.getNextKeyAndValue( aKey, aValue ) ) - { - rtl::OUString keyword( aKey.getData(), aKey.getSize(), - RTL_TEXTENCODING_UTF8 ); - rtl::OUString doclist( aValue.getData(), aValue.getSize(), - RTL_TEXTENCODING_UTF8 ); - - bool bBelongsToDatabase = true; - if( bExtension ) - bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist ); - - if( !bBelongsToDatabase ) - continue; - - aVector.push_back( KeywordInfo::KeywordElement( this, - idmap, - keyword, - doclist ) ); - } - aDBHelp.stopIteration(); - - if( pDBHelp != NULL ) - pDBHelp->releaseHashMap(); - } - -#ifdef TEST_DBHELP - bool bSuccess; - bool bOldDbAccess = false; - bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess ); - - bOldDbAccess = true; - bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess ); - - int nDummy = 0; -#endif - } - - else if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) - { - Db* idmap = getBerkeley( Database,Language ); - - bool first = true; - - Dbc* cursor = 0; - table.cursor( 0,&cursor,0 ); - Dbt key_,data; - key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory - data.set_flags( DB_DBT_MALLOC ); - while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) ) - { - rtl::OUString keyword( static_cast<sal_Char*>(key_.get_data()), - key_.get_size(), - RTL_TEXTENCODING_UTF8 ); - rtl::OUString doclist( static_cast<sal_Char*>(data.get_data()), - data.get_size(), - RTL_TEXTENCODING_UTF8 ); - - bool bBelongsToDatabase = true; - if( bExtension ) - bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist ); - - if( !bBelongsToDatabase ) - continue; - - aVector.push_back( KeywordInfo::KeywordElement( this, - idmap, - keyword, - doclist ) ); - if( first ) - { - key_.set_flags( DB_DBT_REALLOC ); - data.set_flags( DB_DBT_REALLOC ); - first = false; - } - } - - if( cursor ) cursor->close(); - } - table.close( 0 ); - } - - // sorting - Reference< XCollator > xCollator = getCollator( Language,rtl::OUString()); - KeywordElementComparator aComparator( xCollator ); - std::sort(aVector.begin(),aVector.end(),aComparator); - - KeywordInfo* pInfo = it->second = new KeywordInfo( aVector ); - (void)pInfo; - } - - return it->second; -} - -Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& jar, - const rtl::OUString& Language ) -{ - if( ! jar.getLength() || - ! Language.getLength() ) - { - return Reference< XHierarchicalNameAccess >( 0 ); - } - rtl::OUString key = processLang(Language) + aSlash + jar; - - osl::MutexGuard aGuard( m_aMutex ); - - ZipFileTable::iterator it = - m_aZipFileTable.insert( ZipFileTable::value_type( key,Reference< XHierarchicalNameAccess >(0) ) ).first; - - if( ! it->second.is() ) - { - rtl::OUString zipFile; - try - { - // Extension jar file? Search for ? - sal_Int32 nQuestionMark1 = jar.indexOf( sal_Unicode('?') ); - sal_Int32 nQuestionMark2 = jar.lastIndexOf( sal_Unicode('?') ); - if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 ) - { - ::rtl::OUString aExtensionPath = jar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 ); - ::rtl::OUString aPureJar = jar.copy( nQuestionMark2 + 1 ); - - rtl::OUStringBuffer aStrBuf; - aStrBuf.append( aExtensionPath ); - aStrBuf.append( aSlash ); - aStrBuf.append( aPureJar ); - - zipFile = expandURL( aStrBuf.makeStringAndClear() ); - } - else - { - zipFile = getInstallPathAsURL() + key; - } - - Sequence< Any > aArguments( 1 ); - - XInputStream_impl* p = new XInputStream_impl( zipFile ); - if( p->CtorSuccess() ) - { - Reference< XInputStream > xInputStream( p ); - aArguments[ 0 ] <<= xInputStream; - } - else - { - delete p; - aArguments[ 0 ] <<= zipFile; - } - - Reference< XInterface > xIfc - = m_xSMgr->createInstanceWithArgumentsAndContext( - rtl::OUString::createFromAscii( - "com.sun.star.packages.comp.ZipPackage" ), - aArguments, m_xContext ); - - if ( xIfc.is() ) - { - it->second = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY ); - - VOS_ENSURE( it->second.is(), - "ContentProvider::createPackage - " - "Got no hierarchical name access!" ); - - } - } - catch ( RuntimeException & ) - { - } - catch ( Exception & ) - { - } - } - - return it->second; -} - -Reference< XHierarchicalNameAccess > Databases::findJarFileForPath - ( const rtl::OUString& jar, const rtl::OUString& Language, - const rtl::OUString& path, rtl::OUString* o_pExtensionPath ) -{ - Reference< XHierarchicalNameAccess > xNA; - if( ! jar.getLength() || - ! Language.getLength() ) - { - return xNA; - } - - JarFileIterator aJarFileIt( m_xContext, *this, jar, Language ); - Reference< XHierarchicalNameAccess > xTestNA; - Reference< deployment::XPackage > xParentPackageBundle; - while( (xTestNA = aJarFileIt.nextJarFile( xParentPackageBundle, o_pExtensionPath )).is() ) - { - if( xTestNA.is() && xTestNA->hasByHierarchicalName( path ) ) - { - bool bSuccess = true; - if( xParentPackageBundle.is() ) - { - rtl::OUString aIdentifierInPath; - sal_Int32 nFindSlash = path.indexOf( '/' ); - if( nFindSlash != -1 ) - aIdentifierInPath = path.copy( 0, nFindSlash ); - - beans::Optional<rtl::OUString> aIdentifierOptional = xParentPackageBundle->getIdentifier(); - if( aIdentifierInPath.getLength() && aIdentifierOptional.IsPresent ) - { - rtl::OUString aUnencodedIdentifier = aIdentifierOptional.Value; - rtl::OUString aIdentifier = rtl::Uri::encode( aUnencodedIdentifier, - rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 ); - - if( !aIdentifierInPath.equals( aIdentifier ) ) - { - // path does not start with extension identifier -> ignore - bSuccess = false; - } - } - else - { - // No identifier -> ignore - bSuccess = false; - } - } - - if( bSuccess ) - { - xNA = xTestNA; - break; - } - } - } - - return xNA; -} - -void Databases::popupDocument( URLParameter* urlPar,char **buffer,int *byteCount ) -{ - const char* pop1 = - " <html> " - " <head> " - " <help:css-file-link xmlns:help=\"http://openoffice.org/2000/help\"/> " - " </head> " - " <body> " - " <help:popup-cut Id=\""; - const sal_Int32 l1 = strlen( pop1 ); - - const char* pop3 = "\" Eid=\""; - const sal_Int32 l3 = strlen( pop3 ); - - const char* pop5 = - "\" xmlns:help=\"http://openoffice.org/2000/help\"></help:popup-cut> " - " </body> " - " </html>"; - const sal_Int32 l5 = strlen( pop5 ); - sal_Int32 l2,l4; - - rtl::OUString val = urlPar->get_id(); - rtl::OString pop2O( val.getStr(),l2 = val.getLength(),RTL_TEXTENCODING_UTF8 ); - const char* pop2 = pop2O.getStr(); - - val = urlPar->get_eid(); - rtl::OString pop4O( val.getStr(),l4 = val.getLength(),RTL_TEXTENCODING_UTF8 ); - const char* pop4 = pop4O.getStr(); - - (*byteCount) = l1 + l2 + l3 + l4 + l5; - - *buffer = new char[ 1+*byteCount ]; - - rtl_copyMemory( *buffer,pop1,l1 ); - rtl_copyMemory( *buffer+l1,pop2,l2 ); - rtl_copyMemory( *buffer+(l1+l2),pop3,l3 ); - rtl_copyMemory( *buffer+(l1+l2+l3),pop4,l4 ); - rtl_copyMemory( *buffer+(l1+l2+l3+l4),pop5,l5 ); - (*buffer)[*byteCount] = 0; -} - - -void Databases::changeCSS(const rtl::OUString& newStyleSheet) -{ - m_aCSS = newStyleSheet.toAsciiLowerCase(); - delete[] m_pCustomCSSDoc, m_pCustomCSSDoc = 0,m_nCustomCSSDocLength = 0; -} - - - -void Databases::cascadingStylesheet( const rtl::OUString& Language, - char** buffer, - int* byteCount ) -{ - if( ! m_pCustomCSSDoc ) - { - int retry = 2; - bool error = true; - rtl::OUString fileURL; - - while( error && retry ) - { - if( retry == 2 ) - fileURL = - getInstallPathAsURL() + - processLang( Language ) + - rtl::OUString::createFromAscii( "/" ) + - m_aCSS + - rtl::OUString::createFromAscii( ".css" ); - else if( retry == 1 ) - fileURL = - getInstallPathAsURL() + - m_aCSS + - rtl::OUString::createFromAscii( ".css" ); - - osl::DirectoryItem aDirItem; - osl::File aFile( fileURL ); - osl::FileStatus aStatus( FileStatusMask_FileSize ); - - if( osl::FileBase::E_None == osl::DirectoryItem::get( fileURL,aDirItem ) && - osl::FileBase::E_None == aFile.open( OpenFlag_Read ) && - osl::FileBase::E_None == aDirItem.getFileStatus( aStatus ) ) - { - m_nCustomCSSDocLength = int( aStatus.getFileSize() ); - m_pCustomCSSDoc = new char[ 1 + m_nCustomCSSDocLength ]; - m_pCustomCSSDoc[ m_nCustomCSSDocLength ] = 0; - sal_uInt64 a = m_nCustomCSSDocLength,b = m_nCustomCSSDocLength; - aFile.read( m_pCustomCSSDoc,a,b ); - aFile.close(); - error = false; - } - - --retry; - } - - if( error ) - { - m_nCustomCSSDocLength = 0; - m_pCustomCSSDoc = new char[ 1 ]; // Initialize with 1 to avoid gcc compiler warning - } - } - - *byteCount = m_nCustomCSSDocLength; - *buffer = new char[ 1 + *byteCount ]; - (*buffer)[*byteCount] = 0; - rtl_copyMemory( *buffer,m_pCustomCSSDoc,m_nCustomCSSDocLength ); - -} - - -void Databases::setActiveText( const rtl::OUString& Module, - const rtl::OUString& Language, - const rtl::OUString& Id, - char** buffer, - int* byteCount ) -{ - DataBaseIterator aDbIt( m_xContext, *this, Module, Language, true ); - - // #i84550 Cache information about failed ids - rtl::OString id( Id.getStr(),Id.getLength(),RTL_TEXTENCODING_UTF8 ); - EmptyActiveTextSet::iterator it = m_aEmptyActiveTextSet.find( id ); - bool bFoundAsEmpty = ( it != m_aEmptyActiveTextSet.end() ); - Dbt data; - DBData aDBData; - - int nSize = 0; - const sal_Char* pData = NULL; - - bool bSuccess = false; - if( !bFoundAsEmpty ) - { - Db* db; - Dbt key( static_cast< void* >( const_cast< sal_Char* >( id.getStr() ) ),id.getLength() ); - while( !bSuccess && (db = aDbIt.nextDb()) != NULL ) - { - DBHelp* pDBHelp = db->getDBHelp(); - if( pDBHelp != NULL ) - { - bSuccess = pDBHelp->getValueForKey( id, aDBData ); - nSize = aDBData.getSize(); - pData = aDBData.getData(); - } - else - { - int err = db->get( 0, &key, &data, 0 ); - if( err == 0 ) - { - bSuccess = true; - nSize = data.get_size(); - pData = static_cast<sal_Char*>( data.get_data() ); - } - } - } - } - - if( bSuccess ) - { - // ensure existence of tmp after for - rtl::OString tmp; - for( int i = 0; i < nSize; ++i ) - if( pData[i] == '%' || pData[i] == '$' ) - { - // need of replacement - rtl::OUString temp = rtl::OUString( pData, nSize, RTL_TEXTENCODING_UTF8 ); - replaceName( temp ); - tmp = rtl::OString( temp.getStr(), - temp.getLength(), - RTL_TEXTENCODING_UTF8 ); - nSize = tmp.getLength(); - pData = tmp.getStr(); - break; - } - - *byteCount = nSize; - *buffer = new char[ 1 + nSize ]; - (*buffer)[nSize] = 0; - rtl_copyMemory( *buffer, pData, nSize ); - } - else - { - *byteCount = 0; - *buffer = new char[1]; // Initialize with 1 to avoid compiler warnings - if( !bFoundAsEmpty ) - m_aEmptyActiveTextSet.insert( id ); - } -} - - -void Databases::setInstallPath( const rtl::OUString& aInstDir ) -{ - osl::MutexGuard aGuard( m_aMutex ); - - osl::FileBase::getFileURLFromSystemPath( aInstDir,m_aInstallDirectory ); - //TODO: check returned error code - - if( m_aInstallDirectory.lastIndexOf( sal_Unicode( '/' ) ) != m_aInstallDirectory.getLength() - 1 ) - m_aInstallDirectory += rtl::OUString::createFromAscii( "/" ); - - m_aInstallDirectoryWithoutEncoding = rtl::Uri::decode( m_aInstallDirectory, - rtl_UriDecodeWithCharset, - RTL_TEXTENCODING_UTF8 ); -} - - -//=================================================================== -// class ExtensionIteratorBase - -ExtensionHelpExistanceMap ExtensionIteratorBase::aHelpExistanceMap; - -ExtensionIteratorBase::ExtensionIteratorBase( Reference< XComponentContext > xContext, - Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) - : m_xContext( xContext ) - , m_rDatabases( rDatabases ) - , m_eState( INITIAL_MODULE ) - , m_aInitialModule( aInitialModule ) - , m_aLanguage( aLanguage ) -{ - init(); -} - -ExtensionIteratorBase::ExtensionIteratorBase( Databases& rDatabases, - const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) - : m_rDatabases( rDatabases ) - , m_eState( INITIAL_MODULE ) - , m_aInitialModule( aInitialModule ) - , m_aLanguage( aLanguage ) -{ - init(); -} - -void ExtensionIteratorBase::init() -{ - if( !m_xContext.is() ) - { - Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); - Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); - OSL_ASSERT( xProps.is() ); - if (xProps.is()) - { - xProps->getPropertyValue( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext; - OSL_ASSERT( m_xContext.is() ); - } - } - if( !m_xContext.is() ) - { - throw RuntimeException( - ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ), - Reference< XInterface >() ); - } - - Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); - m_xSFA = Reference< ucb::XSimpleFileAccess >( - xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), - m_xContext ), UNO_QUERY_THROW ); - - m_bUserPackagesLoaded = false; - m_bSharedPackagesLoaded = false; - m_iUserPackage = 0; - m_iSharedPackage = 0; -} - -Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage - ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle ) -{ - o_xParentPackageBundle.clear(); - - Reference< deployment::XPackage > xHelpPackage; - if( !xPackage.is() ) - return xHelpPackage; - - // #i84550 Cache information about help content in extension - rtl::OUString aExtensionPath = xPackage->getURL(); - ExtensionHelpExistanceMap::iterator it = aHelpExistanceMap.find( aExtensionPath ); - bool bFound = ( it != aHelpExistanceMap.end() ); - bool bHasHelp = bFound ? it->second : false; - if( bFound && !bHasHelp ) - return xHelpPackage; - - // Check if parent package is registered - beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered - ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) ); - bool bRegistered = false; - if( option.IsPresent ) - { - beans::Ambiguous<sal_Bool> const & reg = option.Value; - if( !reg.IsAmbiguous && reg.Value ) - bRegistered = true; - } - if( bRegistered ) - { - if( xPackage->isBundle() ) - { - Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle - ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ); - sal_Int32 nPkgCount = aPkgSeq.getLength(); - const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray(); - for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg ) - { - const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ]; - const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType(); - rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); - if( aMediaType.equals( aHelpMediaType ) ) - { - xHelpPackage = xSubPkg; - o_xParentPackageBundle = xPackage; - break; - } - } - } - else - { - const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType(); - rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); - if( aMediaType.equals( aHelpMediaType ) ) - xHelpPackage = xPackage; - } - } - - if( !bFound ) - aHelpExistanceMap[ aExtensionPath ] = xHelpPackage.is(); - - return xHelpPackage; -} - -Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage - ( Reference< deployment::XPackage >& o_xParentPackageBundle ) -{ - Reference< deployment::XPackage > xHelpPackage; - - if( !m_bUserPackagesLoaded ) - { - Reference< XPackageManager > xUserManager = - thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") ); - m_aUserPackagesSeq = xUserManager->getDeployedPackages - ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); - - m_bUserPackagesLoaded = true; - } - - if( m_iUserPackage == m_aUserPackagesSeq.getLength() ) - { - m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE - } - else - { - const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray(); - Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ]; - VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" ); - xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); - } - - return xHelpPackage; -} - -Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage - ( Reference< deployment::XPackage >& o_xParentPackageBundle ) -{ - Reference< deployment::XPackage > xHelpPackage; - - if( !m_bSharedPackagesLoaded ) - { - Reference< XPackageManager > xSharedManager = - thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") ); - m_aSharedPackagesSeq = xSharedManager->getDeployedPackages - ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); - - m_bSharedPackagesLoaded = true; - } - - if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() ) - { - m_eState = END_REACHED; - } - else - { - const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray(); - Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ]; - VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" ); - xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); - } - - return xHelpPackage; -} - -rtl::OUString ExtensionIteratorBase::implGetFileFromPackage( - const rtl::OUString& rFileExtension, Reference< deployment::XPackage > xPackage ) -{ - // No extension -> search for pure language folder - bool bLangFolderOnly = (rFileExtension.getLength() == 0); - - rtl::OUString aFile; - rtl::OUString aLanguage = m_aLanguage; - for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass ) - { - rtl::OUStringBuffer aStrBuf; - aStrBuf.append( xPackage->getURL() ); - aStrBuf.append( aSlash ); - aStrBuf.append( aLanguage ); - if( !bLangFolderOnly ) - { - aStrBuf.append( aSlash ); - aStrBuf.append( aHelpFilesBaseName ); - aStrBuf.append( rFileExtension ); - } - - aFile = m_rDatabases.expandURL( aStrBuf.makeStringAndClear() ); - if( iPass == 0 ) - { - if( m_xSFA->exists( aFile ) ) - break; - - ::std::vector< ::rtl::OUString > av; - implGetLanguageVectorFromPackage( av, xPackage ); - ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); - try - { - pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); - } - catch( ::comphelper::Locale::MalFormedLocaleException& ) - {} - if( pFound != av.end() ) - aLanguage = *pFound; - } - } - return aFile; -} - -inline bool isLetter( sal_Unicode c ) -{ - bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); - return bLetter; -} - -void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, - com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ) -{ - rv.clear(); - rtl::OUString aExtensionPath = xPackage->getURL(); - Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true ); - - const rtl::OUString* pSeq = aEntrySeq.getConstArray(); - sal_Int32 nCount = aEntrySeq.getLength(); - for( sal_Int32 i = 0 ; i < nCount ; ++i ) - { - rtl::OUString aEntry = pSeq[i]; - if( m_xSFA->isFolder( aEntry ) ) - { - sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' ); - if( nLastSlash != -1 ) - { - rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 ); - - // Check language sceme - int nLen = aPureEntry.getLength(); - const sal_Unicode* pc = aPureEntry.getStr(); - bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) ); - bool bIsLanguage = bStartCanBeLanguage && - ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) ); - if( bIsLanguage ) - rv.push_back( aPureEntry ); - } - } - } -} - - -//=================================================================== -// class DataBaseIterator - -Db* DataBaseIterator::nextDb( rtl::OUString* o_pExtensionPath ) -{ - Db* pRetDb = NULL; - - while( !pRetDb && m_eState != END_REACHED ) - { - switch( m_eState ) - { - case INITIAL_MODULE: - pRetDb = m_rDatabases.getBerkeley( m_aInitialModule, m_aLanguage, m_bHelpText ); - m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE - break; - - // Later: - //case SHARED_MODULE - //... - - case USER_EXTENSIONS: - { - Reference< deployment::XPackage > xParentPackageBundle; - Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath ); - break; - } - - case SHARED_EXTENSIONS: - { - Reference< deployment::XPackage > xParentPackageBundle; - Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath ); - break; - } - case END_REACHED: - VOS_ENSURE( false, "DataBaseIterator::nextDb(): Invalid case END_REACHED" ); - break; - } - } - - return pRetDb; -} - -Db* DataBaseIterator::implGetDbFromPackage( Reference< deployment::XPackage > xPackage, - rtl::OUString* o_pExtensionPath ) -{ - rtl::OUString aExtensionPath = xPackage->getURL(); - //if( o_pExtensionPath ) - //*o_pExtensionPath = aExtensionPath; - aExtensionPath += aSlash; - - rtl::OUString aUsedLanguage = m_aLanguage; - Db* pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage, - m_bHelpText, &aExtensionPath ); - - // Language fallback - if( !pRetDb ) - { - ::std::vector< ::rtl::OUString > av; - implGetLanguageVectorFromPackage( av, xPackage ); - ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); - try - { - pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); - } - catch( ::comphelper::Locale::MalFormedLocaleException& ) - {} - if( pFound != av.end() ) - { - aUsedLanguage = *pFound; - pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aExtensionPath ); - } - } - - if( o_pExtensionPath ) - *o_pExtensionPath = aExtensionPath + aUsedLanguage; - - return pRetDb; -} - - -//=================================================================== -// class KeyDataBaseFileIterator - -rtl::OUString KeyDataBaseFileIterator::nextDbFile( bool& o_rbExtension ) -{ - rtl::OUString aRetFile; - - while( !aRetFile.getLength() && m_eState != END_REACHED ) - { - switch( m_eState ) - { - case INITIAL_MODULE: - aRetFile = - m_rDatabases.getInstallPathAsSystemPath() + - m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule + - rtl::OUString::createFromAscii( ".key" ); - - o_rbExtension = false; - - m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE - break; - - // Later: - //case SHARED_MODULE - //... - - case USER_EXTENSIONS: - { - Reference< deployment::XPackage > xParentPackageBundle; - Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - aRetFile = implGetDbFileFromPackage( xHelpPackage ); - o_rbExtension = true; - break; - } - - case SHARED_EXTENSIONS: - { - Reference< deployment::XPackage > xParentPackageBundle; - Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - aRetFile = implGetDbFileFromPackage( xHelpPackage ); - o_rbExtension = true; - break; - } - case END_REACHED: - VOS_ENSURE( false, "DataBaseIterator::nextDbFile(): Invalid case END_REACHED" ); - break; - } - } - - return aRetFile; -} - -rtl::OUString KeyDataBaseFileIterator::implGetDbFileFromPackage - ( Reference< deployment::XPackage > xPackage ) -{ - rtl::OUString aExpandedURL = - implGetFileFromPackage( rtl::OUString::createFromAscii( ".key" ), xPackage ); - - rtl::OUString aRetFile; - osl::FileBase::getSystemPathFromFileURL( aExpandedURL, aRetFile ); - - return aRetFile; -} - - -//=================================================================== -// class JarFileIterator - -Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile - ( Reference< deployment::XPackage >& o_xParentPackageBundle, rtl::OUString* o_pExtensionPath ) -{ - Reference< XHierarchicalNameAccess > xNA; - - while( !xNA.is() && m_eState != END_REACHED ) - { - switch( m_eState ) - { - case INITIAL_MODULE: - xNA = m_rDatabases.jarFile( m_aInitialModule, m_aLanguage ); - m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE - break; - - // Later: - //case SHARED_MODULE - //... - - case USER_EXTENSIONS: - { - Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( o_xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath ); - break; - } - - case SHARED_EXTENSIONS: - { - Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( o_xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath ); - break; - } - case END_REACHED: - VOS_ENSURE( false, "JarFileIterator::nextJarFile(): Invalid case END_REACHED" ); - break; - } - } - - return xNA; -} - -Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage - ( Reference< deployment::XPackage > xPackage, rtl::OUString* o_pExtensionPath ) -{ - Reference< XHierarchicalNameAccess > xNA; - - rtl::OUString zipFile = - implGetFileFromPackage( rtl::OUString::createFromAscii( ".jar" ), xPackage ); - - try - { - Sequence< Any > aArguments( 1 ); - aArguments[ 0 ] <<= zipFile; - - Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); - Reference< XInterface > xIfc - = xSMgr->createInstanceWithArgumentsAndContext( - rtl::OUString::createFromAscii( - "com.sun.star.packages.comp.ZipPackage" ), - aArguments, m_xContext ); - - if ( xIfc.is() ) - { - xNA = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY ); - - VOS_ENSURE( xNA.is(), - "JarFileIterator::implGetJarFromPackage() - " - "Got no hierarchical name access!" ); - } - } - catch ( RuntimeException & ) - {} - catch ( Exception & ) - {} - - if( xNA.is() && o_pExtensionPath != NULL ) - { - // Extract path including language from file name - sal_Int32 nLastSlash = zipFile.lastIndexOf( '/' ); - if( nLastSlash != -1 ) - *o_pExtensionPath = zipFile.copy( 0, nLastSlash ); - } - - return xNA; -} - - -//=================================================================== -// class IndexFolderIterator - -rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary ) -{ - rtl::OUString aIndexFolder; - - while( !aIndexFolder.getLength() && m_eState != END_REACHED ) - { - switch( m_eState ) - { - case INITIAL_MODULE: - aIndexFolder = - m_rDatabases.getInstallPathAsURL() + - m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule + - rtl::OUString::createFromAscii( ".idxl" ); - - o_rbTemporary = false; - o_rbExtension = false; - - m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE - break; - - // Later: - //case SHARED_MODULE - //... - - case USER_EXTENSIONS: - { - Reference< deployment::XPackage > xParentPackageBundle; - Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); - o_rbExtension = true; - break; - } - - case SHARED_EXTENSIONS: - { - Reference< deployment::XPackage > xParentPackageBundle; - Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); - if( !xHelpPackage.is() ) - break; - - aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); - o_rbExtension = true; - break; - } - case END_REACHED: - VOS_ENSURE( false, "IndexFolderIterator::nextIndexFolder(): Invalid case END_REACHED" ); - break; - } - } - - return aIndexFolder; -} - -rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( bool& o_rbTemporary, Reference< deployment::XPackage > xPackage ) -{ - rtl::OUString aIndexFolder = - implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage ); - - o_rbTemporary = false; - if( !m_xSFA->isFolder( aIndexFolder ) ) - { - // i98680: Missing index? Try to generate now - rtl::OUString aLangURL = implGetFileFromPackage( rtl::OUString(), xPackage ); - if( m_xSFA->isFolder( aLangURL ) ) - { - // Test write access (shared extension may be read only) - bool bIsWriteAccess = false; - try - { - rtl::OUString aCreateTestFolder = aLangURL + rtl::OUString::createFromAscii( "CreateTestFolder" ); - m_xSFA->createFolder( aCreateTestFolder ); - if( m_xSFA->isFolder( aCreateTestFolder ) ) - bIsWriteAccess = true; - - m_xSFA->kill( aCreateTestFolder ); - } - catch (Exception &) - {} - - // TEST - //bIsWriteAccess = false; - - Reference< script::XInvocation > xInvocation; - Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); - try - { - xInvocation = Reference< script::XInvocation >( - m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( - "com.sun.star.help.HelpIndexer" ), m_xContext ) , UNO_QUERY ); - - if( xInvocation.is() ) - { - Sequence<uno::Any> aParamsSeq( bIsWriteAccess ? 6 : 8 ); - - 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" ) ); - - rtl::OUString aZipDir = aLangURL; - if( !bIsWriteAccess ) - { - rtl::OUString aTempFileURL; - ::osl::FileBase::RC eErr = ::osl::File::createTempFile( 0, 0, &aTempFileURL ); - if( eErr == ::osl::FileBase::E_None ) - { - rtl::OUString aTempDirURL = aTempFileURL; - try - { - m_xSFA->kill( aTempDirURL ); - } - catch (Exception &) - {} - m_xSFA->createFolder( aTempDirURL ); - - aZipDir = aTempDirURL; - o_rbTemporary = true; - } - } - - aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); - rtl::OUString aSystemPath; - osl::FileBase::getSystemPathFromFileURL( aZipDir, aSystemPath ); - aParamsSeq[5] = uno::makeAny( aSystemPath ); - - if( !bIsWriteAccess ) - { - aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-srcdir" ) ); - rtl::OUString aSrcDirVal; - osl::FileBase::getSystemPathFromFileURL( aLangURL, aSrcDirVal ); - aParamsSeq[7] = uno::makeAny( aSrcDirVal ); - } - - Sequence< sal_Int16 > aOutParamIndex; - Sequence< uno::Any > aOutParam; - uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ), - aParamsSeq, aOutParamIndex, aOutParam ); - - if( bIsWriteAccess ) - aIndexFolder = implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage ); - else - aIndexFolder = aZipDir + rtl::OUString::createFromAscii( "/help.idxl" ); - } - } - catch (Exception &) - {} - } - } - - return aIndexFolder; -} - -void IndexFolderIterator::deleteTempIndexFolder( const rtl::OUString& aIndexFolder ) -{ - sal_Int32 nLastSlash = aIndexFolder.lastIndexOf( '/' ); - if( nLastSlash != -1 ) - { - rtl::OUString aTmpFolder = aIndexFolder.copy( 0, nLastSlash ); - try - { - m_xSFA->kill( aTmpFolder ); - } - catch (Exception &) - {} - } -} +
+void Databases::replaceName( rtl::OUString& oustring ) const
+{
+ sal_Int32 idx = -1,idx1 = -1,idx2 = -1,k = 0,off;
+ bool cap = false;
+ rtl::OUStringBuffer aStrBuf( 0 );
+
+ while( true )
+ {
+ ++idx;
+ idx1 = oustring.indexOf( sal_Unicode('%'),idx);
+ idx2 = oustring.indexOf( sal_Unicode('$'),idx);
+
+ if(idx1 == -1 && idx2 == -1)
+ break;
+
+ if(idx1 == -1)
+ idx = idx2;
+ else if(idx2 == -1)
+ idx = idx1;
+ else {
+ // no index is zero
+ if(idx1 < idx2)
+ idx = idx1;
+ else if(idx2 < idx1 )
+ idx = idx2;
+ }
+
+ if( oustring.indexOf( prodName,idx ) == idx )
+ off = PRODUCTNAME;
+ else if( oustring.indexOf( prodVersion,idx ) == idx )
+ off = PRODUCTVERSION;
+ else if( oustring.indexOf( vendName,idx ) == idx )
+ off = VENDORNAME;
+ else if( oustring.indexOf( vendVersion,idx ) == idx )
+ off = VENDORVERSION;
+ else if( oustring.indexOf( vendShort,idx ) == idx )
+ off = VENDORSHORT;
+ else if( oustring.indexOf( newProdName,idx ) == idx )
+ off = NEWPRODUCTNAME;
+ else if( oustring.indexOf( newProdVersion,idx ) == idx )
+ off = NEWPRODUCTVERSION;
+ else
+ off = -1;
+
+ if( off != -1 )
+ {
+ if( ! cap )
+ {
+ cap = true;
+ aStrBuf.ensureCapacity( 256 );
+ }
+
+ aStrBuf.append( &oustring.getStr()[k],idx - k );
+ aStrBuf.append( m_vReplacement[off] );
+ k = idx + m_vAdd[off];
+ }
+ }
+
+ if( cap )
+ {
+ if( k < oustring.getLength() )
+ aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k );
+ oustring = aStrBuf.makeStringAndClear();
+ }
+}
+
+
+
+
+rtl::OUString Databases::getInstallPathAsSystemPath()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ if( ! m_aInstallDirectoryAsSystemPath.getLength() )
+ {
+#ifdef DBG_UTIL
+ bool bla =
+ osl::FileBase::E_None ==
+ osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath );
+ VOS_ENSURE( bla,"HelpProvider, no installpath" );
+#else
+ osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath );
+#endif
+ }
+
+ return m_aInstallDirectoryAsSystemPath;
+}
+
+
+
+
+rtl::OUString Databases::getInstallPathAsURL()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ return m_aInstallDirectory;
+}
+
+
+const std::vector< rtl::OUString >& Databases::getModuleList( const rtl::OUString& Language )
+{
+ if( m_avModules.size() == 0 )
+ {
+ rtl::OUString fileName,dirName = getInstallPathAsURL() + processLang( Language );
+ osl::Directory dirFile( dirName );
+
+ osl::DirectoryItem aDirItem;
+ osl::FileStatus aStatus( FileStatusMask_FileName );
+
+ sal_Int32 idx;
+
+ if( osl::FileBase::E_None != dirFile.open() )
+ return m_avModules;
+
+ while( dirFile.getNextItem( aDirItem ) == osl::FileBase::E_None &&
+ aDirItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
+ {
+ if( ! aStatus.isValid( FileStatusMask_FileName ) )
+ continue;
+
+ fileName = aStatus.getFileName();
+
+ // Check, whether fileName is of the form *.cfg
+ idx = fileName.lastIndexOf( sal_Unicode( '.' ) );
+
+ if( idx == -1 )
+ continue;
+
+ const sal_Unicode* str = fileName.getStr();
+
+ if( fileName.getLength() == idx + 4 &&
+ ( str[idx + 1] == 'c' || str[idx + 1] == 'C' ) &&
+ ( str[idx + 2] == 'f' || str[idx + 2] == 'F' ) &&
+ ( str[idx + 3] == 'g' || str[idx + 3] == 'G' ) &&
+ ( fileName = fileName.copy(0,idx).toAsciiLowerCase() ).compareToAscii( "picture" ) != 0 ) {
+ if(! m_bShowBasic && fileName.compareToAscii("sbasic") == 0 )
+ continue;
+ m_avModules.push_back( fileName );
+ }
+ }
+ }
+ return m_avModules;
+}
+
+
+
+StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OUString& Module,
+ const rtl::OUString& Language )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Module;
+
+ std::pair< ModInfoTable::iterator,bool > aPair =
+ m_aModInfo.insert( ModInfoTable::value_type( key,0 ) );
+
+ ModInfoTable::iterator it = aPair.first;
+
+ if( aPair.second && ! it->second )
+ {
+ osl::File cfgFile( getInstallPathAsURL() +
+ key +
+ rtl::OUString::createFromAscii( ".cfg" ) );
+
+ if( osl::FileBase::E_None != cfgFile.open( OpenFlag_Read ) )
+ it->second = 0;
+ else
+ {
+ sal_uInt32 pos = 0;
+ sal_uInt64 nRead;
+ sal_Char buffer[2048];
+ sal_Unicode lineBuffer[1028];
+ rtl::OUString fileContent;
+
+ while( osl::FileBase::E_None == cfgFile.read( &buffer,2048,nRead ) && nRead )
+ fileContent += rtl::OUString( buffer,sal_Int32( nRead ),RTL_TEXTENCODING_UTF8 );
+
+ cfgFile.close();
+
+ const sal_Unicode* str = fileContent.getStr();
+ rtl::OUString current,lang_,program,startid,title,heading,fulltext;
+ rtl::OUString order = rtl::OUString::createFromAscii( "1" );
+
+ for( sal_Int32 i = 0;i < fileContent.getLength();i++ )
+ {
+ sal_Unicode ch = str[ i ];
+ if( ch == sal_Unicode( '\n' ) || ch == sal_Unicode( '\r' ) )
+ {
+ if( pos )
+ {
+ current = rtl::OUString( lineBuffer,pos );
+
+ if( current.compareToAscii( "Title",5 ) == 0 )
+ {
+ title = current.copy( current.indexOf(sal_Unicode( '=' ) ) + 1 );
+ }
+ else if( current.compareToAscii( "Start",5 ) == 0 )
+ {
+ startid = current.copy( current.indexOf('=') + 1 );
+ }
+ else if( current.compareToAscii( "Language",8 ) == 0 )
+ {
+ lang_ = current.copy( current.indexOf('=') + 1 );
+ }
+ else if( current.compareToAscii( "Program",7 ) == 0 )
+ {
+ program = current.copy( current.indexOf('=') + 1 );
+ }
+ else if( current.compareToAscii( "Heading",7 ) == 0 )
+ {
+ heading = current.copy( current.indexOf('=') + 1 );
+ }
+ else if( current.compareToAscii( "FullText",8 ) == 0 )
+ {
+ fulltext = current.copy( current.indexOf('=') + 1 );
+ }
+ else if( current.compareToAscii( "Order",5 ) == 0 )
+ {
+ order = current.copy( current.indexOf('=') + 1 );
+ }
+ }
+ pos = 0;
+ }
+ else
+ lineBuffer[ pos++ ] = ch;
+ }
+ replaceName( title );
+ it->second = new StaticModuleInformation( title,
+ startid,
+ program,
+ heading,
+ fulltext,
+ order );
+ }
+ }
+
+ return it->second;
+}
+
+
+
+
+rtl::OUString Databases::processLang( const rtl::OUString& Language )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ rtl::OUString ret;
+ LangSetTable::iterator it = m_aLangSet.find( Language );
+
+ if( it == m_aLangSet.end() )
+ {
+ sal_Int32 idx;
+ osl::DirectoryItem aDirItem;
+
+ if( osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language,aDirItem ) )
+ {
+ ret = Language;
+ m_aLangSet[ Language ] = ret;
+ }
+ else if( ( ( idx = Language.indexOf( '-' ) ) != -1 ||
+ ( idx = Language.indexOf( '_' ) ) != -1 ) &&
+ osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language.copy( 0,idx ),
+ aDirItem ) )
+ {
+ ret = Language.copy( 0,idx );
+ m_aLangSet[ Language ] = ret;
+ }
+ }
+ else
+ ret = it->second;
+
+ return ret;
+}
+
+
+rtl::OUString Databases::country( const rtl::OUString& Language )
+{
+ sal_Int32 idx;
+ if( ( idx = Language.indexOf( '-' ) ) != -1 ||
+ ( idx = Language.indexOf( '_' ) ) != -1 )
+ return Language.copy( 1+idx );
+
+ return rtl::OUString();
+}
+
+
+
+Db* Databases::getBerkeley( const rtl::OUString& Database,
+ const rtl::OUString& Language, bool helpText,
+ const rtl::OUString* pExtensionPath )
+{
+ if( ! Database.getLength() || ! Language.getLength() )
+ return 0;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+
+ rtl::OUString aFileExt( rtl::OUString::createFromAscii( helpText ? ".ht" : ".db" ) );
+ rtl::OUString dbFileName = aSlash + Database + aFileExt;
+ rtl::OUString key;
+ if( pExtensionPath == NULL )
+ key = processLang( Language ) + dbFileName;
+ else
+ key = *pExtensionPath + Language + dbFileName; // make unique, don't change language
+
+ std::pair< DatabasesTable::iterator,bool > aPair =
+ m_aDatabases.insert( DatabasesTable::value_type( key,0 ) );
+
+ DatabasesTable::iterator it = aPair.first;
+
+ if( aPair.second && ! it->second )
+ {
+ Db* table = new Db();
+
+ rtl::OUString fileNameOU;
+ if( pExtensionPath )
+ {
+ rtl::OUString aExpandedURL = expandURL( *pExtensionPath );
+ aExpandedURL += Language + dbFileName;
+ osl::FileBase::getSystemPathFromFileURL( aExpandedURL, fileNameOU );
+ }
+ else
+ fileNameOU = getInstallPathAsSystemPath() + key;
+
+
+ rtl::OString fileName( fileNameOU.getStr(),fileNameOU.getLength(),osl_getThreadTextEncoding() );
+
+ rtl::OUString fileNameDBHelp( fileNameOU );
+ if( pExtensionPath != NULL )
+ fileNameDBHelp += rtl::OUString::createFromAscii( "_" );
+ if( m_xSFA->exists( fileNameDBHelp ) )
+ {
+ DBHelp* pDBHelp = new DBHelp( fileNameDBHelp, m_xSFA );
+ table->setDBHelp( pDBHelp );
+
+#ifdef TEST_DBHELP
+ bool bSuccess;
+ bool bOldDbAccess = false;
+ bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess );
+
+ bOldDbAccess = true;
+ bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess );
+#endif
+ }
+ else if( table->open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
+ {
+ table->close( 0 );
+ delete table;
+ table = 0;
+ }
+
+ it->second = table;
+ }
+
+ return it->second;
+}
+
+Reference< XCollator >
+Databases::getCollator( const rtl::OUString& Language,
+ const rtl::OUString& System )
+{
+ (void)System;
+
+ rtl::OUString key = Language;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ CollatorTable::iterator it =
+ m_aCollatorTable.insert( CollatorTable::value_type( key,0 ) ).first;
+
+ if( ! it->second.is() )
+ {
+ it->second =
+ Reference< XCollator > (
+ m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ),
+ m_xContext ), UNO_QUERY );
+ rtl::OUString langStr = processLang(Language);
+ rtl::OUString countryStr = country(Language);
+ if( !countryStr.getLength() )
+ {
+ if( langStr.compareToAscii("de") == 0 )
+ countryStr = rtl::OUString::createFromAscii("DE");
+ else if( langStr.compareToAscii("en") == 0 )
+ countryStr = rtl::OUString::createFromAscii("US");
+ else if( langStr.compareToAscii("es") == 0 )
+ countryStr = rtl::OUString::createFromAscii("ES");
+ else if( langStr.compareToAscii("it") == 0 )
+ countryStr = rtl::OUString::createFromAscii("IT");
+ else if( langStr.compareToAscii("fr") == 0 )
+ countryStr = rtl::OUString::createFromAscii("FR");
+ else if( langStr.compareToAscii("sv") == 0 )
+ countryStr = rtl::OUString::createFromAscii("SE");
+ else if( langStr.compareToAscii("ja") == 0 )
+ countryStr = rtl::OUString::createFromAscii("JP");
+ else if( langStr.compareToAscii("ko") == 0 )
+ countryStr = rtl::OUString::createFromAscii("KR");
+ }
+ it->second->loadDefaultCollator( Locale( langStr,
+ countryStr,
+ rtl::OUString() ),
+ 0 );
+ }
+
+ return it->second;
+}
+
+
+
+namespace chelp {
+
+ struct KeywordElementComparator
+ {
+ KeywordElementComparator( const Reference< XCollator >& xCollator )
+ : m_xCollator( xCollator )
+ { }
+
+ bool operator()( const KeywordInfo::KeywordElement& la,
+ const KeywordInfo::KeywordElement& ra ) const
+ {
+ const rtl::OUString& l = la.key;
+ const rtl::OUString& r = ra.key;
+
+ bool ret;
+
+ if( m_xCollator.is() )
+ {
+ sal_Int32 l1 = l.indexOf( sal_Unicode( ';' ) );
+ sal_Int32 l3 = ( l1 == -1 ? l.getLength() : l1 );
+
+ sal_Int32 r1 = r.indexOf( sal_Unicode( ';' ) );
+ sal_Int32 r3 = ( r1 == -1 ? r.getLength() : r1 );
+
+ sal_Int32 c1 = m_xCollator->compareSubstring( l,0,l3,r,0,r3 );
+
+ if( c1 == +1 )
+ ret = false;
+ else if( c1 == 0 )
+ {
+ sal_Int32 l2 = l.getLength() - l1 - 1;
+ sal_Int32 r2 = r.getLength() - r1 - 1;
+ ret = ( m_xCollator->compareSubstring( l,1+l1,l2,r,1+r1,r2 ) < 0 );
+ }
+ else
+ ret = true;
+ }
+ else
+ ret = bool( l < r );
+
+ return ret;
+ }
+
+ Reference< XCollator > m_xCollator;
+ }; // end struct KeywordElementComparator
+
+}
+
+
+
+KeywordInfo::KeywordElement::KeywordElement( Databases *pDatabases,
+ Db* pDb,
+ rtl::OUString& ky,
+ rtl::OUString& data )
+ : key( ky )
+{
+ pDatabases->replaceName( key );
+ init( pDatabases,pDb,data );
+}
+
+
+
+void KeywordInfo::KeywordElement::init( Databases *pDatabases,Db* pDb,const rtl::OUString& ids )
+{
+ const sal_Unicode* idstr = ids.getStr();
+ std::vector< rtl::OUString > id,anchor;
+ int idx = -1,k;
+ while( ( idx = ids.indexOf( ';',k = ++idx ) ) != -1 )
+ {
+ int h = ids.indexOf( sal_Unicode( '#' ),k );
+ if( h < idx )
+ {
+ // found an anchor
+ id.push_back( rtl::OUString( &idstr[k],h-k ) );
+ anchor.push_back( rtl::OUString( &idstr[h+1],idx-h-1 ) );
+ }
+ else
+ {
+ id.push_back( rtl::OUString( &idstr[k],idx-k ) );
+ anchor.push_back( rtl::OUString() );
+ }
+ }
+
+ listId.realloc( id.size() );
+ listAnchor.realloc( id.size() );
+ listTitle.realloc( id.size() );
+
+ int nSize = 0;
+ const sal_Char* pData = NULL;
+ const sal_Char pEmpty[] = "";
+
+ for( sal_uInt32 i = 0; i < id.size(); ++i )
+ {
+ listId[i] = id[i];
+ listAnchor[i] = anchor[i];
+
+ nSize = 0;
+ pData = pEmpty;
+ if( pDb )
+ {
+ rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 );
+ DBHelp* pDBHelp = pDb->getDBHelp();
+ if( pDBHelp != NULL )
+ {
+ DBData aDBData;
+ bool bSuccess = pDBHelp->getValueForKey( idi, aDBData );
+ if( bSuccess )
+ {
+ nSize = aDBData.getSize();
+ pData = aDBData.getData();
+ }
+ }
+ else
+ {
+ Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ),
+ idi.getLength() );
+ Dbt data;
+ pDb->get( 0,&key_,&data,0 );
+ nSize = data.get_size();
+ pData = static_cast<sal_Char*>( data.get_data() );
+ }
+ }
+
+ DbtToStringConverter converter( pData, nSize );
+
+ rtl::OUString title = converter.getTitle();
+ pDatabases->replaceName( title );
+ listTitle[i] = title;
+ }
+}
+
+
+
+KeywordInfo::KeywordInfo( const std::vector< KeywordElement >& aVec )
+ : listKey( aVec.size() ),
+ listId( aVec.size() ),
+ listAnchor( aVec.size() ),
+ listTitle( aVec.size() )
+{
+ for( unsigned int i = 0; i < aVec.size(); ++i )
+ {
+ listKey[i] = aVec[i].key;
+ listId[i] = aVec[i].listId;
+ listAnchor[i] = aVec[i].listAnchor;
+ listTitle[i] = aVec[i].listTitle;
+ }
+}
+
+bool Databases::checkModuleMatchForExtension
+ ( const rtl::OUString& Database, const rtl::OUString& doclist )
+{
+ bool bBelongsToDatabase = true;
+
+ // Analyse doclist string to find module assignments
+ bool bFoundAtLeastOneModule = false;
+ bool bModuleMatch = false;
+ sal_Int32 nLen = doclist.getLength();
+ sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') );
+ if( nLastFound == -1 )
+ nLastFound = nLen;
+ const sal_Unicode* pStr = doclist.getStr();
+ sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') );
+ while( nFound != -1 )
+ {
+ // Simple optimization, stop if '_' is followed by "id"
+ if( nLen - nFound > 2 )
+ {
+ if( pStr[ nFound + 1 ] == sal_Unicode('i') &&
+ pStr[ nFound + 2 ] == sal_Unicode('d') )
+ break;
+ }
+
+ rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 );
+ std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule );
+ if( result != m_avModules.end() )
+ {
+ bFoundAtLeastOneModule = true;
+ if( Database == aModule )
+ {
+ bModuleMatch = true;
+ break;
+ }
+ }
+
+ nLastFound = nFound;
+ if( nLastFound == 0 )
+ break;
+ nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 );
+ }
+
+ if( bFoundAtLeastOneModule && !bModuleMatch )
+ bBelongsToDatabase = false;
+
+ return bBelongsToDatabase;
+}
+
+
+KeywordInfo* Databases::getKeyword( const rtl::OUString& Database,
+ const rtl::OUString& Language )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Database;
+
+ std::pair< KeywordInfoTable::iterator,bool > aPair =
+ m_aKeywordInfo.insert( KeywordInfoTable::value_type( key,0 ) );
+
+ KeywordInfoTable::iterator it = aPair.first;
+
+ if( aPair.second && ! it->second )
+ {
+ std::vector<KeywordInfo::KeywordElement> aVector;
+
+ KeyDataBaseFileIterator aDbFileIt( m_xContext, *this, Database, Language );
+ rtl::OUString fileNameOU;
+ bool bExtension = false;
+ while( (fileNameOU = aDbFileIt.nextDbFile( bExtension )).getLength() > 0 )
+ {
+ rtl::OString fileName( fileNameOU.getStr(),
+ fileNameOU.getLength(),
+ osl_getThreadTextEncoding() );
+
+ Db table;
+
+ rtl::OUString fileNameDBHelp( fileNameOU );
+ if( bExtension )
+ fileNameDBHelp += rtl::OUString::createFromAscii( "_" );
+ if( m_xSFA->exists( fileNameDBHelp ) )
+ {
+ DBHelp aDBHelp( fileNameDBHelp, m_xSFA );
+
+ DBData aKey;
+ DBData aValue;
+ if( aDBHelp.startIteration() )
+ {
+ Db* idmap = getBerkeley( Database,Language );
+
+ DBHelp* pDBHelp = idmap->getDBHelp();
+ if( pDBHelp != NULL )
+ {
+ bool bOptimizeForPerformance = true;
+ pDBHelp->releaseHashMap();
+ pDBHelp->createHashMap( bOptimizeForPerformance );
+ }
+
+ while( aDBHelp.getNextKeyAndValue( aKey, aValue ) )
+ {
+ rtl::OUString keyword( aKey.getData(), aKey.getSize(),
+ RTL_TEXTENCODING_UTF8 );
+ rtl::OUString doclist( aValue.getData(), aValue.getSize(),
+ RTL_TEXTENCODING_UTF8 );
+
+ bool bBelongsToDatabase = true;
+ if( bExtension )
+ bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist );
+
+ if( !bBelongsToDatabase )
+ continue;
+
+ aVector.push_back( KeywordInfo::KeywordElement( this,
+ idmap,
+ keyword,
+ doclist ) );
+ }
+ aDBHelp.stopIteration();
+
+ if( pDBHelp != NULL )
+ pDBHelp->releaseHashMap();
+ }
+
+#ifdef TEST_DBHELP
+ bool bSuccess;
+ bool bOldDbAccess = false;
+ bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess );
+
+ bOldDbAccess = true;
+ bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess );
+
+ int nDummy = 0;
+#endif
+ }
+
+ else if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) )
+ {
+ Db* idmap = getBerkeley( Database,Language );
+
+ bool first = true;
+
+ Dbc* cursor = 0;
+ table.cursor( 0,&cursor,0 );
+ Dbt key_,data;
+ key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory
+ data.set_flags( DB_DBT_MALLOC );
+ while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) )
+ {
+ rtl::OUString keyword( static_cast<sal_Char*>(key_.get_data()),
+ key_.get_size(),
+ RTL_TEXTENCODING_UTF8 );
+ rtl::OUString doclist( static_cast<sal_Char*>(data.get_data()),
+ data.get_size(),
+ RTL_TEXTENCODING_UTF8 );
+
+ bool bBelongsToDatabase = true;
+ if( bExtension )
+ bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist );
+
+ if( !bBelongsToDatabase )
+ continue;
+
+ aVector.push_back( KeywordInfo::KeywordElement( this,
+ idmap,
+ keyword,
+ doclist ) );
+ if( first )
+ {
+ key_.set_flags( DB_DBT_REALLOC );
+ data.set_flags( DB_DBT_REALLOC );
+ first = false;
+ }
+ }
+
+ if( cursor ) cursor->close();
+ }
+ table.close( 0 );
+ }
+
+ // sorting
+ Reference< XCollator > xCollator = getCollator( Language,rtl::OUString());
+ KeywordElementComparator aComparator( xCollator );
+ std::sort(aVector.begin(),aVector.end(),aComparator);
+
+ KeywordInfo* pInfo = it->second = new KeywordInfo( aVector );
+ (void)pInfo;
+ }
+
+ return it->second;
+}
+
+Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& jar,
+ const rtl::OUString& Language )
+{
+ if( ! jar.getLength() ||
+ ! Language.getLength() )
+ {
+ return Reference< XHierarchicalNameAccess >( 0 );
+ }
+ rtl::OUString key = processLang(Language) + aSlash + jar;
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ ZipFileTable::iterator it =
+ m_aZipFileTable.insert( ZipFileTable::value_type( key,Reference< XHierarchicalNameAccess >(0) ) ).first;
+
+ if( ! it->second.is() )
+ {
+ rtl::OUString zipFile;
+ try
+ {
+ // Extension jar file? Search for ?
+ sal_Int32 nQuestionMark1 = jar.indexOf( sal_Unicode('?') );
+ sal_Int32 nQuestionMark2 = jar.lastIndexOf( sal_Unicode('?') );
+ if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 )
+ {
+ ::rtl::OUString aExtensionPath = jar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 );
+ ::rtl::OUString aPureJar = jar.copy( nQuestionMark2 + 1 );
+
+ rtl::OUStringBuffer aStrBuf;
+ aStrBuf.append( aExtensionPath );
+ aStrBuf.append( aSlash );
+ aStrBuf.append( aPureJar );
+
+ zipFile = expandURL( aStrBuf.makeStringAndClear() );
+ }
+ else
+ {
+ zipFile = getInstallPathAsURL() + key;
+ }
+
+ Sequence< Any > aArguments( 2 );
+
+ XInputStream_impl* p = new XInputStream_impl( zipFile );
+ if( p->CtorSuccess() )
+ {
+ Reference< XInputStream > xInputStream( p );
+ aArguments[ 0 ] <<= xInputStream;
+ }
+ else
+ {
+ delete p;
+ aArguments[ 0 ] <<= zipFile;
+ }
+
+ // let ZipPackage be used ( no manifest.xml is required )
+ beans::NamedValue aArg;
+ aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
+ aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
+ aArguments[ 1 ] <<= aArg;
+
+ Reference< XInterface > xIfc
+ = m_xSMgr->createInstanceWithArgumentsAndContext(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.packages.comp.ZipPackage" ),
+ aArguments, m_xContext );
+
+ if ( xIfc.is() )
+ {
+ it->second = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY );
+
+ VOS_ENSURE( it->second.is(),
+ "ContentProvider::createPackage - "
+ "Got no hierarchical name access!" );
+
+ }
+ }
+ catch ( RuntimeException & )
+ {
+ }
+ catch ( Exception & )
+ {
+ }
+ }
+
+ return it->second;
+}
+
+Reference< XHierarchicalNameAccess > Databases::findJarFileForPath
+ ( const rtl::OUString& jar, const rtl::OUString& Language,
+ const rtl::OUString& path, rtl::OUString* o_pExtensionPath )
+{
+ Reference< XHierarchicalNameAccess > xNA;
+ if( ! jar.getLength() ||
+ ! Language.getLength() )
+ {
+ return xNA;
+ }
+
+ JarFileIterator aJarFileIt( m_xContext, *this, jar, Language );
+ Reference< XHierarchicalNameAccess > xTestNA;
+ Reference< deployment::XPackage > xParentPackageBundle;
+ while( (xTestNA = aJarFileIt.nextJarFile( xParentPackageBundle, o_pExtensionPath )).is() )
+ {
+ if( xTestNA.is() && xTestNA->hasByHierarchicalName( path ) )
+ {
+ bool bSuccess = true;
+ if( xParentPackageBundle.is() )
+ {
+ rtl::OUString aIdentifierInPath;
+ sal_Int32 nFindSlash = path.indexOf( '/' );
+ if( nFindSlash != -1 )
+ aIdentifierInPath = path.copy( 0, nFindSlash );
+
+ beans::Optional<rtl::OUString> aIdentifierOptional = xParentPackageBundle->getIdentifier();
+ if( aIdentifierInPath.getLength() && aIdentifierOptional.IsPresent )
+ {
+ rtl::OUString aUnencodedIdentifier = aIdentifierOptional.Value;
+ rtl::OUString aIdentifier = rtl::Uri::encode( aUnencodedIdentifier,
+ rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 );
+
+ if( !aIdentifierInPath.equals( aIdentifier ) )
+ {
+ // path does not start with extension identifier -> ignore
+ bSuccess = false;
+ }
+ }
+ else
+ {
+ // No identifier -> ignore
+ bSuccess = false;
+ }
+ }
+
+ if( bSuccess )
+ {
+ xNA = xTestNA;
+ break;
+ }
+ }
+ }
+
+ return xNA;
+}
+
+void Databases::popupDocument( URLParameter* urlPar,char **buffer,int *byteCount )
+{
+ const char* pop1 =
+ " <html> "
+ " <head> "
+ " <help:css-file-link xmlns:help=\"http://openoffice.org/2000/help\"/> "
+ " </head> "
+ " <body> "
+ " <help:popup-cut Id=\"";
+ const sal_Int32 l1 = strlen( pop1 );
+
+ const char* pop3 = "\" Eid=\"";
+ const sal_Int32 l3 = strlen( pop3 );
+
+ const char* pop5 =
+ "\" xmlns:help=\"http://openoffice.org/2000/help\"></help:popup-cut> "
+ " </body> "
+ " </html>";
+ const sal_Int32 l5 = strlen( pop5 );
+ sal_Int32 l2,l4;
+
+ rtl::OUString val = urlPar->get_id();
+ rtl::OString pop2O( val.getStr(),l2 = val.getLength(),RTL_TEXTENCODING_UTF8 );
+ const char* pop2 = pop2O.getStr();
+
+ val = urlPar->get_eid();
+ rtl::OString pop4O( val.getStr(),l4 = val.getLength(),RTL_TEXTENCODING_UTF8 );
+ const char* pop4 = pop4O.getStr();
+
+ (*byteCount) = l1 + l2 + l3 + l4 + l5;
+
+ *buffer = new char[ 1+*byteCount ];
+
+ rtl_copyMemory( *buffer,pop1,l1 );
+ rtl_copyMemory( *buffer+l1,pop2,l2 );
+ rtl_copyMemory( *buffer+(l1+l2),pop3,l3 );
+ rtl_copyMemory( *buffer+(l1+l2+l3),pop4,l4 );
+ rtl_copyMemory( *buffer+(l1+l2+l3+l4),pop5,l5 );
+ (*buffer)[*byteCount] = 0;
+}
+
+
+void Databases::changeCSS(const rtl::OUString& newStyleSheet)
+{
+ m_aCSS = newStyleSheet.toAsciiLowerCase();
+ delete[] m_pCustomCSSDoc, m_pCustomCSSDoc = 0,m_nCustomCSSDocLength = 0;
+}
+
+
+
+void Databases::cascadingStylesheet( const rtl::OUString& Language,
+ char** buffer,
+ int* byteCount )
+{
+ if( ! m_pCustomCSSDoc )
+ {
+ int retry = 2;
+ bool error = true;
+ rtl::OUString fileURL;
+
+ while( error && retry )
+ {
+ if( retry == 2 )
+ fileURL =
+ getInstallPathAsURL() +
+ processLang( Language ) +
+ rtl::OUString::createFromAscii( "/" ) +
+ m_aCSS +
+ rtl::OUString::createFromAscii( ".css" );
+ else if( retry == 1 )
+ fileURL =
+ getInstallPathAsURL() +
+ m_aCSS +
+ rtl::OUString::createFromAscii( ".css" );
+
+ osl::DirectoryItem aDirItem;
+ osl::File aFile( fileURL );
+ osl::FileStatus aStatus( FileStatusMask_FileSize );
+
+ if( osl::FileBase::E_None == osl::DirectoryItem::get( fileURL,aDirItem ) &&
+ osl::FileBase::E_None == aFile.open( OpenFlag_Read ) &&
+ osl::FileBase::E_None == aDirItem.getFileStatus( aStatus ) )
+ {
+ m_nCustomCSSDocLength = int( aStatus.getFileSize() );
+ m_pCustomCSSDoc = new char[ 1 + m_nCustomCSSDocLength ];
+ m_pCustomCSSDoc[ m_nCustomCSSDocLength ] = 0;
+ sal_uInt64 a = m_nCustomCSSDocLength,b = m_nCustomCSSDocLength;
+ aFile.read( m_pCustomCSSDoc,a,b );
+ aFile.close();
+ error = false;
+ }
+
+ --retry;
+ }
+
+ if( error )
+ {
+ m_nCustomCSSDocLength = 0;
+ m_pCustomCSSDoc = new char[ 1 ]; // Initialize with 1 to avoid gcc compiler warning
+ }
+ }
+
+ *byteCount = m_nCustomCSSDocLength;
+ *buffer = new char[ 1 + *byteCount ];
+ (*buffer)[*byteCount] = 0;
+ rtl_copyMemory( *buffer,m_pCustomCSSDoc,m_nCustomCSSDocLength );
+
+}
+
+
+void Databases::setActiveText( const rtl::OUString& Module,
+ const rtl::OUString& Language,
+ const rtl::OUString& Id,
+ char** buffer,
+ int* byteCount )
+{
+ DataBaseIterator aDbIt( m_xContext, *this, Module, Language, true );
+
+ // #i84550 Cache information about failed ids
+ rtl::OString id( Id.getStr(),Id.getLength(),RTL_TEXTENCODING_UTF8 );
+ EmptyActiveTextSet::iterator it = m_aEmptyActiveTextSet.find( id );
+ bool bFoundAsEmpty = ( it != m_aEmptyActiveTextSet.end() );
+ Dbt data;
+ DBData aDBData;
+
+ int nSize = 0;
+ const sal_Char* pData = NULL;
+
+ bool bSuccess = false;
+ if( !bFoundAsEmpty )
+ {
+ Db* db;
+ Dbt key( static_cast< void* >( const_cast< sal_Char* >( id.getStr() ) ),id.getLength() );
+ while( !bSuccess && (db = aDbIt.nextDb()) != NULL )
+ {
+ DBHelp* pDBHelp = db->getDBHelp();
+ if( pDBHelp != NULL )
+ {
+ bSuccess = pDBHelp->getValueForKey( id, aDBData );
+ nSize = aDBData.getSize();
+ pData = aDBData.getData();
+ }
+ else
+ {
+ int err = db->get( 0, &key, &data, 0 );
+ if( err == 0 )
+ {
+ bSuccess = true;
+ nSize = data.get_size();
+ pData = static_cast<sal_Char*>( data.get_data() );
+ }
+ }
+ }
+ }
+
+ if( bSuccess )
+ {
+ // ensure existence of tmp after for
+ rtl::OString tmp;
+ for( int i = 0; i < nSize; ++i )
+ if( pData[i] == '%' || pData[i] == '$' )
+ {
+ // need of replacement
+ rtl::OUString temp = rtl::OUString( pData, nSize, RTL_TEXTENCODING_UTF8 );
+ replaceName( temp );
+ tmp = rtl::OString( temp.getStr(),
+ temp.getLength(),
+ RTL_TEXTENCODING_UTF8 );
+ nSize = tmp.getLength();
+ pData = tmp.getStr();
+ break;
+ }
+
+ *byteCount = nSize;
+ *buffer = new char[ 1 + nSize ];
+ (*buffer)[nSize] = 0;
+ rtl_copyMemory( *buffer, pData, nSize );
+ }
+ else
+ {
+ *byteCount = 0;
+ *buffer = new char[1]; // Initialize with 1 to avoid compiler warnings
+ if( !bFoundAsEmpty )
+ m_aEmptyActiveTextSet.insert( id );
+ }
+}
+
+
+void Databases::setInstallPath( const rtl::OUString& aInstDir )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ osl::FileBase::getFileURLFromSystemPath( aInstDir,m_aInstallDirectory );
+ //TODO: check returned error code
+
+ if( m_aInstallDirectory.lastIndexOf( sal_Unicode( '/' ) ) != m_aInstallDirectory.getLength() - 1 )
+ m_aInstallDirectory += rtl::OUString::createFromAscii( "/" );
+
+ m_aInstallDirectoryWithoutEncoding = rtl::Uri::decode( m_aInstallDirectory,
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 );
+}
+
+
+//===================================================================
+// class ExtensionIteratorBase
+
+ExtensionHelpExistanceMap ExtensionIteratorBase::aHelpExistanceMap;
+
+ExtensionIteratorBase::ExtensionIteratorBase( Reference< XComponentContext > xContext,
+ Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
+ : m_xContext( xContext )
+ , m_rDatabases( rDatabases )
+ , m_eState( INITIAL_MODULE )
+ , m_aInitialModule( aInitialModule )
+ , m_aLanguage( aLanguage )
+{
+ init();
+}
+
+ExtensionIteratorBase::ExtensionIteratorBase( Databases& rDatabases,
+ const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage )
+ : m_rDatabases( rDatabases )
+ , m_eState( INITIAL_MODULE )
+ , m_aInitialModule( aInitialModule )
+ , m_aLanguage( aLanguage )
+{
+ init();
+}
+
+void ExtensionIteratorBase::init()
+{
+ if( !m_xContext.is() )
+ {
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+ Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ xProps->getPropertyValue(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext;
+ OSL_ASSERT( m_xContext.is() );
+ }
+ }
+ if( !m_xContext.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ),
+ Reference< XInterface >() );
+ }
+
+ Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
+ m_xSFA = Reference< ucb::XSimpleFileAccess >(
+ xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
+ m_xContext ), UNO_QUERY_THROW );
+
+ m_bUserPackagesLoaded = false;
+ m_bSharedPackagesLoaded = false;
+ m_iUserPackage = 0;
+ m_iSharedPackage = 0;
+}
+
+Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage
+ ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle )
+{
+ o_xParentPackageBundle.clear();
+
+ Reference< deployment::XPackage > xHelpPackage;
+ if( !xPackage.is() )
+ return xHelpPackage;
+
+ // #i84550 Cache information about help content in extension
+ rtl::OUString aExtensionPath = xPackage->getURL();
+ ExtensionHelpExistanceMap::iterator it = aHelpExistanceMap.find( aExtensionPath );
+ bool bFound = ( it != aHelpExistanceMap.end() );
+ bool bHasHelp = bFound ? it->second : false;
+ if( bFound && !bHasHelp )
+ return xHelpPackage;
+
+ // Check if parent package is registered
+ beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
+ ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
+ bool bRegistered = false;
+ if( option.IsPresent )
+ {
+ beans::Ambiguous<sal_Bool> const & reg = option.Value;
+ if( !reg.IsAmbiguous && reg.Value )
+ bRegistered = true;
+ }
+ if( bRegistered )
+ {
+ if( xPackage->isBundle() )
+ {
+ Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
+ ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
+ sal_Int32 nPkgCount = aPkgSeq.getLength();
+ const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
+ for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
+ {
+ const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
+ const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
+ rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
+ if( aMediaType.equals( aHelpMediaType ) )
+ {
+ xHelpPackage = xSubPkg;
+ o_xParentPackageBundle = xPackage;
+ break;
+ }
+ }
+ }
+ else
+ {
+ const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
+ rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
+ if( aMediaType.equals( aHelpMediaType ) )
+ xHelpPackage = xPackage;
+ }
+ }
+
+ if( !bFound )
+ aHelpExistanceMap[ aExtensionPath ] = xHelpPackage.is();
+
+ return xHelpPackage;
+}
+
+Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage
+ ( Reference< deployment::XPackage >& o_xParentPackageBundle )
+{
+ Reference< deployment::XPackage > xHelpPackage;
+
+ if( !m_bUserPackagesLoaded )
+ {
+ Reference< XPackageManager > xUserManager =
+ thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") );
+ m_aUserPackagesSeq = xUserManager->getDeployedPackages
+ ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
+
+ m_bUserPackagesLoaded = true;
+ }
+
+ if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
+ {
+ m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE
+ }
+ else
+ {
+ const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
+ Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ];
+ VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" );
+ xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
+ }
+
+ return xHelpPackage;
+}
+
+Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage
+ ( Reference< deployment::XPackage >& o_xParentPackageBundle )
+{
+ Reference< deployment::XPackage > xHelpPackage;
+
+ if( !m_bSharedPackagesLoaded )
+ {
+ Reference< XPackageManager > xSharedManager =
+ thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") );
+ m_aSharedPackagesSeq = xSharedManager->getDeployedPackages
+ ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
+
+ m_bSharedPackagesLoaded = true;
+ }
+
+ if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
+ {
+ m_eState = END_REACHED;
+ }
+ else
+ {
+ const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
+ Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ];
+ VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" );
+ xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle );
+ }
+
+ return xHelpPackage;
+}
+
+rtl::OUString ExtensionIteratorBase::implGetFileFromPackage(
+ const rtl::OUString& rFileExtension, Reference< deployment::XPackage > xPackage )
+{
+ // No extension -> search for pure language folder
+ bool bLangFolderOnly = (rFileExtension.getLength() == 0);
+
+ rtl::OUString aFile;
+ rtl::OUString aLanguage = m_aLanguage;
+ for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass )
+ {
+ rtl::OUStringBuffer aStrBuf;
+ aStrBuf.append( xPackage->getURL() );
+ aStrBuf.append( aSlash );
+ aStrBuf.append( aLanguage );
+ if( !bLangFolderOnly )
+ {
+ aStrBuf.append( aSlash );
+ aStrBuf.append( aHelpFilesBaseName );
+ aStrBuf.append( rFileExtension );
+ }
+
+ aFile = m_rDatabases.expandURL( aStrBuf.makeStringAndClear() );
+ if( iPass == 0 )
+ {
+ if( m_xSFA->exists( aFile ) )
+ break;
+
+ ::std::vector< ::rtl::OUString > av;
+ implGetLanguageVectorFromPackage( av, xPackage );
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
+ try
+ {
+ pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
+ }
+ catch( ::comphelper::Locale::MalFormedLocaleException& )
+ {}
+ if( pFound != av.end() )
+ aLanguage = *pFound;
+ }
+ }
+ return aFile;
+}
+
+inline bool isLetter( sal_Unicode c )
+{
+ bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+ return bLetter;
+}
+
+void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv,
+ com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage )
+{
+ rv.clear();
+ rtl::OUString aExtensionPath = xPackage->getURL();
+ Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true );
+
+ const rtl::OUString* pSeq = aEntrySeq.getConstArray();
+ sal_Int32 nCount = aEntrySeq.getLength();
+ for( sal_Int32 i = 0 ; i < nCount ; ++i )
+ {
+ rtl::OUString aEntry = pSeq[i];
+ if( m_xSFA->isFolder( aEntry ) )
+ {
+ sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ {
+ rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 );
+
+ // Check language sceme
+ int nLen = aPureEntry.getLength();
+ const sal_Unicode* pc = aPureEntry.getStr();
+ bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) );
+ bool bIsLanguage = bStartCanBeLanguage &&
+ ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) );
+ if( bIsLanguage )
+ rv.push_back( aPureEntry );
+ }
+ }
+ }
+}
+
+
+//===================================================================
+// class DataBaseIterator
+
+Db* DataBaseIterator::nextDb( rtl::OUString* o_pExtensionPath )
+{
+ Db* pRetDb = NULL;
+
+ while( !pRetDb && m_eState != END_REACHED )
+ {
+ switch( m_eState )
+ {
+ case INITIAL_MODULE:
+ pRetDb = m_rDatabases.getBerkeley( m_aInitialModule, m_aLanguage, m_bHelpText );
+ m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
+ break;
+
+ // Later:
+ //case SHARED_MODULE
+ //...
+
+ case USER_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xParentPackageBundle;
+ Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+ pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath );
+ break;
+ }
+
+ case SHARED_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xParentPackageBundle;
+ Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath );
+ break;
+ }
+ case END_REACHED:
+ VOS_ENSURE( false, "DataBaseIterator::nextDb(): Invalid case END_REACHED" );
+ break;
+ }
+ }
+
+ return pRetDb;
+}
+
+Db* DataBaseIterator::implGetDbFromPackage( Reference< deployment::XPackage > xPackage,
+ rtl::OUString* o_pExtensionPath )
+{
+ rtl::OUString aExtensionPath = xPackage->getURL();
+ //if( o_pExtensionPath )
+ //*o_pExtensionPath = aExtensionPath;
+ aExtensionPath += aSlash;
+
+ rtl::OUString aUsedLanguage = m_aLanguage;
+ Db* pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage,
+ m_bHelpText, &aExtensionPath );
+
+ // Language fallback
+ if( !pRetDb )
+ {
+ ::std::vector< ::rtl::OUString > av;
+ implGetLanguageVectorFromPackage( av, xPackage );
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end();
+ try
+ {
+ pFound = ::comphelper::Locale::getFallback( av, m_aLanguage );
+ }
+ catch( ::comphelper::Locale::MalFormedLocaleException& )
+ {}
+ if( pFound != av.end() )
+ {
+ aUsedLanguage = *pFound;
+ pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aExtensionPath );
+ }
+ }
+
+ if( o_pExtensionPath )
+ *o_pExtensionPath = aExtensionPath + aUsedLanguage;
+
+ return pRetDb;
+}
+
+
+//===================================================================
+// class KeyDataBaseFileIterator
+
+rtl::OUString KeyDataBaseFileIterator::nextDbFile( bool& o_rbExtension )
+{
+ rtl::OUString aRetFile;
+
+ while( !aRetFile.getLength() && m_eState != END_REACHED )
+ {
+ switch( m_eState )
+ {
+ case INITIAL_MODULE:
+ aRetFile =
+ m_rDatabases.getInstallPathAsSystemPath() +
+ m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule +
+ rtl::OUString::createFromAscii( ".key" );
+
+ o_rbExtension = false;
+
+ m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
+ break;
+
+ // Later:
+ //case SHARED_MODULE
+ //...
+
+ case USER_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xParentPackageBundle;
+ Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ aRetFile = implGetDbFileFromPackage( xHelpPackage );
+ o_rbExtension = true;
+ break;
+ }
+
+ case SHARED_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xParentPackageBundle;
+ Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ aRetFile = implGetDbFileFromPackage( xHelpPackage );
+ o_rbExtension = true;
+ break;
+ }
+ case END_REACHED:
+ VOS_ENSURE( false, "DataBaseIterator::nextDbFile(): Invalid case END_REACHED" );
+ break;
+ }
+ }
+
+ return aRetFile;
+}
+
+rtl::OUString KeyDataBaseFileIterator::implGetDbFileFromPackage
+ ( Reference< deployment::XPackage > xPackage )
+{
+ rtl::OUString aExpandedURL =
+ implGetFileFromPackage( rtl::OUString::createFromAscii( ".key" ), xPackage );
+
+ rtl::OUString aRetFile;
+ osl::FileBase::getSystemPathFromFileURL( aExpandedURL, aRetFile );
+
+ return aRetFile;
+}
+
+
+//===================================================================
+// class JarFileIterator
+
+Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile
+ ( Reference< deployment::XPackage >& o_xParentPackageBundle, rtl::OUString* o_pExtensionPath )
+{
+ Reference< XHierarchicalNameAccess > xNA;
+
+ while( !xNA.is() && m_eState != END_REACHED )
+ {
+ switch( m_eState )
+ {
+ case INITIAL_MODULE:
+ xNA = m_rDatabases.jarFile( m_aInitialModule, m_aLanguage );
+ m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
+ break;
+
+ // Later:
+ //case SHARED_MODULE
+ //...
+
+ case USER_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( o_xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath );
+ break;
+ }
+
+ case SHARED_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( o_xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath );
+ break;
+ }
+ case END_REACHED:
+ VOS_ENSURE( false, "JarFileIterator::nextJarFile(): Invalid case END_REACHED" );
+ break;
+ }
+ }
+
+ return xNA;
+}
+
+Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage
+ ( Reference< deployment::XPackage > xPackage, rtl::OUString* o_pExtensionPath )
+{
+ Reference< XHierarchicalNameAccess > xNA;
+
+ rtl::OUString zipFile =
+ implGetFileFromPackage( rtl::OUString::createFromAscii( ".jar" ), xPackage );
+
+ try
+ {
+ Sequence< Any > aArguments( 2 );
+ aArguments[ 0 ] <<= zipFile;
+
+ // let ZipPackage be used ( no manifest.xml is required )
+ beans::NamedValue aArg;
+ aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
+ aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
+ aArguments[ 1 ] <<= aArg;
+
+ Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
+ Reference< XInterface > xIfc
+ = xSMgr->createInstanceWithArgumentsAndContext(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.packages.comp.ZipPackage" ),
+ aArguments, m_xContext );
+
+ if ( xIfc.is() )
+ {
+ xNA = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY );
+
+ VOS_ENSURE( xNA.is(),
+ "JarFileIterator::implGetJarFromPackage() - "
+ "Got no hierarchical name access!" );
+ }
+ }
+ catch ( RuntimeException & )
+ {}
+ catch ( Exception & )
+ {}
+
+ if( xNA.is() && o_pExtensionPath != NULL )
+ {
+ // Extract path including language from file name
+ sal_Int32 nLastSlash = zipFile.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ *o_pExtensionPath = zipFile.copy( 0, nLastSlash );
+ }
+
+ return xNA;
+}
+
+
+//===================================================================
+// class IndexFolderIterator
+
+rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary )
+{
+ rtl::OUString aIndexFolder;
+
+ while( !aIndexFolder.getLength() && m_eState != END_REACHED )
+ {
+ switch( m_eState )
+ {
+ case INITIAL_MODULE:
+ aIndexFolder =
+ m_rDatabases.getInstallPathAsURL() +
+ m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule +
+ rtl::OUString::createFromAscii( ".idxl" );
+
+ o_rbTemporary = false;
+ o_rbExtension = false;
+
+ m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE
+ break;
+
+ // Later:
+ //case SHARED_MODULE
+ //...
+
+ case USER_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xParentPackageBundle;
+ Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
+ o_rbExtension = true;
+ break;
+ }
+
+ case SHARED_EXTENSIONS:
+ {
+ Reference< deployment::XPackage > xParentPackageBundle;
+ Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle );
+ if( !xHelpPackage.is() )
+ break;
+
+ aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage );
+ o_rbExtension = true;
+ break;
+ }
+ case END_REACHED:
+ VOS_ENSURE( false, "IndexFolderIterator::nextIndexFolder(): Invalid case END_REACHED" );
+ break;
+ }
+ }
+
+ return aIndexFolder;
+}
+
+rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( bool& o_rbTemporary, Reference< deployment::XPackage > xPackage )
+{
+ rtl::OUString aIndexFolder =
+ implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage );
+
+ o_rbTemporary = false;
+ if( !m_xSFA->isFolder( aIndexFolder ) )
+ {
+ // i98680: Missing index? Try to generate now
+ rtl::OUString aLangURL = implGetFileFromPackage( rtl::OUString(), xPackage );
+ if( m_xSFA->isFolder( aLangURL ) )
+ {
+ // Test write access (shared extension may be read only)
+ bool bIsWriteAccess = false;
+ try
+ {
+ rtl::OUString aCreateTestFolder = aLangURL + rtl::OUString::createFromAscii( "CreateTestFolder" );
+ m_xSFA->createFolder( aCreateTestFolder );
+ if( m_xSFA->isFolder( aCreateTestFolder ) )
+ bIsWriteAccess = true;
+
+ m_xSFA->kill( aCreateTestFolder );
+ }
+ catch (Exception &)
+ {}
+
+ // TEST
+ //bIsWriteAccess = false;
+
+ Reference< script::XInvocation > xInvocation;
+ Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
+ try
+ {
+ xInvocation = Reference< script::XInvocation >(
+ m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.help.HelpIndexer" ), m_xContext ) , UNO_QUERY );
+
+ if( xInvocation.is() )
+ {
+ Sequence<uno::Any> aParamsSeq( bIsWriteAccess ? 6 : 8 );
+
+ 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" ) );
+
+ rtl::OUString aZipDir = aLangURL;
+ if( !bIsWriteAccess )
+ {
+ rtl::OUString aTempFileURL;
+ ::osl::FileBase::RC eErr = ::osl::File::createTempFile( 0, 0, &aTempFileURL );
+ if( eErr == ::osl::FileBase::E_None )
+ {
+ rtl::OUString aTempDirURL = aTempFileURL;
+ try
+ {
+ m_xSFA->kill( aTempDirURL );
+ }
+ catch (Exception &)
+ {}
+ m_xSFA->createFolder( aTempDirURL );
+
+ aZipDir = aTempDirURL;
+ o_rbTemporary = true;
+ }
+ }
+
+ aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) );
+ rtl::OUString aSystemPath;
+ osl::FileBase::getSystemPathFromFileURL( aZipDir, aSystemPath );
+ aParamsSeq[5] = uno::makeAny( aSystemPath );
+
+ if( !bIsWriteAccess )
+ {
+ aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-srcdir" ) );
+ rtl::OUString aSrcDirVal;
+ osl::FileBase::getSystemPathFromFileURL( aLangURL, aSrcDirVal );
+ aParamsSeq[7] = uno::makeAny( aSrcDirVal );
+ }
+
+ Sequence< sal_Int16 > aOutParamIndex;
+ Sequence< uno::Any > aOutParam;
+ uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ),
+ aParamsSeq, aOutParamIndex, aOutParam );
+
+ if( bIsWriteAccess )
+ aIndexFolder = implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage );
+ else
+ aIndexFolder = aZipDir + rtl::OUString::createFromAscii( "/help.idxl" );
+ }
+ }
+ catch (Exception &)
+ {}
+ }
+ }
+
+ return aIndexFolder;
+}
+
+void IndexFolderIterator::deleteTempIndexFolder( const rtl::OUString& aIndexFolder )
+{
+ sal_Int32 nLastSlash = aIndexFolder.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ {
+ rtl::OUString aTmpFolder = aIndexFolder.copy( 0, nLastSlash );
+ try
+ {
+ m_xSFA->kill( aTmpFolder );
+ }
+ catch (Exception &)
+ {}
+ }
+}
diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx index e0d5c9697dad..de1c5396f674 100644 --- a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx +++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx @@ -749,8 +749,8 @@ fileMatch(const char * URI) { } static int -pkgMatch(const char * URI) { - if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.pkg:/", 18)) +zipMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18)) return 1; return 0; } @@ -770,7 +770,7 @@ fileOpen(const char *URI) { } static void * -pkgOpen(const char * /*URI*/) { +zipOpen(const char * /*URI*/) { rtl::OUString language,jar,path; if( ugblData->m_pInitial->get_eid().getLength() ) @@ -855,7 +855,7 @@ helpRead(void * context, char * buffer, int len) { } static int -pkgRead(void * context, char * buffer, int len) { +zipRead(void * context, char * buffer, int len) { if( ugblData->m_pInitial->get_eid().getLength() ) { ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len); @@ -1080,7 +1080,7 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, ugblData = &userData; - xmlRegisterInputCallbacks(pkgMatch, pkgOpen, pkgRead, uriClose); + xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose); xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose); xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose); //xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction ); @@ -1088,7 +1088,7 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, xsltStylesheetPtr cur = xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr()); - xmlDocPtr doc = xmlParseFile("vnd.sun.star.pkg:/"); + xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/"); xmlDocPtr res = xsltApplyStylesheet(cur, doc, parameter); if (res) @@ -1101,7 +1101,7 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, } xmlPopInputCallbacks(); //filePatch xmlPopInputCallbacks(); //helpPatch - xmlPopInputCallbacks(); //pkgMatch + xmlPopInputCallbacks(); //zipMatch xmlFreeDoc(res); xmlFreeDoc(doc); xsltFreeStylesheet(cur); |