source: greenstone3/trunk/src/java/org/greenstone/gsdl3/action/NoCollQueryAction.java@ 14226

Last change on this file since 14226 was 14226, checked in by xiao, 17 years ago

change getFirstChild() to getFirstElementChild() in case an extra line break or white space added before the first element child which might cause a cast exception.

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