source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/Receptionist.java@ 23360

Last change on this file since 23360 was 23360, checked in by sjb48, 13 years ago

Starting working on new format statement save architecture. This involves a new action, FormatAction, which will be responsible for the XSL transform and will pass the format string to the Collection object via the Message Router,

  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 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.Document;
10import org.w3c.dom.Element;
11
12// other java classes
13import java.io.File;
14import java.util.HashMap;
15import java.util.Enumeration;
16import java.util.ArrayList;
17
18import org.apache.log4j.*;
19
20/** the most basic Receptionist, used for interface generation.
21 * Receives requests consisting
22 * of an xml representation of cgi args, and returns the page of data. The requests are processed by the appropriate action class
23 *
24 * @see Action
25 */
26public class Receptionist implements ModuleInterface {
27
28 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.Receptionist.class.getName());
29
30 /** the set up variables */
31 protected HashMap config_params = null;
32 /** container Document to create XML Nodes */
33 protected Document doc=null;
34
35 /** a converter class to parse XML and create Docs */
36 protected XMLConverter converter=null;
37
38 /** the message router that the Receptionist and Actions will talk to */
39 protected ModuleInterface mr=null;
40
41 /** the list of actions */
42 protected HashMap action_map=null;
43
44 /** the list of params */
45 protected GSParams params=null;
46 protected Element language_list = null;
47
48 /** the list of interfaces this is based on */
49 protected ArrayList base_interfaces = null;
50
51 public Receptionist() {
52 this.converter = new XMLConverter();
53 this.doc = this.converter.newDOM();
54 this.action_map= new HashMap();
55 }
56
57 public void cleanUp() {}
58 public void setParams(GSParams params) {
59 this.params = params;
60 }
61 public void setConfigParams(HashMap params) {
62 this.config_params = params;
63 }
64 public HashMap getConfigParams() {
65 return this.config_params;
66 }
67 /** sets the message router - it should already be created and
68 * configured before being passed to the receptionist*/
69 public void setMessageRouter(ModuleInterface m) {
70 this.mr = m;
71 }
72
73 /** configures the receptionist */
74 public boolean configure() {
75
76 if (this.config_params==null) {
77 logger.error(" config variables must be set before calling configure");
78 return false;
79 }
80 if (this.mr==null) {
81 logger.error(" message router must be set before calling configure");
82 return false;
83 }
84
85 // find the config file containing a list of actions
86 File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME))));
87 if (!interface_config_file.exists()) {
88 logger.error(" interface config file: "+interface_config_file.getPath()+" not found!");
89 return false;
90 }
91
92 Document config_doc = this.converter.getDOM(interface_config_file);
93 if (config_doc == null) {
94 logger.error(" could not parse interface config file: "+interface_config_file.getPath());
95 return false;
96 }
97 Element config_elem = config_doc.getDocumentElement();
98 String base_interface = config_elem.getAttribute("baseInterface");
99 setUpBaseInterface(base_interface);
100 setUpInterfaceOptions(config_elem);
101
102 // load up the actions
103 Element action_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
104 NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
105
106 for (int i=0; i<actions.getLength(); i++) {
107 Element action = (Element) actions.item(i);
108 String class_name = action.getAttribute("class");
109 String action_name = action.getAttribute("name");
110 Action ac = null;
111 try {
112 ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
113 } catch (Exception e) {
114 logger.error(" couldn't load in action "+class_name);
115 e.printStackTrace();
116 continue;
117 }
118 ac.setConfigParams(this.config_params);
119 ac.setMessageRouter(this.mr);
120 ac.configure();
121 ac.getActionParameters(this.params);
122 this.action_map.put(action_name, ac);
123 }
124
125 this.language_list = (Element)GSXML.getChildByTagName(config_elem, "languageList");
126 if (language_list == null) {
127 logger.error(" didn't find a language list in the config file!!");
128 }
129
130 return true;
131 }
132
133
134
135 public String process(String xml_in) {
136
137 Node message_node = this.converter.getDOM(xml_in);
138 Node page = process(message_node);
139 return this.converter.getString(page);
140 }
141
142
143 /** process - produce a page of data in response to a request
144 * if something goes wrong, it returns null -
145 * TODO: return a suitable message to the user */
146 public Node process(Node message_node) {
147
148 Element message = this.converter.nodeToElement(message_node);
149
150 // get the request out of the message - assume that there is only one
151 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
152 if (request == null) {
153 logger.error(" message had no request!");
154 return null;
155 }
156 // check the request type
157 String type = request.getAttribute(GSXML.TYPE_ATT); // returns "" if no att of this name
158 if (!type.equals(GSXML.REQUEST_TYPE_PAGE)) {
159 // now Receptionist forwards non-page requests straight to the MR, and returns the responses
160 logger.error(" request type is not '"+GSXML.REQUEST_TYPE_PAGE+"', but it is '"+type+"', so forwarding the message to the MR!");
161 // process the whole message - mr needs <message> tags, and
162 // in this case, there may be more than one request in the message
163 return this.mr.process(message);
164 }
165 // work out which action to pass to
166 String action = request.getAttribute(GSXML.ACTION_ATT);
167 if (action.equals("")) {
168 logger.error(" no action specified in the request!");
169 return null;
170 }
171
172 // find the appropriate action
173 Action a = (Action)this.action_map.get(action);
174
175 String action_name=null;
176 if (a==null) { // not in the map yet
177 // try to load a new action
178 try {
179 action_name = action.substring(0,1).toUpperCase()+action.substring(1)+"Action";
180 Action ac = (Action)Class.forName("org.greenstone.gsdl3.action."+action_name).newInstance();
181 ac.setConfigParams(this.config_params);
182 ac.setMessageRouter(this.mr);
183 ac.configure();
184 ac.getActionParameters(this.params);
185 this.action_map.put(action, ac);
186 a = ac;
187 } catch (Exception e) {
188
189 logger.error(" a new action ("+action_name+") was specified and it couldn't be created. Error message:"+e.getMessage());
190 return null;
191 }
192 }
193
194 // transform the request in some way -- does nothing!
195 preProcessRequest(request);
196 // set up the page
197 Element page = this.doc.createElement(GSXML.PAGE_ELEM);
198 page.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
199 // just in case these namespaces end up in the page and we want to display the XML
200 page.setAttribute("xmlns:gsf","http://www.greenstone.org/greenstone3/schema/ConfigFormat");
201 page.setAttribute("xmlns:xsl", "http://www.w3.org/1999/XSL/Transform");
202
203 //logger.info(a+" mesa=" + this.converter.getPrettyString(message));
204 // get the page data from the action
205 Node action_response = a.process(message);
206
207 boolean response_only=false;
208 Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
209 if (param_list != null) {
210 Element param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, "ro");
211 if (param != null) {
212 String value = param.getAttribute("value");
213 if (value.equals("1")) {
214 response_only = true;
215 }
216 }
217 }
218 if (response_only) {
219 // only the response from the action is sent back
220 return action_response;
221 }
222
223 // the request is part of the page
224 page.appendChild(GSXML.duplicateWithNewName(this.doc, request, GSXML.PAGE_REQUEST_ELEM, true));
225 // add the response too
226 Element page_response = GSXML.duplicateWithNewName(this.doc, (Element)GSXML.getChildByTagName(action_response, GSXML.RESPONSE_ELEM), GSXML.PAGE_RESPONSE_ELEM, true);
227 page.appendChild(page_response);
228
229 //logger.info(" raw page="+this.converter.getString(page));
230 // transform the result in some way
231 //Element resulting_page = postProcessPage(page);
232
233 Node resulting_page = postProcessPage(page);
234
235 logger.debug("receptionist returned response");
236 logger.error("receptionist returned response");
237 logger.debug(this.converter.getString(resulting_page));
238 logger.error(this.converter.getString(resulting_page));
239// logger.info("receptionist returned response");
240// logger.info(this.converter.getString(resulting_page));
241
242 return resulting_page;
243
244 }
245
246 protected boolean setUpBaseInterface(String base_interface) {
247 if (base_interface== null || base_interface.equals("")) {
248 // there was no base interface, the list remains null
249 return true;
250 }
251 // foreach base interface
252 while (!base_interface.equals("")) {
253 // find the base interface config file
254 File base_interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), base_interface)));
255 if (!base_interface_config_file.exists()) {
256 logger.error(" base interface config file: "+base_interface_config_file.getPath()+" not found!");
257 return false;
258 }
259 // the interface name is valid, add it to the list
260 if (base_interfaces == null) {
261 base_interfaces = new ArrayList();
262 }
263 base_interfaces.add(base_interface);
264 // now see if this has a base interface
265 Document config_doc = this.converter.getDOM(base_interface_config_file);
266 if (config_doc == null) {
267 logger.error(" could not parse base interface config file: "+base_interface_config_file.getPath());
268 return false;
269 }
270 Element config_elem = config_doc.getDocumentElement();
271 base_interface = config_elem.getAttribute("baseInterface");
272 }
273 return true;
274 }
275
276 protected boolean setUpInterfaceOptions(Element config_elem) {
277 Element option_list = (Element)GSXML.getChildByTagName(config_elem, "optionList");
278 if (option_list != null) {
279 logger.debug("found an interface optionList");
280 // we set any options in the config params
281 NodeList options = option_list.getElementsByTagName("option");
282 for (int i=0; i<options.getLength(); i++) {
283 Element option = (Element)options.item(i);
284 String name = option.getAttribute(GSXML.NAME_ATT);
285 String value = option.getAttribute(GSXML.VALUE_ATT);
286 logger.debug("option: "+name+", "+value);
287 if (!name.equals("") && !value.equals("")) {
288 this.config_params.put(name, value);
289 }
290 }
291 }
292
293 return true;
294 }
295
296 protected void preProcessRequest(Element request) {
297 return;
298 }
299
300 protected Node postProcessPage(Element page) {
301 return page;
302 }
303
304
305}
Note: See TracBrowser for help on using the repository browser.