source: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS3Search.java@ 6871

Last change on this file since 6871 was 6871, checked in by kjdon, 20 years ago

sql database name is now a combination of site name and coll name

  • Property svn:keywords set to Author Date Id Revision
File size: 13.3 KB
Line 
1/*
2 * GS3Search.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.gsdl3.util.*;
24
25// XML classes
26import org.w3c.dom.Element;
27import org.w3c.dom.Document;
28import org.w3c.dom.NodeList;
29
30import java.io.File;
31
32/**
33 *
34 * @author <a href="mailto:[email protected]">Michael Dewsnip</a>
35 * @version $Revision: 6871 $
36 */
37
38public abstract class GS3Search
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 protected SQLQuery database = null;
71
72 protected Element config_info = null;
73
74 /** the default index */
75 protected String default_index = null;
76
77
78 /** constructor */
79 public GS3Search()
80 {
81 this.database = new SQLQuery();
82 //this.gdbm_src = new GDBMWrapper();
83 }
84
85
86 /** configure this service */
87 public boolean configure(Element info, Element extra_info)
88 {
89 System.out.println("Configuring GS3Search...");
90 addExtraQueryInfo(info, extra_info);
91 this.config_info = info;
92
93 // Get the default index out of <defaultIndex> (buildConfig.xml)
94 Element def = (Element) GSXML.getChildByTagName(info, DEFAULT_INDEX_ELEM);
95 if (def != null) {
96 this.default_index = def.getAttribute(GSXML.NAME_ATT);
97 }
98 if (this.default_index == null || this.default_index.equals("")) {
99 System.err.println("Error: default index not specified!");
100 return false;
101 }
102
103 // these entries should reflect the build config file - some services may not be available depending on how the collection was built.
104 // 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.
105 Element tq_service = this.doc.createElement(GSXML.SERVICE_ELEM);
106 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
107 tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
108 this.short_service_info.appendChild(tq_service);
109
110
111 // Open GDBM database for querying
112 //String gdbm_db_file = GSFile.GDBMDatabaseFile(this.site_home, this.cluster_name);
113 //if (!this.gdbm_src.openDatabase(gdbm_db_file, GDBMWrapper.READER)) {
114 // System.err.println("Error: Could not open GDBM database!");
115 // return false;
116 //}
117 // open the database for querying
118 // the database name is a combination of site name and collection name
119
120 // check that site_home is set
121 if (this.site_home == null || this.site_home.equals("")) {
122 System.err.println("GS3Search Error: site_home is not set, so cannot work out the site name and cannot determine the database name");
123 return false;
124 }
125 String site_name = this.site_home.substring(this.site_home.lastIndexOf(File.separator)+1);
126 if (site_name.equals("")) {
127 System.err.println("GS3Search Error: Cannot extract the site name from site home: "+this.site_home);
128 return false;
129 }
130 if (!database.setDatabase(site_name+"_"+this.cluster_name)) {
131 System.err.println("GS3Search Error: Could not open SQL database!");
132 return false;
133 }
134 // add some format info to service map if there is any
135 Element format = (Element) GSXML.getChildByTagName(info, GSXML.FORMAT_ELEM);
136 if (format != null) {
137 this.format_info_map.put(TEXT_QUERY_SERVICE, this.doc.importNode(format, true));
138 }
139
140 return true;
141 }
142
143 protected Element getServiceDescription(String service, String lang, String subset) {
144
145 if (!service.equals(TEXT_QUERY_SERVICE)) {
146 return null;
147 }
148 Element tq_service = this.doc.createElement(GSXML.SERVICE_ELEM);
149 tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
150 tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
151 if (subset==null || subset.equals(GSXML.DISPLAY_TEXT_ELEM)) {
152 tq_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getTextString(TEXT_QUERY_SERVICE+".name", lang)));
153 tq_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_SUBMIT, getTextString(TEXT_QUERY_SERVICE+".submit", lang)));
154 tq_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(TEXT_QUERY_SERVICE+".description", lang)));
155 }
156 if (subset==null || subset.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
157 Element param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
158 createTextQueryParamList(param_list, lang);
159 tq_service.appendChild(param_list);
160 }
161 return tq_service;
162
163 }
164
165 protected boolean addExtraQueryInfo(Element info, Element extra_info){
166
167 if (extra_info == null) {
168 return false;
169 }
170
171 Document owner = info.getOwnerDocument();
172 // so far we have index specific display elements, and global format elements
173 NodeList indexes = info.getElementsByTagName(GSXML.INDEX_ELEM);
174 Element config_search = (Element)GSXML.getChildByTagName(extra_info, GSXML.SEARCH_ELEM);
175
176 for (int i=0; i<indexes.getLength();i++) {
177 Element ind = (Element)indexes.item(i);
178 String name = ind.getAttribute(GSXML.NAME_ATT);
179 Element node_extra = GSXML.getNamedElement(config_search,
180 GSXML.INDEX_ELEM,
181 GSXML.NAME_ATT,
182 name);
183 if (node_extra == null) {
184 System.err.println("GS3Search: haven't found extra info for index named "+name);
185 continue;
186 }
187
188 // get the display elements if any - displayName
189 NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
190 if (display_names !=null) {
191 for (int j=0; j<display_names.getLength(); j++) {
192 Element e = (Element)display_names.item(j);
193 ind.appendChild(owner.importNode(e, true));
194 }
195 }
196 } // for each index
197
198 // get the format element if any
199 Element format = (Element)GSXML.getChildByTagName(config_search,
200 GSXML.FORMAT_ELEM);
201 if (format!=null) { // append to info
202 info.appendChild(owner.importNode(format, true));
203 }
204 return true;
205
206
207 }
208/** creates a new param element and adds it to the param list */
209 protected void createParameter(String name, Element param_list,
210 /*boolean display,*/ String lang)
211 {
212 Element param=null;
213
214 if (name.equals(INDEX_PARAM)) {
215 // the index info - read from config file
216 Element index_list = (Element)GSXML.getChildByTagName(this.config_info, INDEX_ELEM+GSXML.LIST_MODIFIER);
217 NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
218 int len = indexes.getLength();
219 // now add even if there is only one
220 String [] inds = new String[len];
221 String [] ind_names = new String[len];
222 for (int i=0; i<len; i++) {
223 Element index = (Element)indexes.item(i);
224 inds[i] = index.getAttribute(GSXML.NAME_ATT);
225 ind_names[i] = GSXML.getDisplayText(index, GSXML.DISPLAY_TEXT_NAME, lang, "en");
226
227 }
228 param = GSXML.createParameterDescription(this.doc, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, this.default_index, inds, ind_names);
229
230 }
231 else if (name.equals(CASE_PARAM) || name.equals(STEM_PARAM)) {
232 String[] bool_ops = {"0", "1"};
233 String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)};
234 param = GSXML.createParameterDescription(this.doc, name, getTextString("param."+name, lang), GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, bool_ops, bool_texts);
235 }
236 else if (name.equals(MATCH_PARAM)) {
237 String[] vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
238 String[] val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)};
239 param = GSXML.createParameterDescription(this.doc, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals, val_texts);
240
241 }
242 else if (name.equals(MAXDOCS_PARAM)) {
243 param = GSXML.createParameterDescription(this.doc, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), GSXML.PARAM_TYPE_INTEGER, "10", null, null);
244
245 }
246 else if (name.equals(QUERY_PARAM)) {
247 param = GSXML.createParameterDescription(this.doc, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, 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 String lang);
264
265 /** Creates a new documentNode element containing ID, node type
266 * and docType*/
267 protected Element createDocumentNodeElement(String node_id)
268 {
269 Element doc_node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
270 doc_node.setAttribute(GSXML.NODE_ID_ATT, node_id);
271
272 String top_id = OID.getTop(node_id);
273 boolean is_top = (top_id.equals(node_id) ? true : false);
274
275 doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "hierarchy");
276
277 if (GS3OID.isTop(node_id)) {
278 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_ROOT);
279 } else if (database.documentHasChildren(node_id)){
280 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_INTERIOR);
281 } else {
282 doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_LEAF);
283 }
284
285 return doc_node;
286 }
287// DBInfo info = this.gdbm_src.getInfo(node_id);
288// if (info == null) { // make it up - cant query the gdbm db
289// doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
290// return doc_node;
291// }
292// String children = info.getInfo("contains");
293// boolean is_leaf = (children.equals("") ? true : false);
294
295// // check for simple doc types
296// if (is_top && is_leaf) { // a single section document
297// doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
298// return doc_node;
299// }
300// // set teh node type att
301// if (is_top) {
302// doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_ROOT);
303// } else if (is_leaf) {
304// doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_LEAF);
305// } else {
306// doc_node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_INTERIOR);
307// }
308
309// if (!is_top) { // we need to look at the top info
310// info = this.gdbm_src.getInfo(top_id);
311// }
312
313// String childtype = info.getInfo("childtype");
314// if (childtype.equals("Paged")) {
315// doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "paged");
316// } else {
317// doc_node.setAttribute(GSXML.DOC_TYPE_ATT, "hierarchy");
318// }
319// return doc_node;
320// }
321
322 /** 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 */
323// protected String getDocType(String node_id) {
324
325// String doc_id = OID.getTop(node_id);
326// DBInfo info = this.gdbm_src.getInfo(doc_id);
327// String child_type = info.getInfo("childtype");
328// if (child_type.equals("Paged")) {
329// return "paged";
330// }
331// return "hierarchy";
332
333// }
334
335 /** Returns true if the OID specifies a leaf node, false otherwise
336 Note: this makes a request to the GDBM database so it may not be cheap */
337// protected boolean isLeafNode(String oid)
338// {
339// DBInfo info = this.gdbm_src.getInfo(oid);
340// String children = info.getInfo("contains");
341// return (children.equals(""));
342// }
343
344
345 /** Process a text query - implemented by concrete subclasses */
346 protected abstract Element processTextQuery(Element request);
347}
348
Note: See TracBrowser for help on using the repository browser.