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

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

Reformatting this file

  • 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 // transform the request in some way -- does nothing!
238 preProcessRequest(request);
239 // set up the page
240 Element page = this.doc.createElement(GSXML.PAGE_ELEM);
241 page.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
242 // just in case these namespaces end up in the page and we want to display the XML
243 page.setAttribute("xmlns:gsf", "http://www.greenstone.org/greenstone3/schema/ConfigFormat");
244 page.setAttribute("xmlns:xsl", "http://www.w3.org/1999/XSL/Transform");
245
246 //logger.info(a+" mesa=" + this.converter.getPrettyString(message));
247 // get the page data from the action
248
249 Node action_response = a.process(message);
250 boolean response_only = false;
251 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
252 if (param_list != null)
253 {
254 Element param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, "ro");
255 if (param != null)
256 {
257 String value = param.getAttribute("value");
258 if (value.equals("1"))
259 {
260 response_only = true;
261 }
262 }
263 }
264 if (response_only)
265 {
266 // only the response from the action is sent back
267 return action_response;
268 }
269
270 // the request is part of the page
271 page.appendChild(GSXML.duplicateWithNewName(this.doc, request, GSXML.PAGE_REQUEST_ELEM, true));
272 // add the response too
273 Element page_response = GSXML.duplicateWithNewName(this.doc, (Element) GSXML.getChildByTagName(action_response, GSXML.RESPONSE_ELEM), GSXML.PAGE_RESPONSE_ELEM, true);
274 page.appendChild(page_response);
275
276 //logger.info(" raw page="+this.converter.getString(page));
277 // transform the result in some way
278 //Element resulting_page = postProcessPage(page);
279
280 Node resulting_page = postProcessPage(page);
281
282 logger.debug("receptionist returned response");
283 //logger.error("receptionist returned response");
284 logger.debug(this.converter.getString(resulting_page));
285 //logger.error(this.converter.getString(resulting_page));
286 // logger.info("receptionist returned response");
287 // logger.info(this.converter.getString(resulting_page));
288 return resulting_page;
289 }
290
291 protected boolean setUpBaseInterface(String base_interface)
292 {
293 if (base_interface == null || base_interface.equals(""))
294 {
295 // there was no base interface, the list remains null
296 return true;
297 }
298 // foreach base interface
299 while (!base_interface.equals(""))
300 {
301 // find the base interface config file
302 File base_interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), base_interface)));
303 if (!base_interface_config_file.exists())
304 {
305 logger.error(" base interface config file: " + base_interface_config_file.getPath() + " not found!");
306 return false;
307 }
308 // the interface name is valid, add it to the list
309 if (base_interfaces == null)
310 {
311 base_interfaces = new ArrayList<String>();
312 }
313 base_interfaces.add(base_interface);
314 // now see if this has a base interface
315 Document config_doc = this.converter.getDOM(base_interface_config_file);
316 if (config_doc == null)
317 {
318 logger.error(" could not parse base interface config file: " + base_interface_config_file.getPath());
319 return false;
320 }
321 Element config_elem = config_doc.getDocumentElement();
322 base_interface = config_elem.getAttribute("baseInterface");
323 }
324 return true;
325 }
326
327 protected boolean setUpInterfaceOptions(Element config_elem)
328 {
329 Element option_list = (Element) GSXML.getChildByTagName(config_elem, "optionList");
330 if (option_list != null)
331 {
332 logger.debug("found an interface optionList");
333 // we set any options in the config params
334 NodeList options = option_list.getElementsByTagName("option");
335 for (int i = 0; i < options.getLength(); i++)
336 {
337 Element option = (Element) options.item(i);
338 String name = option.getAttribute(GSXML.NAME_ATT);
339 String value = option.getAttribute(GSXML.VALUE_ATT);
340 logger.debug("option: " + name + ", " + value);
341 if (!name.equals("") && !value.equals(""))
342 {
343 this.config_params.put(name, value);
344 }
345 }
346 }
347
348 return true;
349 }
350
351 protected void preProcessRequest(Element request)
352 {
353 return;
354 }
355
356 protected Node postProcessPage(Element page)
357 {
358 return page;
359 }
360
361}
Note: See TracBrowser for help on using the repository browser.