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

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

Adding in security capabilities for Greenstone 3

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