[4258] | 1 | package org.greenstone.gsdl3.core;
|
---|
| 2 |
|
---|
| 3 | import org.greenstone.gsdl3.util.*;
|
---|
| 4 | import org.greenstone.gsdl3.action.*;
|
---|
| 5 | // XML classes
|
---|
| 6 | import org.w3c.dom.Node;
|
---|
| 7 | import org.w3c.dom.NodeList;
|
---|
| 8 | import org.w3c.dom.Document;
|
---|
| 9 | import org.w3c.dom.Element;
|
---|
| 10 |
|
---|
| 11 | // other java classes
|
---|
| 12 | import java.io.File;
|
---|
| 13 | import java.util.HashMap;
|
---|
| 14 | import java.util.Enumeration;
|
---|
| 15 |
|
---|
| 16 | /** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting
|
---|
| 17 | * of an xml representation of cgi args, and returns the page of data - in
|
---|
| 18 | * html by default. The requests are processed by the appropriate action class
|
---|
| 19 | *
|
---|
| 20 | * @see Action
|
---|
| 21 | */
|
---|
| 22 | public class TransformingReceptionist extends Receptionist{
|
---|
| 23 |
|
---|
| 24 | /** the list of xslt to use for actions */
|
---|
| 25 | protected HashMap xslt_map = null;
|
---|
| 26 |
|
---|
| 27 | /** a transformer class to transform xml using xslt */
|
---|
| 28 | protected XMLTransformer transformer=null;
|
---|
| 29 |
|
---|
| 30 | public TransformingReceptionist() {
|
---|
| 31 | super();
|
---|
| 32 | this.xslt_map = new HashMap();
|
---|
| 33 | this.transformer = new XMLTransformer();
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | /** configures the receptionist - overwrite this to set up the xslt map*/
|
---|
| 37 | public boolean configure() {
|
---|
| 38 |
|
---|
[4691] | 39 | if (this.config_params==null) {
|
---|
[4258] | 40 | System.err.println("Receptionist Error: config variables must be set before calling configure");
|
---|
| 41 | return false;
|
---|
| 42 | }
|
---|
| 43 | if (this.mr==null) {
|
---|
| 44 | System.err.println("Receptionist Error: message router must be set before calling configure");
|
---|
| 45 | return false;
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 | // find the config file containing a list of actions
|
---|
[4691] | 49 | File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.INTERFACE_NAME))));
|
---|
[4258] | 50 | if (!interface_config_file.exists()) {
|
---|
| 51 | System.err.println("TransformingReceptionist: interface config file: "+interface_config_file.getPath()+" not found!");
|
---|
| 52 | return false;
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | Element config_doc = this.converter.getDOM(interface_config_file).getDocumentElement();
|
---|
| 56 | Element action_list = (Element)GSXML.getChildByTagName(config_doc, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
|
---|
| 57 | NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
|
---|
| 58 |
|
---|
| 59 | for (int i=0; i<actions.getLength(); i++) {
|
---|
| 60 | Element action = (Element) actions.item(i);
|
---|
| 61 | String class_name = action.getAttribute("class");
|
---|
| 62 | String action_name = action.getAttribute("name");
|
---|
| 63 | Action ac = null;
|
---|
| 64 | try {
|
---|
| 65 | ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
|
---|
| 66 | } catch (Exception e) {
|
---|
[4691] | 67 | System.err.println("couldn't load in action "+class_name);
|
---|
[4258] | 68 | e.printStackTrace();
|
---|
| 69 | continue;
|
---|
| 70 | }
|
---|
[4691] | 71 | ac.setConfigParams(this.config_params);
|
---|
[4258] | 72 | ac.setMessageRouter(this.mr);
|
---|
| 73 | ac.configure();
|
---|
| 74 | this.action_map.put(action_name, ac);
|
---|
| 75 |
|
---|
| 76 | // now do the xslt map
|
---|
| 77 | String xslt = action.getAttribute("xslt");
|
---|
| 78 | if (!xslt.equals("")) {
|
---|
| 79 | this.xslt_map.put(action_name, xslt);
|
---|
| 80 | }
|
---|
| 81 | NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM);
|
---|
| 82 | for (int j=0; j<subactions.getLength(); j++) {
|
---|
| 83 | Element subaction = (Element)subactions.item(j);
|
---|
| 84 | String subname = subaction.getAttribute(GSXML.NAME_ATT);
|
---|
| 85 | String subxslt = subaction.getAttribute("xslt");
|
---|
| 86 |
|
---|
| 87 | String map_key = action_name+":"+subname;
|
---|
[4691] | 88 | ///ystem.out.println("adding in to xslt map, "+map_key+"->"+subxslt);
|
---|
[4258] | 89 | this.xslt_map.put(map_key, subxslt);
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 |
|
---|
| 93 | }
|
---|
[4691] | 94 |
|
---|
[4258] | 95 | return true;
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 |
|
---|
| 99 | protected Element postProcessPage(Element page) {
|
---|
| 100 |
|
---|
| 101 | // might need to add some data to the page
|
---|
| 102 | addExtraInfo(page);
|
---|
| 103 | // transform the page using xslt
|
---|
| 104 | Element transformed_page = transformPage(page);
|
---|
| 105 |
|
---|
| 106 | return transformed_page;
|
---|
| 107 | }
|
---|
| 108 |
|
---|
[4691] | 109 | /** overwrite this to add any extra info that might be needed in the page before transformation */
|
---|
| 110 | protected void addExtraInfo(Element page) {}
|
---|
[4258] | 111 |
|
---|
[4691] | 112 | /** transform the page using xslt
|
---|
| 113 | * we need to get any format element out of the page and add it to the xslt
|
---|
[4258] | 114 | * before transforming */
|
---|
| 115 | protected Element transformPage(Element page) {
|
---|
| 116 |
|
---|
| 117 | Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
|
---|
| 118 | String action = request.getAttribute("action");
|
---|
| 119 | String subaction = request.getAttribute("subaction");
|
---|
| 120 | String xslt_file = getXSLTFileName(action, subaction);
|
---|
| 121 | if (xslt_file==null) {
|
---|
| 122 | // cant transform the page - return null or the original?
|
---|
| 123 | System.err.println(" cant find the xslt file needed, so returning the original page!");
|
---|
| 124 | return page;
|
---|
| 125 | }
|
---|
| 126 | Document style_doc = this.converter.getDOM(new File(xslt_file));
|
---|
| 127 |
|
---|
| 128 | // look for the format element in the page response
|
---|
| 129 | Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
|
---|
| 130 | Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
|
---|
| 131 | if (format_elem != null) {
|
---|
| 132 | page_response.removeChild(format_elem);
|
---|
| 133 |
|
---|
| 134 | // need to transform the format info
|
---|
[4691] | 135 | String stylesheet_file = GSFile.stylesheetFile((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), (String)this.config_params.get(GSConstants.INTERFACE_NAME), "config_format.xsl");
|
---|
[4258] | 136 | Document stylesheet = this.converter.getDOM(new File(stylesheet_file));
|
---|
[4691] | 137 | Document format_doc = this.converter.newDOM();
|
---|
| 138 | format_doc.appendChild(format_doc.importNode(format_elem, true));
|
---|
| 139 | Element new_format = (Element)this.transformer.transform(stylesheet, format_doc);
|
---|
[4258] | 140 | // add it in to the main stylesheet
|
---|
| 141 | GSXSLT.mergeStylesheets(style_doc, new_format);
|
---|
[4691] | 142 | ///ystem.out.println("the converted stylesheet is:");
|
---|
| 143 | ///ystem.out.println(this.converter.getPrettyString(style_doc.getDocumentElement()));
|
---|
[4258] | 144 | }
|
---|
| 145 |
|
---|
[4691] | 146 | // there is a thing called a URIResolver which you can set for a transformer or transformer factory. may be able to use this instead of this absoluteIncludepaths hack
|
---|
| 147 | GSXSLT.absoluteIncludePaths(style_doc, (String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), (String)this.config_params.get(GSConstants.INTERFACE_NAME));
|
---|
| 148 | // put the page into a document - this is necessary for xslt to get the paths right if you have paths relative to the document root eg /page.
|
---|
| 149 | Document doc = this.converter.newDOM();
|
---|
| 150 | doc.appendChild(doc.importNode(page, true));
|
---|
| 151 | return (Element)this.transformer.transform(style_doc, doc, config_params);
|
---|
[4258] | 152 | }
|
---|
| 153 |
|
---|
| 154 | protected String getXSLTFileName(String action, String subaction) {
|
---|
| 155 |
|
---|
| 156 | String name = null;
|
---|
| 157 | if (!subaction.equals("")) {
|
---|
| 158 | String key = action+":"+subaction;
|
---|
| 159 | name = (String) this.xslt_map.get(key);
|
---|
| 160 | }
|
---|
| 161 | // try the action by itself
|
---|
| 162 | if (name==null) {
|
---|
| 163 | name = (String) this.xslt_map.get(action);
|
---|
| 164 | }
|
---|
| 165 | // now find the absolute path
|
---|
[4691] | 166 | String stylesheet = GSFile.stylesheetFile((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), (String)this.config_params.get(GSConstants.INTERFACE_NAME), name);
|
---|
[4258] | 167 | if (stylesheet==null) {
|
---|
| 168 | System.out.println("cant find stylesheet for "+name);
|
---|
| 169 | }
|
---|
| 170 | return stylesheet;
|
---|
| 171 | }
|
---|
| 172 | /** returns an xml element containing all the text strings
|
---|
| 173 | * needed for an interface
|
---|
| 174 | * currently only uses the current interface - should add in
|
---|
| 175 | * needed ones from the default interface if current != default */
|
---|
| 176 | protected Element getDisplayElement(String lang) {
|
---|
| 177 |
|
---|
| 178 | Element display = this.doc.createElement(GSXML.DISPLAY_ELEM);
|
---|
| 179 | // looks for properties files based on interface name
|
---|
[4691] | 180 | String resource_name = "interface_"+ (String)this.config_params.get(GSConstants.INTERFACE_NAME);
|
---|
[4258] | 181 |
|
---|
| 182 | Dictionary dict = new Dictionary(resource_name, lang);
|
---|
| 183 | Enumeration enum = dict.getKeys();
|
---|
| 184 | while (enum.hasMoreElements()) {
|
---|
| 185 | String key = (String)enum.nextElement();
|
---|
| 186 | String value = dict.get(key);
|
---|
| 187 | Element e = GSXML.createTextElement(this.doc, key, value);
|
---|
| 188 | display.appendChild(e);
|
---|
| 189 | }
|
---|
| 190 | return display;
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 | }
|
---|