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 |
|
---|
39 | if (this.config_params==null) {
|
---|
40 | System.err.println("TransformingReceptionist Error: config variables must be set before calling configure");
|
---|
41 | return false;
|
---|
42 | }
|
---|
43 | if (this.mr==null) {
|
---|
44 | System.err.println("TransformingReceptionist Error: message router must be set before calling configure");
|
---|
45 | return false;
|
---|
46 | }
|
---|
47 |
|
---|
48 | // find the config file containing a list of actions
|
---|
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))));
|
---|
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, "utf-8").getDocumentElement();
|
---|
56 | String base_interface = config_doc.getAttribute("baseInterface");
|
---|
57 | setUpBaseInterface(base_interface);
|
---|
58 | setUpInterfaceOptions(config_doc);
|
---|
59 |
|
---|
60 | Element action_list = (Element)GSXML.getChildByTagName(config_doc, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
|
---|
61 | NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
|
---|
62 |
|
---|
63 | for (int i=0; i<actions.getLength(); i++) {
|
---|
64 | Element action = (Element) actions.item(i);
|
---|
65 | String class_name = action.getAttribute("class");
|
---|
66 | String action_name = action.getAttribute("name");
|
---|
67 | Action ac = null;
|
---|
68 | try {
|
---|
69 | ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
|
---|
70 | } catch (Exception e) {
|
---|
71 | System.err.println("TransformingReceptionist Error: couldn't load in action "+class_name);
|
---|
72 | e.printStackTrace();
|
---|
73 | continue;
|
---|
74 | }
|
---|
75 | ac.setConfigParams(this.config_params);
|
---|
76 | ac.setMessageRouter(this.mr);
|
---|
77 | ac.configure();
|
---|
78 | ac.getActionParameters(this.params);
|
---|
79 | this.action_map.put(action_name, ac);
|
---|
80 |
|
---|
81 | // now do the xslt map
|
---|
82 | String xslt = action.getAttribute("xslt");
|
---|
83 | if (!xslt.equals("")) {
|
---|
84 | this.xslt_map.put(action_name, xslt);
|
---|
85 | }
|
---|
86 | NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM);
|
---|
87 | for (int j=0; j<subactions.getLength(); j++) {
|
---|
88 | Element subaction = (Element)subactions.item(j);
|
---|
89 | String subname = subaction.getAttribute(GSXML.NAME_ATT);
|
---|
90 | String subxslt = subaction.getAttribute("xslt");
|
---|
91 |
|
---|
92 | String map_key = action_name+":"+subname;
|
---|
93 | ///ystem.out.println("adding in to xslt map, "+map_key+"->"+subxslt);
|
---|
94 | this.xslt_map.put(map_key, subxslt);
|
---|
95 | }
|
---|
96 |
|
---|
97 |
|
---|
98 | }
|
---|
99 | Element lang_list = (Element)GSXML.getChildByTagName(config_doc, "languageList");
|
---|
100 | if (lang_list == null) {
|
---|
101 | System.err.println("TransformingReceptionist: didn't find a language list in the config file!!");
|
---|
102 | } else {
|
---|
103 | this.language_list = (Element) this.doc.importNode(lang_list, true);
|
---|
104 | }
|
---|
105 |
|
---|
106 | return true;
|
---|
107 | }
|
---|
108 |
|
---|
109 |
|
---|
110 | protected Element postProcessPage(Element page) {
|
---|
111 |
|
---|
112 | // might need to add some data to the page
|
---|
113 | addExtraInfo(page);
|
---|
114 | // transform the page using xslt
|
---|
115 | Element transformed_page = transformPage(page);
|
---|
116 |
|
---|
117 | return transformed_page;
|
---|
118 | }
|
---|
119 |
|
---|
120 | /** overwrite this to add any extra info that might be needed in the page before transformation */
|
---|
121 | protected void addExtraInfo(Element page) {}
|
---|
122 |
|
---|
123 | /** transform the page using xslt
|
---|
124 | * we need to get any format element out of the page and add it to the xslt
|
---|
125 | * before transforming */
|
---|
126 | protected Element transformPage(Element page) {
|
---|
127 |
|
---|
128 | //ystem.out.println("page before transfomring:");
|
---|
129 | //ystem.out.println(this.converter.getPrettyString(page));
|
---|
130 |
|
---|
131 | Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
|
---|
132 | String action = request.getAttribute(GSXML.ACTION_ATT);
|
---|
133 | String subaction = request.getAttribute(GSXML.SUBACTION_ATT);
|
---|
134 |
|
---|
135 | String output = request.getAttribute(GSXML.OUTPUT_ATT);
|
---|
136 | // we should choose how to transform the data based on output, eg diff
|
---|
137 | // choice for html, and wml??
|
---|
138 | // for now, if output=xml, we don't transform the page, we just return
|
---|
139 | // the page xml
|
---|
140 | if (output.equals("xml")) {
|
---|
141 | return page;
|
---|
142 | }
|
---|
143 |
|
---|
144 | Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
|
---|
145 | String collection = "";
|
---|
146 | if (cgi_param_list != null) {
|
---|
147 | HashMap params = GSXML.extractParams(cgi_param_list, false);
|
---|
148 | collection = (String)params.get(GSParams.COLLECTION);
|
---|
149 | if (collection == null) collection = "";
|
---|
150 | }
|
---|
151 |
|
---|
152 | String xslt_file = getXSLTFileName(action, subaction, collection);
|
---|
153 | if (xslt_file==null) {
|
---|
154 | // cant transform the page - return null or the original?
|
---|
155 | System.err.println("TransformingReceptionist: cant find the xslt file needed, so returning the original page!");
|
---|
156 | return page;
|
---|
157 | }
|
---|
158 | Document style_doc = this.converter.getDOM(new File(xslt_file), "UTF-8");
|
---|
159 |
|
---|
160 | // look for the format element in the page response
|
---|
161 | Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
|
---|
162 | Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
|
---|
163 | if (format_elem != null) {
|
---|
164 | //page_response.removeChild(format_elem);
|
---|
165 | ///ystem.err.println("format elem="+this.converter.getPrettyString(format_elem));
|
---|
166 | // need to transform the format info
|
---|
167 | String stylesheet_file = GSFile.stylesheetFile((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, "config_format.xsl");
|
---|
168 | Document stylesheet = this.converter.getDOM(new File(stylesheet_file));
|
---|
169 | Document format_doc = this.converter.newDOM();
|
---|
170 | format_doc.appendChild(format_doc.importNode(format_elem, true));
|
---|
171 | Element new_format = (Element)this.transformer.transform(stylesheet, format_doc);
|
---|
172 | ///ystem.err.println("new format elem="+this.converter.getPrettyString(new_format));
|
---|
173 |
|
---|
174 | // add it in to the main stylesheet
|
---|
175 | GSXSLT.mergeStylesheets(style_doc, new_format);
|
---|
176 | ///ystem.out.println("the converted stylesheet is:");
|
---|
177 | ///ystem.out.println(this.converter.getPrettyString(style_doc.getDocumentElement()));
|
---|
178 | }
|
---|
179 |
|
---|
180 | // 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
|
---|
181 | GSXSLT.absoluteIncludePaths(style_doc, (String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces);
|
---|
182 | // 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.
|
---|
183 | Document doc = this.converter.newDOM();
|
---|
184 | doc.appendChild(doc.importNode(page, true));
|
---|
185 | return (Element)this.transformer.transform(style_doc, doc, config_params);
|
---|
186 | }
|
---|
187 |
|
---|
188 | protected String getXSLTFileName(String action, String subaction,
|
---|
189 | String collection) {
|
---|
190 |
|
---|
191 | String name = null;
|
---|
192 | if (!subaction.equals("")) {
|
---|
193 | String key = action+":"+subaction;
|
---|
194 | name = (String) this.xslt_map.get(key);
|
---|
195 | }
|
---|
196 | // try the action by itself
|
---|
197 | if (name==null) {
|
---|
198 | name = (String) this.xslt_map.get(action);
|
---|
199 | }
|
---|
200 | // now find the absolute path
|
---|
201 | String stylesheet = GSFile.stylesheetFile((String)this.config_params.get(GSConstants.GSDL3_HOME), (String)this.config_params.get(GSConstants.SITE_NAME), collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces, name);
|
---|
202 | if (stylesheet==null) {
|
---|
203 | System.out.println("TransformingReceptionist: cant find stylesheet for "+name);
|
---|
204 | }
|
---|
205 | return stylesheet;
|
---|
206 | }
|
---|
207 |
|
---|
208 | }
|
---|