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

Last change on this file since 30589 was 30589, checked in by kjdon, 8 years ago

use the new GSXSLT.findExtraMetadataNames in action and transformingReceptionist instead of these two places each implementing this functionality and doing it differently

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