source: greenstone3/trunk/src/java/org/greenstone/gsdl3/action/NoCollQueryAction.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: 8.8 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.Text;
9import org.w3c.dom.Document;
10import org.w3c.dom.Element;
11
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.Vector;
15import java.util.Map;
16import java.util.Iterator;
17import java.io.File;
18
19import org.apache.log4j.*;
20
21/** action class for queries
22 * this is used when querying isn't collection specific, but it occurs across all collections in the site. The service description is assumed to be known by the xslt so we dont ask for it. we just pass all the service params to the TextQuery service of all the collections */
23public class NoCollQueryAction extends Action {
24
25 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.NoCollQueryAction.class.getName());
26 /** process - processes a request.
27 */
28 public Node process (Node message_node) {
29
30 Element message = this.converter.nodeToElement(message_node);
31
32 // get the request - assume there is only one
33 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
34
35 // create the return message
36 Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
37 // for now we only have one type of query - subaction not used
38 Element response = basicQuery(request);
39 result.appendChild(this.doc.importNode(response, true));
40 return result;
41 }
42
43 /** a generic query handler
44 * this gets the service description, does the query (just passes all teh
45 * params to the service, then gets the titles for any results
46 */
47 protected Element basicQuery(Element request) {
48
49 // the result
50 Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
51
52 // extract the params from the cgi-request, and check that we have a coll specified
53 Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
54 HashMap params = GSXML.extractParams(cgi_param_list, false);
55
56 String request_type = (String)params.get(GSParams.REQUEST_TYPE);
57 String lang = request.getAttribute(GSXML.LANG_ATT);
58 String uid = request.getAttribute(GSXML.USER_ID_ATT);
59 if (request_type.equals("d")) {
60 // display the query page
61 // the only info we need to return is the collection list cos the xslt does teh rest
62
63 Element coll_list = getCollectionList(lang, uid);
64 page_response.appendChild(this.doc.importNode(coll_list, true));
65 return page_response;
66
67 }
68
69 // else we have a query
70 String service_name = (String)params.get(GSParams.SERVICE);
71 if (service_name == null || service_name.equals("")) {
72 service_name = "TextQuery";
73 }
74 String query_coll_list = (String)params.get(GSParams.COLLECTION);
75
76 if (query_coll_list == null || query_coll_list.equals("")) {
77 logger.error("no collections were specified!");
78 Element coll_list = getCollectionList(lang, uid);
79 page_response.appendChild(this.doc.importNode(coll_list, true));
80 return page_response;
81 }
82
83 // service paramList
84 HashMap service_params = (HashMap)params.get("s1");
85 if (service_params == null) { // no query
86 return page_response;
87 }
88 Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
89 GSXML.addParametersToList(this.doc, query_param_list, service_params);
90
91 // we will do a query for each coll
92 String [] colls = query_coll_list.split(",");
93
94 Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
95
96 for (int i=0; i< colls.length; i++) {
97 String to = GSPath.appendLink(colls[i], service_name);
98 Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
99 mr_query_message.appendChild(mr_query_request);
100 mr_query_request.appendChild(query_param_list.cloneNode(true));
101
102 }
103
104 // do the query
105 Element mr_query_response = (Element)this.mr.process(mr_query_message);
106
107
108 // get the Title metadata for each node - need Node title and root title
109 Element mr_meta_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
110 NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
111 for (int j=0; j<responses.getLength(); j++) {
112 Element document_list = (Element)GSXML.getChildByTagName((Element)responses.item(j), GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
113 if (document_list != null) {
114 String coll_name = extractCollName(((Element)responses.item(j)).getAttribute(GSXML.FROM_ATT));
115 String path = GSPath.appendLink(coll_name, "DocumentMetadataRetrieve");
116 Element mr_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, path, lang, uid);
117 mr_meta_message.appendChild(mr_meta_request);
118 mr_meta_request.appendChild(this.doc.importNode(document_list, true));
119 // metadata params
120 Element param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
121 Element param = GSXML.createParameter(this.doc, "metadata", "Title");
122 param_list.appendChild(param);
123 param = GSXML.createParameter(this.doc, "metadata", "root_Title");
124 param_list.appendChild(param);
125 mr_meta_request.appendChild(param_list);
126
127 }
128 }
129
130 // do the request
131 Element mr_meta_response = (Element)this.mr.process(mr_meta_message);
132
133 // the result
134 Element result_doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
135 page_response.appendChild(result_doc_list);
136
137 responses = mr_meta_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
138 for (int j=0; j<responses.getLength(); j++) {
139 Element document_list = (Element)GSXML.getChildByTagName((Element)responses.item(j), GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
140 String coll_name = extractCollName(((Element)responses.item(j)).getAttribute(GSXML.FROM_ATT));
141
142 mergeDocLists(result_doc_list, document_list, coll_name );
143 }
144
145
146 return page_response;
147 }
148
149 protected String extractCollName(String path) {
150 return GSPath.removeLastLink(path);
151 }
152
153 protected void mergeDocLists(Element result_list, Element from_list, String collection) {
154
155 Document owner = result_list.getOwnerDocument();
156 Node child = from_list.getFirstChild();
157 while (child != null && child.getNodeType() == Node.ELEMENT_NODE) {
158 ((Element)child).setAttribute("collection", collection);
159 result_list.appendChild(owner.importNode(child, true));
160 child = child.getNextSibling();
161 }
162
163 }
164
165
166 protected Element getCollectionList(String lang, String uid) {
167
168 // first, get the message router info
169 Element coll_list_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
170 Element coll_list_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", lang, uid);
171 coll_list_message.appendChild(coll_list_request);
172 Element coll_list_response = (Element)this.mr.process(coll_list_message);
173 if (coll_list_response==null) {
174 logger.error("couldn't query the message router!");
175 return null;
176 }
177
178 // second, get the display info for each collection
179 NodeList colls = coll_list_response.getElementsByTagName(GSXML.COLLECTION_ELEM);
180
181 Element coll_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
182 Element param = GSXML.createParameter(this.doc, GSXML.SUBSET_PARAM, GSXML.DISPLAY_TEXT_ELEM+GSXML.LIST_MODIFIER);
183 coll_param_list.appendChild(param);
184 // we will send all the requests in a single message
185 Element metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
186 for (int i=0; i<colls.getLength(); i++) {
187 Element c = (Element)colls.item(i);
188 String name = c.getAttribute(GSXML.NAME_ATT);
189
190 Element metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, name, lang, uid);
191 metadata_request.appendChild(coll_param_list.cloneNode(true));
192 metadata_message.appendChild(metadata_request);
193 }
194
195 Element metadata_response = (Element)this.mr.process(metadata_message);
196
197 NodeList coll_responses = metadata_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
198 // check that have same number of responses as collections
199 if (colls.getLength() != coll_responses.getLength()) {
200 logger.error("didn't get a response for each collection - somethings gone wrong!");
201 // for now, dont use the metadata
202 } else {
203 for (int i=0; i<colls.getLength(); i++) {
204 Element c1 = (Element)colls.item(i);
205 Element c2 = (Element)coll_responses.item(i);
206 if (c1.getAttribute(GSXML.NAME_ATT).equals(c2.getAttribute(GSXML.FROM_ATT))) {
207 //add the collection data into the original response
208 GSXML.mergeElements(c1, (Element)GSXML.getChildByTagName(c2, GSXML.COLLECTION_ELEM));
209 } else {
210 logger.error("response does not correspond to request!");
211 }
212
213 }
214 }
215
216 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER);
217 Element response = (Element) GSXML.getNodeByPath(coll_list_response, path);
218 return response;
219
220 }
221}
Note: See TracBrowser for help on using the repository browser.