source: trunk/gsdl3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java@ 9405

Last change on this file since 9405 was 9405, checked in by kjdon, 19 years ago

replaced a couple of strings with constants, and made teh transformPage funciton return the original page if the output att in the request is set to xml

  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1package org.greenstone.gsdl3.core;
2
3import org.greenstone.gsdl3.util.*;
4import org.greenstone.gsdl3.action.*;
5// XML classes
6import org.w3c.dom.Node;
7import org.w3c.dom.NodeList;
8import org.w3c.dom.Document;
9import org.w3c.dom.Element;
10
11// other java classes
12import java.io.File;
13import java.util.HashMap;
14import 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 */
22public 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}
Note: See TracBrowser for help on using the repository browser.