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

Last change on this file since 23405 was 23405, checked in by sjb48, 13 years ago

FormatAction constructs message containing format string that is sent to the collection. The message knows the service, and if it is the browse service, then it also knows the classifer list number.

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