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

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

commented out a debug statement as it has huge output and clogs up the log file

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