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

Last change on this file was 38844, checked in by kjdon, 6 weeks ago

we have already added displayItems and metadata, so don't need to call addSiteMetadata in the home page code

  • 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 // first, get the message router info
194 Element info_message = doc.createElement(GSXML.MESSAGE_ELEM);
195 Element info_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
196 //Create param list
197 Element param_list_element = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
198 info_request.appendChild(param_list_element);
199
200 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
201 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
202 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.SITE_ELEM + GSXML.LIST_MODIFIER);
203 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
204 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
205
206 // are we using collection groups?
207 // if not, get the coll list from MR
208 if (this.groupInfoServiceName.equals ("NO_GROUPS")) {
209 GSXML.addParameterToList(param_list_element, GSXML.SUBSET_PARAM, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
210 }
211 info_message.appendChild(info_request);
212
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 addInterfaceOptions(info_response);
312 // all the components have been merged into info_response
313
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.