source: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Search.java@ 4903

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

tidied up a lot of stuff, particularly the display text stuff, including how its formatted, and some of the service rack methods

  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/*
2 * GS2Search.java
3 * Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.service;
20
21
22// Greenstone classes
23import org.greenstone.gdbm.*;
24import org.greenstone.gsdl3.util.*;
25
26// XML classes
27import org.w3c.dom.Element;
28import org.w3c.dom.Document;
29import org.w3c.dom.NodeList;
30
31
32/**
33 *
34 * @author <a href="mailto:[email protected]">Michael Dewsnip</a>
35 * @version $Revision: 4903 $
36 */
37
38public abstract class GS2Search
39 extends ServiceRack {
40
41 // the services on offer
42 // these strings must match what is found in the properties file
43 protected static final String TEXT_QUERY_SERVICE = "TextQuery";
44
45 // Parameters used
46 protected static final String INDEX_PARAM = "index";
47 protected static final String CASE_PARAM = "case";
48 protected static final String STEM_PARAM = "stem";
49 protected static final String MATCH_PARAM = "matchMode";
50 protected static final String MATCH_PARAM_ALL = "all";
51 protected static final String MATCH_PARAM_SOME = "some";
52 protected static final String MAXDOCS_PARAM = "maxDocs";
53 protected static final String BOOLEAN_PARAM_ON = "1";
54 protected static final String BOOLEAN_PARAM_OFF = "0";
55 protected static final String QUERY_PARAM = "query";
56
57 protected static final String EQUIV_TERM_ELEM = "equivTerm";
58
59 protected static final String STEM_ATT = "stem";
60 protected static final String NUM_DOCS_MATCH_ATT = "numDocsMatch";
61 protected static final String FREQ_ATT = "freq";
62
63 // Elements used in the config file that are specific to this class
64 protected static final String DEFAULT_INDEX_ELEM = "defaultIndex";
65 protected static final String DEFAULT_LEVEL_ELEM = "defaultLevel";
66 protected static final String INDEX_ELEM = "index";
67 protected static final String LEVEL_ELEM = "level";
68
69 protected GDBMWrapper gdbm_src_ = null;
70
71 protected Element config_info_ = null;
72
73 /** the default index */
74 protected String default_index_ = null;
75
76
77 /** constructor */
78 public GS2Search()
79 {
80 gdbm_src_ = new GDBMWrapper();
81 }
82
83
84 /** configure this service */
85 public boolean configure(Element info, Element extra_info)
86 {
87 System.out.println("Configuring GS2Search...");
88 addExtraQueryInfo(info, extra_info);
89 config_info_ = info;
90
91 // Get the default index out of <defaultIndex> (buildConfig.xml)
92 Element def = (Element) GSXML.getChildByTagName(info, DEFAULT_INDEX_ELEM);
93 if (def != null) {
94 default_index_ = def.getAttribute(GSXML.NAME_ATT);
95 }
96 if (default_index_ == null || default_index_.equals("")) {
97 System.err.println("Error: default index not specified!");
98 return false;
99 }
100
101 // these entries should reflect the build config file - some services may not be available depending on how the collection was built.
102 // set up short_service_info_ - for now just has id and type. the name (lang dependent) will be added in if the list is requested.
103 Element tq_service = doc_.createElement(GSXML.SERVICE_ELEM);
104 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
105 tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
106 short_service_info_.appendChild(tq_service);
107
108
109 // Open GDBM database for querying
110 String gdbm_db_file = GSFile.GDBMDatabaseFile(site_home_, cluster_name_);
111 if (!gdbm_src_.openDatabase(gdbm_db_file, GDBMWrapper.READER)) {
112 System.err.println("Error: Could not open GDBM database!");
113 return false;
114 }
115
116 // add some format info to service map if there is any
117 Element format = (Element) GSXML.getChildByTagName(info, GSXML.FORMAT_ELEM);
118 if (format != null) {
119 format_info_map_.put(TEXT_QUERY_SERVICE, doc_.importNode(format, true));
120 }
121
122 return true;
123 }
124
125 protected Element getServiceDescription(String service, String lang) {
126
127 if (!service.equals(TEXT_QUERY_SERVICE)) {
128 return null;
129 }
130 Element tq_service = doc_.createElement(GSXML.SERVICE_ELEM);
131 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
132 tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
133 tq_service.appendChild(GSXML.createDisplayTextElement(doc_, GSXML.DISPLAY_TEXT_NAME, getTextString(TEXT_QUERY_SERVICE+".name", lang)));
134 tq_service.appendChild(GSXML.createDisplayTextElement(doc_, GSXML.DISPLAY_TEXT_SUBMIT, getTextString(TEXT_QUERY_SERVICE+".submit", lang)));
135 Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
136 createTextQueryParamList(param_list, lang);
137 tq_service.appendChild(param_list);
138 return tq_service;
139
140 }
141
142 protected boolean addExtraQueryInfo(Element info, Element extra_info){
143
144 if (extra_info == null) {
145 return false;
146 }
147
148 Document owner = info.getOwnerDocument();
149 // so far we have index specific display elements, and global format elements
150 NodeList indexes = info.getElementsByTagName(GSXML.INDEX_ELEM);
151 Element config_search = (Element)GSXML.getChildByTagName(extra_info, GSXML.SEARCH_ELEM);
152
153 for (int i=0; i<indexes.getLength();i++) {
154 Element ind = (Element)indexes.item(i);
155 String name = ind.getAttribute(GSXML.NAME_ATT);
156 Element node_extra = GSXML.getNamedElement(config_search,
157 GSXML.INDEX_ELEM,
158 GSXML.NAME_ATT,
159 name);
160 if (node_extra == null) {
161 System.err.println("GS2Search: haven't found extra info for index named "+name);
162 continue;
163 }
164
165 // get the display elements if any - displayName
166 NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
167 if (display_names !=null) {
168 for (int j=0; j<display_names.getLength(); j++) {
169 Element e = (Element)display_names.item(j);
170 ind.appendChild(owner.importNode(e, true));
171 }
172 }
173 } // for each index
174
175 // get the format element if any
176 Element format = (Element)GSXML.getChildByTagName(config_search,
177 GSXML.FORMAT_ELEM);
178 if (format!=null) { // append to info
179 info.appendChild(owner.importNode(format, true));
180 }
181 return true;
182
183
184 }
185/** creates a new param element and adds it to the param list */
186 protected void createParameter(String name, Element param_list,
187 /*boolean display,*/ String lang)
188 {
189 Element param=null;
190
191 if (name.equals(INDEX_PARAM)) {
192 // the index info - read from config file
193 Element index_list = (Element)GSXML.getChildByTagName(config_info_, INDEX_ELEM+GSXML.LIST_MODIFIER);
194 NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
195 int len = indexes.getLength();
196 // now add even if there is only one
197 String [] inds = new String[len];
198 String [] ind_names = new String[len];
199 for (int i=0; i<len; i++) {
200 Element index = (Element)indexes.item(i);
201 inds[i] = index.getAttribute(GSXML.NAME_ATT);
202 ind_names[i] = GSXML.getDisplayText(index, GSXML.DISPLAY_TEXT_NAME, lang, "en");
203
204 }
205 param = GSXML.createParameterDescription(doc_, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, default_index_, inds, ind_names);
206
207 }
208 else if (name.equals(CASE_PARAM) || name.equals(STEM_PARAM)) {
209 String[] bool_ops = {"0", "1"};
210 String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)};
211 param = GSXML.createParameterDescription(doc_, name, getTextString("param."+name, lang), GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, bool_ops, bool_texts);
212 }
213 else if (name.equals(MATCH_PARAM)) {
214 String[] vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
215 String[] val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)};
216 param = GSXML.createParameterDescription(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals, val_texts);
217
218 }
219 else if (name.equals(MAXDOCS_PARAM)) {
220 param = GSXML.createParameterDescription(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), GSXML.PARAM_TYPE_INTEGER, "10", null, null);
221
222 }
223 else if (name.equals(QUERY_PARAM)) {
224 param = GSXML.createParameterDescription(doc_, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, null, null);
225
226 }
227
228 // add the param to the list
229 if (param != null) {
230 param_list.appendChild(param);
231 }
232 }
233
234
235 /** this creates all the params and appends them to param_list.
236 * if display=true it creates the text strings version
237 * otherwise it creates the description version
238 */
239 protected abstract boolean createTextQueryParamList(Element param_list,
240 String lang);
241
242 /** Creates a new documentNode element containing ID, node type
243 * and docType*/
244 protected Element createDocumentNodeElement(String node_id)
245 {
246 Element doc_node = doc_.createElement(GSXML.DOC_NODE_ELEM);
247 doc_node.setAttribute(GSXML.NODE_ID_ATT, node_id);
248
249 String top_id = OID.getTop(node_id);
250 boolean is_top = (top_id.equals(node_id) ? true : false);
251
252 DBInfo info = gdbm_src_.getInfo(node_id);
253 if (info == null) { // make it up - cant query the gdbm db
254 doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
255 return doc_node;
256 }
257 String children = info.getInfo("contains");
258 boolean is_leaf = (children.equals("") ? true : false);
259
260 // check for simple doc types
261 if (is_top && is_leaf) { // a single section document
262 doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
263 return doc_node;
264 }
265 // set teh node type att
266 if (is_top) {
267 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_ROOT);
268 } else if (is_leaf) {
269 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_LEAF);
270 } else {
271 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_INTERIOR);
272 }
273
274 if (!is_top) { // we need to look at the top info
275 info = gdbm_src_.getInfo(top_id);
276 }
277
278 String childtype = info.getInfo("childtype");
279 if (childtype.equals("Paged")) {
280 doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "paged");
281 } else {
282 doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "hierarchy");
283 }
284 return doc_node;
285 }
286
287 /** returns the document type of a node - if the node is a subnode, it returns teh type of teh top document node. for now, only does paged and hierarchical, but eventually will have more types */
288 protected String getDocType(String node_id) {
289
290 String doc_id = OID.getTop(node_id);
291 DBInfo info = gdbm_src_.getInfo(doc_id);
292 String child_type = info.getInfo("childtype");
293 if (child_type.equals("Paged")) {
294 return "paged";
295 }
296 return "hierarchy";
297
298 }
299
300 /** Returns true if the OID specifies a leaf node, false otherwise
301 Note: this makes a request to the GDBM database so it may not be cheap */
302 protected boolean isLeafNode(String oid)
303 {
304 DBInfo info = gdbm_src_.getInfo(oid);
305 String children = info.getInfo("contains");
306 return (children.equals(""));
307 }
308
309
310 /** Process a text query - implemented by concrete subclasses */
311 protected abstract Element processTextQuery(Element request);
312}
Note: See TracBrowser for help on using the repository browser.