source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/PageAction.java@ 32991

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

refactored the code as lots of functions were doing the same thing. for new verify page, we get and add the security info to teh page response. this may still need tidying up as I have run out of time today

  • Property svn:keywords set to Author Date Id Revision
File size: 18.0 KB
Line 
1package org.greenstone.gsdl3.action;
2
3import java.io.Serializable;
4import java.util.HashMap;
5
6import org.apache.log4j.Logger;
7import org.greenstone.gsdl3.service.CollectionGroups;
8import org.greenstone.gsdl3.util.GSParams;
9import org.greenstone.gsdl3.util.GSPath;
10import org.greenstone.gsdl3.util.GSXML;
11import org.greenstone.gsdl3.util.UserContext;
12import org.greenstone.gsdl3.util.XMLConverter;
13import org.greenstone.util.GlobalProperties;
14import org.w3c.dom.Document;
15import org.w3c.dom.Element;
16import org.w3c.dom.Node;
17import org.w3c.dom.NodeList;
18
19public class PageAction extends Action
20{
21
22 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.PageAction.class.getName());
23
24 public static final String HOME_PAGE = "home";
25 public static final String ABOUT_PAGE = "about";
26 public static final String PREFS_PAGE = "pref";
27 public static final String GLI4GS3_PAGE = "gli4gs3";
28 public static final String VERIFY_PAGE = "verify";
29
30 // this gets set to the groupInfo service name if there is one.
31 protected String groupInfoServiceName = null;
32
33 public Node process(Node message_node)
34
35 {
36 Element message = GSXML.nodeToElement(message_node);
37 Document doc = XMLConverter.newDOM();
38
39 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
40 Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
41 String collection = "";
42 if (paramList != null)
43 {
44 HashMap<String, Serializable> params = GSXML.extractParams(paramList, false);
45 if (params != null && params.get(GSParams.COLLECTION) != null)
46 {
47 collection = (String) params.get(GSParams.COLLECTION);
48 }
49 }
50
51 // the page name is the subaction
52 String page_name = request.getAttribute(GSXML.SUBACTION_ATT);
53 if (page_name.equals(""))
54 { // if no page specified, assume home page
55 page_name = HOME_PAGE;
56 }
57
58 Element result = doc.createElement(GSXML.MESSAGE_ELEM);
59 Element response;
60 if (page_name.equals(HOME_PAGE))
61 {
62 response = homePage(request);
63
64 }
65 else if (page_name.equals(GLI4GS3_PAGE))
66 {
67 response = gli4gs3Page(request);
68 } else if (collection.equals("")) {
69 // we are not in a collection. eg could be library prefs or other page
70 response = generalLibraryPage(request, page_name);
71 } else {
72 // we are in a collection
73 response = collectionPage(request, page_name, collection);
74 }
75
76
77 result.appendChild(doc.importNode(response, true));
78 logger.debug("page action result: " + this.converter.getPrettyString(result));
79
80 return result;
81 }
82
83 // A general library page just adds site metadata and interface options.
84 // customise: prefs: add language list
85 protected Element generalLibraryPage(Element request, String page_name) {
86
87 Document doc = XMLConverter.newDOM();
88 UserContext userContext = new UserContext(request);
89 Element response = doc.createElement(GSXML.RESPONSE_ELEM);
90 addSiteMetadata(response, userContext);
91 addInterfaceOptions(response);
92 if (page_name.equals(PREFS_PAGE) && this.language_list != null) {
93 response.appendChild(doc.importNode(this.language_list, true));
94 }
95 return response;
96 }
97
98 protected Element collectionPage(Element request, String page_name, String collection) {
99
100 Document doc = XMLConverter.newDOM();
101
102 UserContext userContext = new UserContext(request);
103 // extract the params from the cgi-request,
104 Element cgi_paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
105 HashMap<String, Serializable> params = GSXML.extractParams(cgi_paramList, false);
106
107 // get the collection or cluster description
108 Element coll_about_message = doc.createElement(GSXML.MESSAGE_ELEM);
109
110 Element coll_about_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, collection, userContext);
111 coll_about_message.appendChild(coll_about_request);
112
113 Element coll_about_response = (Element) this.mr.process(coll_about_message);
114
115 Element response = (Element) GSXML.getChildByTagName(coll_about_response, GSXML.RESPONSE_ELEM);
116
117 if (response == null) {
118 // what should we be returning?
119 return null;
120 }
121
122 //add the site metadata
123 addSiteMetadata(response, userContext);
124 addInterfaceOptions(response);
125
126 if (page_name.equals(PREFS_PAGE) && this.language_list != null) {
127 response.appendChild(response.getOwnerDocument().importNode(this.language_list, true));
128 }
129
130 // is this collection part of a group?
131 String group = (String) params.get(GSParams.GROUP);
132 if (group != null && !group.equals("")) {
133 // ...yes it is. get the group path info
134 Element group_info_response = getGroupInfo(group, userContext);
135 Element path_list = (Element) GSXML.getChildByTagName(group_info_response,
136 GSXML.PATH_ELEM + GSXML.LIST_MODIFIER);
137 if (path_list != null) {
138 response.appendChild(response.getOwnerDocument().importNode(path_list, true));
139 }
140 }
141
142 if (page_name.equals(ABOUT_PAGE)) {
143 // get service descriptions. Actually only want displayItems
144 NodeList services = coll_about_response.getElementsByTagName(GSXML.SERVICE_ELEM);
145 if (services.getLength() > 0)
146 {
147 sendMultipleRequests(doc, services, collection, GSXML.REQUEST_TYPE_DESCRIBE, userContext);
148 }
149
150 }
151 // old code had adding a ct param to the paramList - for about/prefs page, only used for gs2 interface. Since we don't support that anymore, am leaving it out.
152
153 // add the global collection format info
154 Element formatMessage = doc.createElement(GSXML.MESSAGE_ELEM);
155 Element formatRequest = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_FORMAT, collection, userContext);
156 formatMessage.appendChild(formatRequest);
157 Element formatResponseMessage = (Element) this.mr.process(formatMessage);
158 Element formatResponse = (Element) GSXML.getChildByTagName(formatResponseMessage, GSXML.RESPONSE_ELEM);
159
160 Element globalFormat = (Element) GSXML.getChildByTagName(formatResponse, GSXML.FORMAT_ELEM);
161 if (globalFormat != null)
162 {
163 response.appendChild(response.getOwnerDocument().importNode(globalFormat, true));
164 }
165
166 if (page_name.equals(VERIFY_PAGE)) {
167 addSecurityInfo(request, collection, response);
168 }
169
170 return response;
171 }
172
173
174 protected Element homePage(Element request)
175 {
176 Document doc = XMLConverter.newDOM();
177
178 UserContext userContext = new UserContext(request);
179 // first, get the message router info
180 Element info_message = doc.createElement(GSXML.MESSAGE_ELEM);
181 Element info_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
182 //Create param list
183 Element param_list_element = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
184 info_request.appendChild(param_list_element);
185 //Describe params without collectionlist. Collectionlist provided by CollectionGroup service
186 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
187 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
188 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.SITE_ELEM + GSXML.LIST_MODIFIER);
189 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
190 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
191 info_message.appendChild(info_request);
192 //Send request to message router
193 Element info_response_message = (Element) this.mr.process(info_message);
194 //Check if it is not null
195 if (info_response_message == null)
196 {
197 logger.error(" couldn't query the message router!");
198 return null;
199 }
200 //Check if it is not null
201 Element info_response = (Element) GSXML.getChildByTagName(info_response_message, GSXML.RESPONSE_ELEM);
202 if (info_response == null)
203 {
204 logger.error("couldn't query the message router!");
205 return null;
206 }
207
208 // import it into our current doc.
209 info_response = (Element) doc.importNode(info_response, true);
210
211 Element resp_service_list = (Element) GSXML.getChildByTagName(info_response, GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
212
213 // TODO - is this true? can we run with no MR services? can't we still query for the collections/MR info?
214 if (resp_service_list == null) {
215 logger.error("No services available. Couldn't query the message router!");
216 return null;
217 }
218
219 // if we haven't done so already, check for group info type service
220 if (this.groupInfoServiceName == null) {
221
222 Element groupInfoService = GSXML.getNamedElement(resp_service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT,
223 CollectionGroups.GROUP_CONTENT);
224
225 if (groupInfoService != null) {
226 this.groupInfoServiceName = CollectionGroups.GROUP_CONTENT;
227 } else {
228 this.groupInfoServiceName = "NO_GROUPS";
229 }
230 }
231
232 if (!this.groupInfoServiceName.equals("NO_GROUPS")) {
233 String group = null;
234 Element cgi_paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
235 HashMap<String, Serializable> params = GSXML.extractParams(cgi_paramList, false);
236 if (params != null) {
237 group = (String) params.get(GSParams.GROUP);
238 if (group != null && group.equals("")) {
239 group = null;
240 }
241 }
242
243 Element group_info_response = getGroupInfo(group, userContext);
244
245 // Add all the needed parts of the response to the main page response
246 Element collection_list = (Element) GSXML.getChildByTagName(group_info_response,
247 GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
248
249 if (collection_list != null) {
250 info_response.appendChild(doc.importNode(collection_list, true));
251 } else {
252 logger.warn("Home page had no collection list");
253 }
254 Element group_list = (Element) GSXML.getChildByTagName(group_info_response,
255 GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
256 if (group_list != null) {
257 info_response.appendChild(doc.importNode(group_list, true));
258 }
259 Element path_list = (Element) GSXML.getChildByTagName(group_info_response,
260 GSXML.PATH_ELEM + GSXML.LIST_MODIFIER);
261 if (path_list != null) {
262 info_response.appendChild(doc.importNode(path_list, true));
263 }
264
265 } else {
266
267 // If no service with type SERVICE_TYPE_GROUPINFO could be provided
268 // request message router for all available collections
269 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM,
270 GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
271 info_response_message = (Element) this.mr.process(info_message);
272
273 if (info_response_message == null) {
274 logger.error(" couldn't query the message router!");
275 return null;
276 }
277 info_response = (Element) GSXML.getChildByTagName(info_response_message, GSXML.RESPONSE_ELEM);
278 if (info_response == null) {
279 logger.error("couldn't query the message router!");
280 return null;
281 }
282 }
283
284 // second, get the metadata for each collection - we only want specific
285 // elements but for now, we'll just get it all
286 Element collection_list = (Element) GSXML.getChildByTagName(info_response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
287 if (collection_list != null)
288 {
289 NodeList colls = GSXML.getChildrenByTagName(collection_list, GSXML.COLLECTION_ELEM);
290 if (colls.getLength() > 0)
291 {
292 sendMultipleRequests(doc, colls, null, GSXML.REQUEST_TYPE_DESCRIBE, userContext);
293 }
294 }
295
296 // get metadata for any services
297 Element service_list = (Element) GSXML.getChildByTagName(info_response, GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
298 if (service_list != null)
299 {
300 NodeList services = GSXML.getChildrenByTagName(service_list, GSXML.SERVICE_ELEM);
301 if (services.getLength() > 0)
302 {
303 sendMultipleRequests(doc, services, null, GSXML.REQUEST_TYPE_DESCRIBE, userContext);
304 }
305 }
306
307 // get metadata for service clusters
308 Element cluster_list = (Element) GSXML.getChildByTagName(info_response, GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
309 if (cluster_list != null)
310 {
311 NodeList clusters = GSXML.getChildrenByTagName(cluster_list, GSXML.CLUSTER_ELEM);
312 if (clusters.getLength() > 0)
313 {
314 sendMultipleRequests(doc, clusters, null, GSXML.REQUEST_TYPE_DESCRIBE, userContext);
315
316 }
317 }
318
319 addSiteMetadata(info_response, userContext);
320 addInterfaceOptions(info_response);
321 // all the components have been merged into info_response
322 return info_response;
323
324 } // homePage
325
326 /** sends a request to GroupCurrentContent service to get group info. null group will give top level info,
327 otherwise will just give info for specified group */
328 protected Element getGroupInfo(String group, UserContext userContext) {
329 Document doc = XMLConverter.newDOM();
330 // collections and groups list
331 Element group_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
332 Element group_info_request = GSXML.createBasicRequest(doc, GSXML.TO_ATT,
333 groupInfoServiceName, userContext);
334 group_info_message.appendChild(group_info_request);
335 if (group != null) {
336 Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
337 GSXML.addParameterToList(param_list, GSParams.GROUP, group);
338 group_info_request.appendChild(param_list);
339 }
340 // send off the request
341 Element group_info_response_message = (Element) this.mr.process(group_info_message);
342 Element group_info_response = (Element) GSXML.getChildByTagName(group_info_response_message,
343 GSXML.RESPONSE_ELEM);
344 return group_info_response;
345 }
346
347
348 protected boolean addSecurityInfo(Element request, String collection, Element response) {
349 logger.error("in add security");
350 Document doc = XMLConverter.newDOM();
351 Element securityMessage = doc.createElement(GSXML.MESSAGE_ELEM);
352 Element securityRequest = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_SECURITY, collection, new UserContext(request));
353 securityMessage.appendChild(securityRequest);
354
355 Element securityResponse = (Element) GSXML.getChildByTagName(this.mr.process(securityMessage), GSXML.RESPONSE_ELEM);
356 logger.error("security response = "+XMLConverter.getPrettyString(securityResponse));
357
358 Document r_doc = response.getOwnerDocument();
359 // just get the top level node and attributes
360 // Element new_sec = (Element)r_doc.importNode(securityResponse, true); //createElement(GSXML.SECURITY_ELEMENT);
361 Element new_sec = GSXML.duplicateWithNewName(r_doc, securityResponse, "security", true);
362 // just in case this is present
363 new_sec.removeAttribute("secretKey");
364 logger.error("new security element = "+XMLConverter.getPrettyString(new_sec));
365 response.appendChild(new_sec);
366 return true;
367
368 }
369
370 protected boolean sendMultipleRequests(Document doc, NodeList items, String path_prefix, String request_type, UserContext userContext)
371 {
372 // we will send all the requests in a single message
373 Element message = doc.createElement(GSXML.MESSAGE_ELEM);
374 for (int i = 0; i < items.getLength(); i++)
375 {
376 Element c = (Element) items.item(i);
377 String path = c.getAttribute(GSXML.NAME_ATT);
378 if (path_prefix != null)
379 {
380 path = GSPath.appendLink(path_prefix, path);
381 }
382 Element request = GSXML.createBasicRequest(doc, request_type, path, userContext);
383 message.appendChild(request);
384 }
385
386 Element response_message = (Element) this.mr.process(message);
387
388 NodeList responses = response_message.getElementsByTagName(GSXML.RESPONSE_ELEM);
389 // check that have same number of responses as requests
390 if (items.getLength() != responses.getLength())
391 {
392 logger.error("didn't get a response for each request - somethings gone wrong!");
393 return false;
394 }
395
396 for (int i = 0; i < items.getLength(); i++)
397 {
398 Element c1 = (Element) items.item(i);
399 Element c2 = (Element) GSXML.getChildByTagName((Element) responses.item(i), c1.getTagName());
400 if (c1 != null && c2 != null && c1.getAttribute(GSXML.NAME_ATT).endsWith(c2.getAttribute(GSXML.NAME_ATT)))
401 {
402 //add the new data into the original element
403 GSXML.mergeElements(c1, c2);
404 }
405 else
406 {
407 logger.debug(" response does not correspond to request!");
408 }
409
410 }
411
412 return true;
413
414 }
415
416 protected Element gli4gs3Page(Element request)
417 {
418 Document doc = XMLConverter.newDOM();
419
420 String lang = request.getAttribute(GSXML.LANG_ATT);
421 String uid = request.getAttribute(GSXML.USER_ID_ATT);
422
423 Element page_response = doc.createElement(GSXML.RESPONSE_ELEM);
424
425 Element applet_elem = doc.createElement("Applet");
426 page_response.appendChild(applet_elem);
427 applet_elem.setAttribute("ARCHIVE", "SignedGatherer.jar"); // SignedGatherer.jar should be placed in web/applet.
428 applet_elem.setAttribute("CODE", "org.greenstone.gatherer.WebGatherer");
429 applet_elem.setAttribute("CODEBASE", "applet"); // SignedGatherer.jar is in web/applet. But CODEBASE is the *URL* path to the (jar) file containing the main class, and is relative to documentroot "web".
430 applet_elem.setAttribute("HEIGHT", "50");
431 applet_elem.setAttribute("WIDTH", "380");
432
433 Element gwcgi_param_elem = doc.createElement("PARAM");
434 gwcgi_param_elem.setAttribute("name", "gwcgi");
435 String library_name = GlobalProperties.getGSDL3WebAddress();
436 gwcgi_param_elem.setAttribute("value", library_name);
437 applet_elem.appendChild(gwcgi_param_elem);
438
439 Element gsdl3_param_elem = doc.createElement("PARAM");
440 gsdl3_param_elem.setAttribute("name", "gsdl3");
441 gsdl3_param_elem.setAttribute("value", "true");
442 applet_elem.appendChild(gsdl3_param_elem);
443
444 // When an applet doesn't work in the browser, set the default display text to provide a link to the JNLP file to run with Java Web Start
445 // The display text will be:
446 // Applets don't seem to work in your browser. In place of the GLI Applet, try running its alternative <a href="applet/GLIappWebStart.jnlp">Java Web Start (JNLP) version</a>
447 Node default_text = doc.createTextNode("Applets don't seem to work in your browser. In place of the GLI Applet, try running its alternative ");
448 Element link_to_jnlp = doc.createElement("a");
449 link_to_jnlp.setAttribute("href", "applet/GLIappWebStart.jnlp");
450 Node anchor_text = doc.createTextNode("Java Web Start (JNLP) version");
451 link_to_jnlp.appendChild(anchor_text);
452 applet_elem.appendChild(default_text);
453 applet_elem.appendChild(link_to_jnlp);
454
455 return page_response;
456 }
457}
Note: See TracBrowser for help on using the repository browser.