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

Last change on this file since 25635 was 25635, checked in by sjm84, 12 years ago

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

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