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

Last change on this file since 36648 was 36648, checked in by kjdon, 19 months ago

made this a bit tidier. configure now gets the groupinfoservicename. we use that to determine whether to query MR for collection list, or the group service. if we are just querying mr, then add collectionlist param to main request - saves making another request for it later.

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