source: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/DocumentAction.java@ 4144

Last change on this file since 4144 was 4144, checked in by kjdon, 21 years ago

all stuff for the page generated by teh Receptionist (config and display) is now put into a pageExtra element, so actions only need to append one extra piece to the page

  • Property svn:keywords set to Author Date Id Revision
File size: 16.5 KB
Line 
1/*
2 * DocumentAction.java
3 * Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.action;
20
21// Greenstone classes
22import org.greenstone.gsdl3.core.ModuleInterface;
23import org.greenstone.gsdl3.util.*;
24
25// XML classes
26import org.w3c.dom.Document;
27import org.w3c.dom.Element;
28import org.w3c.dom.Node;
29import org.w3c.dom.NodeList;
30
31// General Java classes
32import java.util.HashMap;
33import java.io.File;
34
35
36/** Action class for retrieving Documents via the message router
37 */
38public class DocumentAction extends Action {
39
40 // this is used to specify that the sibling nodes of a selected one should be obtained
41 public static final String SIBLING_ARG = "sib";
42
43 /** if this is set to true, when a document is displayed, any annotation
44 * type services (enrich) will be offered to the user as well */
45 protected static final boolean provide_annotations = true;
46
47 /* add the action specific args to the cgi param list
48 */
49 public void addCGIParams() {
50 cgi_.addStaticParam(SIBLING_ARG);
51 }
52
53
54 public Element process (Element message)
55 {
56 // for now, no subaction eventually we may want to have subactions such as text assoc or something ?
57
58 // check that the stylesheet is present
59 String stylesheet = GSFile.stylesheetFile(config_, "document.xsl");
60 if (stylesheet == null) {
61 System.err.println("DocumentAction Error: document stylesheet not found!");
62 return null;
63 }
64
65 // get the request - assume only one
66 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
67 Element cgi_paramList = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
68 HashMap params = GSXML.extractParams(cgi_paramList, false);
69
70 String collection = (String) params.get(GSCGI.COLLECTION_ARG);
71 String lang = request.getAttribute(GSXML.LANG_ATT);
72 String document_name = (String) params.get(GSCGI.DOCUMENT_ARG);
73 if (document_name == null || document_name.equals("")) {
74 System.err.println("DocumentAction Error: no document specified!");
75 return null;
76 }
77
78 //whether to retrieve siblings or not
79 boolean get_siblings = false;
80 String sibs = (String) params.get(SIBLING_ARG);
81 if (sibs != null && sibs.equals("1")) {
82 get_siblings = true;
83 }
84
85 // Create the return page tree
86 Element page = doc_.createElement(GSXML.PAGE_ELEM);
87 page.setAttribute(GSXML.LANG_ATT, lang);
88
89 // Add the page extra element, and original request from the message
90 page.appendChild(doc_.importNode(GSXML.getChildByTagName(message, GSXML.PAGE_EXTRA_ELEM), true));
91 Element page_request = GSXML.duplicateWithNewName(doc_, request, GSXML.PAGE_REQUEST_ELEM, true);
92 page.appendChild(page_request);
93 // the element for all the response data
94 Element page_response = doc_.createElement(GSXML.PAGE_RESPONSE_ELEM);
95 page.appendChild(page_response);
96
97 // get the additional data needed for the page
98 getBackgroundData(page_response, collection, lang);
99
100 // the_document is where all the doc info - structure and metadata etc
101 //- is added into, to be returned in the page
102 Element the_document = doc_.createElement(GSXML.DOCUMENT_ELEM);
103 page_response.appendChild(the_document);
104
105
106 // Build a request to obtain the document structure
107 Element ds_message = doc_.createElement(GSXML.MESSAGE_ELEM);
108 String to = GSPath.appendLink(collection, "DocumentStructureRetrieve"); // Hard-wired?
109 Element ds_request = GSXML.createBasicRequest(doc_,GSXML.REQUEST_TYPE_PROCESS, to, lang);
110 ds_message.appendChild(ds_request);
111
112 // Create a parameter list to specify the required structure information
113 Element ds_param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
114 ds_request.appendChild(ds_param_list);
115 Element ds_param = doc_.createElement(GSXML.PARAM_ELEM);
116 ds_param_list.appendChild(ds_param);
117 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
118 ds_param.setAttribute(GSXML.VALUE_ATT, "ancestors");
119 ds_param = doc_.createElement(GSXML.PARAM_ELEM);
120 ds_param_list.appendChild(ds_param);
121 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
122 ds_param.setAttribute(GSXML.VALUE_ATT, "children");
123 if (get_siblings) {
124 ds_param = doc_.createElement(GSXML.PARAM_ELEM);
125 ds_param_list.appendChild(ds_param);
126 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
127 ds_param.setAttribute(GSXML.VALUE_ATT, "siblings");
128 }
129 // create a doc_node_list and put in the doc_node that we are interested in
130 Element ds_doc_list = doc_.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
131 ds_request.appendChild(ds_doc_list);
132 Element ds_doc = doc_.createElement(GSXML.DOC_NODE_ELEM);
133 ds_doc_list.appendChild(ds_doc);
134 ds_doc.setAttribute(GSXML.NODE_ID_ATT, document_name);
135
136 // Process the document structure retrieve message
137 // System.out.println("(DocumentAction) Structure request:\n" + converter_.getString(ds_message));
138 Element ds_response_message = (Element) mr_.process(ds_message);
139 // System.out.println("(DocumentAction) Structure response:\n" + converter_.getString(ds_response_message));
140
141 // get the doc_node bit
142 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
143 path = GSPath.appendLink(path, GSXML.DOC_NODE_ELEM);
144 path = GSPath.appendLink(path, GSXML.NODE_STRUCTURE_ELEM);
145 Element ds_response_structure = (Element) GSXML.getNodeByPath(ds_response_message, path);
146
147 // add the contents of the structure bit into the_document
148 NodeList structs = ds_response_structure.getChildNodes();
149 for (int i=0; i<structs.getLength();i++) {
150 the_document.appendChild(doc_.importNode(structs.item(i), true));
151 }
152
153 // Build a request to obtain some document metadata
154 Element dm_message = doc_.createElement(GSXML.MESSAGE_ELEM);
155 to = GSPath.appendLink(collection, "DocumentMetadataRetrieve"); // Hard-wired?
156 Element dm_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_PROCESS, to, lang);
157 dm_message.appendChild(dm_request);
158 // Create a parameter list to specify the required metadata information
159 // for now get Title
160 Element dm_param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
161 dm_request.appendChild(dm_param_list);
162 Element dm_param = doc_.createElement(GSXML.PARAM_ELEM);
163 dm_param_list.appendChild(dm_param);
164 dm_param.setAttribute(GSXML.NAME_ATT, "metadata");
165 dm_param.setAttribute(GSXML.VALUE_ATT, "Title");
166
167 // create the doc node list for the metadata request
168 Element dm_doc_list = doc_.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
169 dm_request.appendChild(dm_doc_list);
170
171 // Add each node from the structure response into the metadata request
172 NodeList doc_nodes = the_document.getElementsByTagName(GSXML.DOC_NODE_ELEM);
173 for (int i = 0; i < doc_nodes.getLength(); i++) {
174 Element doc_node = (Element) doc_nodes.item(i);
175 String doc_node_id = doc_node.getAttribute(GSXML.NODE_ID_ATT);
176
177 // Add the documentNode to the list
178 Element dm_doc_node = doc_.createElement(GSXML.DOC_NODE_ELEM);
179 dm_doc_list.appendChild(dm_doc_node);
180 dm_doc_node.setAttribute(GSXML.NODE_ID_ATT, doc_node_id);
181 dm_doc_node.setAttribute(GSXML.NODE_TYPE_ATT,
182 doc_node.getAttribute(GSXML.NODE_TYPE_ATT));
183 }
184
185 // we also want a metadata request to the top level document to get
186 // assocfilepath - this could be cached too
187 Element doc_meta_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_PROCESS, to, lang);
188 dm_message.appendChild(doc_meta_request);
189 Element doc_meta_param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
190 doc_meta_request.appendChild(doc_meta_param_list);
191 Element doc_param = doc_.createElement(GSXML.PARAM_ELEM);
192 doc_meta_param_list.appendChild(doc_param);
193 doc_param.setAttribute(GSXML.NAME_ATT, "metadata");
194 doc_param.setAttribute(GSXML.VALUE_ATT, "assocfilepath");
195
196 // create the doc node list for the metadata request
197 Element doc_list = doc_.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
198 doc_meta_request.appendChild(doc_list);
199
200 Element doc_node = doc_.createElement(GSXML.DOC_NODE_ELEM);
201 // teh node we want is the root document node
202 doc_node.setAttribute(GSXML.NODE_ID_ATT, document_name+".rt");
203 doc_list.appendChild(doc_node);
204 // System.out.println("(DocumentAction) Metadata request:\n" + converter_.getString(dm_request));
205 Element dm_response_message = (Element) mr_.process(dm_message);
206 // System.out.println("(DocumentAction) Metadata response:\n" + converter_.getString(dm_response));
207
208 path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
209 Element dm_response_doc_list = (Element) GSXML.getNodeByPath(dm_response_message, path);
210
211 // Merge the metadata with the structure information
212 NodeList dm_response_docs = dm_response_doc_list.getChildNodes();
213 for (int i = 0; i < doc_nodes.getLength(); i++) {
214 GSXML.mergeMetadataLists(doc_nodes.item(i), dm_response_docs.item(i));
215 }
216 // get teh top level do metadata out
217 Element doc_meta_response = (Element)dm_response_message.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1);
218 Element doc_meta_list = (Element)GSXML.getNodeByPath(doc_meta_response, "documentNodeList/documentNode/metadataList");
219 the_document.appendChild(doc_.importNode(doc_meta_list, true));
220
221 // Build a request to obtain some document content
222 Element dc_message = doc_.createElement(GSXML.MESSAGE_ELEM);
223 to = GSPath.appendLink(collection, "DocumentContentRetrieve"); // Hard-wired?
224 Element dc_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_PROCESS, to, lang);
225 dc_message.appendChild(dc_request);
226
227
228 // Create a parameter list to specify the request parameters - empty for now
229 Element dc_param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
230 dc_request.appendChild(dc_param_list);
231
232 // the doc list for the content request is the same as the one for the structure request
233 dc_request.appendChild(ds_doc_list);
234
235 Element dc_response_message = (Element) mr_.process(dc_message);
236
237 path = GSPath.appendLink(path, GSXML.DOC_NODE_ELEM);
238 Element dc_response_doc = (Element) GSXML.getNodeByPath(dc_response_message, path);
239 Element dc_response_doc_content = (Element) GSXML.getChildByTagName(dc_response_doc, GSXML.NODE_CONTENT_ELEM);
240 if (provide_annotations) {
241 // now we can modifiy the response doc if needed
242 String enrich_service = (String)params.get(GSCGI.SERVICE_ARG);
243 if (enrich_service != null && !enrich_service.equals("")) {
244 // send a message to the service
245 Element enrich_message = doc_.createElement(GSXML.MESSAGE_ELEM);
246 Element enrich_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_PROCESS, enrich_service, lang);
247 enrich_message.appendChild(enrich_request);
248 Element enrich_pl = getServiceParamList(cgi_paramList);
249 enrich_request.appendChild(enrich_pl);
250 Element e_doc_list = doc_.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
251 enrich_request.appendChild(e_doc_list);
252 e_doc_list.appendChild(doc_.importNode(dc_response_doc, true));
253
254 Element enrich_response = mr_.process(enrich_message);
255
256 String [] links = {GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER, GSXML.DOC_NODE_ELEM, GSXML.NODE_CONTENT_ELEM};
257 path = GSPath.createPath(links);
258 dc_response_doc_content = (Element)GSXML.getNodeByPath(enrich_response, path);
259 }
260 }
261 // use the returned id rather than the sent one cos there may have
262 // been modifiers such as .pr that are removed.
263 String modified_doc_id = dc_response_doc.getAttribute(GSXML.NODE_ID_ATT);
264 the_document.setAttribute("selectedNode", modified_doc_id);
265 // Merge the document content with the metadata and structure information
266 for (int i = 0; i < doc_nodes.getLength(); i++) {
267 Node dn = doc_nodes.item(i);
268 String dn_id = ((Element)dn).getAttribute(GSXML.NODE_ID_ATT);
269 if (dn_id.equals(modified_doc_id)) {
270 dn.appendChild(doc_.importNode(dc_response_doc_content, true));
271 break;
272 }
273 }
274
275
276 Document style_doc = converter_.getDOM(new File(stylesheet));
277 GSXSLT.absoluteIncludePaths(style_doc, config_);
278 return (Element) transformer_.transform(style_doc, page);
279 }
280
281 protected Element getServiceParamList(Element cgi_param_list) {
282
283 Element new_param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
284 Element param;
285 NodeList cgi_params = cgi_param_list.getChildNodes();
286 for (int i=0; i<cgi_params.getLength(); i++) {
287 Element p = (Element) cgi_params.item(i);
288 String name = p.getAttribute(GSXML.NAME_ATT);
289 if (name.equals(GSCGI.SERVICE_ARG) || name.equals(GSCGI.REQUEST_TYPE_ARG) || name.equals(GSCGI.CLUSTER_ARG) || name.equals(GSCGI.DOCUMENT_ARG) || name.equals(SIBLING_ARG) ) {
290 continue;
291 }
292 // esle add it in to the list
293 new_param_list.appendChild(doc_.importNode(p, true));
294 }
295 return new_param_list;
296 }
297
298 /** this method gets the collection description, the format info, the
299 * list of enrich services, etc - stuff that is needed for the page,
300 * but is the same whatever the query is - should be cached */
301 protected boolean getBackgroundData(Element page_response,
302 String collection, String lang) {
303
304 // create a message to process - contains requests for the collection
305 // description, the format element, the enrich services on offer
306 // these could all be cached
307 Element info_message = doc_.createElement(GSXML.MESSAGE_ELEM);
308
309 // the collection request
310 Element coll_about_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_DESCRIBE, collection, lang);
311 info_message.appendChild(coll_about_request);
312
313 // the format request - ignore for now, where does this request go to??
314 //Element format_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_FORMAT, ???, lang);
315 //info_message.appendChild(format_request);
316
317 // the enrich_services request - only do this if provide_annotations is true
318
319 if (provide_annotations) {
320 Element enrich_services_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_DESCRIBE, "", lang);
321 enrich_services_request.setAttribute(GSXML.INFO_ATT, "serviceList");
322 info_message.appendChild(enrich_services_request);
323 }
324
325 Element info_response = (Element)mr_.process(info_message);
326
327 // the collection is the first response
328 NodeList responses = info_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
329 Element coll_resp = (Element)responses.item(0);
330 page_response.appendChild(doc_.importNode(GSXML.getChildByTagName(coll_resp, GSXML.COLLECTION_ELEM), true));
331
332 //Element format_resp = (Element) responses.item(1);
333 //page_reponse.appendChild(doc_.importNode(GSXML.getChildByTagName(format_resp, GSXML.FORMAT_ELEM), true));
334
335
336 if (provide_annotations) {
337 Element services_resp = (Element)responses.item(1); // change when format request added in
338
339 // a new message for the mr
340 Element enrich_message = doc_.createElement(GSXML.MESSAGE_ELEM);
341
342 NodeList e_services = services_resp.getElementsByTagName(GSXML.SERVICE_ELEM);
343 boolean service_found = false;
344 for (int j=0; j<e_services.getLength(); j++) {
345 if (((Element)e_services.item(j)).getAttribute(GSXML.TYPE_ATT).equals("enrich")) {
346 Element s = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_DESCRIBE, ((Element)e_services.item(j)).getAttribute(GSXML.NAME_ATT), lang);
347 enrich_message.appendChild(s);
348 service_found = true;
349 }
350 }
351 if (service_found) {
352 Element enrich_response = mr_.process(enrich_message);
353
354 NodeList e_responses = enrich_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
355 Element service_list = doc_.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
356 for (int i=0; i<e_responses.getLength(); i++) {
357 Element e_resp = (Element)e_responses.item(i);
358 Element e_service = (Element)doc_.importNode(GSXML.getChildByTagName(e_resp, GSXML.SERVICE_ELEM), true);
359 e_service.setAttribute(GSXML.NAME_ATT, e_resp.getAttribute(GSXML.FROM_ATT));
360 Element pl = (Element)GSXML.getChildByTagName(e_service, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
361 if (pl != null) {
362 // add short names to the params in the param list
363 cgi_.paramListAddShortNames(pl);
364 }
365 service_list.appendChild(e_service);
366 }
367 page_response.appendChild(service_list);
368 }
369 } // if provide_annotations
370 return true;
371
372 }
373}
Note: See TracBrowser for help on using the repository browser.