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

Last change on this file since 38373 was 38373, checked in by kjdon, 7 months ago

if we are page action (used as default when no action was specified), and no subaction specified, if collection is specified, use about page, otherwise use home page. This is to allow urls like library/collection/lucene-demo. This means that MR must only set a=p as teh default, not sa=home

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