1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir 
29*cdf0e10cSrcweir #include "HelpCompiler.hxx"
30*cdf0e10cSrcweir #include <limits.h>
31*cdf0e10cSrcweir #include <stdlib.h>
32*cdf0e10cSrcweir #include <string.h>
33*cdf0e10cSrcweir #include <libxslt/xslt.h>
34*cdf0e10cSrcweir #include <libxslt/xsltInternals.h>
35*cdf0e10cSrcweir #include <libxslt/transform.h>
36*cdf0e10cSrcweir #include <libxslt/xsltutils.h>
37*cdf0e10cSrcweir #ifdef __MINGW32__
38*cdf0e10cSrcweir #include <tools/prewin.h>
39*cdf0e10cSrcweir #include <tools/postwin.h>
40*cdf0e10cSrcweir #endif
41*cdf0e10cSrcweir #include <osl/thread.hxx>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir static void impl_sleep( sal_uInt32 nSec )
44*cdf0e10cSrcweir {
45*cdf0e10cSrcweir     TimeValue aTime;
46*cdf0e10cSrcweir     aTime.Seconds = nSec;
47*cdf0e10cSrcweir     aTime.Nanosec = 0;
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir     osl::Thread::wait( aTime );
50*cdf0e10cSrcweir }
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir HelpCompiler::HelpCompiler(StreamTable &in_streamTable, const fs::path &in_inputFile,
53*cdf0e10cSrcweir     const fs::path &in_src, const fs::path &in_resEmbStylesheet,
54*cdf0e10cSrcweir     const std::string &in_module, const std::string &in_lang, bool in_bExtensionMode)
55*cdf0e10cSrcweir     : streamTable(in_streamTable), inputFile(in_inputFile),
56*cdf0e10cSrcweir     src(in_src), module(in_module), lang(in_lang), resEmbStylesheet(in_resEmbStylesheet),
57*cdf0e10cSrcweir 	bExtensionMode( in_bExtensionMode )
58*cdf0e10cSrcweir {
59*cdf0e10cSrcweir     xmlKeepBlanksDefaultValue = 0;
60*cdf0e10cSrcweir }
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir xmlDocPtr HelpCompiler::getSourceDocument(const fs::path &filePath)
63*cdf0e10cSrcweir {
64*cdf0e10cSrcweir     static const char *params[4 + 1];
65*cdf0e10cSrcweir     static xsltStylesheetPtr cur = NULL;
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir 	xmlDocPtr res;
68*cdf0e10cSrcweir 	if( bExtensionMode )
69*cdf0e10cSrcweir 	{
70*cdf0e10cSrcweir 		res = xmlParseFile(filePath.native_file_string().c_str());
71*cdf0e10cSrcweir         if( !res ){
72*cdf0e10cSrcweir             impl_sleep( 3 );
73*cdf0e10cSrcweir             res = xmlParseFile(filePath.native_file_string().c_str());
74*cdf0e10cSrcweir         }
75*cdf0e10cSrcweir 	}
76*cdf0e10cSrcweir 	else
77*cdf0e10cSrcweir 	{
78*cdf0e10cSrcweir 		if (!cur)
79*cdf0e10cSrcweir 		{
80*cdf0e10cSrcweir 			static std::string fsroot('\'' + src.toUTF8() + '\'');
81*cdf0e10cSrcweir 			static std::string esclang('\'' + lang + '\'');
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir 			xmlSubstituteEntitiesDefault(1);
84*cdf0e10cSrcweir 			xmlLoadExtDtdDefaultValue = 1;
85*cdf0e10cSrcweir 			cur = xsltParseStylesheetFile((const xmlChar *)resEmbStylesheet.native_file_string().c_str());
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir 			int nbparams = 0;
88*cdf0e10cSrcweir 			params[nbparams++] = "Language";
89*cdf0e10cSrcweir 			params[nbparams++] = esclang.c_str();
90*cdf0e10cSrcweir 			params[nbparams++] = "fsroot";
91*cdf0e10cSrcweir 			params[nbparams++] = fsroot.c_str();
92*cdf0e10cSrcweir 			params[nbparams] = NULL;
93*cdf0e10cSrcweir 		}
94*cdf0e10cSrcweir 		xmlDocPtr doc = xmlParseFile(filePath.native_file_string().c_str());
95*cdf0e10cSrcweir 		if( !doc )
96*cdf0e10cSrcweir         {
97*cdf0e10cSrcweir             impl_sleep( 3 );
98*cdf0e10cSrcweir             doc = xmlParseFile(filePath.native_file_string().c_str());
99*cdf0e10cSrcweir         }
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir 		//???res = xmlParseFile(filePath.native_file_string().c_str());
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir         res = xsltApplyStylesheet(cur, doc, params);
104*cdf0e10cSrcweir 		xmlFreeDoc(doc);
105*cdf0e10cSrcweir 	}
106*cdf0e10cSrcweir     return res;
107*cdf0e10cSrcweir }
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir HashSet HelpCompiler::switchFind(xmlDocPtr doc)
110*cdf0e10cSrcweir {
111*cdf0e10cSrcweir     HashSet hs;
112*cdf0e10cSrcweir     xmlChar *xpath = (xmlChar*)"//switchinline";
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir     xmlXPathContextPtr context = xmlXPathNewContext(doc);
115*cdf0e10cSrcweir     xmlXPathObjectPtr result = xmlXPathEvalExpression(xpath, context);
116*cdf0e10cSrcweir     xmlXPathFreeContext(context);
117*cdf0e10cSrcweir     if (result)
118*cdf0e10cSrcweir     {
119*cdf0e10cSrcweir         xmlNodeSetPtr nodeset = result->nodesetval;
120*cdf0e10cSrcweir         for (int i = 0; i < nodeset->nodeNr; i++)
121*cdf0e10cSrcweir         {
122*cdf0e10cSrcweir             xmlNodePtr el = nodeset->nodeTab[i];
123*cdf0e10cSrcweir             xmlChar *select = xmlGetProp(el, (xmlChar*)"select");
124*cdf0e10cSrcweir             if (select)
125*cdf0e10cSrcweir             {
126*cdf0e10cSrcweir                 if (!strcmp((const char*)select, "appl"))
127*cdf0e10cSrcweir                 {
128*cdf0e10cSrcweir                     xmlNodePtr n1 = el->xmlChildrenNode;
129*cdf0e10cSrcweir                     while (n1)
130*cdf0e10cSrcweir                     {
131*cdf0e10cSrcweir                         if ((!xmlStrcmp(n1->name, (const xmlChar*)"caseinline")))
132*cdf0e10cSrcweir                         {
133*cdf0e10cSrcweir                             xmlChar *appl = xmlGetProp(n1, (xmlChar*)"select");
134*cdf0e10cSrcweir                             hs.push_back(std::string((const char*)appl));
135*cdf0e10cSrcweir                             xmlFree(appl);
136*cdf0e10cSrcweir                         }
137*cdf0e10cSrcweir                         else if ((!xmlStrcmp(n1->name, (const xmlChar*)"defaultinline")))
138*cdf0e10cSrcweir                             hs.push_back(std::string("DEFAULT"));
139*cdf0e10cSrcweir                         n1 = n1->next;
140*cdf0e10cSrcweir                     }
141*cdf0e10cSrcweir                 }
142*cdf0e10cSrcweir                 xmlFree(select);
143*cdf0e10cSrcweir             }
144*cdf0e10cSrcweir         }
145*cdf0e10cSrcweir         xmlXPathFreeObject(result);
146*cdf0e10cSrcweir     }
147*cdf0e10cSrcweir     hs.push_back(std::string("DEFAULT"));
148*cdf0e10cSrcweir     return hs;
149*cdf0e10cSrcweir }
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir // returns a node representing the whole stuff compiled for the current
152*cdf0e10cSrcweir // application.
153*cdf0e10cSrcweir xmlNodePtr HelpCompiler::clone(xmlNodePtr node, const std::string& appl)
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir     xmlNodePtr parent = xmlCopyNode(node, 2);
156*cdf0e10cSrcweir     xmlNodePtr n = node->xmlChildrenNode;
157*cdf0e10cSrcweir     while (n != NULL)
158*cdf0e10cSrcweir     {
159*cdf0e10cSrcweir         bool isappl = false;
160*cdf0e10cSrcweir         if ( (!strcmp((const char*)n->name, "switchinline")) ||
161*cdf0e10cSrcweir              (!strcmp((const char*)n->name, "switch")) )
162*cdf0e10cSrcweir         {
163*cdf0e10cSrcweir             xmlChar *select = xmlGetProp(n, (xmlChar*)"select");
164*cdf0e10cSrcweir             if (select)
165*cdf0e10cSrcweir             {
166*cdf0e10cSrcweir                 if (!strcmp((const char*)select, "appl"))
167*cdf0e10cSrcweir                     isappl = true;
168*cdf0e10cSrcweir                 xmlFree(select);
169*cdf0e10cSrcweir             }
170*cdf0e10cSrcweir         }
171*cdf0e10cSrcweir         if (isappl)
172*cdf0e10cSrcweir         {
173*cdf0e10cSrcweir             xmlNodePtr caseNode = n->xmlChildrenNode;
174*cdf0e10cSrcweir             if (appl == "DEFAULT")
175*cdf0e10cSrcweir             {
176*cdf0e10cSrcweir                 while (caseNode)
177*cdf0e10cSrcweir                 {
178*cdf0e10cSrcweir                     if (!strcmp((const char*)caseNode->name, "defaultinline"))
179*cdf0e10cSrcweir                     {
180*cdf0e10cSrcweir                         xmlNodePtr cnl = caseNode->xmlChildrenNode;
181*cdf0e10cSrcweir                         while (cnl)
182*cdf0e10cSrcweir                         {
183*cdf0e10cSrcweir                             xmlAddChild(parent, clone(cnl, appl));
184*cdf0e10cSrcweir                             cnl = cnl->next;
185*cdf0e10cSrcweir                         }
186*cdf0e10cSrcweir                         break;
187*cdf0e10cSrcweir                     }
188*cdf0e10cSrcweir                     caseNode = caseNode->next;
189*cdf0e10cSrcweir                 }
190*cdf0e10cSrcweir             }
191*cdf0e10cSrcweir             else
192*cdf0e10cSrcweir             {
193*cdf0e10cSrcweir                 while (caseNode)
194*cdf0e10cSrcweir                 {
195*cdf0e10cSrcweir                     isappl=false;
196*cdf0e10cSrcweir                     if (!strcmp((const char*)caseNode->name, "caseinline"))
197*cdf0e10cSrcweir                     {
198*cdf0e10cSrcweir                         xmlChar *select = xmlGetProp(n, (xmlChar*)"select");
199*cdf0e10cSrcweir                         if (select)
200*cdf0e10cSrcweir                         {
201*cdf0e10cSrcweir                             if (!strcmp((const char*)select, appl.c_str()))
202*cdf0e10cSrcweir                                 isappl = true;
203*cdf0e10cSrcweir                             xmlFree(select);
204*cdf0e10cSrcweir                         }
205*cdf0e10cSrcweir                         if (isappl)
206*cdf0e10cSrcweir                         {
207*cdf0e10cSrcweir                             xmlNodePtr cnl = caseNode->xmlChildrenNode;
208*cdf0e10cSrcweir                             while (cnl)
209*cdf0e10cSrcweir                             {
210*cdf0e10cSrcweir                                 xmlAddChild(parent, clone(cnl, appl));
211*cdf0e10cSrcweir                                 cnl = cnl->next;
212*cdf0e10cSrcweir                             }
213*cdf0e10cSrcweir                             break;
214*cdf0e10cSrcweir                         }
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir                     }
217*cdf0e10cSrcweir                     caseNode = caseNode->next;
218*cdf0e10cSrcweir                 }
219*cdf0e10cSrcweir             }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir         }
222*cdf0e10cSrcweir         else
223*cdf0e10cSrcweir             xmlAddChild(parent, clone(n, appl));
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir         n = n->next;
226*cdf0e10cSrcweir     }
227*cdf0e10cSrcweir     return parent;
228*cdf0e10cSrcweir }
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir class myparser
231*cdf0e10cSrcweir {
232*cdf0e10cSrcweir public:
233*cdf0e10cSrcweir     std::string documentId;
234*cdf0e10cSrcweir     std::string fileName;
235*cdf0e10cSrcweir     std::string title;
236*cdf0e10cSrcweir     HashSet *hidlist;
237*cdf0e10cSrcweir     Hashtable *keywords;
238*cdf0e10cSrcweir     Stringtable *helptexts;
239*cdf0e10cSrcweir private:
240*cdf0e10cSrcweir     HashSet extendedHelpText;
241*cdf0e10cSrcweir public:
242*cdf0e10cSrcweir     myparser(const std::string &indocumentId, const std::string &infileName,
243*cdf0e10cSrcweir         const std::string &intitle) : documentId(indocumentId), fileName(infileName),
244*cdf0e10cSrcweir         title(intitle)
245*cdf0e10cSrcweir     {
246*cdf0e10cSrcweir         hidlist = new HashSet;
247*cdf0e10cSrcweir         keywords = new Hashtable;
248*cdf0e10cSrcweir         helptexts = new Stringtable;
249*cdf0e10cSrcweir     }
250*cdf0e10cSrcweir     void traverse( xmlNodePtr parentNode );
251*cdf0e10cSrcweir private:
252*cdf0e10cSrcweir     std::string dump(xmlNodePtr node);
253*cdf0e10cSrcweir };
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir std::string myparser::dump(xmlNodePtr node)
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     std::string app;
258*cdf0e10cSrcweir     if (node->xmlChildrenNode)
259*cdf0e10cSrcweir     {
260*cdf0e10cSrcweir         xmlNodePtr list = node->xmlChildrenNode;
261*cdf0e10cSrcweir         while (list)
262*cdf0e10cSrcweir         {
263*cdf0e10cSrcweir             app += dump(list);
264*cdf0e10cSrcweir             list = list->next;
265*cdf0e10cSrcweir         }
266*cdf0e10cSrcweir     }
267*cdf0e10cSrcweir     if (xmlNodeIsText(node))
268*cdf0e10cSrcweir     {
269*cdf0e10cSrcweir         xmlChar *pContent = xmlNodeGetContent(node);
270*cdf0e10cSrcweir         app += std::string((const char*)pContent);
271*cdf0e10cSrcweir         xmlFree(pContent);
272*cdf0e10cSrcweir         // std::cout << app << std::endl;
273*cdf0e10cSrcweir     }
274*cdf0e10cSrcweir     return app;
275*cdf0e10cSrcweir }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir void trim(std::string& str)
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir     std::string::size_type pos = str.find_last_not_of(' ');
280*cdf0e10cSrcweir     if(pos != std::string::npos)
281*cdf0e10cSrcweir     {
282*cdf0e10cSrcweir         str.erase(pos + 1);
283*cdf0e10cSrcweir         pos = str.find_first_not_of(' ');
284*cdf0e10cSrcweir         if(pos != std::string::npos)
285*cdf0e10cSrcweir             str.erase(0, pos);
286*cdf0e10cSrcweir     }
287*cdf0e10cSrcweir     else
288*cdf0e10cSrcweir         str.erase(str.begin(), str.end());
289*cdf0e10cSrcweir }
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir void myparser::traverse( xmlNodePtr parentNode )
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir     // traverse all nodes that belong to the parent
294*cdf0e10cSrcweir     xmlNodePtr test ;
295*cdf0e10cSrcweir     for (test = parentNode->xmlChildrenNode; test; test = test->next)
296*cdf0e10cSrcweir     {
297*cdf0e10cSrcweir         if (fileName.empty() && !strcmp((const char*)test->name, "filename"))
298*cdf0e10cSrcweir         {
299*cdf0e10cSrcweir             xmlNodePtr node = test->xmlChildrenNode;
300*cdf0e10cSrcweir             if (xmlNodeIsText(node))
301*cdf0e10cSrcweir             {
302*cdf0e10cSrcweir                 xmlChar *pContent = xmlNodeGetContent(node);
303*cdf0e10cSrcweir                 fileName = std::string((const char*)pContent);
304*cdf0e10cSrcweir                 xmlFree(pContent);
305*cdf0e10cSrcweir             }
306*cdf0e10cSrcweir         }
307*cdf0e10cSrcweir         else if (title.empty() && !strcmp((const char*)test->name, "title"))
308*cdf0e10cSrcweir         {
309*cdf0e10cSrcweir             title = dump(test);
310*cdf0e10cSrcweir             if (title.empty())
311*cdf0e10cSrcweir                 title = "<notitle>";
312*cdf0e10cSrcweir         }
313*cdf0e10cSrcweir         else if (!strcmp((const char*)test->name, "bookmark"))
314*cdf0e10cSrcweir         {
315*cdf0e10cSrcweir             xmlChar *branchxml = xmlGetProp(test, (const xmlChar*)"branch");
316*cdf0e10cSrcweir             xmlChar *idxml = xmlGetProp(test, (const xmlChar*)"id");
317*cdf0e10cSrcweir             std::string branch((const char*)branchxml);
318*cdf0e10cSrcweir             std::string anchor((const char*)idxml);
319*cdf0e10cSrcweir             xmlFree (branchxml);
320*cdf0e10cSrcweir             xmlFree (idxml);
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir             std::string hid;
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir             if (branch.find("hid") == 0)
325*cdf0e10cSrcweir             {
326*cdf0e10cSrcweir                 size_t index = branch.find('/');
327*cdf0e10cSrcweir                 if (index != std::string::npos)
328*cdf0e10cSrcweir                 {
329*cdf0e10cSrcweir                     hid = branch.substr(1 + index);
330*cdf0e10cSrcweir                     // one shall serve as a documentId
331*cdf0e10cSrcweir                     if (documentId.empty())
332*cdf0e10cSrcweir                         documentId = hid;
333*cdf0e10cSrcweir                     extendedHelpText.push_back(hid);
334*cdf0e10cSrcweir                     std::string foo = anchor.empty() ? hid : hid + "#" + anchor;
335*cdf0e10cSrcweir                     HCDBG(std::cerr << "hid pushback" << foo << std::endl);
336*cdf0e10cSrcweir                     hidlist->push_back( anchor.empty() ? hid : hid + "#" + anchor);
337*cdf0e10cSrcweir                 }
338*cdf0e10cSrcweir                 else
339*cdf0e10cSrcweir                     continue;
340*cdf0e10cSrcweir             }
341*cdf0e10cSrcweir             else if (branch.compare("index") == 0)
342*cdf0e10cSrcweir             {
343*cdf0e10cSrcweir                 LinkedList ll;
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir                 for (xmlNodePtr nd = test->xmlChildrenNode; nd; nd = nd->next)
346*cdf0e10cSrcweir                 {
347*cdf0e10cSrcweir                     if (strcmp((const char*)nd->name, "bookmark_value"))
348*cdf0e10cSrcweir                         continue;
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir                     std::string embedded;
351*cdf0e10cSrcweir                     xmlChar *embeddedxml = xmlGetProp(nd, (const xmlChar*)"embedded");
352*cdf0e10cSrcweir                     if (embeddedxml)
353*cdf0e10cSrcweir                     {
354*cdf0e10cSrcweir                         embedded = std::string((const char*)embeddedxml);
355*cdf0e10cSrcweir                         xmlFree (embeddedxml);
356*cdf0e10cSrcweir                         std::transform (embedded.begin(), embedded.end(),
357*cdf0e10cSrcweir                             embedded.begin(), tolower);
358*cdf0e10cSrcweir                     }
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir                     bool isEmbedded = !embedded.empty() && embedded.compare("true") == 0;
361*cdf0e10cSrcweir                     if (isEmbedded)
362*cdf0e10cSrcweir                         continue;
363*cdf0e10cSrcweir 
364*cdf0e10cSrcweir                     std::string keyword = dump(nd);
365*cdf0e10cSrcweir                     size_t keywordSem = keyword.find(';');
366*cdf0e10cSrcweir                     if (keywordSem != std::string::npos)
367*cdf0e10cSrcweir                     {
368*cdf0e10cSrcweir                         std::string tmppre =
369*cdf0e10cSrcweir                                     keyword.substr(0,keywordSem);
370*cdf0e10cSrcweir                         trim(tmppre);
371*cdf0e10cSrcweir                         std::string tmppos =
372*cdf0e10cSrcweir                                     keyword.substr(1+keywordSem);
373*cdf0e10cSrcweir                         trim(tmppos);
374*cdf0e10cSrcweir                         keyword = tmppre + ";" + tmppos;
375*cdf0e10cSrcweir                     }
376*cdf0e10cSrcweir                     ll.push_back(keyword);
377*cdf0e10cSrcweir                 }
378*cdf0e10cSrcweir                 if (!ll.empty())
379*cdf0e10cSrcweir                     (*keywords)[anchor] = ll;
380*cdf0e10cSrcweir             }
381*cdf0e10cSrcweir             else if (branch.compare("contents") == 0)
382*cdf0e10cSrcweir             {
383*cdf0e10cSrcweir                 // currently not used
384*cdf0e10cSrcweir             }
385*cdf0e10cSrcweir         }
386*cdf0e10cSrcweir         else if (!strcmp((const char*)test->name, "ahelp"))
387*cdf0e10cSrcweir         {
388*cdf0e10cSrcweir             std::string text = dump(test);
389*cdf0e10cSrcweir             trim(text);
390*cdf0e10cSrcweir             std::string name;
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir             HashSet::const_iterator aEnd = extendedHelpText.end();
393*cdf0e10cSrcweir             for (HashSet::const_iterator iter = extendedHelpText.begin(); iter != aEnd;
394*cdf0e10cSrcweir                 ++iter)
395*cdf0e10cSrcweir             {
396*cdf0e10cSrcweir                 name = *iter;
397*cdf0e10cSrcweir                 (*helptexts)[name] = text;
398*cdf0e10cSrcweir             }
399*cdf0e10cSrcweir             extendedHelpText.clear();
400*cdf0e10cSrcweir         }
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir         // traverse children
403*cdf0e10cSrcweir         traverse(test);
404*cdf0e10cSrcweir     }
405*cdf0e10cSrcweir }
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir bool HelpCompiler::compile( void ) throw( HelpProcessingException )
408*cdf0e10cSrcweir {
409*cdf0e10cSrcweir     // we now have the jaroutputstream, which will contain the document.
410*cdf0e10cSrcweir     // now determine the document as a dom tree in variable docResolved
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     xmlDocPtr docResolvedOrg = getSourceDocument(inputFile);
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir     // now add path to the document
415*cdf0e10cSrcweir     // resolve the dom
416*cdf0e10cSrcweir     if (!docResolvedOrg)
417*cdf0e10cSrcweir     {
418*cdf0e10cSrcweir         impl_sleep( 3 );
419*cdf0e10cSrcweir         docResolvedOrg = getSourceDocument(inputFile);
420*cdf0e10cSrcweir         if( !docResolvedOrg )
421*cdf0e10cSrcweir         {
422*cdf0e10cSrcweir             std::stringstream aStrStream;
423*cdf0e10cSrcweir             aStrStream << "ERROR: file not existing: " << inputFile.native_file_string().c_str() << std::endl;
424*cdf0e10cSrcweir 		    throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
425*cdf0e10cSrcweir         }
426*cdf0e10cSrcweir     }
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir     // now find all applications for which one has to compile
429*cdf0e10cSrcweir     std::string documentId;
430*cdf0e10cSrcweir     std::string fileName;
431*cdf0e10cSrcweir     std::string title;
432*cdf0e10cSrcweir     // returns all applications for which one has to compile
433*cdf0e10cSrcweir     HashSet applications = switchFind(docResolvedOrg);
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir     HashSet::const_iterator aEnd = applications.end();
436*cdf0e10cSrcweir     for (HashSet::const_iterator aI = applications.begin(); aI != aEnd; ++aI)
437*cdf0e10cSrcweir     {
438*cdf0e10cSrcweir         std::string appl = *aI;
439*cdf0e10cSrcweir         std::string modulename = appl;
440*cdf0e10cSrcweir         if (modulename[0] == 'S')
441*cdf0e10cSrcweir         {
442*cdf0e10cSrcweir             modulename = modulename.substr(1);
443*cdf0e10cSrcweir             std::transform(modulename.begin(), modulename.end(), modulename.begin(), tolower);
444*cdf0e10cSrcweir         }
445*cdf0e10cSrcweir         if (modulename != "DEFAULT" && modulename != module)
446*cdf0e10cSrcweir             continue;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir         // returns a clone of the document with swich-cases resolved
449*cdf0e10cSrcweir         xmlNodePtr docResolved = clone(xmlDocGetRootElement(docResolvedOrg), appl);
450*cdf0e10cSrcweir         myparser aparser(documentId, fileName, title);
451*cdf0e10cSrcweir         aparser.traverse(docResolved);
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir         documentId = aparser.documentId;
454*cdf0e10cSrcweir         fileName = aparser.fileName;
455*cdf0e10cSrcweir         title = aparser.title;
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir         HCDBG(std::cerr << documentId << " : " << fileName << " : " << title << std::endl);
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir         xmlDocPtr docResolvedDoc = xmlCopyDoc(docResolvedOrg, false);
460*cdf0e10cSrcweir         xmlDocSetRootElement(docResolvedDoc, docResolved);
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir         if (modulename == "DEFAULT")
463*cdf0e10cSrcweir         {
464*cdf0e10cSrcweir             streamTable.dropdefault();
465*cdf0e10cSrcweir             streamTable.default_doc = docResolvedDoc;
466*cdf0e10cSrcweir             streamTable.default_hidlist = aparser.hidlist;
467*cdf0e10cSrcweir             streamTable.default_helptexts = aparser.helptexts;
468*cdf0e10cSrcweir             streamTable.default_keywords = aparser.keywords;
469*cdf0e10cSrcweir         }
470*cdf0e10cSrcweir         else if (modulename == module)
471*cdf0e10cSrcweir         {
472*cdf0e10cSrcweir             streamTable.dropappl();
473*cdf0e10cSrcweir             streamTable.appl_doc = docResolvedDoc;
474*cdf0e10cSrcweir             streamTable.appl_hidlist = aparser.hidlist;
475*cdf0e10cSrcweir             streamTable.appl_helptexts = aparser.helptexts;
476*cdf0e10cSrcweir             streamTable.appl_keywords = aparser.keywords;
477*cdf0e10cSrcweir         }
478*cdf0e10cSrcweir         else
479*cdf0e10cSrcweir         {
480*cdf0e10cSrcweir 			std::stringstream aStrStream;
481*cdf0e10cSrcweir 	        aStrStream << "ERROR: Found unexpected module name \"" << modulename
482*cdf0e10cSrcweir 					   << "\" in file" << src.native_file_string().c_str() << std::endl;
483*cdf0e10cSrcweir 			throw HelpProcessingException( HELPPROCESSING_GENERAL_ERROR, aStrStream.str() );
484*cdf0e10cSrcweir         }
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     } // end iteration over all applications
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir     streamTable.document_id = documentId;
489*cdf0e10cSrcweir     streamTable.document_path = fileName;
490*cdf0e10cSrcweir     streamTable.document_title = title;
491*cdf0e10cSrcweir     std::string actMod = module;
492*cdf0e10cSrcweir     if ( !bExtensionMode && !fileName.empty())
493*cdf0e10cSrcweir     {
494*cdf0e10cSrcweir         if (fileName.find("/text/") == 0)
495*cdf0e10cSrcweir         {
496*cdf0e10cSrcweir             int len = strlen("/text/");
497*cdf0e10cSrcweir             actMod = fileName.substr(len);
498*cdf0e10cSrcweir             actMod = actMod.substr(0, actMod.find('/'));
499*cdf0e10cSrcweir         }
500*cdf0e10cSrcweir     }
501*cdf0e10cSrcweir     streamTable.document_module = actMod;
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir     xmlFreeDoc(docResolvedOrg);
504*cdf0e10cSrcweir     return true;
505*cdf0e10cSrcweir }
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir namespace fs
508*cdf0e10cSrcweir {
509*cdf0e10cSrcweir 	rtl_TextEncoding getThreadTextEncoding( void )
510*cdf0e10cSrcweir 	{
511*cdf0e10cSrcweir 		static bool bNeedsInit = true;
512*cdf0e10cSrcweir 		static rtl_TextEncoding nThreadTextEncoding;
513*cdf0e10cSrcweir 		if( bNeedsInit )
514*cdf0e10cSrcweir 		{
515*cdf0e10cSrcweir 			bNeedsInit = false;
516*cdf0e10cSrcweir 			nThreadTextEncoding = osl_getThreadTextEncoding();
517*cdf0e10cSrcweir 		}
518*cdf0e10cSrcweir 		return nThreadTextEncoding;
519*cdf0e10cSrcweir 	}
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir     void create_directory(const fs::path indexDirName)
522*cdf0e10cSrcweir     {
523*cdf0e10cSrcweir         HCDBG(
524*cdf0e10cSrcweir             std::cerr << "creating " <<
525*cdf0e10cSrcweir             rtl::OUStringToOString(indexDirName.data, RTL_TEXTENCODING_UTF8).getStr()
526*cdf0e10cSrcweir             << std::endl
527*cdf0e10cSrcweir            );
528*cdf0e10cSrcweir         osl::Directory::createPath(indexDirName.data);
529*cdf0e10cSrcweir     }
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir     void rename(const fs::path &src, const fs::path &dest)
532*cdf0e10cSrcweir     {
533*cdf0e10cSrcweir         osl::File::move(src.data, dest.data);
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir     void copy(const fs::path &src, const fs::path &dest)
537*cdf0e10cSrcweir     {
538*cdf0e10cSrcweir         osl::File::copy(src.data, dest.data);
539*cdf0e10cSrcweir     }
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir     bool exists(const fs::path &in)
542*cdf0e10cSrcweir     {
543*cdf0e10cSrcweir         osl::File tmp(in.data);
544*cdf0e10cSrcweir         return (tmp.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None);
545*cdf0e10cSrcweir     }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir     void remove(const fs::path &in)
548*cdf0e10cSrcweir     {
549*cdf0e10cSrcweir         osl::File::remove(in.data);
550*cdf0e10cSrcweir     }
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir     void removeRecursive(rtl::OUString const& _suDirURL)
553*cdf0e10cSrcweir     {
554*cdf0e10cSrcweir         {
555*cdf0e10cSrcweir             osl::Directory aDir(_suDirURL);
556*cdf0e10cSrcweir             aDir.open();
557*cdf0e10cSrcweir             if (aDir.isOpen())
558*cdf0e10cSrcweir             {
559*cdf0e10cSrcweir                 osl::DirectoryItem aItem;
560*cdf0e10cSrcweir                 osl::FileStatus aStatus(osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Attributes);
561*cdf0e10cSrcweir                 while (aDir.getNextItem(aItem) == ::osl::FileBase::E_None)
562*cdf0e10cSrcweir                 {
563*cdf0e10cSrcweir                     if (osl::FileBase::E_None == aItem.getFileStatus(aStatus) &&
564*cdf0e10cSrcweir                         aStatus.isValid(osl_FileStatus_Mask_FileName | osl_FileStatus_Mask_Attributes))
565*cdf0e10cSrcweir                     {
566*cdf0e10cSrcweir                         rtl::OUString suFilename = aStatus.getFileName();
567*cdf0e10cSrcweir                         rtl::OUString suFullFileURL;
568*cdf0e10cSrcweir                         suFullFileURL += _suDirURL;
569*cdf0e10cSrcweir                         suFullFileURL += rtl::OUString::createFromAscii("/");
570*cdf0e10cSrcweir                         suFullFileURL += suFilename;
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir                         if (aStatus.getFileType() == osl::FileStatus::Directory)
573*cdf0e10cSrcweir                             removeRecursive(suFullFileURL);
574*cdf0e10cSrcweir                         else
575*cdf0e10cSrcweir                             osl::File::remove(suFullFileURL);
576*cdf0e10cSrcweir                     }
577*cdf0e10cSrcweir                 }
578*cdf0e10cSrcweir                 aDir.close();
579*cdf0e10cSrcweir             }
580*cdf0e10cSrcweir         }
581*cdf0e10cSrcweir         osl::Directory::remove(_suDirURL);
582*cdf0e10cSrcweir     }
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir     void remove_all(const fs::path &in)
585*cdf0e10cSrcweir     {
586*cdf0e10cSrcweir         removeRecursive(in.data);
587*cdf0e10cSrcweir     }
588*cdf0e10cSrcweir }
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir /* vi:set tabstop=4 shiftwidth=4 expandtab: */
591