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

Last change on this file since 25635 was 25635, checked in by sjm84, 12 years ago

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

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