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

Last change on this file since 33078 was 33078, checked in by kjdon, 5 years ago

adding in processing <format><paramDefault> in siteConfig and interfaceConfig.

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