source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java@ 39009

Last change on this file since 39009 was 39009, checked in by kjdon, 5 weeks ago

added a comment

  • Property svn:keywords set to Author Date Id Revision
File size: 43.9 KB
Line 
1package org.greenstone.gsdl3.core;
2
3import java.io.File;
4import java.io.FileReader;
5import java.io.Serializable;
6import java.io.StringWriter;
7import java.util.ArrayList;
8import java.util.HashMap;
9import java.util.HashSet;
10import java.util.regex.Pattern;
11import java.util.regex.Matcher;
12
13import javax.xml.transform.Transformer;
14import javax.xml.transform.TransformerException;
15import javax.xml.transform.TransformerFactory;
16import javax.xml.transform.dom.DOMSource;
17import javax.xml.transform.stream.StreamResult;
18
19import org.apache.commons.lang3.StringUtils;
20import org.apache.log4j.Logger;
21import org.apache.xerces.parsers.DOMParser;
22import org.greenstone.gsdl3.action.Action;
23import org.greenstone.gsdl3.util.GSConstants;
24import org.greenstone.gsdl3.util.GSFile;
25import org.greenstone.gsdl3.util.GSParams;
26import org.greenstone.gsdl3.util.GSXML;
27import org.greenstone.gsdl3.util.GSXSLT;
28import org.greenstone.gsdl3.util.UserContext;
29import org.greenstone.gsdl3.util.XMLConverter;
30import org.greenstone.gsdl3.util.XMLTransformer;
31import org.greenstone.gsdl3.util.XSLTUtil;
32import org.greenstone.util.GlobalProperties;
33import org.w3c.dom.Comment;
34import org.w3c.dom.Document;
35import org.w3c.dom.Element;
36import org.w3c.dom.Node;
37import org.w3c.dom.NodeList;
38import org.w3c.dom.Text;
39import org.xml.sax.InputSource;
40
41/**
42 * A receptionist that uses xslt to transform the page_data before returning it.
43 * . Receives requests consisting of an xml representation of cgi args, and
44 * returns the page of data - in html by default. The requests are processed by
45 * the appropriate action class
46 *
47 * @see Action
48 */
49public class TransformingReceptionist extends Receptionist
50{
51 protected static final String EXPAND_GSF_FILE = "expand-gsf.xsl";
52 protected static final String EXPAND_GSF_PASS1_FILE = "expand-gsf-pass1.xsl";
53 protected static final String EXPAND_GSLIB_FILE = "expand-gslib.xsl";
54 protected static final String GSLIB_FILE = "gslib.xsl";
55
56 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.TransformingReceptionist.class.getName());
57
58 /** The expand-gslib.xsl file is in a fixed location */
59 static final String expand_gslib_filepath = GlobalProperties.getGSDL3Home() + File.separatorChar + "interfaces" + File.separatorChar + "core" + File.separatorChar + "transform" + File.separatorChar + EXPAND_GSLIB_FILE;
60
61 /** the list of xslt to use for actions */
62 protected HashMap<String, String> xslt_map = null;
63
64 /** a transformer class to transform xml using xslt */
65 protected XMLTransformer transformer = null;
66
67 protected TransformerFactory transformerFactory = null;
68 protected DOMParser parser = null;
69
70 protected HashMap<String, ArrayList<String>> _metadataRequiredMap = new HashMap<String, ArrayList<String>>();
71
72 boolean _debug = true;
73
74 public TransformingReceptionist()
75 {
76 super();
77 this.xslt_map = new HashMap<String, String>();
78 this.transformer = new XMLTransformer();
79 try
80 {
81 transformerFactory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
82 this.converter = new XMLConverter();
83 //transformerFactory.setURIResolver(new MyUriResolver()) ;
84
85 parser = new DOMParser();
86 parser.setFeature("http://xml.org/sax/features/validation", false);
87 // don't try and load external DTD - no need if we are not validating, and may cause connection errors if a proxy is not set up.
88 parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
89 // a performance test showed that having this on lead to increased
90 // memory use for small-medium docs, and not much gain for large
91 // docs.
92 // http://www.sosnoski.com/opensrc/xmlbench/conclusions.html
93 parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
94 parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
95 // setting a handler for when fatal errors, errors or warnings happen during xml parsing
96 // call XMLConverter's getParseErrorMessage() to get the errorstring that can be rendered as web page
97 this.parser.setErrorHandler(new XMLConverter.ParseErrorHandler());
98 }
99 catch (Exception e)
100 {
101 e.printStackTrace();
102 }
103 }
104
105 /** configures the receptionist - adding in setting up the xslt map */
106 public boolean configure()
107 {
108 if (!super.configure()) {
109
110 return false;
111 }
112
113 logger.info("configuring the TransformingReceptionist");
114
115 // find the config file containing a list of actions
116 File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.INTERFACE_NAME))));
117 Document config_doc = this.converter.getDOM(interface_config_file, "UTF-8");
118 Element config_elem = config_doc.getDocumentElement();
119
120 // Find the actions again so that we can set up the xslt map
121 Element action_list = (Element) GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM + GSXML.LIST_MODIFIER);
122 NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
123
124 for (int i = 0; i < actions.getLength(); i++)
125 {
126 Element action = (Element) actions.item(i);
127 String class_name = action.getAttribute("class");
128 String action_name = action.getAttribute("name");
129
130 // now do the xslt map
131 String xslt = action.getAttribute("xslt");
132 if (!xslt.equals(""))
133 {
134 this.xslt_map.put(action_name, xslt);
135 }
136 NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM);
137 for (int j = 0; j < subactions.getLength(); j++)
138 {
139 Element subaction = (Element) subactions.item(j);
140 String subname = subaction.getAttribute(GSXML.NAME_ATT);
141 String subxslt = subaction.getAttribute("xslt");
142
143 String map_key = action_name + ":" + subname;
144 logger.debug("adding in to xslt map, " + map_key + "->" + subxslt);
145 this.xslt_map.put(map_key, subxslt);
146 }
147 }
148
149 getRequiredMetadataNamesFromXSLFiles();
150
151 return true;
152 }
153
154 protected void getRequiredMetadataNamesFromXSLFiles()
155 {
156 ArrayList<File> xslFiles = GSFile.getAllXSLFiles((String) this.config_params.get(GSConstants.SITE_NAME));
157
158 HashMap<String, ArrayList<String>> includes = new HashMap<String, ArrayList<String>>();
159 HashMap<String, ArrayList<File>> files = new HashMap<String, ArrayList<File>>();
160 HashMap<String, ArrayList<String>> metaNames = new HashMap<String, ArrayList<String>>();
161
162 //First exploratory pass
163 for (File currentFile : xslFiles)
164 {
165
166 String full_filename = currentFile.getPath();
167 int sep_pos = full_filename.lastIndexOf(File.separator)+1;
168 String local_filename = full_filename.substring(sep_pos);
169 if (local_filename.startsWith(".")) {
170 logger.warn("Greenstone does not normally rely on 'dot' files for XSL transformations.\n Is the following file intended to be part of the digital library installation?\n XSL File being read in:\n " + currentFile.getPath());
171 }
172
173 Document currentDoc = this.converter.getDOM(currentFile);
174 if (currentDoc == null)
175 {
176 // Can happen if an editor creates an auto-save temporary file
177 // (such as #header.xsl#) that is not well formed XML
178 logger.warn("Skipping XSL file. DOM returned was null for:\n " + currentFile.getPath());
179 continue;
180 }
181
182 HashSet<String> extra_meta_names = new HashSet<String>();
183 GSXSLT.findExtraMetadataNames(currentDoc.getDocumentElement(), extra_meta_names);
184 ArrayList<String> names = new ArrayList<String>(extra_meta_names);
185
186 metaNames.put(currentFile.getAbsolutePath(), names);
187
188 NodeList includeElems = currentDoc.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "include");
189 NodeList importElems = currentDoc.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "import");
190
191
192 ArrayList<String> includeAndImportList = new ArrayList<String>();
193 for (int i = 0; i < includeElems.getLength(); i++)
194 {
195 includeAndImportList.add(((Element) includeElems.item(i)).getAttribute(GSXML.HREF_ATT));
196 }
197 for (int i = 0; i < importElems.getLength(); i++)
198 {
199 includeAndImportList.add(((Element) importElems.item(i)).getAttribute(GSXML.HREF_ATT));
200 }
201 includes.put(currentFile.getAbsolutePath(), includeAndImportList);
202
203 String filename = currentFile.getName();
204 if (files.get(filename) == null)
205 {
206 ArrayList<File> fileList = new ArrayList<File>();
207 fileList.add(currentFile);
208 files.put(currentFile.getName(), fileList);
209 }
210 else
211 {
212 ArrayList<File> fileList = files.get(filename);
213 fileList.add(currentFile);
214 }
215 }
216
217 //Second pass
218 for (File currentFile : xslFiles)
219 {
220 ArrayList<File> filesToGet = new ArrayList<File>();
221 filesToGet.add(currentFile);
222
223 ArrayList<String> fullNameList = new ArrayList<String>();
224
225 while (filesToGet.size() > 0)
226 {
227 File currentFileTemp = filesToGet.remove(0);
228
229 //Add the names from this file
230 ArrayList<String> currentNames = metaNames.get(currentFileTemp.getAbsolutePath());
231 if (currentNames == null)
232 {
233 continue;
234 }
235
236 fullNameList.addAll(currentNames);
237
238 ArrayList<String> includedHrefs = includes.get(currentFileTemp.getAbsolutePath());
239
240 for (String href : includedHrefs)
241 {
242 int lastSepIndex = href.lastIndexOf("/");
243 if (lastSepIndex != -1)
244 {
245 href = href.substring(lastSepIndex + 1);
246 }
247
248 ArrayList<File> filesToAdd = files.get(href);
249 if (filesToAdd != null)
250 {
251 filesToGet.addAll(filesToAdd);
252 }
253 }
254 }
255
256 _metadataRequiredMap.put(currentFile.getAbsolutePath(), fullNameList);
257 }
258 }
259
260 protected void preProcessRequest(Element request)
261 {
262 String action = request.getAttribute(GSXML.ACTION_ATT);
263 String subaction = request.getAttribute(GSXML.SUBACTION_ATT);
264
265 String name = null;
266 if (!subaction.equals(""))
267 {
268 String key = action + ":" + subaction;
269 name = this.xslt_map.get(key);
270 }
271 // try the action by itself
272 if (name == null)
273 {
274 name = this.xslt_map.get(action);
275 }
276
277 Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
278 String collection = "";
279
280 if (cgi_param_list != null)
281 {
282 // Don't waste time getting all the parameters
283 HashMap<String, Serializable> params = GSXML.extractParams(cgi_param_list, false);
284 collection = (String) params.get(GSParams.COLLECTION);
285 if (collection == null)
286 {
287 collection = "";
288 }
289 }
290
291 ArrayList<File> stylesheets = GSFile.getStylesheetFiles(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, name);
292
293 Document doc = XMLConverter.newDOM();
294 Element extraMetadataList = doc.createElement(GSXML.EXTRA_METADATA + GSXML.LIST_MODIFIER);
295 HashSet<String> name_set = new HashSet<String>();
296 for (File stylesheet : stylesheets)
297 {
298 ArrayList<String> requiredMetadata = _metadataRequiredMap.get(stylesheet.getAbsolutePath());
299
300 if (requiredMetadata != null)
301 {
302 for (String metadataString : requiredMetadata)
303 {
304 if (!name_set.contains(metadataString)) {
305 name_set.add(metadataString);
306 Element metadataElem = doc.createElement(GSXML.EXTRA_METADATA);
307 metadataElem.setAttribute(GSXML.NAME_ATT, metadataString);
308 extraMetadataList.appendChild(metadataElem);
309 }
310 }
311 }
312 }
313 request.appendChild(request.getOwnerDocument().importNode(extraMetadataList, true));
314 }
315
316 protected Node postProcessPage(Element page)
317 {
318 // might need to add some data to the page
319 addExtraInfo(page);
320
321
322 // transform the page using xslt
323
324 String currentInterface = (String) config_params.get(GSConstants.INTERFACE_NAME);
325
326 Element request = (Element) GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
327 String output = request.getAttribute(GSXML.OUTPUT_ATT);
328
329 boolean useClientXSLT = (Boolean) config_params.get(GSConstants.USE_CLIENT_SIDE_XSLT);
330 //logger.info("Client side transforms allowed? " + allowsClientXSLT);
331
332 if (useClientXSLT)
333 {
334 // if not specified, output defaults to 'html', but this isn't what we want when useClientXSLT is on
335 if (output.equals("html")) {
336 output = "xsltclient";
337 }
338 }
339 Node transformed_page = transformPage(page,currentInterface,output);
340
341 if (useClientXSLT) {
342 return transformed_page;
343 }
344 // if the user has specified they want only a part of the full page then subdivide it
345 boolean subdivide = false;
346 String excerptID = null;
347 String excerptIDText = null;
348 String excerptTag = null;
349 Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
350
351 // **** Now that the number of cases handled has risen to 3, the following would be worth refactoring ****
352 if (cgi_param_list != null)
353 {
354 HashMap<String, Serializable> params = GSXML.extractParams(cgi_param_list, false);
355 if ((excerptID = (String) params.get(GSParams.EXCERPT_ID)) != null)
356 {
357 subdivide = true;
358 }
359 if ((excerptIDText = (String) params.get(GSParams.EXCERPT_ID_TEXT)) != null)
360 {
361 subdivide = true;
362 }
363 if ((excerptTag = (String) params.get(GSParams.EXCERPT_TAG)) != null)
364 {
365 subdivide = true;
366 }
367 }
368
369 if (subdivide)
370 {
371 Node subdivided_page = subdivide(transformed_page, excerptID, excerptIDText, excerptTag);
372 if (subdivided_page != null)
373 {
374 return subdivided_page;
375 }
376 else return null;
377 }
378
379 return transformed_page;
380 }
381
382 protected Node subdivide(Node transformed_page, String excerptID, String excerptIDText, String excerptTag)
383 {
384 if (excerptID != null)
385 {
386 Node selectedElement = getNodeByIdRecursive(transformed_page, excerptID);
387 modifyNodesByTagRecursive(selectedElement, "a");
388 return selectedElement;
389 }
390 if (excerptIDText != null)
391 {
392 Node selectedElement = getNodeByIdRecursive(transformed_page, excerptIDText);
393
394 String selectedTextString = selectedElement.getTextContent();
395 Document forexcerptid_doc = XMLConverter.newDOM();
396 Node selectedElementChildTextNode = forexcerptid_doc.createTextNode(selectedTextString);
397
398 return selectedElementChildTextNode;
399 }
400 else if (excerptTag != null)
401 {
402 Node selectedElement = getNodeByTagRecursive(transformed_page, excerptTag);
403 return selectedElement;
404 }
405 return transformed_page;
406 }
407
408 protected Node getNodeByIdRecursive(Node parent, String id)
409 {
410 if (parent.hasAttributes() && ((Element) parent).getAttribute("id").equals(id))
411 {
412 return parent;
413 }
414
415 NodeList children = parent.getChildNodes();
416 for (int i = 0; i < children.getLength(); i++)
417 {
418 Node result = null;
419 if ((result = getNodeByIdRecursive(children.item(i), id)) != null)
420 {
421 return result;
422 }
423 }
424 return null;
425 }
426
427 protected Node getNodeByTagRecursive(Node parent, String tag)
428 {
429 if (parent.getNodeType() == Node.ELEMENT_NODE && ((Element) parent).getTagName().equals(tag))
430 {
431 return parent;
432 }
433
434 NodeList children = parent.getChildNodes();
435 for (int i = 0; i < children.getLength(); i++)
436 {
437 Node result = null;
438 if ((result = getNodeByTagRecursive(children.item(i), tag)) != null)
439 {
440 return result;
441 }
442 }
443 return null;
444 }
445
446 protected Node modifyNodesByTagRecursive(Node parent, String tag)
447 {
448 if (parent == null || (parent.getNodeType() == Node.ELEMENT_NODE && ((Element) parent).getTagName().equals(tag)))
449 {
450 return parent;
451 }
452
453 NodeList children = parent.getChildNodes();
454 for (int i = 0; i < children.getLength(); i++)
455 {
456 Node result = null;
457 if ((result = modifyNodesByTagRecursive(children.item(i), tag)) != null)
458 {
459 //TODO: DO SOMETHING HERE?
460 }
461 }
462 return null;
463 }
464
465 protected void replaceNodeWithInterfaceText(Document doc, String interface_name, String lang,
466 Element elem, String attr_name, String attr_val)
467 {
468 String pattern_str_3arg = "util:getInterfaceText\\([^,]+,[^,]+,\\s*'(.+?)'\\s*\\)";
469 String pattern_str_4arg = "util:getInterfaceText\\([^,]+,[^,]+,\\s*'(.+?)'\\s*,\\s*(.+?)\\s*\\)$";
470
471 Pattern pattern3 = Pattern.compile(pattern_str_3arg);
472 Matcher matcher3 = pattern3.matcher(attr_val);
473 if (matcher3.find()) {
474 String dict_key = matcher3.group(1);
475 String dict_val = XSLTUtil.getInterfaceText(interface_name,lang,dict_key);
476
477 Node parent_node = elem.getParentNode();
478
479 Text replacement_text_node = doc.createTextNode(dict_val);
480 parent_node.replaceChild(replacement_text_node,elem);
481 }
482 else {
483 Pattern pattern4 = Pattern.compile(pattern_str_4arg);
484 Matcher matcher4 = pattern4.matcher(attr_val);
485 StringBuffer string_buffer4 = new StringBuffer();
486
487 if (matcher4.find()) {
488 String dict_key = matcher4.group(1);
489 String args = matcher4.group(2);
490 args = args.replaceAll("\\$","\\\\\\$");
491
492 String dict_val = XSLTUtil.getInterfaceText(interface_name,lang,dict_key);
493
494 matcher4.appendReplacement(string_buffer4, "js:getInterfaceTextSubstituteArgs('"+dict_val+"',string("+args+"))");
495 matcher4.appendTail(string_buffer4);
496
497 attr_val = string_buffer4.toString();
498 elem.setAttribute(attr_name,attr_val);
499 }
500 else {
501 logger.error("Failed to find match in attribute: " + attr_name + "=\"" + attr_val + "\"");
502 attr_val = attr_val.replaceAll("util:getInterfaceText\\(.+?,.+?,\\s*(.+?)\\s*\\)","$1");
503 elem.setAttribute(attr_name,attr_val);
504 }
505 }
506
507 }
508
509 protected void resolveExtendedNamespaceAttributesXSLT(Document doc, String interface_name, String lang)
510 {
511 String[] attr_list = new String[] {"select","test"};
512
513 // http://stackoverflow.com/questions/13220520/javascript-replace-child-loop-issue
514 // go through nodeList in reverse to avoid the 'skipping' problem, due to
515 // replaceChild() calls removing items from the "live" nodeList
516
517 NodeList nodeList = doc.getElementsByTagName("*");
518 for (int i=nodeList.getLength()-1; i>=0; i--) {
519 Node node = nodeList.item(i);
520 if (node.getNodeType() == Node.ELEMENT_NODE) {
521 Element elem = (Element)node;
522 for (String attr_name : attr_list) {
523 if (elem.hasAttribute(attr_name)) {
524 String attr_val = elem.getAttribute(attr_name);
525
526 if (attr_val.startsWith("util:getInterfaceText(")) {
527 // replace the node with dictionary lookup
528 replaceNodeWithInterfaceText(doc, interface_name,lang, elem,attr_name,attr_val);
529 }
530 else if (attr_val.contains("util:")) {
531
532 attr_val = attr_val.replaceAll("util:getInterfaceStringsAsJavascript\\(.+?,.+?,\\s*(.+?)\\)","$1");
533
534 //attr_val = attr_val.replaceAll("util:escapeNewLinesAndQuotes\\(\\s*(.+?)\\s*\\)","'escapeNLandQ $1'");
535 //attr_val = attr_val.replaceAll("util:escapeNewLinesAndQuotes\\(\\s*(.+?)\\s*\\)","$1");
536
537 // 'contains()' supported in XSLT 1.0, so OK to change any util:contains() into contains()
538 attr_val = attr_val.replaceAll("util:(contains\\(.+?\\))","$1");
539
540 elem.setAttribute(attr_name,attr_val);
541 }
542
543 if (attr_val.contains("java:")) {
544 if (attr_val.indexOf("getInterfaceTextSubstituteArgs")>=4) {
545
546 attr_val = attr_val.replaceAll("java:.+?\\.(\\w+)\\((.*?)\\)$","js:$1($2)");
547 }
548
549 elem.setAttribute(attr_name,attr_val);
550 }
551 }
552 }
553
554 }
555 }
556 }
557
558
559 protected void resolveExtendedNamespaceAttributesXML(Document doc, String interface_name, String lang)
560 {
561 String[] attr_list = new String[] {"src", "href"};
562
563 // http://stackoverflow.com/questions/13220520/javascript-replace-child-loop-issue
564 // go through nodeList in reverse to avoid the 'skipping' problem, due to
565 // replaceChild() calls removing items from the "live" nodeList
566
567 NodeList nodeList = doc.getElementsByTagName("*");
568 for (int i=nodeList.getLength()-1; i>=0; i--) {
569 Node node = nodeList.item(i);
570 if (node.getNodeType() == Node.ELEMENT_NODE) {
571 Element elem = (Element)node;
572 for (String attr_name : attr_list) {
573 if (elem.hasAttribute(attr_name)) {
574 String attr_val = elem.getAttribute(attr_name);
575
576 if (attr_val.contains("util:getInterfaceText(")) {
577 String pattern_str_3arg = "util:getInterfaceText\\([^,]+,[^,]+,\\s*'(.+?)'\\s*\\)";
578 Pattern pattern3 = Pattern.compile(pattern_str_3arg);
579 Matcher matcher3 = pattern3.matcher(attr_val);
580
581 StringBuffer string_buffer3 = new StringBuffer();
582
583 boolean found_match = false;
584
585 while (matcher3.find()) {
586 found_match = true;
587 String dict_key = matcher3.group(1);
588 String dict_val = XSLTUtil.getInterfaceText(interface_name,lang,dict_key);
589
590 matcher3.appendReplacement(string_buffer3, dict_val);
591 }
592 matcher3.appendTail(string_buffer3);
593
594 if (found_match) {
595 attr_val = string_buffer3.toString();
596 elem.setAttribute(attr_name,attr_val);
597 }
598 else {
599 logger.error("Failed to find match in attribute: " + attr_name + "=\"" + attr_val + "\"");
600 attr_val = attr_val.replaceAll("util:getInterfaceText\\(.+?,.+?,\\s*(.+?)\\s*\\)","$1");
601 elem.setAttribute(attr_name,attr_val);
602 }
603 }
604 else if (attr_val.contains("util:")) {
605
606 logger.error("Encountered unexpected 'util:' prefix exension: " + attr_name + "=\"" + attr_val + "\"");
607 }
608
609 if (attr_val.contains("java:")) {
610 // make anything java: safe from the point of an XSLT without extensions
611 logger.error("Encountered unexpected 'java:' prefix exension: " + attr_name + "=\"" + attr_val + "\"");
612
613 }
614 }
615 }
616
617 }
618 }
619 }
620
621
622
623 /**
624 * overwrite this to add any extra info that might be needed in the page
625 * before transformation
626 */
627 protected void addExtraInfo(Element page)
628 {
629 }
630
631 /**
632 * transform the page using xslt.
633 * we need to get any format element out of the page and add it to the xslt before transforming
634 */
635 protected Node transformPage(Element page_xml, String currentInterface, String output)
636 {
637 _debug = false;
638
639 Element request = (Element) GSXML.getChildByTagName(page_xml, GSXML.PAGE_REQUEST_ELEM);
640
641 //logger.info("Current output mode is: " + output + ", current interface name is: " + currentInterface);
642
643 if (output.equals("xsltclient"))
644 {
645 return generateXSLTClientOutput(request);
646 }
647
648 String action = request.getAttribute(GSXML.ACTION_ATT);
649 String subaction = request.getAttribute(GSXML.SUBACTION_ATT);
650
651 // we should choose how to transform the data based on output, eg diff
652 // choice for html, and wml??
653 // for now, if output=xml, we don't transform the page, we just return
654 // the page xml
655 Document page_with_xslt_params_doc = null;
656
657 if (output.equals("xml") || (output.equals("json")) || output.equals("clientside"))
658 {
659 // Append the xsltparams to the page
660 page_with_xslt_params_doc = converter.newDOM();
661 // Import into new document first!
662 Node page_with_xslt_params = page_with_xslt_params_doc.importNode(page_xml, true);
663 page_with_xslt_params_doc.appendChild(page_with_xslt_params);
664 Element xslt_params = page_with_xslt_params_doc.createElement("xsltparams");
665 page_with_xslt_params.appendChild(xslt_params);
666
667 GSXML.addParameter2ToList(xslt_params, "library_name", (String) config_params.get(GSConstants.LIBRARY_NAME));
668 GSXML.addParameter2ToList(xslt_params, "interface_name", (String) config_params.get(GSConstants.INTERFACE_NAME));
669 GSXML.addParameter2ToList(xslt_params, "site_name", (String) config_params.get(GSConstants.SITE_NAME));
670 GSXML.addParameter2ToList(xslt_params, "cookie_consent", (String) config_params.get(GSConstants.COOKIE_CONSENT));
671 Boolean useClientXSLT = (Boolean) config_params.get(GSConstants.USE_CLIENT_SIDE_XSLT);
672 GSXML.addParameter2ToList(xslt_params, "use_client_side_xslt", useClientXSLT.toString());
673 GSXML.addParameter2ToList(xslt_params, "filepath", GlobalProperties.getGSDL3Home());
674
675 if ((output.equals("xml")) || output.equals("json"))
676 {
677 // Just return the page XML
678 // in the case of "json", calling method responsible for converting to JSON-string
679 return page_with_xslt_params_doc.getDocumentElement();
680 }
681 // in the case of client side, later on we'll use this doc with xslt params added,
682 // along with the xsl.
683 }
684
685 Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
686 String collection = "";
687 String inline_template = "";
688 if (cgi_param_list != null)
689 {
690 // Don't waste time getting all the parameters
691 HashMap<String, Serializable> params = GSXML.extractParams(cgi_param_list, false);
692 collection = (String) params.get(GSParams.COLLECTION);
693 if (collection == null)
694 {
695 collection = "";
696 }
697
698 inline_template = (String) params.get(GSParams.INLINE_TEMPLATE);
699 String debug_p = (String) params.get(GSParams.DEBUG);
700 if (debug_p != null && (debug_p.equals("on") || debug_p.equals("1") || debug_p.equals("true")))
701 {
702 String[] groups = new UserContext(request).getGroups();
703
704 boolean found = false;
705 for (String g : groups)
706 {
707 if (g.equals("administrator"))
708 {
709 found = true;
710 break;
711 }
712 if (!collection.equals("")) {
713 if (g.equals("all-collections-editor")) {
714 found = true;
715 break;
716 }
717
718 if (g.equals(collection+"-collection-editor")) {
719 found = true;
720 break;
721 }
722 }
723 }
724 if (found)
725 {
726 _debug = true;
727 }
728 }
729 }
730
731 config_params.put("collName", collection);
732
733 // find the appropriate stylesheet (based on action/subaction) - eg a=p&sa=home will be home.xsl
734 // This mapping is defined in interfaceConfig.xsl
735 // All versions of the stylesheet (base interface, interface, site, collection) are
736 // merged together into one document
737 Document page_xsl = getXSLTDocument(action, subaction, collection);
738 String page_xsl_filename = getXSLTFilename(action, subaction); // for debug purposes
739 if (page_xsl == null)
740 {
741 logger.error("Couldn't find and/or load the stylesheet ("+page_xsl_filename+") for a="+action+", sa="+subaction+", in collection="+collection);
742 return XMLTransformer.constructErrorXHTMLPage("Couldn't find and/or load the stylesheet \""+page_xsl_filename+"\" for a="+action+", sa="+subaction+", in collection="+collection);
743 }
744
745 if (output.equals("xsl1")) {
746 // if we just output the page_xsl directly then there may be unescaped & in the javascript,
747 // and the page won't display properly
748 return converter.getDOM(getStringFromDocument(page_xsl));
749 }
750
751
752 // put the page into a document - this is necessary for xslt to get
753 // the paths right if you have paths relative to the document root
754 // eg /page.
755 Document page_xml_doc = XMLConverter.newDOM();
756 page_xml_doc.appendChild(page_xml_doc.importNode(page_xml, true));
757 Element page_response = (Element) GSXML.getChildByTagName(page_xml, GSXML.PAGE_RESPONSE_ELEM);
758 Element format_elem = (Element) GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
759
760 if (output.equals("format1"))
761 {
762 return format_elem;
763 }
764
765 // do we have language attribute for page?
766 String lang_att = page_xml.getAttribute(GSXML.LANG_ATT);
767 if (lang_att != null && lang_att.length() > 0)
768 {
769 config_params.put("lang", lang_att);
770 }
771
772 if (format_elem != null)
773 {
774 //page_response.removeChild(format_elem);
775
776 // need to transform the format info
777 // run expand-gsf.xsl over the format_elem. We need to do this now to turn
778 // eg gsf:template into xsl:template so that the merging works properly.
779 // xsl:templates will get merged
780 // into the main stylesheet, but gsf:templates won't.
781
782 Document format_doc = XMLConverter.newDOM();
783 format_doc.appendChild(format_doc.importNode(format_elem, true));
784
785 if (_debug) {
786
787 String siteHome = GSFile.siteHome(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.SITE_NAME));
788 GSXSLT.insertDebugElements(format_doc, GSFile.collectionConfigFile(siteHome, collection));
789 }
790
791 // should we be doing the double pass here too?
792 Node result = transformGSFElements(collection, format_doc, EXPAND_GSF_FILE);
793 // Since we started creating documents with DocTypes, we can end up with
794 // Document objects here. But we will be working with an Element instead,
795 // so we grab the DocumentElement() of the Document object in such a case.
796 Element new_format;
797 if (result.getNodeType() == Node.DOCUMENT_NODE)
798 {
799 new_format = ((Document) result).getDocumentElement();
800 }
801 else
802 {
803 new_format = (Element) result;
804 }
805
806 if (output.equals("format"))
807 {
808 return new_format;
809 }
810
811 // add the extracted format statements in to the main stylesheet
812 if (_debug)
813 {
814 String siteHome = GSFile.siteHome(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.SITE_NAME));
815 GSXSLT.mergeStylesheetsDebug(page_xsl, new_format, true, true, "OTHER1", GSFile.collectionConfigFile(siteHome, collection));
816 }
817 else
818 {
819 GSXSLT.mergeStylesheets(page_xsl, new_format, true);
820 }
821
822
823 }
824
825 if (output.equals("xsl2")) {
826 return converter.getDOM(getStringFromDocument(page_xsl));
827 }
828
829 Document inline_template_doc = null;
830 if (inline_template != null)
831 {
832 try
833 {
834 inline_template_doc = this.converter.getDOM("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsl:stylesheet version=\"1.0\" "+GSXML.ALL_NAMESPACES_ATTS + ">" + inline_template + "</xsl:stylesheet>", "UTF-8");
835
836 if (_debug)
837 {
838 GSXSLT.mergeStylesheetsDebug(page_xsl, inline_template_doc.getDocumentElement(), true, true, "OTHER2", "INLINE");
839 }
840 else
841 {
842 //GSXSLT.mergeStylesheets(skinAndLibraryDoc, inlineTemplateDoc.getDocumentElement(), true);
843 GSXSLT.mergeStylesheets(page_xsl, inline_template_doc.getDocumentElement(), true);
844 }
845 }
846 catch (Exception ex)
847 {
848 ex.printStackTrace();
849 }
850 }
851
852
853 if (output.equals("ilt")) {
854 return converter.getDOM(getStringFromDocument(inline_template_doc));
855 }
856 if (output.equals("xsl3")) {
857 return converter.getDOM(getStringFromDocument(page_xsl));
858 }
859
860 // once we are here, have got the main page xsl loaded up. Have added in any format statements from the source xml, and added in any inline template which came through cgi params.
861
862 // next we load in the import and include files. - these, too, go through the inheritance cascade (base interface, interface, site, collection) before being added into the main document
863
864 if (_debug)
865 {
866 GSXSLT.inlineImportAndIncludeFilesDebug(page_xsl, null, _debug, page_xsl_filename, (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces);
867 }
868 else
869 {
870 GSXSLT.inlineImportAndIncludeFiles(page_xsl, null, (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces);
871
872 }
873
874 if (output.equals("xsl4")) {
875 return converter.getDOM(getStringFromDocument(page_xsl));
876 }
877
878 // The next step is to process the page_xsl + gslib_xsl by
879 // expand-gslib.xsl to expand all the gslib elements
880
881 Document expand_gslib_xsl_doc;
882 try
883 {
884 // interfaces/core/transform/expand-gslib.xsl
885 // this takes skinandLibraryXsl, copies skinXSL, merges elements of libraryXsl into it, and replaces gslib elements
886 expand_gslib_xsl_doc = getDoc(expand_gslib_filepath);
887 String errMsg = ((XMLConverter.ParseErrorHandler) parser.getErrorHandler()).getErrorMessage();
888 if (errMsg != null)
889 {
890 return XMLTransformer.constructErrorXHTMLPage("error loading file: " + expand_gslib_filepath + "\n" + errMsg);
891 }
892 }
893 catch (java.io.FileNotFoundException e)
894 {
895 return fileNotFoundErrorPage(e.getMessage());
896 }
897 catch (Exception e)
898 {
899 e.printStackTrace();
900 System.out.println("error loading "+expand_gslib_filepath);
901 return XMLTransformer.constructErrorXHTMLPage("Error loading file: "+ expand_gslib_filepath+"\n" + e.getMessage());
902 }
903
904 // gslib.xsl
905 Document gslib_xsl_doc = null;
906 try
907 {
908 gslib_xsl_doc = GSXSLT.mergedXSLTDocumentCascade(GSLIB_FILE, (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, _debug);
909 }
910 catch (Exception e)
911 {
912 e.printStackTrace();
913 System.out.println("error loading gslib xslt");
914 return XMLTransformer.constructErrorXHTMLPage("error loading gslib xslt\n" + e.getMessage());
915 }
916
917 if (output.equals("gslib-expander")) {
918 return converter.getDOM(getStringFromDocument(expand_gslib_xsl_doc));
919 }
920 if (output.equals("gslib1")) {
921 return converter.getDOM(getStringFromDocument(gslib_xsl_doc));
922 }
923 // Combine the skin file and library variables/templates into one document.
924 // Please note: We dont just use xsl:import because the preprocessing stage
925 // needs to know what's available in the library.
926
927
928 // add in all gslib.xsl's include and import files
929 // debug?? use debug method?? or does it not make sense here??
930 GSXSLT.inlineImportAndIncludeFiles(gslib_xsl_doc, null, (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces);
931 if (output.equals("gslib")) {
932 return converter.getDOM(getStringFromDocument(gslib_xsl_doc));
933 }
934
935 // if the page xsl or gslib xsl uses namespaces that are not listed in
936 // expand_gslib, then they will be ignored. So just check through and add
937 // any in that are missing.
938 GSXML.addMissingNamespaceAttributes(expand_gslib_xsl_doc.getDocumentElement(), page_xsl.getDocumentElement());
939 GSXML.addMissingNamespaceAttributes(expand_gslib_xsl_doc.getDocumentElement(), gslib_xsl_doc.getDocumentElement());
940
941 Document pageAndGslibXsl = null;
942 Document pageAndGslibDoc = converter.newDOM();
943
944 // now, we transform all the gslib elements
945 {
946
947
948 pageAndGslibXsl = converter.newDOM();
949 Element root = pageAndGslibXsl.createElement("pageAndGslibXsl");
950 pageAndGslibXsl.appendChild(root);
951
952 Element s = pageAndGslibXsl.createElement("pageXsl");
953 s.appendChild(pageAndGslibXsl.importNode(page_xsl.getDocumentElement(), true));
954 root.appendChild(s);
955
956 Element l = pageAndGslibXsl.createElement("gslibXsl");
957 if (gslib_xsl_doc != null)
958 {
959 Element gslib_xsl_el = gslib_xsl_doc.getDocumentElement();
960 l.appendChild(pageAndGslibXsl.importNode(gslib_xsl_el, true));
961 }
962 root.appendChild(l);
963
964 if (output.equals("xsl5")) {
965 return converter.getDOM(getStringFromDocument(pageAndGslibXsl));
966 }
967 // actually merge the gslib file with the page
968 // this is where we go from having pagexsl and gslibxsl nodes
969 // to a single proper stylesheet
970 XMLTransformer preProcessor = new XMLTransformer();
971 preProcessor.transform_withResultNode(expand_gslib_xsl_doc, pageAndGslibXsl, pageAndGslibDoc);
972 }
973 if (output.equals("xsl6")) {
974 return converter.getDOM(getStringFromDocument(pageAndGslibDoc));
975 }
976
977 pageAndGslibDoc = (Document) transformGSFElements(collection, pageAndGslibDoc, EXPAND_GSF_PASS1_FILE);
978
979 if (output.equals("xsl7")) {
980 return converter.getDOM(getStringFromDocument(pageAndGslibDoc));
981 }
982
983 pageAndGslibDoc = (Document) transformGSFElements(collection, pageAndGslibDoc, EXPAND_GSF_FILE);
984
985 if (output.equals("xsl") || output.equals("skinandlibdocfinal"))
986 {
987 return converter.getDOM(getStringFromDocument(pageAndGslibDoc));
988 }
989
990 if (output.equals("clientside"))
991 {
992
993 // Go through and 'fix up' any 'util:...' or 'java:...' attributes the pageAndGslibDoc has
994 String lang = (String)config_params.get("lang");
995 resolveExtendedNamespaceAttributesXSLT(pageAndGslibDoc,currentInterface,lang); // test= and select= attributes
996 resolveExtendedNamespaceAttributesXML(pageAndGslibDoc,currentInterface,lang); // href= and src= attributes
997 Node skinAndLibFinal = converter.getDOM(getStringFromDocument(pageAndGslibDoc));
998
999 // Send XML and skinandlibdoc down the line together
1000 Document finalDoc = converter.newDOM();
1001 Node finalDocSkin = finalDoc.importNode(pageAndGslibDoc.getDocumentElement(), true);
1002 Node finalDocXML = finalDoc.importNode(page_with_xslt_params_doc.getDocumentElement(), true);
1003 Element root = finalDoc.createElement("skinlibfinalPlusXML");
1004 root.appendChild(finalDocSkin);
1005 root.appendChild(finalDocXML);
1006 finalDoc.appendChild(root);
1007 return (Node) finalDoc.getDocumentElement();
1008 }
1009
1010 ///logger.debug("final xml is ");
1011 ///logger.debug(XMLConverter.getPrettyString(page_xml_doc));
1012
1013 ///logger.debug("final xsl is");
1014 ///logger.debug(XMLConverter.getPrettyString(pageAndGslibDoc));
1015
1016 // The transformer will now work out the resulting doctype from any set in the (merged) stylesheets and
1017 // will set this in the output document it creates. So don't pass in any docWithDocType to the transformer
1018
1019 // Here, we finally transform the page xml source with the complete xsl file
1020 Node finalResult = this.transformer.transform(pageAndGslibDoc, page_xml_doc, config_params);
1021
1022 if (_debug)
1023 {
1024 GSXSLT.fixTables((Document) finalResult);
1025 }
1026
1027 return finalResult;
1028
1029 }
1030
1031 protected Node generateXSLTClientOutput(Element request) {
1032
1033 // DocType defaults in case the skin doesn't have an "xsl:output" element
1034 String qualifiedName = "html";
1035 String publicID = "-//W3C//DTD HTML 4.01 Transitional//EN";
1036 String systemID = "http://www.w3.org/TR/html4/loose.dtd";
1037
1038 // We need to create an empty document with a predefined DocType,
1039 // that will then be used for the transformation by the DOMResult
1040 Document docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID);
1041 String baseURL = request.getAttribute(GSXML.BASE_URL);
1042
1043 // If you're just getting the client-side transform page, why bother with the rest of this?
1044 Element html = docWithDoctype.createElement("html");
1045 Element img = docWithDoctype.createElement("img");
1046 img.setAttribute("src", "loading.gif"); // Make it dynamic
1047 img.setAttribute("alt", "Please wait...");
1048 Text title_text = docWithDoctype.createTextNode("Please wait..."); // Make this language dependent
1049 Element head = docWithDoctype.createElement("head");
1050
1051 // e.g., <base href="http://localhost:8383/greenstone3/" /><!-- [if lte IE 6]></base><![endif] -->
1052 Element base = docWithDoctype.createElement("base");
1053 base.setAttribute("href",baseURL);
1054 Comment opt_end_base = docWithDoctype.createComment("[if lte IE 6]></base><![endif]");
1055
1056 Element title = docWithDoctype.createElement("title");
1057 title.appendChild(title_text);
1058
1059 Element body = docWithDoctype.createElement("body");
1060
1061 Element jquery_script = docWithDoctype.createElement("script");
1062 jquery_script.setAttribute("src", "jquery-3.6.0.min.js");
1063 jquery_script.setAttribute("type", "text/javascript");
1064 Comment jquery_comment = docWithDoctype.createComment("jQuery");
1065 jquery_script.appendChild(jquery_comment);
1066
1067 Element saxonce_script = docWithDoctype.createElement("script");
1068 saxonce_script.setAttribute("src", "Saxonce/Saxonce.nocache.js");
1069 saxonce_script.setAttribute("type", "text/javascript");
1070 Comment saxonce_comment = docWithDoctype.createComment("SaxonCE");
1071 saxonce_script.appendChild(saxonce_comment);
1072
1073 Element xsltutil_script = docWithDoctype.createElement("script");
1074 xsltutil_script.setAttribute("src", "xslt-util.js");
1075 xsltutil_script.setAttribute("type", "text/javascript");
1076 Comment xsltutil_comment = docWithDoctype.createComment("JavaScript version of XSLTUtil.java");
1077 xsltutil_script.appendChild(xsltutil_comment);
1078
1079 Element script = docWithDoctype.createElement("script");
1080 Comment script_comment = docWithDoctype.createComment("Filler for browser");
1081 script.setAttribute("src", "client-side-xslt.js");
1082 script.setAttribute("type", "text/javascript");
1083 script.appendChild(script_comment);
1084
1085 Element pagevar = docWithDoctype.createElement("script");
1086 Element style = docWithDoctype.createElement("style");
1087 style.setAttribute("type", "text/css");
1088 Text style_text = docWithDoctype.createTextNode("body { text-align: center; padding: 50px; font: 14pt Arial, sans-serif; font-weight: bold; }");
1089 pagevar.setAttribute("type", "text/javascript");
1090 Text page_var_text = docWithDoctype.createTextNode("var placeholder = true;");
1091
1092 html.appendChild(head);
1093 head.appendChild(base); head.appendChild(opt_end_base);
1094 head.appendChild(title);
1095 head.appendChild(style);
1096 style.appendChild(style_text);
1097 html.appendChild(body);
1098 head.appendChild(pagevar);
1099 head.appendChild(jquery_script);
1100 head.appendChild(saxonce_script);
1101 head.appendChild(xsltutil_script);
1102 head.appendChild(script);
1103 pagevar.appendChild(page_var_text);
1104
1105 body.appendChild(img);
1106 docWithDoctype.appendChild(html);
1107
1108 return (Node) docWithDoctype;
1109
1110 }
1111
1112 // transform the xsl with xsl to replace all gsf elements. We do this in 2 stages -
1113 // first do just a text pass, that way we can have gsf elements in the text content
1114 protected Node transformGSFElements(String collection, Document source_xsl, String expand_gsf_filename) {
1115
1116 String expand_gsf_file = GSFile.stylesheetFile(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, expand_gsf_filename);
1117 Document expand_gsf_doc = this.converter.getDOM(new File(expand_gsf_file));
1118
1119 if (expand_gsf_doc != null)
1120 {
1121 return this.transformer.transform(expand_gsf_doc, source_xsl, config_params);
1122 }
1123 return source_xsl;
1124
1125 }
1126
1127 // method to convert Document to a proper XML string for debug purposes only
1128 protected String getStringFromDocument(Document doc)
1129 {
1130 String content = "";
1131 try
1132 {
1133 DOMSource domSource = new DOMSource(doc);
1134 StringWriter writer = new StringWriter();
1135 StreamResult result = new StreamResult(writer);
1136 TransformerFactory tf = TransformerFactory.newInstance();
1137 Transformer transformer = tf.newTransformer();
1138 transformer.transform(domSource, result);
1139 content = writer.toString();
1140 System.out.println("Change the & to &Amp; for proper debug display");
1141 content = StringUtils.replace(content, "&", "&amp;");
1142 writer.flush();
1143 }
1144 catch (TransformerException ex)
1145 {
1146 ex.printStackTrace();
1147 return null;
1148 }
1149 return content;
1150 }
1151
1152 protected synchronized Document getDoc(String docName) throws Exception
1153 {
1154 File xslt_file = new File(docName);
1155
1156 FileReader reader = new FileReader(xslt_file);
1157 InputSource xml_source = new InputSource(reader);
1158 this.parser.parse(xml_source);
1159 Document doc = this.parser.getDocument();
1160
1161 return doc;
1162 }
1163
1164 protected String getXSLTFilename(String action, String subaction) {
1165 String name = null;
1166 if (!subaction.equals(""))
1167 {
1168 String key = action + ":" + subaction;
1169 name = this.xslt_map.get(key);
1170 }
1171 // try the action by itself
1172 if (name == null)
1173 {
1174 name = this.xslt_map.get(action);
1175 }
1176 if (name == null)
1177 {
1178 // so we can reandomly create any named page
1179 if (action.equals("p") && !subaction.equals(""))
1180 {
1181 // TODO: pages/ won't work for interface other than default!!
1182 name = "pages/" + subaction + ".xsl";
1183 }
1184
1185 }
1186 return name;
1187 }
1188
1189
1190 protected Document getXSLTDocument(String action, String subaction, String collection)
1191 {
1192 String name = getXSLTFilename(action, subaction);
1193 Document finalDoc = null;
1194 if(name != null)
1195 {
1196 // this finds all the stylesheets named "name" and merges them together, in the order of
1197 // base interface, current interface, site, collection - the latter overriding the former.
1198 // templates with the same name will replace earlier versions
1199 finalDoc = GSXSLT.mergedXSLTDocumentCascade(name, (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, _debug);
1200 }
1201 return finalDoc;
1202 }
1203
1204 // returns the path to the gslib.xsl file that is applicable for the current interface
1205 protected String getGSLibXSLFilename()
1206 {
1207 return GSFile.xmlTransformDir(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.INTERFACE_NAME))) + File.separatorChar + "gslib.xsl";
1208 }
1209
1210 // Call this when a FileNotFoundException could be thrown when loading an xsl (xml) file.
1211 // Returns an error xhtml page indicating which xsl (or other xml) file is missing.
1212 protected Document fileNotFoundErrorPage(String filenameMessage)
1213 {
1214 String errorMessage = "ERROR missing file: " + filenameMessage;
1215 Element errPage = XMLTransformer.constructErrorXHTMLPage(errorMessage);
1216 logger.error(errorMessage);
1217 return errPage.getOwnerDocument();
1218 }
1219}
Note: See TracBrowser for help on using the repository browser.