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 | import org.apache.log4j.*;
|
---|
17 |
|
---|
18 | /** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting
|
---|
19 | * of an xml representation of cgi args, and returns the page of data - in
|
---|
20 | * html by default. The requests are processed by the appropriate action class
|
---|
21 | *
|
---|
22 | * @see Action
|
---|
23 | */
|
---|
24 | public class TransformingReceptionist extends Receptionist{
|
---|
25 |
|
---|
26 | static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.TransformingReceptionist.class.getName());
|
---|
27 |
|
---|
28 | /** the list of xslt to use for actions */
|
---|
29 | protected HashMap xslt_map = null;
|
---|
30 |
|
---|
31 | /** a transformer class to transform xml using xslt */
|
---|
32 | protected XMLTransformer transformer=null;
|
---|
33 |
|
---|
34 | public TransformingReceptionist() {
|
---|
35 | super();
|
---|
36 | this.xslt_map = new HashMap();
|
---|
37 | this.transformer = new XMLTransformer();
|
---|
38 | }
|
---|
39 |
|
---|
40 | /** configures the receptionist - overwrite this to set up the xslt map*/
|
---|
41 | public boolean configure() {
|
---|
42 |
|
---|
43 | if (this.config_params==null) {
|
---|
44 | logger.error(" config variables must be set before calling configure");
|
---|
45 | return false;
|
---|
46 | }
|
---|
47 | if (this.mr==null) {
|
---|
48 | logger.error(" message router must be set before calling configure");
|
---|
49 | return false;
|
---|
50 | }
|
---|
51 |
|
---|
52 | // find the config file containing a list of actions
|
---|
53 | File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME))));
|
---|
54 | if (!interface_config_file.exists()) {
|
---|
55 | logger.error(" interface config file: "+interface_config_file.getPath()+" not found!");
|
---|
56 | return false;
|
---|
57 | }
|
---|
58 | Document config_doc = this.converter.getDOM(interface_config_file, "utf-8");
|
---|
59 | if (config_doc == null) {
|
---|
60 | logger.error(" could not parse interface config file: "+interface_config_file.getPath());
|
---|
61 | return false;
|
---|
62 | }
|
---|
63 | Element config_elem = config_doc.getDocumentElement();
|
---|
64 | String base_interface = config_elem.getAttribute("baseInterface");
|
---|
65 | setUpBaseInterface(base_interface);
|
---|
66 | setUpInterfaceOptions(config_elem);
|
---|
67 |
|
---|
68 | Element action_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
|
---|
69 | NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
|
---|
70 |
|
---|
71 | for (int i=0; i<actions.getLength(); i++) {
|
---|
72 | Element action = (Element) actions.item(i);
|
---|
73 | String class_name = action.getAttribute("class");
|
---|
74 | String action_name = action.getAttribute("name");
|
---|
75 | Action ac = null;
|
---|
76 | try {
|
---|
77 | ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
|
---|
78 | } catch (Exception e) {
|
---|
79 | logger.error(" couldn't load in action "+class_name);
|
---|
80 | e.printStackTrace();
|
---|
81 | continue;
|
---|
82 | }
|
---|
83 | ac.setConfigParams(this.config_params);
|
---|
84 | ac.setMessageRouter(this.mr);
|
---|
85 | ac.configure();
|
---|
86 | ac.getActionParameters(this.params);
|
---|
87 | this.action_map.put(action_name, ac);
|
---|
88 |
|
---|
89 | // now do the xslt map
|
---|
90 | String xslt = action.getAttribute("xslt");
|
---|
91 | if (!xslt.equals("")) {
|
---|
92 | this.xslt_map.put(action_name, xslt);
|
---|
93 | }
|
---|
94 | NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM);
|
---|
95 | for (int j=0; j<subactions.getLength(); j++) {
|
---|
96 | Element subaction = (Element)subactions.item(j);
|
---|
97 | String subname = subaction.getAttribute(GSXML.NAME_ATT);
|
---|
98 | String subxslt = subaction.getAttribute("xslt");
|
---|
99 |
|
---|
100 | String map_key = action_name+":"+subname;
|
---|
101 | logger.debug("adding in to xslt map, "+map_key+"->"+subxslt);
|
---|
102 | this.xslt_map.put(map_key, subxslt);
|
---|
103 | }
|
---|
104 |
|
---|
105 |
|
---|
106 | }
|
---|
107 | Element lang_list = (Element)GSXML.getChildByTagName(config_elem, "languageList");
|
---|
108 | if (lang_list == null) {
|
---|
109 | logger.error(" didn't find a language list in the config file!!");
|
---|
110 | } else {
|
---|
111 | this.language_list = (Element) this.doc.importNode(lang_list, true);
|
---|
112 | }
|
---|
113 |
|
---|
114 | return true;
|
---|
115 | }
|
---|
116 |
|
---|
117 |
|
---|
118 | protected Node postProcessPage(Element page) {
|
---|
119 |
|
---|
120 | // might need to add some data to the page
|
---|
121 | addExtraInfo(page);
|
---|
122 | // transform the page using xslt
|
---|
123 | Node transformed_page = transformPage(page);
|
---|
124 |
|
---|
125 | return transformed_page;
|
---|
126 | }
|
---|
127 |
|
---|
128 | /** overwrite this to add any extra info that might be needed in the page before transformation */
|
---|
129 | protected void addExtraInfo(Element page) {}
|
---|
130 |
|
---|
131 | /** transform the page using xslt
|
---|
132 | * we need to get any format element out of the page and add it to the xslt
|
---|
133 | * before transforming */
|
---|
134 | protected Node transformPage(Element page) {
|
---|
135 |
|
---|
136 | logger.debug("page before transfomring:");
|
---|
137 | logger.debug(this.converter.getPrettyString(page));
|
---|
138 |
|
---|
139 | Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
|
---|
140 | String action = request.getAttribute(GSXML.ACTION_ATT);
|
---|
141 | String subaction = request.getAttribute(GSXML.SUBACTION_ATT);
|
---|
142 |
|
---|
143 | String output = request.getAttribute(GSXML.OUTPUT_ATT);
|
---|
144 | // we should choose how to transform the data based on output, eg diff
|
---|
145 | // choice for html, and wml??
|
---|
146 | // for now, if output=xml, we don't transform the page, we just return
|
---|
147 | // the page xml
|
---|
148 | if (output.equals("xml")) {
|
---|
149 | return page;
|
---|
150 | }
|
---|
151 |
|
---|
152 | Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
|
---|
153 | String collection = "";
|
---|
154 | if (cgi_param_list != null) {
|
---|
155 | HashMap params = GSXML.extractParams(cgi_param_list, false);
|
---|
156 | collection = (String)params.get(GSParams.COLLECTION);
|
---|
157 | if (collection == null) collection = "";
|
---|
158 | }
|
---|
159 |
|
---|
160 | String xslt_file = getXSLTFileName(action, subaction, collection);
|
---|
161 | if (xslt_file==null) {
|
---|
162 | // cant transform the page - return null or the original?
|
---|
163 | logger.error(" cant find the xslt file needed, so returning the original page!");
|
---|
164 | return page;
|
---|
165 | }
|
---|
166 | Document style_doc = this.converter.getDOM(new File(xslt_file), "UTF-8");
|
---|
167 | if (style_doc == null) {
|
---|
168 | logger.error(" cant parse the xslt file needed, so returning the original page!");
|
---|
169 | return page;
|
---|
170 |
|
---|
171 | }
|
---|
172 |
|
---|
173 | // look for the format element in the page response
|
---|
174 | Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
|
---|
175 | Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
|
---|
176 | if (format_elem != null) {
|
---|
177 | //page_response.removeChild(format_elem);
|
---|
178 | logger.debug("format elem="+this.converter.getPrettyString(format_elem));
|
---|
179 | // need to transform the format info
|
---|
180 | String stylesheet_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");
|
---|
181 | Document stylesheet_doc = this.converter.getDOM(new File(stylesheet_file));
|
---|
182 | if (stylesheet_doc != null) {
|
---|
183 | Document format_doc = this.converter.newDOM();
|
---|
184 | format_doc.appendChild(format_doc.importNode(format_elem, true));
|
---|
185 | Element new_format = (Element)this.transformer.transform(stylesheet_doc, format_doc);
|
---|
186 | logger.debug("new format elem="+this.converter.getPrettyString(new_format));
|
---|
187 |
|
---|
188 | // add it in to the main stylesheet
|
---|
189 | GSXSLT.mergeStylesheets(style_doc, new_format);
|
---|
190 | } else {
|
---|
191 | logger.error(" couldn't parse the config_format stylesheet, adding the format info as is");
|
---|
192 | GSXSLT.mergeStylesheets(style_doc, format_elem);
|
---|
193 | }
|
---|
194 | logger.debug("the converted stylesheet is:");
|
---|
195 | logger.debug(this.converter.getPrettyString(style_doc.getDocumentElement()));
|
---|
196 | }
|
---|
197 |
|
---|
198 | // there is a thing called a URIResolver which you can set for a
|
---|
199 | // transformer or transformer factory. may be able to use this
|
---|
200 | // instead of this absoluteIncludepaths hack
|
---|
201 |
|
---|
202 | GSXSLT.absoluteIncludePaths(style_doc, GlobalProperties.getGSDL3Home(),
|
---|
203 | (String)this.config_params.get(GSConstants.SITE_NAME),
|
---|
204 | collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME),
|
---|
205 | base_interfaces);
|
---|
206 |
|
---|
207 | // put the page into a document - this is necessary for xslt to get
|
---|
208 | // the paths right if you have paths relative to the document root
|
---|
209 | // eg /page.
|
---|
210 |
|
---|
211 | Document doc = this.converter.newDOM();
|
---|
212 | doc.appendChild(doc.importNode(page, true));
|
---|
213 | return (Element)this.transformer.transform(style_doc, doc, config_params);
|
---|
214 | }
|
---|
215 |
|
---|
216 | protected String getXSLTFileName(String action, String subaction,
|
---|
217 | String collection) {
|
---|
218 |
|
---|
219 | String name = null;
|
---|
220 | if (!subaction.equals("")) {
|
---|
221 | String key = action+":"+subaction;
|
---|
222 | name = (String) this.xslt_map.get(key);
|
---|
223 | }
|
---|
224 | // try the action by itself
|
---|
225 | if (name==null) {
|
---|
226 | name = (String) this.xslt_map.get(action);
|
---|
227 | }
|
---|
228 | // now find the absolute path
|
---|
229 | 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);
|
---|
230 | if (stylesheet==null) {
|
---|
231 | logger.info(" cant find stylesheet for "+name);
|
---|
232 | }
|
---|
233 | return stylesheet;
|
---|
234 | }
|
---|
235 |
|
---|
236 | }
|
---|