source: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java@ 4980

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

a new simplified browse action for gs2 colls

  • Property svn:keywords set to Author Date Id Revision
File size: 14.4 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
16/** action for GS2 style classifier browsing */
17public class GS2BrowseAction extends Action {
18
19 public static final String CLASSIFIER_ARG = "cl";
20 //public static final String SIBLING_ARG = "sib";
21 // public static final String HORIZ_AT_TOP_ARG = "hat";
22
23 /** process the request */
24 public Element process (Element message) {
25
26 // get the request - assume only one
27 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
28
29 // the result
30 Element result = doc_.createElement(GSXML.MESSAGE_ELEM);
31 Element response = classifierBrowse(request);
32 result.appendChild(response);
33 return result;
34 }
35
36
37 protected Element classifierBrowse(Element request) {
38
39 Element page_response = doc_.createElement(GSXML.RESPONSE_ELEM);
40
41 // extract the params from the cgi-request, and check that we have a coll specified
42 Element cgi_paramList = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
43 HashMap params = GSXML.extractParams(cgi_paramList, false);
44
45 String service_name = (String)params.get(GSCGI.SERVICE_ARG);
46 String collection = (String)params.get(GSCGI.COLLECTION_ARG);
47 if (collection == null || collection.equals("")) {
48 System.err.println("GS2BrowseAction Error:classifierBrowse, need to specify a collection!");
49 return page_response;
50
51 }
52
53// boolean horizontal_at_top = false;
54// String hat = (String) params.get(HORIZ_AT_TOP_ARG);
55// if (hat != null && hat.equals("1")) {
56// horizontal_at_top = true;
57// }
58 //whether to retrieve siblings or not
59// boolean get_siblings = false;
60// String sibs = (String) params.get(SIBLING_ARG);
61// if (sibs != null && sibs.equals("1")) {
62// get_siblings = true;
63// }
64
65 String lang = request.getAttribute(GSXML.LANG_ATT);
66 String to = GSPath.appendLink(collection, service_name);
67
68 // the first part of the response is the service description
69 // for now get this again from the service.
70 // this should be cached somehow later on.
71
72 Element info_message = doc_.createElement(GSXML.MESSAGE_ELEM);
73 Element info_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_DESCRIBE, to, lang);
74 info_message.appendChild(info_request);
75
76 // also get the format stuff now if there is some
77 Element format_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_FORMAT, to, lang);
78 info_message.appendChild(format_request);
79 // process the requests
80
81 Element info_response = (Element) mr_.process(info_message);
82
83 // the two responses
84 NodeList responses = info_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
85 Element service_response = (Element)responses.item(0);
86 Element format_response = (Element)responses.item(1);
87
88 Element service_description = (Element)GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM);
89 page_response.appendChild(doc_.importNode(service_description, true));
90
91 // if rt=d, then we are just displaying the service
92 String request_type = (String)params.get(GSCGI.REQUEST_TYPE_ARG);
93 if (request_type.equals("d")) {
94 //return the page that we have so far
95 return page_response;
96 }
97
98 // get the node that the user has clicked on
99 String classifier_node = (String)params.get(CLASSIFIER_ARG);
100
101 // if the node is not defined, return the page that we have so far
102 if (classifier_node ==null || classifier_node.equals("")) {
103 return page_response;
104 }
105
106 // the id of the classifier is the top id of the selected node
107 String top_id = OID.getTop(classifier_node);
108
109 HashSet doc_meta_names = new HashSet();
110 HashSet class_meta_names = new HashSet();
111 // add in the defaults
112 doc_meta_names.add("Title");
113 class_meta_names.add("Title");
114
115 // add the format info into the response
116 Element format_elem = (Element)GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);
117 if (format_elem != null) {
118
119 // find the one for the classifier we are in
120 Element this_format = GSXML.getNamedElement(format_elem, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id);
121 if (this_format != null) {
122 Element new_format = GSXML.duplicateWithNewName(doc_, this_format, GSXML.FORMAT_ELEM, false);
123 extractMetadataNames(new_format, doc_meta_names, class_meta_names);
124 // set teh format type
125 new_format.setAttribute(GSXML.TYPE_ATT, "browse");
126
127 page_response.appendChild(new_format);
128 }
129 }
130
131 // find out if this classifier is horizontal at top
132 Element class_list = (Element)GSXML.getChildByTagName(service_description, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
133 Element this_classifier = GSXML.getNamedElement(class_list, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id);
134 boolean horizontal_at_top = false;
135 if (!this_classifier.getAttribute("horizontalAtTop").equals("")) {
136 horizontal_at_top = true;
137 }
138
139 // get the browse structure for the selected node
140 Element classify_message = doc_.createElement(GSXML.MESSAGE_ELEM);
141 Element classify_request = doc_.createElement(GSXML.REQUEST_ELEM);
142 classify_message.appendChild(classify_request);
143
144 classify_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
145 classify_request.setAttribute(GSXML.TO_ATT, to);
146 classify_request.setAttribute(GSXML.LANG_ATT, lang);
147
148
149 //Create a parameter list to specify the required structure information
150 // for now, always get ancestors and children
151 Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
152 classify_request.appendChild(param_list);
153 Element param = doc_.createElement(GSXML.PARAM_ELEM);
154 param_list.appendChild(param);
155 param.setAttribute(GSXML.NAME_ATT, "structure");
156 param.setAttribute(GSXML.VALUE_ATT, "ancestors");
157 param = doc_.createElement(GSXML.PARAM_ELEM);
158 param_list.appendChild(param);
159 param.setAttribute(GSXML.NAME_ATT, "structure");
160 param.setAttribute(GSXML.VALUE_ATT, "children");
161// if (get_siblings) {
162// param = doc_.createElement(GSXML.PARAM_ELEM);
163// param_list.appendChild(param);
164// param.setAttribute(GSXML.NAME_ATT, "structure");
165// param.setAttribute(GSXML.VALUE_ATT, "siblings");
166// }
167
168 // put the classifier node into a classifier node list
169 Element classifier_list = doc_.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
170 Element classifier = doc_.createElement(GSXML.CLASS_NODE_ELEM);
171 classifier.setAttribute(GSXML.NODE_ID_ATT, classifier_node);
172 classifier_list.appendChild(classifier);
173 classify_request.appendChild(classifier_list);
174
175 if (horizontal_at_top && !classifier_node.equals(top_id)) {
176 // also put the top id in, to get teh persistant horizontal info
177 classifier = doc_.createElement(GSXML.CLASS_NODE_ELEM);
178 classifier.setAttribute(GSXML.NODE_ID_ATT, top_id);
179 classifier_list.appendChild(classifier);
180 System.out.println("GS2Browse:adding in the top node");
181 }
182 // process the request
183 Element classify_response = (Element)mr_.process(classify_message);
184 System.out.println("GS2Browse: classify response***********");
185 System.out.println(converter_.getPrettyString(classify_response));
186 // get the structure element
187 //String [] links = {GSXML.MESSAGE_ELEM, GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER};
188 //String path = GSPath.createPath(links);
189 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
190 Element class_node_list = (Element)GSXML.getNodeByPath(classify_response, path);
191
192 //path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM);
193 path = GSPath.appendLink(GSXML.CLASS_NODE_ELEM, GSXML.NODE_STRUCTURE_ELEM);
194 // assume that we always get back the top level CL1 node - this becomes the page_classifier node
195 path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM);
196 Element cl_structure = (Element)GSXML.getNodeByPath(class_node_list,
197 path);
198 if (cl_structure ==null) {
199 System.err.println("GS2BrowseAction: classifier structure request returned no structure");
200 return page_response;
201 }
202
203 Element page_classifier = null;
204 if (horizontal_at_top && !classifier_node.equals(top_id)) {
205 // get the info for the top node
206 //NodeList class_nodes = class_node_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
207
208 Element top_node = GSXML.getNamedElement(class_node_list, GSXML.CLASS_NODE_ELEM, GSXML.NODE_ID_ATT, top_id);
209 if (top_node !=null) {
210 path = GSPath.appendLink(GSXML.NODE_STRUCTURE_ELEM, GSXML.CLASS_NODE_ELEM);
211 Element top_structure = (Element)GSXML.getNodeByPath(top_node, path);
212 // add this as the classifier elem
213 page_classifier = GSXML.duplicateWithNewName(doc_, top_structure, GSXML.CLASSIFIER_ELEM, true);
214 page_response.appendChild(page_classifier);
215 // now replace the child with the structure from the other request
216 Element new_classifier = (Element)GSXML.getChildByTagName(cl_structure, GSXML.CLASS_NODE_ELEM);
217 String replace_name = new_classifier.getAttribute(GSXML.NODE_ID_ATT);
218
219 // find the appropriate child
220 Element old_classifier = GSXML.getNamedElement(page_classifier, GSXML.CLASS_NODE_ELEM, GSXML.NODE_ID_ATT, replace_name);
221 page_classifier.replaceChild(doc_.importNode(new_classifier, true), old_classifier);
222 page_classifier.setAttribute(GSXML.NAME_ATT, top_id);
223 } else {
224 // add the single classifier node as the page classifier
225 page_classifier = GSXML.duplicateWithNewName(doc_, cl_structure, GSXML.CLASSIFIER_ELEM, true);
226 page_response.appendChild(page_classifier);
227 page_classifier.setAttribute(GSXML.NAME_ATT, top_id);
228 }
229
230 } else {
231 // add the single classifier node as the page classifier
232 page_classifier = GSXML.duplicateWithNewName(doc_, cl_structure, GSXML.CLASSIFIER_ELEM, true);
233 page_response.appendChild(page_classifier);
234 page_classifier.setAttribute(GSXML.NAME_ATT, top_id);
235 }
236 // get the metadata for each classifier node,
237 // then for each document node
238
239 Element metadata_message = doc_.createElement(GSXML.MESSAGE_ELEM);
240
241 boolean did_classifier = false;
242 boolean did_documents = false;
243
244
245 // if there are classifier nodes
246 // create a metadata request for the classifier, and add it to
247 // the the message
248 NodeList cl_nodes = page_classifier.getElementsByTagName(GSXML.CLASS_NODE_ELEM);
249
250 if (cl_nodes.getLength() > 0) {
251 did_classifier = true;
252 Element cl_meta_request = doc_.createElement(GSXML.REQUEST_ELEM);
253 metadata_message.appendChild(cl_meta_request);
254 cl_meta_request.setAttribute(GSXML.TO_ATT, to+"MetadataRetrieve");
255 cl_meta_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
256 cl_meta_request.setAttribute(GSXML.LANG_ATT, lang);
257
258 Element new_cl_nodes_list = doc_.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
259 cl_meta_request.appendChild(new_cl_nodes_list);
260
261 for (int c=0; c<cl_nodes.getLength(); c++) {
262
263 Element cl = doc_.createElement(GSXML.CLASS_NODE_ELEM);
264 cl.setAttribute(GSXML.NODE_ID_ATT, ((Element)cl_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT));
265 new_cl_nodes_list.appendChild(cl);
266 }
267
268 // create and add in the param list - for now get all the metadata
269 // should be based on info sent in from the recept, and the
270 // format stuff
271 Element cl_param_list = createMetadataParamList(class_meta_names);
272 cl_meta_request.appendChild(cl_param_list);
273
274 }
275
276 // if there are document nodes in the classification (happens
277 // sometimes), create a second request for document metadata and
278 // append to the message
279 NodeList doc_nodes = page_classifier.getElementsByTagName(GSXML.DOC_NODE_ELEM);
280 if (doc_nodes.getLength() > 0) {
281 did_documents = true;
282 Element doc_meta_request = doc_.createElement(GSXML.REQUEST_ELEM);
283 metadata_message.appendChild(doc_meta_request);
284 doc_meta_request.setAttribute(GSXML.TO_ATT, GSPath.appendLink(collection, "DocumentMetadataRetrieve"));
285 doc_meta_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
286 doc_meta_request.setAttribute(GSXML.LANG_ATT, lang);
287
288 Element doc_list = doc_.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
289 doc_meta_request.appendChild(doc_list);
290
291 for (int c=0; c<doc_nodes.getLength(); c++) {
292
293 Element d = doc_.createElement(GSXML.DOC_NODE_ELEM);
294 d.setAttribute(GSXML.NODE_ID_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT));
295 doc_list.appendChild(d);
296 }
297
298 // create and add in the param list - add all for now
299 Element doc_param_list = createMetadataParamList(doc_meta_names);
300 doc_meta_request.appendChild(doc_param_list);
301
302 }
303
304 // process the metadata requests
305 Element metadata_response = (Element)mr_.process(metadata_message);
306 if (did_classifier) {
307 // the classifier one will be the first response
308 // add the metadata lists for each node back into the
309 // page_classifier nodes
310 path = GSPath.appendLink(GSXML.RESPONSE_ELEM,
311 GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
312 NodeList meta_response_cls = GSXML.getNodeByPath(metadata_response, path).getChildNodes();
313 for (int i = 0; i < cl_nodes.getLength(); i++) {
314 GSXML.mergeMetadataLists(cl_nodes.item(i), meta_response_cls.item(i));
315 }
316 }
317 if (did_documents) {
318 NodeList meta_response_docs = null;
319 if (!did_classifier) {
320 // its the first response
321 path = GSPath.appendLink(GSXML.RESPONSE_ELEM,
322 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
323 meta_response_docs = GSXML.getNodeByPath(metadata_response, path).getChildNodes();
324 } else { // its the second response
325 meta_response_docs = GSXML.getChildByTagName(metadata_response.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1), GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER).getChildNodes();
326 }
327
328 for (int i = 0; i < doc_nodes.getLength(); i++) {
329 GSXML.mergeMetadataLists(doc_nodes.item(i), meta_response_docs.item(i));
330 }
331 }
332
333
334 System.out.println("(GS2BrowseAction) Page:\n" + converter_.getPrettyString(page_response));
335 return page_response;
336 }
337
338
339 protected void extractMetadataNames(Element new_format, HashSet doc_meta_names, HashSet class_meta_names) {
340
341 NodeList templates = new_format.getElementsByTagName("gsf:template");
342 for (int i=0; i<templates.getLength(); i++) {
343 Element template = (Element)templates.item(i);
344 String match = template.getAttribute("match");
345 if (match.equals("documentNode")) {
346 extractMetadataNames(template, doc_meta_names);
347 } else if (match.equals("classifierNode")) {
348 extractMetadataNames(template, class_meta_names);
349 }
350 }
351 }
352
353}
354
355
Note: See TracBrowser for help on using the repository browser.