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

Last change on this file since 3822 was 3822, checked in by mdewsnip, 21 years ago

Generic base class of GS2MGSearch and GS2MGPPSearch. Implements shared functionality: configuring a textQuery service, with case folding, stemming, "some"/"all" matching, and a maximum number of hits to retrieve. This class is intentionally specific to the abilities of MG and MGPP, and is not intended to be subclassed by any other search engines.

  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 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;
28
29
30/**
31 *
32 * @author <a href="mailto:[email protected]">Katherine Don</a>
33 * @version $Revision: 3822 $
34 */
35
36public abstract class GS2Search
37 extends ServiceRack {
38
39 // the services on offer
40 // these strings must match what is found in the properties file
41 protected static final String TEXT_QUERY_SERVICE = "TextQuery";
42
43 // Parameters used
44 protected static final String CASE_PARAM = "case";
45 protected static final String STEM_PARAM = "stem";
46 protected static final String MATCH_PARAM = "matchMode";
47 protected static final String MATCH_PARAM_ALL = "all";
48 protected static final String MATCH_PARAM_SOME = "some";
49 protected static final String MAXDOCS_PARAM = "maxDocs";
50 protected static final String BOOLEAN_PARAM_ON = "1";
51 protected static final String BOOLEAN_PARAM_OFF = "0";
52 protected static final String QUERY_PARAM = "query";
53
54 protected static final String EQUIV_TERM_ELEM = "equivTerm";
55
56 protected static final String STEM_ATT = "stem";
57 protected static final String NUM_DOCS_MATCH_ATT = "numDocsMatch";
58 protected static final String FREQ_ATT = "freq";
59
60 protected GDBMWrapper gdbm_src_ = null;
61
62 protected Element config_info_ = null;
63
64
65 /** constructor */
66 public GS2Search()
67 {
68 gdbm_src_ = new GDBMWrapper();
69 }
70
71
72 /** configure this service */
73 public boolean configure(Element info)
74 {
75 System.out.println("Configuring GS2Search...");
76 config_info_ = info;
77
78 // these entries should reflect the build config file - some services may not be available depending on how the colleciton was built.
79 // set up short_service_info_ - for now just has name and type
80 Element tq_service = doc_.createElement(GSXML.SERVICE_ELEM);
81 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
82 tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
83 short_service_info_.appendChild(tq_service);
84
85 // set up service_info_map_ - for now, just has the same elements as above
86 // should have full details about each service incl params lists etc.
87 Element tq_service_full = (Element) tq_service.cloneNode(true);
88 Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
89 createTextQueryParamList(param_list, false, null);
90 tq_service_full.appendChild(param_list);
91 service_info_map_.put(TEXT_QUERY_SERVICE, tq_service_full);
92
93 // Open GDBM database for querying
94 String gdbm_db_file = GSFile.GDBMDatabaseFile(site_home_, cluster_name_);
95 if (!gdbm_src_.openDatabase(gdbm_db_file, GDBMWrapper.READER)) {
96 System.err.println("Error: Could not open GDBM database!");
97 return false;
98 }
99
100 return true;
101 }
102
103
104 /** creates a new param element and adds it to the param list */
105 protected void createParameter(String name, Element param_list, boolean display,
106 String lang)
107 {
108 Element param=null;
109
110 if (name.equals(CASE_PARAM)) {
111 if (display) {
112 String[] bool_ops = {"0", "1"};
113 String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)};
114 param = GSXML.createParameterDisplay(doc_, CASE_PARAM, getTextString("param."+CASE_PARAM, lang), bool_ops, bool_texts);
115 } else {
116 param = GSXML.createParameter(doc_, CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
117 }
118 }
119 else if (name.equals(STEM_PARAM)) {
120 if (display) {
121 String[] bool_ops = {"0", "1"};
122 String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)};
123 param = GSXML.createParameterDisplay(doc_, STEM_PARAM, getTextString("param."+STEM_PARAM, lang), bool_ops, bool_texts);
124 } else {
125 param = GSXML.createParameter(doc_, STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
126 }
127 }
128 else if (name.equals(MATCH_PARAM)) {
129 String[] vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
130 if (display) {
131 String[] val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)};
132
133 param = GSXML.createParameterDisplay(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), vals, val_texts);
134 } else {
135 param = GSXML.createParameter(doc_, MATCH_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals);
136 }
137 }
138 else if (name.equals(MAXDOCS_PARAM)) {
139 if (display) {
140 param = GSXML.createParameterDisplay(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), null, null);
141 } else {
142 param = GSXML.createParameter(doc_, MAXDOCS_PARAM, GSXML.PARAM_TYPE_INTEGER, "10", null);
143 }
144 }
145 else if (name.equals(QUERY_PARAM)) {
146 if (display) {
147 param = GSXML.createParameterDisplay(doc_, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), null, null);
148 } else {
149 param = GSXML.createParameter(doc_, QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
150 }
151 }
152
153 // add the param to the list
154 if (param != null) {
155 param_list.appendChild(param);
156 }
157 }
158
159
160 /** this creates all the params and appends them to param_list.
161 * if display=true it creates the text strings version
162 * otherwise it creates the description version
163 */
164 protected boolean createTextQueryParamList(Element param_list, boolean display,
165 String lang)
166 {
167 // the order they are specified here is the order they appear on
168 // the query form
169 createParameter(CASE_PARAM, param_list, display, lang);
170 createParameter(STEM_PARAM, param_list, display, lang);
171 createParameter(MATCH_PARAM, param_list, display, lang);
172 createParameter(MAXDOCS_PARAM, param_list, display, lang);
173 createParameter(QUERY_PARAM, param_list, display, lang);
174 return true;
175 }
176
177
178 /** creates a display element containing all the text strings needed to display
179 the service page, in the language specified */
180 protected Element createServiceDisplay(String service, String lang)
181 {
182 // Create a service display for the basic text query service
183 Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
184 display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,
185 getTextString(service+".name", lang)));
186 display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_SUBMIT_ELEM,
187 getTextString(service+".submit", lang)));
188
189 // now need to add in the params
190 if (service.equals(TEXT_QUERY_SERVICE)) {
191 createTextQueryParamList(display, true, lang);
192 }
193
194 return display;
195 }
196
197
198 /** Creates a new documentNode element containing ID and type */
199 protected Element createDocumentNodeElement(String doc_id)
200 {
201 Element doc_node = doc_.createElement(GSXML.DOC_NODE_ELEM);
202 doc_node.setAttribute(GSXML.DOC_NODE_ID_ATT, doc_id);
203 if (OID.isTop(doc_id))
204 doc_node.setAttribute(GSXML.DOC_NODE_TYPE_ATT, GSXML.NODE_TYPE_ROOT);
205 else if (isLeafNode(doc_id))
206 doc_node.setAttribute(GSXML.DOC_NODE_TYPE_ATT, GSXML.NODE_TYPE_LEAF);
207 else
208 doc_node.setAttribute(GSXML.DOC_NODE_TYPE_ATT, GSXML.NODE_TYPE_INTERIOR);
209 return doc_node;
210 }
211
212
213 /** Returns true if the OID specifies a leaf node, false otherwise
214 Note: this makes a request to the GDBM database so it may not be cheap */
215 protected boolean isLeafNode(String oid)
216 {
217 DBInfo info = gdbm_src_.getInfo(oid);
218 String children = info.getInfo("contains");
219 return (children == "");
220 }
221
222
223 /** Process a text query - implemented by concrete subclasses */
224 protected abstract Element processTextQuery(Element request);
225}
Note: See TracBrowser for help on using the repository browser.