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

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

receptionist now passes languageList (from interfaceConfig) to teh actions, so an action can add it into the page response if it needs to, rather than the receptionist adding it in to every page. its only ever used in prefs page

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