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

Last change on this file since 23839 was 23839, checked in by sjm84, 13 years ago

Restoring this file back to what it was after an accidental commit

  • Property svn:keywords set to Author Date Id Revision
File size: 31.9 KB
Line 
1package org.greenstone.gsdl3.core;
2
3import org.greenstone.util.GlobalProperties;
4import org.greenstone.gsdl3.util.*;
5import org.greenstone.gsdl3.action.*;
6// XML classes
7import org.w3c.dom.Node;
8import org.w3c.dom.NodeList;
9import org.w3c.dom.Comment;
10import org.w3c.dom.Text;
11import org.w3c.dom.Document;
12import org.w3c.dom.Element;
13import org.xml.sax.InputSource;
14import org.w3c.dom.NamedNodeMap;
15
16// other java classes
17import java.io.File;
18import java.io.StringWriter;
19import java.io.FileReader;
20import java.io.FileNotFoundException;
21import java.util.HashMap;
22import java.util.Enumeration;
23
24import javax.xml.parsers.*;
25import javax.xml.transform.*;
26import javax.xml.transform.dom.*;
27import javax.xml.transform.stream.*;
28import org.apache.log4j.*;
29import org.apache.xerces.dom.*;
30import org.apache.xerces.parsers.DOMParser;
31
32import org.apache.commons.lang3.StringUtils;
33
34/** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting
35 * of an xml representation of cgi args, and returns the page of data - in
36 * html by default. The requests are processed by the appropriate action class
37 *
38 * @see Action
39 */
40public class TransformingReceptionist extends Receptionist{
41
42 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.TransformingReceptionist.class.getName());
43
44 /** The preprocess.xsl file is in a fixed location */
45 static final String preprocess_xsl_filename = GlobalProperties.getGSDL3Home() + File.separatorChar
46 + "ui" + File.separatorChar + "xslt" + File.separatorChar + "preProcess.xsl";
47
48 /** the list of xslt to use for actions */
49 protected HashMap xslt_map = null;
50
51 /** a transformer class to transform xml using xslt */
52 protected XMLTransformer transformer=null;
53
54 protected TransformerFactory transformerFactory=null;
55 protected DOMParser parser = null;
56 public TransformingReceptionist() {
57 super();
58 this.xslt_map = new HashMap();
59 this.transformer = new XMLTransformer();
60 try {
61 transformerFactory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
62 this.converter = new XMLConverter();
63 //transformerFactory.setURIResolver(new MyUriResolver()) ;
64
65 parser = new DOMParser();
66 parser.setFeature("http://xml.org/sax/features/validation", false);
67 // 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.
68 parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
69 // a performance test showed that having this on lead to increased
70 // memory use for small-medium docs, and not much gain for large
71 // docs.
72 // http://www.sosnoski.com/opensrc/xmlbench/conclusions.html
73 parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
74 parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
75 // setting a handler for when fatal errors, errors or warnings happen during xml parsing
76 // call XMLConverter's getParseErrorMessage() to get the errorstring that can be rendered as web page
77 this.parser.setErrorHandler(new XMLConverter.ParseErrorHandler());
78 }
79 catch (Exception e) {
80 e.printStackTrace();
81 }
82
83 }
84
85 /** configures the receptionist - overwrite this to set up the xslt map*/
86 public boolean configure() {
87
88 if (this.config_params==null) {
89 logger.error(" config variables must be set before calling configure");
90 return false;
91 }
92 if (this.mr==null) {
93 logger.error(" message router must be set before calling configure");
94 return false;
95 }
96
97 // find the config file containing a list of actions
98 File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME))));
99 if (!interface_config_file.exists()) {
100 logger.error(" interface config file: "+interface_config_file.getPath()+" not found!");
101 return false;
102 }
103 Document config_doc = this.converter.getDOM(interface_config_file, "utf-8");
104 if (config_doc == null) {
105 logger.error(" could not parse interface config file: "+interface_config_file.getPath());
106 return false;
107 }
108 Element config_elem = config_doc.getDocumentElement();
109 String base_interface = config_elem.getAttribute("baseInterface");
110 setUpBaseInterface(base_interface);
111 setUpInterfaceOptions(config_elem);
112
113 Element action_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
114 NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
115
116 for (int i=0; i<actions.getLength(); i++) {
117 Element action = (Element) actions.item(i);
118 String class_name = action.getAttribute("class");
119 String action_name = action.getAttribute("name");
120 Action ac = null;
121 try {
122 ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
123 } catch (Exception e) {
124 logger.error(" couldn't load in action "+class_name);
125 e.printStackTrace();
126 continue;
127 }
128 ac.setConfigParams(this.config_params);
129 ac.setMessageRouter(this.mr);
130 ac.configure();
131 ac.getActionParameters(this.params);
132 this.action_map.put(action_name, ac);
133
134 // now do the xslt map
135 String xslt = action.getAttribute("xslt");
136 if (!xslt.equals("")) {
137 this.xslt_map.put(action_name, xslt);
138 }
139 NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM);
140 for (int j=0; j<subactions.getLength(); j++) {
141 Element subaction = (Element)subactions.item(j);
142 String subname = subaction.getAttribute(GSXML.NAME_ATT);
143 String subxslt = subaction.getAttribute("xslt");
144
145 String map_key = action_name+":"+subname;
146 logger.debug("adding in to xslt map, "+map_key+"->"+subxslt);
147 this.xslt_map.put(map_key, subxslt);
148 }
149 }
150 Element lang_list = (Element)GSXML.getChildByTagName(config_elem, "languageList");
151 if (lang_list == null) {
152 logger.error(" didn't find a language list in the config file!!");
153 } else {
154 this.language_list = (Element) this.doc.importNode(lang_list, true);
155 }
156
157 return true;
158 }
159
160
161 protected Node postProcessPage(Element page) {
162 // might need to add some data to the page
163 addExtraInfo(page);
164 // transform the page using xslt
165 Node transformed_page = transformPage(page);
166
167 // if the user has specified they want only a part of the full page then subdivide it
168 boolean subdivide = false;
169 String excerptID = null;
170 String excerptTag = null;
171 Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
172 Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
173 if (cgi_param_list != null) {
174 HashMap params = GSXML.extractParams(cgi_param_list, false);
175 if((excerptID = (String)params.get(GSParams.EXCERPT_ID)) != null)
176 {
177 subdivide = true;
178 }
179 if((excerptTag = (String)params.get(GSParams.EXCERPT_TAG)) != null)
180 {
181 subdivide = true;
182 }
183 }
184
185 if(subdivide)
186 {
187 Node subdivided_page = subdivide(transformed_page, excerptID, excerptTag);
188 if(subdivided_page != null)
189 {
190 return subdivided_page;
191 }
192 }
193
194 return transformed_page;
195 }
196
197 protected Node subdivide(Node transformed_page, String excerptID, String excerptTag)
198 {
199 if(excerptID != null)
200 {
201 Node selectedElement = getNodeByIdRecursive(transformed_page, excerptID);
202 modifyNodesByTagRecursive(selectedElement, "a");
203 return selectedElement;
204 }
205 else if(excerptTag != null)
206 {
207 // define a list
208
209 Node selectedElement = modifyNodesByTagRecursive(transformed_page, excerptTag);
210 return selectedElement;
211 }
212 return transformed_page;
213 }
214
215 protected Node getNodeByIdRecursive(Node parent, String id)
216 {
217 if(parent.hasAttributes() && ((Element)parent).getAttribute("id").equals(id))
218 {
219 return parent;
220 }
221
222 NodeList children = parent.getChildNodes();
223 for(int i = 0; i < children.getLength(); i++)
224 {
225 Node result = null;
226 if((result = getNodeByIdRecursive(children.item(i), id)) != null)
227 {
228 return result;
229 }
230 }
231 return null;
232 }
233
234 protected Node getNodeByTagRecursive(Node parent, String tag)
235 {
236 if(parent.getNodeType() == Node.ELEMENT_NODE && ((Element)parent).getTagName().equals(tag))
237 {
238 return parent;
239 }
240
241 NodeList children = parent.getChildNodes();
242 for(int i = 0; i < children.getLength(); i++)
243 {
244 Node result = null;
245 if((result = getNodeByTagRecursive(children.item(i), tag)) != null)
246 {
247 return result;
248 }
249 }
250 return null;
251 }
252
253 protected Node modifyNodesByTagRecursive(Node parent, String tag)
254 {
255 if(parent.getNodeType() == Node.ELEMENT_NODE && ((Element)parent).getTagName().equals(tag))
256 {
257 return parent;
258 }
259
260 NodeList children = parent.getChildNodes();
261 for(int i = 0; i < children.getLength(); i++)
262 {
263 Node result = null;
264 if((result = modifyNodesByTagRecursive(children.item(i), tag)) != null)
265 {
266 //return result;
267 //logger.error("Modify node value = "+result.getNodeValue()); //NamedItem("href"););
268 logger.error("BEFORE Modify node attribute = "+result.getAttributes().getNamedItem("href").getNodeValue());
269 String url = result.getAttributes().getNamedItem("href").getNodeValue();
270 url = url + "&excerptid=results";
271 result.getAttributes().getNamedItem("href").setNodeValue(url);
272 logger.error("AFTER Modify node attribute = "+result.getAttributes().getNamedItem("href").getNodeValue());
273
274 }
275 }
276 return null;
277 }
278
279 /** overwrite this to add any extra info that might be needed in the page before transformation */
280 protected void addExtraInfo(Element page) {}
281
282 /** transform the page using xslt
283 * we need to get any format element out of the page and add it to the xslt
284 * before transforming */
285 protected Node transformPage(Element page) {
286
287 boolean allowsClientXSLT = (Boolean)config_params.get(GSConstants.ALLOW_CLIENT_SIDE_XSLT);
288 //System.out.println("Client side transforms allowed? " + allowsClientXSLT);
289
290 // Force it back to traditional
291 if(!allowsClientXSLT)
292 config_params.put(GSConstants.INTERFACE_NAME, "traditional");
293
294 Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
295 String output = request.getAttribute(GSXML.OUTPUT_ATT);
296
297 String currentInterface = (String)config_params.get(GSConstants.INTERFACE_NAME);
298 //System.out.println("Current output mode is: " + output + ", current interface name is: " + currentInterface);
299
300 if(allowsClientXSLT) {
301 if((currentInterface.equals("default") && output.equals("html")) || output.equals("server"))
302 // Switch the interface
303 config_params.put(GSConstants.INTERFACE_NAME, "traditional");
304 else if(currentInterface.equals("traditional") && !output.equals("html"))
305 // The reverse needs to happen too
306 config_params.put(GSConstants.INTERFACE_NAME, "default");
307 }
308
309 // DocType defaults in case the skin doesn't have an "xsl:output" element
310 String qualifiedName = "html";
311 String publicID = "-//W3C//DTD HTML 4.01 Transitional//EN";
312 String systemID = "http://www.w3.org/TR/html4/loose.dtd";
313
314 // We need to create an empty document with a predefined DocType,
315 // that will then be used for the transformation by the DOMResult
316 Document docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID);
317
318 if(output.equals("xsltclient")) {
319 // If you're just getting the client-side transform page, why bother with the rest of this?
320 Element html = docWithDoctype.createElement("html");
321 Element img = docWithDoctype.createElement("img");
322 img.setAttribute("src", "interfaces/default/images/loading.gif"); // Make it dynamic
323 img.setAttribute("alt", "Please wait...");
324 Text title_text = docWithDoctype.createTextNode("Please wait..."); // Make this language dependent
325 Element head = docWithDoctype.createElement("head");
326 Element title = docWithDoctype.createElement("title");
327 title.appendChild(title_text);
328 Element body = docWithDoctype.createElement("body");
329 Element script = docWithDoctype.createElement("script");
330 Element jquery = docWithDoctype.createElement("script");
331 jquery.setAttribute("src", "jquery.js");
332 jquery.setAttribute("type", "text/javascript");
333 Comment jquery_comment = docWithDoctype.createComment("jQuery");
334 Comment script_comment = docWithDoctype.createComment("Filler for browser");
335 script.setAttribute("src", "test.js");
336 script.setAttribute("type", "text/javascript");
337 Element pagevar = docWithDoctype.createElement("script");
338 Element style = docWithDoctype.createElement("style");
339 style.setAttribute("type", "text/css");
340 Text style_text = docWithDoctype.createTextNode("body { text-align: center; padding: 50px; font: 14pt Arial, sans-serif; font-weight: bold; }");
341 pagevar.setAttribute("type", "text/javascript");
342 Text page_var_text = docWithDoctype.createTextNode("var placeholder = true;");
343
344 html.appendChild(head);
345 head.appendChild(title);
346 head.appendChild(style);
347 style.appendChild(style_text);
348 html.appendChild(body);
349 head.appendChild(pagevar);
350 head.appendChild(jquery);
351 head.appendChild(script);
352 pagevar.appendChild(page_var_text);
353 jquery.appendChild(jquery_comment);
354 script.appendChild(script_comment);
355 body.appendChild(img);
356 docWithDoctype.appendChild(html);
357
358 return (Node)docWithDoctype;
359 }
360
361 // 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
362 logger.debug("page before transforming:");
363 logger.debug(this.converter.getPrettyStringLogger(page, logger));
364
365 String action = request.getAttribute(GSXML.ACTION_ATT);
366 String subaction = request.getAttribute(GSXML.SUBACTION_ATT);
367
368 // we should choose how to transform the data based on output, eg diff
369 // choice for html, and wml??
370 // for now, if output=xml, we don't transform the page, we just return
371 // the page xml
372 Document theXML = null;
373
374 if (output.equals("xml") || output.equals("clientside")) {
375 // Append some bits and pieces first...
376 theXML = converter.newDOM();
377 // Import into new document first!
378 Node newPage = theXML.importNode(page, true);
379 theXML.appendChild(newPage);
380 Element root = theXML.createElement("xsltparams");
381 newPage.appendChild(root);
382
383 Element libname = theXML.createElement("param");
384 libname.setAttribute("name", "library_name");
385 Text libnametext = theXML.createTextNode((String)config_params.get(GSConstants.LIBRARY_NAME));
386 libname.appendChild(libnametext);
387
388 Element intname = theXML.createElement("param");
389 intname.setAttribute("name", "interface_name");
390 Text intnametext = theXML.createTextNode((String)config_params.get(GSConstants.INTERFACE_NAME));
391 intname.appendChild(intnametext);
392
393 Element filepath = theXML.createElement("param");
394 filepath.setAttribute("name", "filepath");
395 Text filepathtext = theXML.createTextNode(GlobalProperties.getGSDL3Home());
396 filepath.appendChild(filepathtext);
397
398 root.appendChild(libname);
399 root.appendChild(intname);
400 root.appendChild(filepath);
401
402 if(output.equals("xml"))
403 return theXML.getDocumentElement();
404 }
405
406
407 Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
408 String collection = "";
409 if (cgi_param_list != null) {
410 // Don't waste time getting all the parameters
411 HashMap params = GSXML.extractParams(cgi_param_list, false, GSParams.COLLECTION);
412 collection = (String)params.get(GSParams.COLLECTION);
413 if (collection == null) collection = "";
414 }
415
416 String xslt_file = getXSLTFileName(action, subaction, collection);
417 if (xslt_file==null) {
418 // returning file not found error page to indicate which file is missing
419 return fileNotFoundErrorPage(xslt_file);
420 }
421
422 Document style_doc = this.converter.getDOM(new File(xslt_file), "UTF-8");
423 String errorPage = this.converter.getParseErrorMessage();
424 if(errorPage != null) {
425 return XMLTransformer.constructErrorXHTMLPage("Cannot parse the xslt file: " + xslt_file + "\n" + errorPage);
426 }
427 if (style_doc == null) {
428 logger.error(" cant parse the xslt file needed, so returning the original page!");
429 return page;
430 }
431
432
433 // put the page into a document - this is necessary for xslt to get
434 // the paths right if you have paths relative to the document root
435 // eg /page.
436 Document doc = this.converter.newDOM();
437 doc.appendChild(doc.importNode(page, true));
438 Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
439 Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
440 if (output.equals("formatelem")) {
441 return format_elem;
442 }
443 if (format_elem != null) {
444 //page_response.removeChild(format_elem);
445 logger.debug("format elem="+this.converter.getPrettyStringLogger(format_elem, logger));
446 // need to transform the format info
447 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");
448 Document configStylesheet_doc = this.converter.getDOM(new File(configStylesheet_file));
449
450 if (configStylesheet_doc != null) {
451 Document format_doc = this.converter.newDOM();
452 format_doc.appendChild(format_doc.importNode(format_elem, true));
453 Node result = this.transformer.transform(configStylesheet_doc, format_doc); // Needs addressing <-
454
455 // Since we started creating documents with DocTypes, we can end up with
456 // Document objects here. But we will be working with an Element instead,
457 // so we grab the DocumentElement() of the Document object in such a case.
458 Element new_format;
459 if(result.getNodeType() == Node.DOCUMENT_NODE) {
460 new_format = ((Document)result).getDocumentElement();
461 } else {
462 new_format = (Element)result;
463 }
464 logger.debug("new format elem="+this.converter.getPrettyStringLogger(new_format, logger));
465 if (output.equals("newformat")) {
466 return new_format;
467 }
468
469 // add extracted GSF statements in to the main stylesheet
470 GSXSLT.mergeStylesheets(style_doc, new_format);
471 //System.out.println("added extracted GSF statements into the main stylesheet") ;
472
473 // add extracted GSF statements in to the debug test stylesheet
474 //GSXSLT.mergeStylesheets(oldStyle_doc, new_format);
475 } else {
476 logger.error(" couldn't parse the config_format stylesheet, adding the format info as is");
477 GSXSLT.mergeStylesheets(style_doc, format_elem);
478 //GSXSLT.mergeStylesheets(oldStyle_doc, format_elem);
479 }
480 logger.debug("the converted stylesheet is:");
481 logger.debug(this.converter.getPrettyStringLogger(style_doc.getDocumentElement(), logger));
482 }
483
484 //for debug purposes only
485 Document oldStyle_doc = style_doc;
486
487
488 Document preprocessingXsl;
489 try {
490 preprocessingXsl = getPreprocessDoc();
491 String errMsg = ((XMLConverter.ParseErrorHandler)parser.getErrorHandler()).getErrorMessage();
492 if(errMsg != null) {
493 return XMLTransformer.constructErrorXHTMLPage("error loading preprocess xslt file: "
494 + preprocess_xsl_filename + "\n" + errMsg);
495 }
496 } catch (java.io.FileNotFoundException e) {
497 return fileNotFoundErrorPage(e.getMessage());
498 } catch (Exception e) {
499 e.printStackTrace() ;
500 System.out.println("error loading preprocess xslt") ;
501 return XMLTransformer.constructErrorXHTMLPage("error loading preprocess xslt\n" + e.getMessage());
502 }
503
504 Document libraryXsl = null;
505 try {
506 libraryXsl = getLibraryDoc() ;
507 String errMsg = ((XMLConverter.ParseErrorHandler)parser.getErrorHandler()).getErrorMessage();
508 if(errMsg != null) {
509 return XMLTransformer.constructErrorXHTMLPage("Error loading xslt file: "
510 + this.getLibraryXSLFilename() + "\n" + errMsg);
511 }
512 } catch (java.io.FileNotFoundException e) {
513 return fileNotFoundErrorPage(e.getMessage());
514 } catch (Exception e) {
515 e.printStackTrace() ;
516 System.out.println("error loading library xslt") ;
517 return XMLTransformer.constructErrorXHTMLPage("error loading library xslt\n" + e.getMessage()) ;
518 }
519
520 // Combine the skin file and library variables/templates into one document.
521 // Please note: We dont just use xsl:import because the preprocessing stage
522 // needs to know what's available in the library.
523
524 Document skinAndLibraryXsl = null ;
525 Document skinAndLibraryDoc = converter.newDOM();
526 try {
527
528 skinAndLibraryXsl = converter.newDOM();
529 Element root = skinAndLibraryXsl.createElement("skinAndLibraryXsl") ;
530 skinAndLibraryXsl.appendChild(root) ;
531
532 Element s = skinAndLibraryXsl.createElement("skinXsl") ;
533 s.appendChild(skinAndLibraryXsl.importNode(style_doc.getDocumentElement(), true)) ;
534 root.appendChild(s) ;
535
536 Element l = skinAndLibraryXsl.createElement("libraryXsl") ;
537 Element libraryXsl_el = libraryXsl.getDocumentElement();
538 l.appendChild(skinAndLibraryXsl.importNode(libraryXsl_el, true)) ;
539 root.appendChild(l) ;
540 //System.out.println("Skin and Library XSL are now together") ;
541
542
543 //System.out.println("Pre-processing the skin file...") ;
544
545 //pre-process the skin style sheet
546 //In other words, apply the preProcess.xsl to 'skinAndLibraryXsl' in order to
547 //expand all GS-Lib statements into complete XSL statements and also to create
548 //a valid xsl style sheet document.
549
550 Transformer preProcessor = transformerFactory.newTransformer(new DOMSource(preprocessingXsl));
551 preProcessor.setErrorListener(new XMLTransformer.TransformErrorListener());
552 DOMResult result = new DOMResult();
553 result.setNode(skinAndLibraryDoc);
554 preProcessor.transform(new DOMSource(skinAndLibraryXsl), result);
555 //System.out.println("GS-Lib statements are now expanded") ;
556
557 }
558 catch (TransformerException e) {
559 e.printStackTrace() ;
560 System.out.println("TransformerException while preprocessing the skin xslt") ;
561 return XMLTransformer.constructErrorXHTMLPage(e.getMessage()) ;
562 }
563 catch (Exception e) {
564 e.printStackTrace() ;
565 System.out.println("Error while preprocessing the skin xslt") ;
566 return XMLTransformer.constructErrorXHTMLPage(e.getMessage()) ;
567 }
568
569 //The following code is to be uncommented if we need to append the extracted GSF statements
570 //after having extracted the GSLib elements. In case of a problem during postprocessing.
571 /*
572 // put the page into a document - this is necessary for xslt to get
573 // the paths right if you have paths relative to the document root
574 // eg /page.
575 Document doc = this.converter.newDOM();
576 doc.appendChild(doc.importNode(page, true));
577 Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
578 Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
579 if (output.equals("formatelem")) {
580 return format_elem;
581 }
582 if (format_elem != null) {
583 //page_response.removeChild(format_elem);
584 logger.debug("format elem="+this.converter.getPrettyString(format_elem));
585 // need to transform the format info
586 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");
587 Document configStylesheet_doc = this.converter.getDOM(new File(configStylesheet_file));
588 if (configStylesheet_doc != null) {
589 Document format_doc = this.converter.newDOM();
590 format_doc.appendChild(format_doc.importNode(format_elem, true));
591 Node result = this.transformer.transform(configStylesheet_doc, format_doc);
592
593 // Since we started creating documents with DocTypes, we can end up with
594 // Document objects here. But we will be working with an Element instead,
595 // so we grab the DocumentElement() of the Document object in such a case.
596 Element new_format;
597 if(result.getNodeType() == Node.DOCUMENT_NODE) {
598 new_format = ((Document)result).getDocumentElement();
599 } else {
600 new_format = (Element)result;
601 }
602 logger.debug("new format elem="+this.converter.getPrettyString(new_format));
603 if (output.equals("newformat")) {
604 return new_format;
605 }
606
607 // add extracted GSF statements in to the main stylesheet
608 GSXSLT.mergeStylesheets(skinAndLibraryDoc, new_format);
609 //System.out.println("added extracted GSF statements into the main stylesheet") ;
610
611 // add extracted GSF statements in to the debug test stylesheet
612 //GSXSLT.mergeStylesheets(oldStyle_doc, new_format);
613 } else {
614 logger.error(" couldn't parse the config_format stylesheet, adding the format info as is");
615 GSXSLT.mergeStylesheets(skinAndLibraryDoc, format_elem);
616 // GSXSLT.mergeStylesheets(oldStyle_doc, format_elem);
617 }
618 logger.debug("the converted stylesheet is:");
619 logger.debug(this.converter.getPrettyString(skinAndLibraryDoc.getDocumentElement()));
620 }
621 */
622
623 // there is a thing called a URIResolver which you can set for a
624 // transformer or transformer factory. may be able to use this
625 // instead of this absoluteIncludepaths hack
626
627 GSXSLT.absoluteIncludePaths(skinAndLibraryDoc, GlobalProperties.getGSDL3Home(),
628 (String)this.config_params.get(GSConstants.SITE_NAME),
629 collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME),
630 base_interfaces);
631
632
633 //Same but for the debug version when we want the do the transformation like we use to do
634 //without any gslib elements.
635 GSXSLT.absoluteIncludePaths(oldStyle_doc, GlobalProperties.getGSDL3Home(),
636 (String)this.config_params.get(GSConstants.SITE_NAME),
637 collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME),
638 base_interfaces);
639
640 //Send different stages of the skin xslt to the browser for debug purposes only
641 //using &o=skindoc or &o=skinandlib etc...
642 if (output.equals("skindoc")) {
643 return converter.getDOM(getStringFromDocument(style_doc));
644 }
645 if (output.equals("skinandlib")) {
646 return converter.getDOM(getStringFromDocument(skinAndLibraryXsl));
647 }
648 if (output.equals("skinandlibdoc") || output.equals("clientside")) {
649
650 Node skinAndLib = converter.getDOM(getStringFromDocument(skinAndLibraryDoc));
651
652 if(output.equals("skinandlibdoc")) {
653 return skinAndLib;
654 } else {
655 // Send XML and skinandlibdoc down the line together
656 Document finalDoc = converter.newDOM();
657 Node finalDocSkin = finalDoc.importNode(skinAndLibraryDoc.getDocumentElement(), true);
658 Node finalDocXML = finalDoc.importNode(theXML.getDocumentElement(), true);
659 Element root = finalDoc.createElement("skinlibPlusXML");
660 root.appendChild(finalDocSkin);
661 root.appendChild(finalDocXML);
662 finalDoc.appendChild(root);
663 return (Node)finalDoc.getDocumentElement();
664 }
665 }
666 if (output.equals("oldskindoc")) {
667 return converter.getDOM(getStringFromDocument(oldStyle_doc));
668 }
669
670 // Try to get the system and public ID from the current skin xsl document
671 // otherwise keep the default values.
672 Element root = skinAndLibraryDoc.getDocumentElement();
673 NodeList nodes = root.getElementsByTagName("xsl:output");
674 // If there is at least one "xsl:output" command in the final xsl then...
675 if(nodes.getLength() != 0) {
676 // There should be only one element called xsl:output,
677 // but if this is not the case get the last one
678 Element xsl_output = (Element)nodes.item(nodes.getLength()-1);
679 if (xsl_output != null) {
680 // Qualified name will always be html even for xhtml pages
681 //String attrValue = xsl_output.getAttribute("method");
682 //qualifiedName = attrValue.equals("") ? qualifiedName : attrValue;
683
684 String attrValue = xsl_output.getAttribute("doctype-system");
685 systemID = attrValue.equals("") ? systemID : attrValue;
686
687 attrValue = xsl_output.getAttribute("doctype-public");
688 publicID = attrValue.equals("") ? publicID : attrValue;
689 }
690 }
691
692 //System.out.println(converter.getPrettyString(docWithDoctype));
693 //System.out.println("Doctype vals: " + qualifiedName + " " + publicID + " " + systemID) ;
694
695 docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID);
696
697 //System.out.println("Generate final HTML from current skin") ;
698 //Transformation of the XML message from the receptionist to HTML with doctype
699
700 return this.transformer.transform(skinAndLibraryDoc, doc, config_params, docWithDoctype); // The default
701
702 // The line below will do the transformation like we use to do before having Skin++ implemented,
703 // it will not contain any GS-Lib statements expanded, and the result will not contain any doctype.
704
705 //return (Element)this.transformer.transform(style_doc, doc, config_params);
706 //return null; // For now - change later
707 }
708
709
710 // method to convert Document to a proper XML string for debug purposes only
711 protected String getStringFromDocument(Document doc)
712 {
713 String content = "";
714 try
715 {
716 DOMSource domSource = new DOMSource(doc);
717 StringWriter writer = new StringWriter();
718 StreamResult result = new StreamResult(writer);
719 TransformerFactory tf = TransformerFactory.newInstance();
720 Transformer transformer = tf.newTransformer();
721 transformer.transform(domSource, result);
722 content = writer.toString();
723 System.out.println("Change the & to &Amp; for proper debug dispay") ;
724 content = StringUtils.replace(content, "&", "&amp;");
725 writer.flush();
726 }
727 catch(TransformerException ex)
728 {
729 ex.printStackTrace();
730 return null;
731 }
732 return content;
733 }
734
735
736 protected Document getPreprocessDoc() throws Exception {
737
738 File xslt_file = new File(preprocess_xsl_filename) ;
739
740 FileReader reader = new FileReader(xslt_file);
741 InputSource xml_source = new InputSource(reader);
742 this.parser.parse(xml_source);
743 Document doc = this.parser.getDocument();
744
745 return doc ;
746 }
747
748 protected Document getLibraryDoc() throws Exception {
749 Document doc = null;
750 File xslt_file = new File(this.getLibraryXSLFilename()) ;
751
752 FileReader reader = new FileReader(xslt_file);
753 InputSource xml_source = new InputSource(reader);
754 this.parser.parse(xml_source);
755
756 doc = this.parser.getDocument();
757 return doc ;
758 }
759
760 protected String getXSLTFileName(String action, String subaction,
761 String collection) {
762
763 String name = null;
764 if (!subaction.equals("")) {
765 String key = action+":"+subaction;
766 name = (String) this.xslt_map.get(key);
767 }
768 // try the action by itself
769 if (name==null) {
770 name = (String) this.xslt_map.get(action);
771 }
772 // now find the absolute path
773 String stylesheet = GSFile.stylesheetFile(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.SITE_NAME), collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, name);
774 if (stylesheet==null) {
775 logger.info(" cant find stylesheet for "+name);
776 }
777 logger.error("stylesheet:"+stylesheet);
778 return stylesheet;
779 }
780
781 // returns the library.xsl path of the library file that is applicable for the current interface
782 protected String getLibraryXSLFilename() {
783 return GSFile.xmlTransformDir(GSFile.interfaceHome(
784 GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME)))
785 + File.separatorChar + "library.xsl";
786 }
787
788 // Call this when a FileNotFoundException could be thrown when loading an xsl (xml) file.
789 // Returns an error xhtml page indicating which xsl (or other xml) file is missing.
790 protected Document fileNotFoundErrorPage(String filenameMessage) {
791 String errorMessage = "ERROR missing file: " + filenameMessage;
792 Element errPage = XMLTransformer.constructErrorXHTMLPage(errorMessage);
793 logger.error(errorMessage);
794 return errPage.getOwnerDocument();
795 }
796}
Note: See TracBrowser for help on using the repository browser.