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

Last change on this file since 25871 was 25871, checked in by kjdon, 12 years ago

commented out some long debug things

  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 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 if (this.mr != null)
63 {
64 this.mr.cleanUp();
65 }
66 }
67
68 public void setParams(GSParams params)
69 {
70 this.params = params;
71 }
72
73 public void setConfigParams(HashMap<String, Comparable> params)
74 {
75 this.config_params = params;
76 }
77
78 public HashMap<String, Comparable> getConfigParams()
79 {
80 return this.config_params;
81 }
82
83 /**
84 * sets the message router - it should already be created and configured
85 * before being passed to the receptionist
86 */
87 public void setMessageRouter(ModuleInterface m)
88 {
89 this.mr = m;
90 }
91
92 /**
93 * gets the message router
94 */
95 public ModuleInterface getMessageRouter()
96 {
97 return this.mr;
98 }
99
100 /** configures the receptionist */
101 public boolean configure()
102 {
103
104 if (this.config_params == null)
105 {
106 logger.error(" config variables must be set before calling configure");
107 return false;
108 }
109 if (this.mr == null)
110 {
111 logger.error(" message router must be set before calling configure");
112 return false;
113 }
114
115 // find the config file containing a list of actions
116 File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String) this.config_params.get(GSConstants.INTERFACE_NAME))));
117 if (!interface_config_file.exists())
118 {
119 logger.error(" interface config file: " + interface_config_file.getPath() + " not found!");
120 return false;
121 }
122
123 Document config_doc = this.converter.getDOM(interface_config_file);
124 if (config_doc == null)
125 {
126 logger.error(" could not parse interface config file: " + interface_config_file.getPath());
127 return false;
128 }
129 Element config_elem = config_doc.getDocumentElement();
130 String base_interface = config_elem.getAttribute("baseInterface");
131 setUpBaseInterface(base_interface);
132 setUpInterfaceOptions(config_elem);
133
134 // load up the actions
135 Element action_list = (Element) GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM + GSXML.LIST_MODIFIER);
136 NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
137
138 for (int i = 0; i < actions.getLength(); i++)
139 {
140 Element action = (Element) actions.item(i);
141 String class_name = action.getAttribute("class");
142 String action_name = action.getAttribute("name");
143 Action ac = null;
144 try
145 {
146 ac = (Action) Class.forName("org.greenstone.gsdl3.action." + class_name).newInstance();
147 }
148 catch (Exception e)
149 {
150 logger.error(" couldn't load in action " + class_name);
151 e.printStackTrace();
152 continue;
153 }
154 ac.setConfigParams(this.config_params);
155 ac.setMessageRouter(this.mr);
156 ac.configure();
157 ac.addActionParameters(this.params);
158 this.action_map.put(action_name, ac);
159 }
160
161 this.language_list = (Element) GSXML.getChildByTagName(config_elem, "languageList");
162 if (language_list == null)
163 {
164 logger.error(" didn't find a language list in the config file!!");
165 }
166
167 return true;
168 }
169
170 public String process(String xml_in)
171 {
172
173 Node message_node = this.converter.getDOM(xml_in);
174 Node page = process(message_node);
175 return this.converter.getString(page);
176 }
177
178 /**
179 * process - produce a page of data in response to a request if something
180 * goes wrong, it returns null - TODO: return a suitable message to the user
181 */
182 public Node process(Node message_node)
183 {
184 Element message = this.converter.nodeToElement(message_node);
185
186 // get the request out of the message - assume that there is only one
187 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
188 if (request == null)
189 {
190 logger.error(" message had no request!");
191 return null;
192 }
193 // check the request type
194 String type = request.getAttribute(GSXML.TYPE_ATT); // returns "" if no att of this name
195 if (type.equals(GSXML.REQUEST_TYPE_SECURITY))
196 {
197 return this.mr.process(message);
198 }
199
200 if (!type.equals(GSXML.REQUEST_TYPE_PAGE))
201 {
202 // now Receptionist forwards non-page requests straight to the MR, and returns the responses
203 logger.error(" request type is not '" + GSXML.REQUEST_TYPE_PAGE + "', but it is '" + type + "', so forwarding the message to the MR!");
204 // process the whole message - mr needs <message> tags, and
205 // in this case, there may be more than one request in the message
206 return this.mr.process(message);
207 }
208 // work out which action to pass to
209 String action = request.getAttribute(GSXML.ACTION_ATT);
210 if (action.equals(""))
211 {
212 logger.error(" no action specified in the request!");
213 return null;
214 }
215
216 // find the appropriate action
217 Action a = this.action_map.get(action);
218
219 String action_name = null;
220 if (a == null)
221 { // not in the map yet
222 // try to load a new action
223 try
224 {
225 action_name = action.substring(0, 1).toUpperCase() + action.substring(1) + "Action";
226 Action ac = (Action) Class.forName("org.greenstone.gsdl3.action." + action_name).newInstance();
227 ac.setConfigParams(this.config_params);
228 ac.setMessageRouter(this.mr);
229 ac.configure();
230 ac.addActionParameters(this.params);
231 this.action_map.put(action, ac);
232 a = ac;
233 }
234 catch (Exception e)
235 {
236
237 logger.error(" a new action (" + action_name + ") was specified and it couldn't be created. Error message:" + e.getMessage());
238 return null;
239 }
240 }
241 // transform the request in some way -- does nothing!
242 preProcessRequest(request);
243 // set up the page
244 Element page = this.doc.createElement(GSXML.PAGE_ELEM);
245 page.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
246 // just in case these namespaces end up in the page and we want to display the XML
247 page.setAttribute("xmlns:gsf", "http://www.greenstone.org/greenstone3/schema/ConfigFormat");
248 page.setAttribute("xmlns:xsl", "http://www.w3.org/1999/XSL/Transform");
249
250 //logger.info(a+" mesa=" + this.converter.getPrettyString(message));
251 // get the page data from the action
252
253 Node action_response = a.process(message);
254 boolean response_only = false;
255 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
256 if (param_list != null)
257 {
258 Element param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, "ro");
259 if (param != null)
260 {
261 String value = param.getAttribute("value");
262 if (value.equals("1"))
263 {
264 response_only = true;
265 }
266 }
267 }
268 if (response_only)
269 {
270 // only the response from the action is sent back
271 return action_response;
272 }
273
274 // the request is part of the page
275 page.appendChild(GSXML.duplicateWithNewName(this.doc, request, GSXML.PAGE_REQUEST_ELEM, true));
276 // add the response too
277 Element page_response = GSXML.duplicateWithNewName(this.doc, (Element) GSXML.getChildByTagName(action_response, GSXML.RESPONSE_ELEM), GSXML.PAGE_RESPONSE_ELEM, true);
278 page.appendChild(page_response);
279
280 //logger.info(" raw page="+this.converter.getString(page));
281 // transform the result in some way
282 //Element resulting_page = postProcessPage(page);
283
284 Node resulting_page = postProcessPage(page);
285
286 //logger.debug("receptionist returned response");
287 //logger.error("receptionist returned response");
288 //logger.debug(this.converter.getString(resulting_page));
289 //logger.error(this.converter.getString(resulting_page));
290 // logger.info("receptionist returned response");
291 // logger.info(this.converter.getString(resulting_page));
292 return resulting_page;
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.