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

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

Adding UserContext to replace the use of lang and uid

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