source: greenstone3/trunk/src/java/org/greenstone/gsdl3/action/BrowseAction.java@ 16688

Last change on this file since 16688 was 16688, checked in by davidb, 16 years ago

Changed 'Element process(Element)' in ModuleInterface to 'Node process(Node)'. After some deliberation is was decided this is a more useful (generic) layer of the DOM to pass information around in. Helps with the DocType problem when producing XSL Transformed pages, for example. When this was an Element, it would loose track of its DocType. Supporting method provided in XMLConverter 'Element nodeToElement(Node)' which checks a nodes docType and casts to Element if appropriate, or if a Document, typecasts to that and then extracts the top-level Element. With this fundamental change in ModuleInterface, around 20 files needed to be updated (Actions, Services, etc) that build on top of 'process()' to reflect this change, and use nodeToElement where necessary.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1package org.greenstone.gsdl3.action;
2
3import org.greenstone.gsdl3.core.ModuleInterface;
4import org.greenstone.gsdl3.util.*;
5// XML classes
6import org.w3c.dom.Node;
7import org.w3c.dom.NodeList;
8import org.w3c.dom.Document;
9import org.w3c.dom.Element;
10
11import java.util.HashMap;
12import java.util.HashSet;
13import java.util.Vector;
14import java.io.File;
15
16import org.apache.log4j.*;
17
18//NOTE: this class not used at present!!!!!
19/** action for classifier browsing */
20public class BrowseAction extends Action {
21
22 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.BrowseAction.class.getName());
23
24 public static final String CLASSIFIER_ARG = "cl";
25 public static final String SIBLING_ARG = "sib";
26
27 /** process the request */
28 public Node process (Node message_node) {
29
30 Element message = this.converter.nodeToElement(message_node);
31
32 // get the request - assume only one
33 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
34
35 // the result
36 Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
37 Element response = classifierBrowse(request);
38 result.appendChild(response);
39 return result;
40 }
41
42
43 protected Element classifierBrowse(Element request) {
44
45 Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
46
47 // extract the params from the cgi-request, and check that we have a coll specified
48 Element cgi_paramList = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
49 HashMap params = GSXML.extractParams(cgi_paramList, false);
50
51 String service_name = (String)params.get(GSParams.SERVICE);
52 String collection = (String)params.get(GSParams.COLLECTION);
53 if (collection == null || collection.equals("")) {
54 logger.error("classifierBrowse, need to specify a collection!");
55 return page_response;
56
57 }
58
59 //whether to retrieve siblings or not
60 boolean get_siblings = false;
61 String sibs = (String) params.get(SIBLING_ARG);
62 if (sibs != null && sibs.equals("1")) {
63 get_siblings = true;
64 }
65
66 String lang = request.getAttribute(GSXML.LANG_ATT);
67 String uid = request.getAttribute(GSXML.USER_ID_ATT);
68 String to = GSPath.appendLink(collection, service_name);
69
70 // the first part of the response is the service description
71 // for now get this again from the service.
72 // this should be cached somehow later on.
73
74 Element info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
75 Element info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid);
76 info_message.appendChild(info_request);
77
78 // also get the format stuff now if there is some
79 Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid);
80 info_message.appendChild(format_request);
81 // process the requests
82
83 Element info_response = (Element) this.mr.process(info_message);
84
85 // the two responses
86 NodeList responses = info_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
87 Element service_response = (Element)responses.item(0);
88 Element format_response = (Element)responses.item(1);
89
90 Element service_description = (Element)GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM);
91 page_response.appendChild(this.doc.importNode(service_description, true));
92
93 // if rt=d, then we are just displaying the service
94 String request_type = (String)params.get(GSParams.REQUEST_TYPE);
95 if (request_type.equals("d")) {
96 //return the page that we have so far
97 return page_response;
98 }
99
100 // get the node that the user has clicked on
101 String classifier_node = (String)params.get(CLASSIFIER_ARG);
102
103 // if the node is not defined, return the page that we have so far
104 if (classifier_node ==null || classifier_node.equals("")) {
105 return page_response;
106 }
107
108 // the id of the classifier is the top id of the selected node
109 String top_id = OID.getTop(classifier_node);
110
111 HashSet metadata_names = new HashSet();
112
113 // add the format info into the response
114 Element format_elem = (Element)GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);
115 if (format_elem != null) {
116 // find the one for the classifier we are in
117 Element this_format = GSXML.getNamedElement(format_elem, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id);
118 if (this_format == null) {
119 this_format = (Element)GSXML.getChildByTagName(format_elem, GSXML.DEFAULT_ELEM);
120 }
121 if (this_format != null) {
122 Element new_format = GSXML.duplicateWithNewName(this.doc, this_format, GSXML.FORMAT_ELEM, false);
123 // set teh format type
124 new_format.setAttribute(GSXML.TYPE_ATT, "browse");
125
126 page_response.appendChild(new_format);
127 extractMetadataNames(new_format, metadata_names);
128 }
129 }
130
131 logger.info("extracted meta names, "+metadata_names.toString());
132 // get the browse structure for the selected node
133 Element classify_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
134 Element classify_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
135 classify_message.appendChild(classify_request);
136
137 //Create a parameter list to specify the required structure information
138 // for now, always get ancestors and children
139 Element param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
140 classify_request.appendChild(param_list);
141 Element param = this.doc.createElement(GSXML.PARAM_ELEM);
142 param_list.appendChild(param);
143 param.setAttribute(GSXML.NAME_ATT, "structure");
144 param.setAttribute(GSXML.VALUE_ATT, "ancestors");
145 param = this.doc.createElement(GSXML.PARAM_ELEM);
146 param_list.appendChild(param);
147 param.setAttribute(GSXML.NAME_ATT, "structure");
148 param.setAttribute(GSXML.VALUE_ATT, "children");
149 if (get_siblings) {
150 param = this.doc.createElement(GSXML.PARAM_ELEM);
151 param_list.appendChild(param);
152 param.setAttribute(GSXML.NAME_ATT, "structure");
153 param.setAttribute(GSXML.VALUE_ATT, "siblings");
154 }
155
156 // put the classifier node into a classifier node list
157 Element classifier_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
158 Element classifier = this.doc.createElement(GSXML.CLASS_NODE_ELEM);
159 classifier.setAttribute(GSXML.NODE_ID_ATT, classifier_node);
160 classifier_list.appendChild(classifier);
161 classify_request.appendChild(classifier_list);
162
163 // process the request
164 Element classify_response = (Element)this.mr.process(classify_message);
165 // get the structure element
166 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
167 path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM);
168 path = GSPath.appendLink(path, GSXML.NODE_STRUCTURE_ELEM);
169 // assume that we always get back the top level CL1 node - this becomes the page_classifier node
170 path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM);
171 Element cl_structure = (Element)GSXML.getNodeByPath(classify_response,
172 path);
173 if (cl_structure ==null) {
174 logger.error("classifier structure request returned no structure");
175 return page_response;
176 }
177
178 // add the classifier node as the page classifier
179 Element page_classifier = GSXML.duplicateWithNewName(this.doc, cl_structure, GSXML.CLASSIFIER_ELEM, true);
180 page_response.appendChild(page_classifier);
181 page_classifier.setAttribute(GSXML.NAME_ATT, top_id);
182
183 // get the metadata for each classifier node,
184 // then for each document node
185
186 Element metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
187
188 boolean did_classifier = false;
189 boolean did_documents = false;
190
191
192 // if there are classifier nodes
193 // create a metadata request for the classifier, and add it to
194 // the the message
195 NodeList cl_nodes = page_classifier.getElementsByTagName(GSXML.CLASS_NODE_ELEM);
196
197 if (cl_nodes.getLength() > 0) {
198 did_classifier = true;
199 Element cl_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to+"MetadataRetrieve", lang, uid);
200 metadata_message.appendChild(cl_meta_request);
201
202 Element new_cl_nodes_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
203 cl_meta_request.appendChild(new_cl_nodes_list);
204
205 for (int c=0; c<cl_nodes.getLength(); c++) {
206
207 Element cl = this.doc.createElement(GSXML.CLASS_NODE_ELEM);
208 cl.setAttribute(GSXML.NODE_ID_ATT, ((Element)cl_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT));
209 new_cl_nodes_list.appendChild(cl);
210 }
211
212 // create and add in the param list - for now get all the metadata
213 // should be based on info sent in from the recept, and the
214 // format stuff
215 Element cl_param_list = null;
216 if (metadata_names.isEmpty()) {
217 cl_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
218 Element p = this.doc.createElement(GSXML.PARAM_ELEM);
219 cl_param_list.appendChild(p);
220 p.setAttribute(GSXML.NAME_ATT, "metadata");
221 p.setAttribute(GSXML.VALUE_ATT, "Title");
222 } else {
223 cl_param_list = createMetadataParamList(metadata_names);
224 }
225
226 cl_meta_request.appendChild(cl_param_list);
227
228 }
229
230 // if there are document nodes in the classification (happens
231 // sometimes), create a second request for document metadata and
232 // append to the message
233 NodeList doc_nodes = page_classifier.getElementsByTagName(GSXML.DOC_NODE_ELEM);
234 if (doc_nodes.getLength() > 0) {
235 did_documents = true;
236 Element doc_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, GSPath.appendLink(collection, "DocumentMetadataRetrieve"), lang, uid);
237 metadata_message.appendChild(doc_meta_request);
238
239 Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
240 doc_meta_request.appendChild(doc_list);
241
242 for (int c=0; c<doc_nodes.getLength(); c++) {
243
244 Element d = this.doc.createElement(GSXML.DOC_NODE_ELEM);
245 d.setAttribute(GSXML.NODE_ID_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT));
246 doc_list.appendChild(d);
247 }
248
249 // create and add in the param list - add all for now
250 Element doc_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
251 Element p = this.doc.createElement(GSXML.PARAM_ELEM);
252 doc_param_list.appendChild(p);
253 p.setAttribute(GSXML.NAME_ATT, "metadata");
254 p.setAttribute(GSXML.VALUE_ATT, "all");
255 doc_meta_request.appendChild(doc_param_list);
256
257 }
258
259 // process the metadata requests
260 Element metadata_response = (Element)this.mr.process(metadata_message);
261 if (did_classifier) {
262 // the classifier one will be the first response
263 // add the metadata lists for each node back into the
264 // page_classifier nodes
265 path = GSPath.appendLink(GSXML.RESPONSE_ELEM,
266 GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
267 NodeList meta_response_cls = GSXML.getNodeByPath(metadata_response, path).getChildNodes();
268 for (int i = 0; i < cl_nodes.getLength(); i++) {
269 GSXML.mergeMetadataLists(cl_nodes.item(i), meta_response_cls.item(i));
270 }
271 }
272 if (did_documents) {
273 NodeList meta_response_docs = null;
274 if (!did_classifier) {
275 // its the first response
276 path = GSPath.appendLink(GSXML.RESPONSE_ELEM,
277 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
278 meta_response_docs = GSXML.getNodeByPath(metadata_response, path).getChildNodes();
279 } else { // its the second response
280 meta_response_docs = GSXML.getChildByTagName(metadata_response.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1), GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER).getChildNodes();
281 }
282
283 for (int i = 0; i < doc_nodes.getLength(); i++) {
284 GSXML.mergeMetadataLists(doc_nodes.item(i), meta_response_docs.item(i));
285 }
286 }
287
288
289 logger.debug("(BrowseAction) Page:\n" + this.converter.getPrettyString(page_response));
290 return page_response;
291 }
292
293 protected Element unknownBrowse(Element page, Element request, String browse_type) {
294 logger.error("unknown browse subtype: "+browse_type);
295 return null;
296 }
297}
298
299
Note: See TracBrowser for help on using the repository browser.