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

Last change on this file since 33079 was 33079, checked in by kjdon, 5 years ago

make TransformingReceptionist call Receptionist.configure rather than having the entire method copied in this class.

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