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

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

docNodeXXX stuff changed to nodeXXX

  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 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: 3975 $
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 colleciton was built.
102 // set up short_service_info_ - for now just has name and type
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 // set up service_info_map_ - for now, just has the same elements as above
109 // should have full details about each service incl params lists etc.
110 Element tq_service_full = (Element) tq_service.cloneNode(true);
111 Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
112 createTextQueryParamList(param_list, false, null);
113 tq_service_full.appendChild(param_list);
114 service_info_map_.put(TEXT_QUERY_SERVICE, tq_service_full);
115
116 // Open GDBM database for querying
117 String gdbm_db_file = GSFile.GDBMDatabaseFile(site_home_, cluster_name_);
118 if (!gdbm_src_.openDatabase(gdbm_db_file, GDBMWrapper.READER)) {
119 System.err.println("Error: Could not open GDBM database!");
120 return false;
121 }
122
123 // add some format info to service map if there is any
124 Element format = (Element) GSXML.getChildByTagName(info, GSXML.FORMAT_ELEM);
125 if (format != null) {
126 format_info_map_.put(TEXT_QUERY_SERVICE, doc_.importNode(format, true));
127 }
128
129 return true;
130 }
131
132
133 protected boolean addExtraQueryInfo(Element info, Element extra_info){
134
135 if (extra_info == null) {
136 return false;
137 }
138
139 Document owner = info.getOwnerDocument();
140 // so far we have index specific display elements, and global format elements
141 NodeList indexes = info.getElementsByTagName(GSXML.INDEX_ELEM);
142 Element config_search = (Element)GSXML.getChildByTagName(extra_info, GSXML.SEARCH_ELEM);
143
144 for (int i=0; i<indexes.getLength();i++) {
145 Element ind = (Element)indexes.item(i);
146 String name = ind.getAttribute(GSXML.NAME_ATT);
147 Element node_extra = GSXML.getNamedElement(config_search,
148 GSXML.INDEX_ELEM,
149 GSXML.NAME_ATT,
150 name);
151 if (node_extra == null) {
152 System.err.println("GS2Search: haven't found extra info for index named "+name);
153 continue;
154 }
155
156 // get the display elements if any - displayName
157 NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAYNAME_ELEM);
158 if (display_names !=null) {
159 Element display = owner.createElement(GSXML.DISPLAY_ELEM);
160 for (int j=0; j<display_names.getLength(); j++) {
161 Element e = (Element)display_names.item(j);
162
163 Element display_name = GSXML.createTextElement(owner, GSXML.DISPLAY_NAME_ELEM, GSXML.getNodeText(e));
164 display_name.setAttribute(GSXML.LANG_ATT, e.getAttribute(GSXML.LANG_ATT));
165 display.appendChild(display_name);
166 }
167 ind.appendChild(display);
168 }
169 } // for each index
170
171 // get the format element if any
172 Element format = (Element)GSXML.getChildByTagName(config_search,
173 GSXML.FORMAT_ELEM);
174 if (format!=null) { // append to info
175 info.appendChild(owner.importNode(format, true));
176 }
177 return true;
178
179
180 }
181/** creates a new param element and adds it to the param list */
182 protected void createParameter(String name, Element param_list,
183 boolean display, String lang)
184 {
185 Element param=null;
186
187 if (name.equals(INDEX_PARAM)) {
188 // the index info - read from config file
189 Element index_list = (Element)GSXML.getChildByTagName(config_info_, INDEX_ELEM+GSXML.LIST_MODIFIER);
190 NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
191 int len = indexes.getLength();
192 if (len > 1) { // add index param to list only if more than one index specified
193 String [] inds = new String[len];
194 String [] ind_names = new String[len];
195 for (int i=0; i<len; i++) {
196 inds[i] = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT);
197 if (display) {
198 Element disp = (Element)GSXML.getChildByTagName(indexes.item(i), GSXML.DISPLAY_ELEM);
199 ind_names[i] = GSXML.getDisplayText(disp, GSXML.DISPLAY_NAME_ELEM, lang, "en");
200 }
201 }
202 if (display) {
203 param = GSXML.createParameterDisplay(doc_, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), inds, ind_names);
204 } else {
205 param = GSXML.createParameter(doc_, INDEX_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_index_, inds);
206 }
207 }
208 } else if (name.equals(CASE_PARAM)) {
209 if (display) {
210 String[] bool_ops = {"0", "1"};
211 String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)};
212 param = GSXML.createParameterDisplay(doc_, CASE_PARAM, getTextString("param."+CASE_PARAM, lang), bool_ops, bool_texts);
213 } else {
214 param = GSXML.createParameter(doc_, CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
215 }
216 }
217 else if (name.equals(STEM_PARAM)) {
218 if (display) {
219 String[] bool_ops = {"0", "1"};
220 String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)};
221 param = GSXML.createParameterDisplay(doc_, STEM_PARAM, getTextString("param."+STEM_PARAM, lang), bool_ops, bool_texts);
222 } else {
223 param = GSXML.createParameter(doc_, STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
224 }
225 }
226 else if (name.equals(MATCH_PARAM)) {
227 String[] vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
228 if (display) {
229 String[] val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)};
230
231 param = GSXML.createParameterDisplay(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), vals, val_texts);
232 } else {
233 param = GSXML.createParameter(doc_, MATCH_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals);
234 }
235 }
236 else if (name.equals(MAXDOCS_PARAM)) {
237 if (display) {
238 param = GSXML.createParameterDisplay(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), null, null);
239 } else {
240 param = GSXML.createParameter(doc_, MAXDOCS_PARAM, GSXML.PARAM_TYPE_INTEGER, "10", null);
241 }
242 }
243 else if (name.equals(QUERY_PARAM)) {
244 if (display) {
245 param = GSXML.createParameterDisplay(doc_, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), null, null);
246 } else {
247 param = GSXML.createParameter(doc_, QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
248 }
249 }
250
251 // add the param to the list
252 if (param != null) {
253 param_list.appendChild(param);
254 }
255 }
256
257
258 /** this creates all the params and appends them to param_list.
259 * if display=true it creates the text strings version
260 * otherwise it creates the description version
261 */
262 protected abstract boolean createTextQueryParamList(Element param_list,
263 boolean display,
264 String lang);
265
266 /** creates a display element containing all the text strings needed to display
267 the service page, in the language specified */
268 protected Element createServiceDisplay(String service, String lang)
269 {
270 // Create a service display for the basic text query service
271 Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
272 display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM, getTextString(service+".name", lang)));
273 display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
274
275 // now need to add in the params
276 if (service.equals(TEXT_QUERY_SERVICE)) {
277 createTextQueryParamList(display, true, lang);
278 }
279
280 return display;
281 }
282
283
284 /** Creates a new documentNode element containing ID and type */
285 protected Element createDocumentNodeElement(String doc_id)
286 {
287 Element doc_node = doc_.createElement(GSXML.DOC_NODE_ELEM);
288 doc_node.setAttribute(GSXML.NODE_ID_ATT, doc_id);
289 if (OID.isTop(doc_id))
290 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_ROOT);
291 else if (isLeafNode(doc_id))
292 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_LEAF);
293 else
294 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_INTERIOR);
295 return doc_node;
296 }
297
298
299 /** Returns true if the OID specifies a leaf node, false otherwise
300 Note: this makes a request to the GDBM database so it may not be cheap */
301 protected boolean isLeafNode(String oid)
302 {
303 DBInfo info = gdbm_src_.getInfo(oid);
304 String children = info.getInfo("contains");
305 return (children == "");
306 }
307
308
309 /** Process a text query - implemented by concrete subclasses */
310 protected abstract Element processTextQuery(Element request);
311}
Note: See TracBrowser for help on using the repository browser.