Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Browse.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Browse.java	(revision 3649)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Browse.java	(revision 3649)
@@ -0,0 +1,239 @@
+/*
+ *    GS2Browse.java
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.service;
+
+import org.greenstone.gdbm.*;
+import org.greenstone.gsdl3.util.*;
+
+import org.w3c.dom.Document; 
+import org.w3c.dom.Node; 
+import org.w3c.dom.Text; 
+import org.w3c.dom.Element; 
+import org.w3c.dom.NodeList; 
+/**
+ * A ServicesImpl class for GSDL2-style Classifiers
+ *
+ * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+ * @version $Revision$
+ */
+public class GS2Browse 
+    extends ServiceRack {
+
+    // the services on offer
+    private static final String CLASSIFIER_SERVICE = "ClassifierBrowse";
+
+    /** gdbm wrapper */
+    private GDBMWrapper gdbm_src_=null;
+
+    public GS2Browse() {
+	gdbm_src_ = new GDBMWrapper();
+
+    }
+ 
+    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
+    protected Element createServiceDisplay(String service, String lang) {
+	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
+	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
+	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
+
+	Element param;
+
+	return display;
+	
+    }
+
+    /** processes the request */
+    protected Element processClassifierBrowse(Element request) {
+
+	// the response element
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	String from = GSPath.appendLink(cluster_name_, CLASSIFIER_SERVICE);
+	result.setAttribute(GSXML.FROM_ATT, from);
+	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
+	Element result_content = doc_.createElement(GSXML.CONTENT_ELEM);
+	result.appendChild(result_content);
+
+	// get the classifier name out of request content - assume only one for now
+	String path = GSXML.CONTENT_ELEM;
+	path = GSPath.appendLink(path, GSXML.DOCUMENT_ELEM+GSXML.LIST_MODIFIER);
+	path = GSPath.appendLink(path, GSXML.DOCUMENT_ELEM);
+
+	Element elem = (Element)GSXML.getNodeByPath(request, path);
+	String elem_name = elem.getAttribute(GSXML.NAME_ATT);
+
+	if (OID.needsTranslating(elem_name)) {
+	    elem_name = gdbm_src_.translateOID(elem_name);
+	}
+	// get the info from gdbm db
+	DBInfo info = gdbm_src_.getInfo(elem_name);
+
+	// build up the XML
+	Element classifier = doc_.createElement(GSXML.CLASSIFIER_ELEM);
+	
+	String classifier_name = OID.getTop(elem_name);
+	classifier.setAttribute(GSXML.NAME_ATT, classifier_name);
+	result_content.appendChild(classifier);
+	DBInfo top_info;
+
+	if (elem_name.equals(classifier_name)) { 
+	    top_info = info;
+	} else {
+	    top_info = gdbm_src_.getInfo(classifier_name);
+	}
+
+	// a substitute template - should be read from config file
+	//String extra = "<stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template match='document' priority='3'><xsl:param name='collName'>coll-name</xsl:param><xsl:variable name='library' select='ancestor::page/config/library_name'/><td><a href='{$library}?a=r&amp;c={$collName}&amp;r={@name}'><img src='interfaces/default/images/book.gif' width='18' height='11' border='0'/></a></td><td>***</td><td><xsl:value-of select='metadataList/metadata[@name=\"Title\"]'/></td></xsl:template></stylesheet>";
+	//Element extra_doc = converter_.getDOM(extra).getDocumentElement();
+	//result.appendChild(doc_.importNode(extra_doc, true));
+	
+	// get the classifier attributes
+	String type = top_info.getInfo("childtype");
+	if (type.equals("VList")) {
+	    
+	    classifier.setAttribute("type", "vertical");
+	    classifier.setAttribute("interleave", "true");
+	    classifier.setAttribute("link", "icon");
+	}
+	else if (type.equals("HList")){
+	    classifier.setAttribute("type", "horizontal");
+	    classifier.setAttribute("interleave", "false");
+	    classifier.setAttribute("link", "name");
+	} else {
+	    System.out.println("unknown type!!! check this");
+	    classifier.setAttribute("type", "vertical");
+	    classifier.setAttribute("interleave", "true");
+	    classifier.setAttribute("link", "icon");
+	}
+
+	Element this_node;
+	if (elem_name.equals(classifier_name)) {
+	    this_node = classifier;
+	} else { // have to build up the parents 
+	    // the current node
+	    this_node = doc_.createElement("node");
+	    this_node.setAttribute("name", elem_name);
+	    type = info.getInfo("childtype");
+	    if (type.equals("VList")) {
+		this_node.setAttribute("type", "vertical");
+	    } else {
+		this_node.setAttribute("type", "horzizontal");
+	    }
+	    String title = info.getInfo("Title");
+	    Element meta_list = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+	    GSXML.addMetadata(doc_, meta_list, "Title", title);
+	    this_node.appendChild(meta_list);
+
+	    // the parents
+	    String middle_name = OID.getParent(elem_name);
+	    Element middle_node = this_node;
+	    while (!middle_name.equals(classifier_name)) {
+		// add in a new node
+		Element temp_node = doc_.createElement("node");
+		temp_node.setAttribute("name", middle_name);
+		
+		DBInfo i = gdbm_src_.getInfo(middle_name);
+		type = i.getInfo("childtype");
+		if (type.equals("VList")) {
+		    temp_node.setAttribute("type", "vertical");
+		} else {
+		    temp_node.setAttribute("type", "horzizontal");
+		}
+		title = i.getInfo("Title");
+		meta_list = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+		GSXML.addMetadata(doc_, meta_list, "Title", title);
+		temp_node.appendChild(meta_list);
+
+		// link into the tree
+		temp_node.appendChild(middle_node);
+		middle_node = temp_node;
+		middle_name = OID.getParent(middle_name);
+	    }
+	    classifier.appendChild(middle_node);
+	}
+	// get the child nodes
+	String contains = info.getInfo("contains");
+	// replace the " with parent name
+	contains = OID.translateParent(contains, elem_name);
+	String [] children = contains.split(";");
+	for (int i=0; i<children.length; i++) {
+	    String child = children[i];
+	    DBInfo child_info = gdbm_src_.getInfo(child);
+	    String title = child_info.getInfo("Title");
+	    Element node;
+	    // should have a type here, not rely on HASH ids
+	    if (child.startsWith("HASH")) {
+		// a document
+		node = doc_.createElement(GSXML.DOCUMENT_ELEM);
+	    } else { // a node in the classification
+		node = doc_.createElement("node");
+		
+	    }
+	    
+	    node.setAttribute(GSXML.NAME_ATT, child);
+	    Element meta_list = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
+	    GSXML.addMetadata(doc_, meta_list, "Title", title);
+	    node.appendChild(meta_list);
+	    this_node.appendChild(node);
+	    
+	}
+	
+	return result;
+	
+    }
+    
+
+    /** configure this service */
+    public boolean configure(Element info) {
+
+	System.out.println("configuring GS2Browse");
+
+	Element e = null;
+	// these entries should reflect the build config file - some services may not be available depending on how the colleciton was built.
+	// set up short_service_info_ - for now just has name and type
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
+	short_service_info_.appendChild(e);
+
+	// set up service_info_map_ - for now, just has the same elements as above
+	// should have full details about each service incl params lists etc.
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
+
+	// get the classifier list out of the service info
+	Node classList = GSXML.getChildByTagName(info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
+	e.appendChild(doc_.importNode(classList, true));
+
+	service_info_map_.put(CLASSIFIER_SERVICE, e);
+	
+	if (gdbm_src_.openDatabase(GSFile.GDBMDatabaseFile(site_home_, cluster_name_), GDBMWrapper.READER)) {
+	    return true;
+	}
+	else {
+	    System.err.println("couldn't open gdbm database!");
+	    return false;
+	}
+	
+    }
+
+
+}  
+ 
+
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Construct.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Construct.java	(revision 3649)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2Construct.java	(revision 3649)
@@ -0,0 +1,584 @@
+/*
+ *    GS2Construct.java 
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.service;
+
+import org.greenstone.gsdl3.util.*;
+import org.greenstone.gsdl3.build.*;
+
+import org.w3c.dom.Document; 
+import org.w3c.dom.Node; 
+import org.w3c.dom.Text; 
+import org.w3c.dom.Element; 
+import org.w3c.dom.NodeList; 
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.File;
+import java.util.Locale;
+
+/**
+ * A Services class for building collections
+ * provides a wrapper around the old perl scripts
+ *
+ * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+ * @version $Revision$
+ */
+public class GS2Construct 
+    extends ServiceRack { //implements ConstructionEventListener {
+    
+    // services offered
+    private static final String NEW_SERVICE = "NewCollection";
+    private static final String IMPORT_SERVICE = "ImportCollection";
+    private static final String BUILD_SERVICE = "BuildCollection";
+    private static final String ACTIVATE_SERVICE = "ActivateCollection";
+    private static final String DELETE_SERVICE = "DeleteCollection";
+    private static final String RELOAD_SERVICE = "ReloadCollection";
+
+    // params used
+    private static final String COL_PARAM = "collection";
+    private static final String NEW_COL_NAME_PARAM = "collectionName";
+    private static final String CREATOR_PARAM = "creator";
+    private static final String HANDLE_PARAM = "id";
+
+    //private static final String STATUS_PARAM = "us";
+    // the list of the collections - store between some method calls
+    private String[] collection_list_ = null;
+
+    // set of listeners for nay construciton commands
+    protected Map listeners_ = null;
+    
+    public GS2Construct() {
+	listeners_ = Collections.synchronizedMap(new HashMap());
+    }
+
+    /** returns the service list for the subclass */
+    protected Element getServiceList(String lang) {
+	// for now, it is static and there is no lang stuff
+	return short_service_info_;
+    }
+
+    /** returns a specific service description */
+    protected Element getServiceDescription(String service, String lang) {
+	Element descript = (Element)((Element)service_info_map_.get(service)).cloneNode(true);
+	// need to add in collection param list
+	if (!service.equals(NEW_SERVICE)) {
+	    Element param_list = (Element) GSXML.getChildByTagName(descript, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	    Element old_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, COL_PARAM);
+	    collection_list_ = getCollectionList();
+	    Element param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, null, collection_list_);
+	    // put at front of the list
+	    param_list.replaceChild(param, old_param);
+	}
+	// for now, create it on the fly - look at caching it later
+	Element display = createServiceDisplay(service, lang);
+	addServiceDisplay(descript, display);
+	return descript;
+	
+    }
+
+    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
+    protected Element createServiceDisplay(String service, String lang) {
+	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
+	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
+	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
+
+	Element param;
+	if (service.equals(NEW_SERVICE)) {
+	    // have the coll name and creator params
+	    param = GSXML.createParameterDisplay(doc_, NEW_COL_NAME_PARAM, getTextString("param."+NEW_COL_NAME_PARAM, lang), null, null);
+	    display.appendChild(param);
+	    param = GSXML.createParameterDisplay(doc_, CREATOR_PARAM, getTextString("param."+CREATOR_PARAM, lang), null, null);
+	    display.appendChild(param);
+	} else {
+	    // have just the coll param
+	    //use the colleciton list already created - this method is only called directly after getServiceDescription()
+	    param = GSXML.createParameterDisplay(doc_, COL_PARAM, getTextString("param."+COL_PARAM, lang), collection_list_, collection_list_);
+	    display.appendChild(param);
+	}	    
+
+	return display;
+	
+    }
+
+     /** passes the request Element to the appropriate service function*/
+    protected Element processService(String name, Element request) {
+
+	System.out.println("perl build request = ");
+	System.out.println(converter_.getString(request));
+	String language = request.getAttribute(GSXML.LANG_ATT);
+	String request_type = request.getAttribute(GSXML.TYPE_ATT);
+	boolean get_status_only = false;
+	if (request_type.equals(GSXML.REQUEST_TYPE_STATUS)) {
+	    get_status_only = true;
+	}
+	System.out.println("get status only = "+get_status_only);
+	// extract the collection out of here
+	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	HashMap params = GSXML.extractParams(param_list);
+	String coll_name = (String)params.get(COL_PARAM);
+	
+	String id = (String)params.get(HANDLE_PARAM);
+	
+	Element response = doc_.createElement(GSXML.RESPONSE_ELEM);
+	response.setAttribute(GSXML.FROM_ATT, name);
+	Element status=null;
+	if (name.equals(NEW_SERVICE)) {
+	    // need to do something different here
+	    status = newCollection(coll_name, language, get_status_only);
+	} else if (name.equals(IMPORT_SERVICE)) {
+	    status = importCollection(coll_name, language, get_status_only, id);
+	} else if (name.equals(BUILD_SERVICE)) {
+	    status = buildCollection(coll_name, language, get_status_only, id);
+	} else if (name.equals(ACTIVATE_SERVICE)) {
+	    status = activateCollection(coll_name, language, get_status_only);
+	} else if (name.equals(DELETE_SERVICE)) {
+	    status = deleteCollection(coll_name, language, get_status_only);
+	} else if (name.equals(RELOAD_SERVICE)) {
+	    status = reloadCollection(coll_name, language, get_status_only);
+	} 
+	
+	if (status !=null) {
+	    response.appendChild(status);
+	    return response;
+	} else {
+	    System.err.println("error: status is null!");
+	    return response;
+	}
+	
+	//System.err.println("GS2Construct: should never get here. service type wrong:"+name);
+	//return null;
+	    
+    }
+
+    /** configure the service module
+     * for now, all services have type=build - need to think about this
+     */
+    public boolean configure(Element info) {
+	System.out.println("configuring GS2Construct");
+
+	Element e = null;
+	// hard code in the services for now
+
+	// set up short_service_info_ - for now just has name and type
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, NEW_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, IMPORT_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, BUILD_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, ACTIVATE_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, DELETE_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, RELOAD_SERVICE);
+	short_service_info_.appendChild(e);
+
+	//e = doc_.createElement(GSXML.SERVICE_ELEM);
+	//e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	//e.setAttribute(GSXML.NAME_ATT, "AddDocument");
+	//short_service_info_.appendChild(e);
+
+	// set up service_info_map_ - for now, just has the same elements as above
+
+	Element param_list; 
+	Element param;
+
+	String lang = Locale.US.toString();
+	
+	// should have full details about each service incl params lists etc.
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, NEW_SERVICE);
+	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	param = GSXML.createParameter(doc_, NEW_COL_NAME_PARAM, GSXML.PARAM_TYPE_STRING, "", null);
+	param_list.appendChild(param);
+	param = GSXML.createParameter(doc_, CREATOR_PARAM, GSXML.PARAM_TYPE_STRING, "", null);
+	param_list.appendChild(param);
+	e.appendChild(param_list);
+	service_info_map_.put(NEW_SERVICE, e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, IMPORT_SERVICE);
+	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
+	param_list.appendChild(param);
+	e.appendChild(param_list);
+	service_info_map_.put(IMPORT_SERVICE, e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, BUILD_SERVICE);
+	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
+	param_list.appendChild(param);
+	e.appendChild(param_list);
+	service_info_map_.put(BUILD_SERVICE, e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, ACTIVATE_SERVICE);
+	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
+	param_list.appendChild(param);
+	e.appendChild(param_list);
+	service_info_map_.put(ACTIVATE_SERVICE, e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, DELETE_SERVICE);
+	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
+	param_list.appendChild(param);
+	e.appendChild(param_list);
+	service_info_map_.put(DELETE_SERVICE, e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
+	e.setAttribute(GSXML.NAME_ATT, RELOAD_SERVICE);
+	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
+	param_list.appendChild(param);
+	e.appendChild(param_list);
+	service_info_map_.put(RELOAD_SERVICE, e);
+
+
+	return true;
+    }
+
+    /** creates a new collection using mkcol.pl */
+    protected Element newCollection(String coll_name, String lang, boolean get_status_only) {
+	Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	Text t;
+	if (get_status_only) {
+	    t = doc_.createTextNode("status for create new coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.SUCCESS));
+	} else {
+	    t = doc_.createTextNode("trying to start to create new coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+
+	}
+	status.appendChild(t);
+	return status;
+    }   
+    
+    /** imports a collection using import.pl */
+    protected Element importCollection(String coll_name, String lang, boolean get_status_only, String id) {
+
+	if (get_status_only) {
+	    
+	    Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	    GS2PerlListener listener = (GS2PerlListener)listeners_.get(id);
+	    if (listener==null) {
+		Text t = doc_.createTextNode("invalid id error");
+		status.appendChild(t);
+		status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+	    } else {
+		Text t = doc_.createTextNode(listener.getUpdate());
+		status.appendChild(t);
+		status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(listener.getStatus()));
+		if (listener.isFinished()) { // remove this listener - its job is done
+		    listeners_.remove(id); // not working
+		}
+	    }
+	    return status;
+	}
+		
+	// do the actual import
+	CollectionConstructor constructor = new GS2PerlConstructor("perl_build");
+	constructor.setSiteHome(site_home_);
+	constructor.setCollectionName(coll_name);
+	constructor.setActionType(CollectionConstructor.IMPORT);
+
+	// the listener
+	GS2PerlListener listener = new GS2PerlListener();
+	constructor.addListener(listener);
+	constructor.start();
+
+	id = newID();
+	listeners_.put(id, listener);
+
+	Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	status.setAttribute(GSXML.STATUS_PROCESS_ID_ATT, id);
+	status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+	Text t = doc_.createTextNode("starting");
+	status.appendChild(t);
+	return status;
+    }   
+    /** builds a collection using buildcol.pl */
+    protected Element buildCollection(String coll_name, String lang, boolean get_status_only, String id) {
+
+	if (get_status_only) {
+	    
+	    Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	    GS2PerlListener listener = (GS2PerlListener)listeners_.get(id);
+	    if (listener==null) {
+		Text t = doc_.createTextNode("invalid id error");
+		status.appendChild(t);
+		status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+	    } else {
+		Text t = doc_.createTextNode(listener.getUpdate());
+		status.appendChild(t);
+		status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(listener.getStatus()));
+		if (listener.isFinished()) { // remove this listener - its job is done
+		    System.out.println("listener is finished, remove it");
+		    listeners_.remove(id); // not working
+		}
+	    }
+	    return status;
+	}
+		
+	// do the actual import
+	CollectionConstructor constructor = new GS2PerlConstructor("perl_build");
+	constructor.setSiteHome(site_home_);
+	constructor.setCollectionName(coll_name);
+	constructor.setActionType(CollectionConstructor.BUILD);
+
+	// the listener
+	GS2PerlListener listener = new GS2PerlListener();
+	constructor.addListener(listener);
+	constructor.start();
+
+	id = newID();
+	listeners_.put(id, listener);
+
+	Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	status.setAttribute(GSXML.STATUS_PROCESS_ID_ATT, id);
+	status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+	Text t = doc_.createTextNode("starting");
+	status.appendChild(t);
+	return status;
+
+	/*Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	Text t;
+	if (get_status_only) {
+	    t = doc_.createTextNode("status for build coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.SUCCESS));
+	} else {
+	    t= doc_.createTextNode("trying to build coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+	}
+	status.appendChild(t);
+	return status;*/
+    }   
+    protected Element reloadCollection(String coll_name, String lang, boolean get_status_only) {
+	Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	Text t;
+	if (get_status_only) { // this makes no sense for this service
+	    t = doc_.createTextNode("no status for reload coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.SUCCESS));
+	} else {
+	    Element message = doc_.createElement(GSXML.MESSAGE_ELEM);
+	    Element request = doc_.createElement(GSXML.REQUEST_ELEM);
+	    request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_CONFIGURE);
+	    request.setAttribute(GSXML.TO_ATT, "");
+	    message.appendChild(request);
+	    Element command = doc_.createElement(GSXML.CONFIGURE_ELEM);
+	    command.setAttribute(GSXML.TYPE_ATT, GSXML.COLLECTION_ELEM);
+	    command.setAttribute(GSXML.NAME_ATT, coll_name);
+	    command.setAttribute(GSXML.ACTION_ATT, GSXML.CONFIG_ACTION_ACTIVATE);
+	    request.appendChild(command);
+	    Element response = router_.process(message); // at the moment, get no info in response so ignore it
+	    
+	    String[] args={coll_name};
+	    
+	    if (response == null) {
+		t = doc_.createTextNode(getTextString("reload.activate_error", args , lang));
+		status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+		status.appendChild(t);
+		return status;
+	    }
+	    
+	    // if we got here, we have succeeded!
+	t = doc_.createTextNode(getTextString("reload.success", args, lang));
+	status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.SUCCESS));
+	}
+	status.appendChild(t);
+	return status;	
+    }   
+
+    /** activates a collection by removing index, copying building over 
+     * also instructs the MR to activate this new/modified collection
+     * fails if no valid building directory */ 
+    protected Element activateCollection(String coll_name, String lang, boolean get_status_only) {
+	// the return element
+	Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	Text t;
+	if (get_status_only) { // makes no sense
+	    t = doc_.createTextNode("no status for activate coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+	    status.appendChild(t);
+	    return status;
+	}
+	
+	String[] args={coll_name};
+	
+	// check that we have buildcfg.xml in the building directory
+	File coll_build_dir = new File(GSFile.collectionBuildDir(site_home_, coll_name));
+	if (!coll_build_dir.exists()) {
+	    t = doc_.createTextNode(getTextString("activate.build_dir_error", args, lang));
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+	    status.appendChild(t);
+	    return status;
+	}
+
+	/*
+	File coll_build_file = new File(GSFile.collectionBuildConfigFileBuilding(site_home_, coll_name));
+	if (!coll_build_file.exists()) {
+	    t = doc_.createTextNode(getTextString("activate.build_config_error", args, lang));
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+	    status.appendChild(t);
+	    return status;
+	}
+	
+	
+	File coll_index_dir = new File(GSFile.collectionIndexDir(site_home_, coll_name));
+	if (coll_index_dir.exists()) {
+	    // remove it
+	    if (!GSFile.deleteFile(coll_index_dir)) {
+		t = doc_.createTextNode(getTextString("activate.rm_index_error", args, lang));
+		status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+		status.appendChild(t);
+		return status;
+	    }
+	}
+	
+	// copy building to index
+	if (!GSFile.moveDirectory(coll_build_dir, coll_index_dir)) {
+	    t = doc_.createTextNode(getTextString("activate.rename_building_error", args, lang));
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+	    status.appendChild(t);
+	    return status;
+	}
+	*/
+	// now have to tell the message router
+	return reloadCollection(coll_name, lang, get_status_only);
+
+    }
+    /** deletes a collection - removes the whole directory
+     * also instructs the MR to deactivate this  collection*/ 
+    protected Element deleteCollection(String coll_name, String lang, boolean get_status_only) {
+	
+	Element status = doc_.createElement(GSXML.STATUS_ELEM);
+	Text t;
+	if (get_status_only) {
+	    t = doc_.createTextNode("no status for delete coll:"+coll_name);
+	    status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+	    status.appendChild(t);
+	    return status;
+	}
+	
+	String[] args={coll_name};
+	File coll_dir = new File(GSFile.collectionBaseDir(site_home_, coll_name));
+	if (coll_dir.exists()) {
+	    if (!GSFile.deleteFile(coll_dir)) {
+		 t = doc_.createTextNode(getTextString("delete.delete_error", args, lang));
+		 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+		status.appendChild(t);
+		return status;
+	    }
+	    // now tell the MR about it
+
+	    Element message = doc_.createElement(GSXML.MESSAGE_ELEM);
+	    Element request = doc_.createElement(GSXML.REQUEST_ELEM);
+	    request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_CONFIGURE);
+	    request.setAttribute(GSXML.TO_ATT, "");
+	    message.appendChild(request);
+	    Element command = doc_.createElement(GSXML.CONFIGURE_ELEM);
+	    command.setAttribute(GSXML.TYPE_ATT, GSXML.COLLECTION_ELEM);
+	    command.setAttribute(GSXML.NAME_ATT, coll_name);
+	    command.setAttribute(GSXML.ACTION_ATT, GSXML.CONFIG_ACTION_DEACTIVATE);
+	    request.appendChild(command);
+	    
+	    Element response = router_.process(message); // at the moment, get no info in response so ignore it
+	    if (response == null) {
+		 t = doc_.createTextNode(getTextString("delete.deactivate_error", args, lang));
+		 status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ERROR));
+		 status.appendChild(t);
+		 return status;
+	    }
+	}
+	// success   
+       
+	t = doc_.createTextNode(getTextString("delete.success", args, lang));
+	status.setAttribute(GSXML.STATUS_ERROR_CODE_ATT, Integer.toString(GSStatus.ACCEPTED));
+	status.appendChild(t);
+	return status;
+    }
+
+    protected String[] getCollectionList() {
+	
+	File collectDir = new File(GSFile.collectDir(site_home_));
+	if (!collectDir.exists()) {
+	    System.err.println("couldn't find collect dir: "+collectDir.toString());
+	    return null;
+	}
+	System.out.println("GS2Construct: reading thru directory "+collectDir.getPath()+" to find collections.");
+	File[] contents = collectDir.listFiles();
+	int num_colls=0;
+	for (int i=0; i<contents.length;i++) {
+	    if(contents[i].isDirectory() && !contents[i].getName().startsWith("CVS")) {
+		num_colls ++;
+	    }
+	}
+	
+	String[] names= new String[num_colls];
+	
+	for (int i=0, j=0; i<contents.length;i++) {
+	    if(contents[i].isDirectory()) {
+		String colName = contents[i].getName();
+		if (!colName.startsWith("CVS")) {
+		    names[j] = colName;
+		    j++;
+		}
+		
+	    } 
+	}
+	
+	return names;
+	
+    }
+   
+    private int current_id = 0;
+    private String newID() {
+	current_id++;
+	return Integer.toString(current_id);
+    }
+}
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGPPRetrieve.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGPPRetrieve.java	(revision 3649)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGPPRetrieve.java	(revision 3649)
@@ -0,0 +1,229 @@
+/*
+ *    GS2MGPPRetrieve.java
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.service;
+
+// greenstone classes
+import org.greenstone.mgpp.*;
+import org.greenstone.gdbm.*;
+import org.greenstone.gsdl3.util.*;
+
+// xml classes
+import org.w3c.dom.Document; 
+import org.w3c.dom.Node; 
+import org.w3c.dom.Text; 
+import org.w3c.dom.Element; 
+import org.w3c.dom.NodeList; 
+
+// general java classes
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.Set;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.Locale;
+
+/**
+ * A ServiceRack class for retrieval in greenstone 2 MGPP collections
+ *
+ * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+ * @version $Revision$
+ * @see ServiceRack
+ */
+public class GS2MGPPRetrieve 
+    extends ServiceRack {
+
+    // these strings must match what is found in the properties file
+    // the services on offer
+    private static final String DOCUMENT_RETRIEVE_SERVICE = "DocumentRetrieve";
+    private static final String METADATA_RETRIEVE_SERVICE = "MetadataRetrieve";
+
+    // params used
+    private static final String LEVEL_PARAM = "level";
+
+    // elements used in the config file that are specific to this class
+    private static final String DEFAULT_LEVEL_ELEM = "defaultLevel";
+    
+    private MGPPWrapper mgpp_src_=null;
+    private GDBMWrapper gdbm_src_=null;
+    
+    private String default_level_=null;
+
+    private Element config_info_ = null;
+
+    public GS2MGPPRetrieve() {
+	mgpp_src_ = new MGPPWrapper();
+	gdbm_src_ = new GDBMWrapper();
+
+    }
+    
+    /** configure this service */
+    public boolean configure(Element info) {
+
+	System.out.println("configuring GS2MGPPRetrieve");
+	config_info_ = info;
+
+	// get the default level out of <defaultLevel>
+	Element def = (Element)GSXML.getChildByTagName(info, DEFAULT_LEVEL_ELEM);
+	if (def !=null) {
+	    default_level_ = def.getAttribute(GSXML.NAME_ATT);
+	}
+	if (default_level_==null||default_level_.equals("")) {
+	    System.err.println("Error: default level not specified!");
+	    return false;
+	}
+
+	// set up which services are available for this collection
+	Element e = null;
+	// these entries should reflect the build config file - some services may not be available depending on how the collection was built.
+
+	// set up short_service_info_ - for now just has name and type
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, DOCUMENT_RETRIEVE_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
+	short_service_info_.appendChild(e);
+
+	// set up service_info_map_ - for now, just has the same elements as above
+	// should have full details about each service incl params lists etc.
+	// do the text query one - for now a static list. later use buildcfg.xml values to dynamically change this
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, DOCUMENT_RETRIEVE_SERVICE);
+	service_info_map_.put(DOCUMENT_RETRIEVE_SERVICE, e);
+	
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
+	service_info_map_.put(METADATA_RETRIEVE_SERVICE, e);
+
+	if (gdbm_src_.openDatabase(GSFile.GDBMDatabaseFile(site_home_, cluster_name_), GDBMWrapper.READER)) {
+	    return true;
+	}
+	else {
+	    System.err.println("couldn't open gdbm database!");
+	    return false;
+	}
+    }
+  
+
+    /** creates a display element containing all the text strings needed to display the service page, in the language specified 
+     * these retrieval services dont get displayed to the users - they are only used internally by the actions. so this returns an empty display element*/
+    protected Element createServiceDisplay(String service, String lang) {
+	return doc_.createElement(GSXML.DISPLAY_ELEM);
+    }
+
+
+    /** retrieve a document */
+    protected Element processDocumentRetrieve(Element request) {
+
+	// where the mgpp text files are
+	String basedir = GSFile.collectionBaseDir(site_home_, 
+						  cluster_name_);
+	String textdir = GSFile.collectionTextPath(cluster_name_);
+
+	// an empty result
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	String from = GSPath.appendLink(cluster_name_, DOCUMENT_RETRIEVE_SERVICE);
+	result.setAttribute(GSXML.FROM_ATT, from);
+	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
+	Element result_doc = doc_.createElement(GSXML.CONTENT_ELEM);
+	result.appendChild(result_doc);
+	
+	// get param list and content 
+	Element param_elem=null;
+	Element content_elem=null;
+	Node n = request.getFirstChild();
+	while (n!=null) {
+	  String node_name = n.getNodeName();
+	  if (node_name.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
+	      param_elem = (Element)n;
+	  } else if (node_name.equals(GSXML.CONTENT_ELEM)) {
+	      content_elem = (Element)n;
+	  }
+	  n = n.getNextSibling();
+	}
+
+	if (param_elem==null || content_elem==null) {
+	    System.err.println("GS2MGPPRetrieve: malformed request sent to DocumentRetrieve service");
+	    return result; // empty result
+	}
+	
+	HashMap params = GSXML.extractParams(param_elem);
+
+	// get docs from mgpp
+	String level = (String)params.get(LEVEL_PARAM); // level at which to retrieve a doc
+	if (level==null) {
+	    level=default_level_;
+	}
+	// get the text for each doc in the list
+	String []ids = GSXML.getDocumentNameList(content_elem);
+	for (int j=0; j<ids.length; j++) {
+	    long real_num = gdbm_src_.oid2Docnum(ids[j]);
+	    String document = mgpp_src_.getDocument(basedir, textdir,  level, real_num);
+	    // for now, stick it in a text node - eventually should be parsed as xml??
+	    // something funny with the doc - 
+	    Element new_doc = GSXML.createDocumentElement(doc_, ids[j]);
+	    GSXML.addDocText(doc_, new_doc, document);
+	    result_doc.appendChild(new_doc);
+	}
+	return result;
+    }
+
+    /** retrieve metadata */
+    protected Element processMetadataRetrieve(Element request) {
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	String from = GSPath.appendLink(cluster_name_, METADATA_RETRIEVE_SERVICE);
+	result.setAttribute(GSXML.FROM_ATT, from);
+	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
+	Element result_content = doc_.createElement(GSXML.CONTENT_ELEM);
+	result.appendChild(result_content);
+	Element document_list = doc_.createElement(GSXML.DOCUMENT_ELEM+GSXML.LIST_MODIFIER);
+	result_content.appendChild(document_list);
+	// get the metadata
+	
+	Element content = (Element)request.getElementsByTagName(GSXML.CONTENT_ELEM).item(0);
+	if (content==null) {
+	    // error: query had no content!! - should make an error message
+	    return result;
+	}
+	String []metas = GSXML.getMetaNameList(content);
+	String []ids = GSXML.getDocumentNameList(content);
+	for (int j=0; j<ids.length; j++) { // for each document
+	    Element doc = GSXML.createDocumentElement(doc_, ids[j]);
+	    Element list = GSXML.addMetaList(doc_, doc);
+	    DBInfo info = gdbm_src_.getInfo(ids[j]);
+	    for (int m=0; m<metas.length; m++) {
+		String value = info.getInfo(metas[m]);
+		GSXML.addMetadata(doc_, list, metas[m], value);
+	    }
+	    document_list.appendChild(doc);
+	}
+	return result;
+    }
+
+
+
+
+}
+ 
+
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGPPSearch.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGPPSearch.java	(revision 3649)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGPPSearch.java	(revision 3649)
@@ -0,0 +1,743 @@
+/*
+ *    GS2MGPPSearch.java
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.service;
+
+// greenstone classes
+import org.greenstone.mgpp.*;
+import org.greenstone.gdbm.*;
+import org.greenstone.gsdl3.util.*;
+// xml classes
+import org.w3c.dom.Document; 
+import org.w3c.dom.Node; 
+import org.w3c.dom.Text; 
+import org.w3c.dom.Element; 
+import org.w3c.dom.NodeList; 
+// general java classes
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.Set;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.Locale;
+
+/**
+ * A ServiceRack class for searching in greenstone 2 MGPP collections
+ *
+ * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+ * @version $Revision$
+ * @see ServiceRack
+ */
+public class GS2MGPPSearch 
+    extends ServiceRack {
+
+    // these strings must match what is found in the properties file
+    // the services on offer
+    private static final String TEXT_QUERY_SERVICE = "TextQuery";
+    private static final String FIELD_QUERY_SERVICE = "FieldQuery";
+    private static final String ADVANCED_FIELD_QUERY_SERVICE = "AdvancedFieldQuery";
+    // params used
+    private static final String CASE_PARAM = "case";
+    private static final String STEM_PARAM = "stem";
+    private static final String MATCH_PARAM = "matchMode";
+    private static final String MATCH_PARAM_ALL = "all";
+    private static final String MATCH_PARAM_SOME = "some";
+    private static final String INDEX_PARAM = "index";
+    private static final String LEVEL_PARAM = "level";
+    private static final String RANK_PARAM = "sortBy";
+    private static final String RANK_PARAM_RANK = "rank";
+    private static final String RANK_PARAM_NONE = "natural";
+    private static final String MAXDOCS_PARAM = "maxDocs";
+    private static final String BOOLEAN_PARAM_ON = "1";
+    private static final String BOOLEAN_PARAM_OFF = "0";
+    private static final String QUERY_PARAM = "query";
+    private static final String SIMPLE_FIELD_PARAM = "simpleField";
+    private static final String ADVANCED_FIELD_PARAM = "complexField";
+    // more params for field query
+    private static final String FIELD_QUERY_PARAM = "fqv";
+    private static final String FIELD_STEM_PARAM = "fqs";
+    private static final String FIELD_CASE_PARAM = "fqc";
+    private static final String FIELD_FIELD_PARAM = "fqf";
+    private static final String FIELD_COMBINE_PARAM = "fqk";
+    private static final String FIELD_COMBINE_PARAM_AND = "0";
+    private static final String FIELD_COMBINE_PARAM_OR = "1";
+    private static final String FIELD_COMBINE_PARAM_NOT = "2";
+    
+    // elements used in the config file that are specific to this class
+    private static final String DEFAULT_INDEX_ELEM = "defaultIndex";
+    private static final String DEFAULT_LEVEL_ELEM = "defaultLevel";
+    private static final String INDEX_ELEM = "index";
+    private static final String LEVEL_ELEM = "level";
+    
+    private MGPPWrapper mgpp_src_=null;
+    private GDBMWrapper gdbm_src_=null;
+    
+    private String default_index_=null;
+    private String default_level_=null;
+
+    private Element config_info_ = null;
+    
+    /** constructor */
+    public GS2MGPPSearch() {
+	mgpp_src_ = new MGPPWrapper();
+	gdbm_src_ = new GDBMWrapper();
+
+    }
+    
+    /** configure this service */
+    public boolean configure(Element info) {
+
+	System.out.println("configuring GS2MGPPSearch");
+	config_info_ = info;
+
+	// get the default index from <defaultIndex>
+	Element def = (Element)GSXML.getChildByTagName(info, DEFAULT_INDEX_ELEM );
+	if (def !=null) {
+	    default_index_ = def.getAttribute(GSXML.NAME_ATT);
+	}
+	if (default_index_==null||default_index_.equals("")) {
+	    System.err.println("Error: default index not specified!");
+	    return false;
+	}
+
+	// get the default level out of <defaultLevel>
+	def = (Element)GSXML.getChildByTagName(info, DEFAULT_LEVEL_ELEM);
+	if (def !=null) {
+	    default_level_ = def.getAttribute(GSXML.NAME_ATT);
+	}
+	if (default_level_==null||default_level_.equals("")) {
+	    System.err.println("Error: default level not specified!");
+	    return false;
+	}
+	// the default level is also the level which gdbm is expecting
+	mgpp_src_.setReturnLevel(default_level_);
+
+	// set up which services are available for this collection
+	Element e = null;
+	// these entries should reflect the build config file - some services may not be available depending on how the collection was built.
+
+	// set up short_service_info_ - for now just has name and type
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, FIELD_QUERY_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, ADVANCED_FIELD_QUERY_SERVICE);
+	short_service_info_.appendChild(e);
+
+	// set up service_info_map_ - for now, just has the same elements as above
+	// should have full details about each service incl params lists etc.
+	// do the text query one - for now a static list. later use buildcfg.xml values to dynamically change this
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
+	Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	createTextQueryParamList(param_list, false, null);
+	e.appendChild(param_list);
+	service_info_map_.put(TEXT_QUERY_SERVICE, e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, FIELD_QUERY_SERVICE);
+	Element param_list1 = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	createFieldQueryParamList(param_list1, false, null);
+	e.appendChild(param_list1);
+	service_info_map_.put(FIELD_QUERY_SERVICE, e);
+	
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, ADVANCED_FIELD_QUERY_SERVICE);
+	Element param_list2 = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	createAdvancedFieldQueryParamList(param_list2, false, null);
+	e.appendChild(param_list2);
+	service_info_map_.put(ADVANCED_FIELD_QUERY_SERVICE, e);
+
+	if (gdbm_src_.openDatabase(GSFile.GDBMDatabaseFile(site_home_, cluster_name_), GDBMWrapper.READER)) {
+	    return true;
+	}
+	else {
+	    System.err.println("couldn't open gdbm database!");
+	    return false;
+	}
+    }
+  
+    /** creates a new param element and adds it to the param list */
+    protected void createParameter(String name, Element param_list, boolean display, String lang) {
+	Element param=null;
+	
+	if (name.equals(INDEX_PARAM)) {
+	    // the index info - read from config file
+	    Element index_list = (Element)GSXML.getChildByTagName(config_info_, INDEX_ELEM+GSXML.LIST_MODIFIER);
+	    NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
+	    int len = indexes.getLength();
+	    if (len > 1) { // add index param to list only if more than one index specified
+		String [] inds  = new String[len];
+		for (int i=0; i<len; i++) {
+		    inds[i] = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT);
+		}
+		if (display) {
+		    // use the same index names for now - should get these out of the config info
+		    param = GSXML.createParameterDisplay(doc_, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), inds, inds);
+		} else {
+		    param = GSXML.createParameter(doc_, INDEX_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_index_, inds);
+		}
+	    } 
+	} else if (name.equals(LEVEL_PARAM)) {
+	    // the level info - read from config file
+	    Element level_list = (Element)GSXML.getChildByTagName(config_info_, LEVEL_ELEM+GSXML.LIST_MODIFIER);
+	    NodeList levels = level_list.getElementsByTagName(LEVEL_ELEM);
+	    int len = levels.getLength();
+	    if (len > 1) { // add level param to list only if more than one index specified
+		String [] levs  = new String[len];
+		for (int i=0; i<len; i++) {
+		    levs[i] = ((Element)levels.item(i)).getAttribute(GSXML.NAME_ATT);
+		}
+		if (display) {
+		    param =  GSXML.createParameterDisplay(doc_, LEVEL_PARAM, getTextString("param."+LEVEL_PARAM, lang), levs, levs);
+		} else {
+		    param = GSXML.createParameter(doc_, LEVEL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_level_, levs);
+		}
+	    }
+	} else if (name.equals(STEM_PARAM)) {
+	    if (display) {
+		String[] bool_ops = {"0", "1"};
+		String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
+		param = GSXML.createParameterDisplay(doc_, STEM_PARAM, getTextString("param."+STEM_PARAM, lang),  bool_ops, bool_texts);
+	    } else {
+		param = GSXML.createParameter(doc_, STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
+	    }
+	} else if (name.equals(CASE_PARAM)) {
+	    if (display) {
+		String[] bool_ops = {"0", "1"};
+		String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
+		param = GSXML.createParameterDisplay(doc_, CASE_PARAM, getTextString("param."+CASE_PARAM, lang),  bool_ops, bool_texts);
+	    } else {
+		param = GSXML.createParameter(doc_, CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
+	    }
+	} else if (name.equals(MATCH_PARAM)) {
+	    String []vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
+	    if (display) {
+		String []val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)}; 
+
+		param = GSXML.createParameterDisplay(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), vals, val_texts);
+	    } else {
+		param = GSXML.createParameter(doc_, MATCH_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals);
+	    }	
+	} else if (name.equals(RANK_PARAM)) {
+	    String [] vals1 = {RANK_PARAM_RANK, RANK_PARAM_NONE };
+	    if (display) {
+		String [] vals1_texts = { getTextString("param."+RANK_PARAM+"."+RANK_PARAM_RANK, lang),
+					  getTextString("param."+RANK_PARAM+"."+RANK_PARAM_NONE, lang)};
+		
+		param = GSXML.createParameterDisplay(doc_, RANK_PARAM, getTextString("param."+RANK_PARAM, lang), vals1, vals1_texts);
+	    } else {
+		param = GSXML.createParameter(doc_, RANK_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, RANK_PARAM_RANK, vals1 );
+	    }
+	} else if (name.equals(MAXDOCS_PARAM)) {
+	    if (display) {
+		param = GSXML.createParameterDisplay(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), null, null);
+	    } else {
+		param = GSXML.createParameter(doc_, MAXDOCS_PARAM, GSXML.PARAM_TYPE_INTEGER, "10", null);
+	    }
+	} else if (name.equals(QUERY_PARAM)) {
+	    if (display) {
+		param = GSXML.createParameterDisplay(doc_, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), null, null);
+	    } else {
+		param = GSXML.createParameter(doc_, QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
+	    }
+	} else if (name.equals(FIELD_QUERY_PARAM)) {
+	    if (display) {
+		param = GSXML.createParameterDisplay(doc_, FIELD_QUERY_PARAM, getTextString("param."+FIELD_QUERY_PARAM, lang), null, null);
+	    } else {
+		param = GSXML.createParameter(doc_, FIELD_QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
+	    }
+	    
+	    
+	} else if (name.equals(FIELD_CASE_PARAM)) {
+	    if (display) {
+		String[] bool_ops = {"0", "1"};
+		String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
+		param = GSXML.createParameterDisplay(doc_, FIELD_CASE_PARAM, getTextString("param."+FIELD_CASE_PARAM, lang),  bool_ops, bool_texts);
+		
+	    } else {
+		param = GSXML.createParameter(doc_, FIELD_CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
+		
+	    }
+	} else if (name.equals(FIELD_STEM_PARAM)) {
+	    if (display) {
+		String[] bool_ops = {"0", "1"};
+		String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
+		param = GSXML.createParameterDisplay(doc_, FIELD_STEM_PARAM, getTextString("param."+FIELD_STEM_PARAM, lang),  bool_ops, bool_texts);
+	    } else {
+		param = GSXML.createParameter(doc_, FIELD_STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
+		
+	    }
+	} else if (name.equals(FIELD_FIELD_PARAM)) {
+	    
+	    // the field list - should be read from config file
+	    String [] vals2 = {"TX", "SU", "TI"};
+	    String [] vals2_texts = {"TextOnly", "Subject", "Title"};
+	    
+	    if (display) {
+		param = GSXML.createParameterDisplay(doc_, FIELD_FIELD_PARAM, getTextString("param."+FIELD_FIELD_PARAM, lang), vals2, vals2_texts);
+		
+	    } else {
+		param = GSXML.createParameter(doc_, FIELD_FIELD_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", vals2 );
+		
+	    }
+	} else if (name.equals(FIELD_COMBINE_PARAM)) {
+      
+	    String []vals = {FIELD_COMBINE_PARAM_AND, FIELD_COMBINE_PARAM_OR, FIELD_COMBINE_PARAM_NOT};
+	    if (display) {
+		String []val_texts = {getTextString("param."+FIELD_COMBINE_PARAM+"."+FIELD_COMBINE_PARAM_AND, lang), getTextString("param."+FIELD_COMBINE_PARAM+"."+FIELD_COMBINE_PARAM_OR, lang), getTextString("param."+FIELD_COMBINE_PARAM+"."+FIELD_COMBINE_PARAM_NOT, lang)}; 
+		
+		param = GSXML.createParameterDisplay(doc_, FIELD_COMBINE_PARAM, "", vals, val_texts);
+		
+	    } else {
+		param = GSXML.createParameter(doc_, FIELD_COMBINE_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, FIELD_COMBINE_PARAM_AND, vals);
+		param.setAttribute(GSXML.PARAM_IGNORE_POS_ATT, "0");
+		
+	    }	
+	}
+
+	// add the param to the list
+	if (param !=null) {
+	    param_list.appendChild(param);
+	}
+    }
+    /** this creates all teh params and appends them to param_list.
+     * if display=true it creates the text strings version
+     * otherwise it creates the description version
+     */
+    protected boolean createTextQueryParamList(Element param_list, boolean display, String lang) {
+
+	// the order they are specified here is the order they appear on 
+	// the query form
+	createParameter(INDEX_PARAM, param_list, display, lang);
+	createParameter(LEVEL_PARAM, param_list, display, lang);
+	createParameter(CASE_PARAM, param_list, display, lang);
+	createParameter(STEM_PARAM, param_list, display, lang);
+	createParameter(MATCH_PARAM, param_list, display, lang);
+	createParameter(RANK_PARAM, param_list, display, lang);
+	createParameter(MAXDOCS_PARAM, param_list, display, lang);
+	createParameter(QUERY_PARAM, param_list, display, lang);
+	return true;
+    }
+    /** this creates all teh params and appends them to param_list.
+     * if display=true it creates the text strings version
+     * otherwise it creates the description version
+     */
+    protected boolean createFieldQueryParamList(Element param_list, boolean display, String lang) {
+
+	createParameter(MATCH_PARAM, param_list, display, lang);
+	createParameter(LEVEL_PARAM, param_list, display, lang);
+	createParameter(CASE_PARAM, param_list, display, lang);
+	createParameter(STEM_PARAM, param_list, display, lang);
+	createParameter(RANK_PARAM, param_list, display, lang);
+	createParameter(MAXDOCS_PARAM, param_list, display, lang);
+
+	// create a multi param for the fields etc
+	// text box, field
+	Element multiparam = null;
+	Element param=null;
+	if (display) {
+	    param = GSXML.createParameterDisplay(doc_, SIMPLE_FIELD_PARAM, "",  null, null);
+	    param_list.appendChild(param);
+	} else {
+	    multiparam = GSXML.createParameter(doc_, SIMPLE_FIELD_PARAM, GSXML.PARAM_TYPE_MULTI, null, null);
+	    multiparam.setAttribute("occurs", "4");
+	    param_list.appendChild(multiparam);
+	}
+	// the components
+	if (display) {
+	    createParameter(FIELD_QUERY_PARAM, param_list, display, lang);
+	    createParameter(FIELD_FIELD_PARAM, param_list, display, lang);
+	} else {
+	    createParameter(FIELD_QUERY_PARAM, multiparam, display, lang);
+	    createParameter(FIELD_FIELD_PARAM, multiparam, display, lang);
+	}
+	return true;
+    }
+
+    protected boolean createAdvancedFieldQueryParamList(Element param_list, boolean display, String lang) {
+
+	// first do index and level params
+	createParameter(LEVEL_PARAM, param_list, display, lang);
+	createParameter(RANK_PARAM, param_list, display, lang);
+	createParameter(MAXDOCS_PARAM, param_list, display, lang);
+
+
+	// create a multi param for the fields etc
+	// text box, stem, case, field
+
+	Element multiparam = null;
+	Element param=null;
+
+	if (display) {
+	    param = GSXML.createParameterDisplay(doc_, ADVANCED_FIELD_PARAM, "",  null, null);
+	    param_list.appendChild(param);
+	} else {
+	    multiparam = GSXML.createParameter(doc_, ADVANCED_FIELD_PARAM, GSXML.PARAM_TYPE_MULTI, null, null);
+	    multiparam.setAttribute("occurs", "4");
+	    param_list.appendChild(multiparam);
+	}
+	
+	// the components
+
+	//the combiners
+	
+
+	if (display) {
+	    createParameter(FIELD_COMBINE_PARAM, param_list, display, lang);
+	    createParameter(FIELD_QUERY_PARAM, param_list, display, lang);
+	    createParameter(FIELD_CASE_PARAM, param_list, display, lang);
+	    createParameter(FIELD_STEM_PARAM, param_list, display, lang);
+	    createParameter(FIELD_FIELD_PARAM, param_list, display, lang);
+	} else {
+	    createParameter(FIELD_COMBINE_PARAM, multiparam, display, lang);
+	    createParameter(FIELD_QUERY_PARAM, multiparam, display, lang);
+	    createParameter(FIELD_CASE_PARAM, multiparam, display, lang);
+	    createParameter(FIELD_STEM_PARAM, multiparam, display, lang);
+	    createParameter(FIELD_FIELD_PARAM, multiparam, display, lang);    
+	}
+
+	return true;
+    }
+    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
+    protected Element createServiceDisplay(String service, String lang) {
+	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
+	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
+	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
+
+	// now need to add in the params
+	if (service.equals(TEXT_QUERY_SERVICE)) {
+	    
+	    createTextQueryParamList(display, true, lang);
+	}
+	// now need to add in the params
+	if (service.equals(FIELD_QUERY_SERVICE)) {
+	    
+	    createFieldQueryParamList(display, true, lang);
+	}
+	// now need to add in the params
+	if (service.equals(ADVANCED_FIELD_QUERY_SERVICE)) {
+	    
+	    createAdvancedFieldQueryParamList(display, true, lang);
+	}
+	return display;
+	
+    }
+
+    
+    /** process a text query */
+    protected Element processTextQuery(Element request) {
+
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	String from = GSPath.appendLink(cluster_name_, TEXT_QUERY_SERVICE);
+	result.setAttribute(GSXML.FROM_ATT, from);
+	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
+	
+	// get param list
+	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	if (param_list==null) {
+	    System.err.println("GS2MGPPSearch, TextQuery Error: no param list in request!");
+	    return result; // empty result
+	}
+	HashMap params = GSXML.extractParams(param_list);
+	String query = (String)params.get(QUERY_PARAM);
+	if (query == null) {
+	    // nothing to query
+	    return result;
+	}
+	
+	String index = (String)params.get(INDEX_PARAM); 
+	if (index==null) { // if its not present, use the default index
+	    index=default_index_;
+	}
+
+	// now set up the mgpp stuff
+	String basedir = GSFile.collectionBaseDir(site_home_, 
+						  cluster_name_);
+	String indexdir = GSFile.collectionIndexPath(cluster_name_, index);
+
+	mgpp_src_.loadIndexData(basedir, indexdir);
+	setStandardQueryParams(params);
+	
+	mgpp_src_.runQuery(query);
+	MGPPQueryResult mqr= mgpp_src_.getQueryResult();
+	
+	// get the docnums out, and convert to HASH ids
+	Vector docs = mqr.getDocs();
+	if (docs.size()==0) {
+	    // no docs found
+	    return result;
+	}
+	// create a documentList element
+	Element c = doc_.createElement(GSXML.CONTENT_ELEM);
+	result.appendChild(c);
+	Element document_list = doc_.createElement(GSXML.DOCUMENT_ELEM+GSXML.LIST_MODIFIER);
+	c.appendChild(document_list);
+	// add each document
+	for (int d=0; d<docs.size(); d++) {
+	    long docnum = ((MGPPDocInfo)docs.elementAt(d)).num_;
+	    String id = gdbm_src_.docnum2Oid(docnum);
+	    Node no = GSXML.createDocumentElement(doc_, id);
+	    document_list.appendChild(no);
+	}
+	return result;
+    }//processTextQuery
+
+    protected Element processFieldQuery(Element request) {
+	return processFieldQuery(request, "simple");
+    }
+
+    protected Element processAdvancedFieldQuery(Element request) {
+	return processFieldQuery(request, "advanced");
+    }
+
+    /** process a fielded query */
+    protected Element processFieldQuery(Element request, String type) {
+	
+	System.out.println("processing Field Query...");
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	String from = GSPath.appendLink(cluster_name_, FIELD_QUERY_SERVICE);
+	result.setAttribute(GSXML.FROM_ATT, from);
+	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
+	
+	// get param list
+	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	if (param_list==null) {
+	    System.err.println("GS2MGPPSearch, FieldQuery Error: no param list in request!");
+	    return result; // empty result
+	}
+
+	HashMap params = GSXML.extractAllParams(param_list);
+	printHash(params);
+
+	//check one of the params to see if it is present
+	String test_param = (String)params.get(FIELD_QUERY_PARAM);
+	if (test_param == null) { // no query
+	    return result;
+	}
+
+	// for now we are using the default index
+	String index = default_index_;
+	
+	// now set up the mgpp stuff
+	String basedir = GSFile.collectionBaseDir(site_home_, 
+						  cluster_name_);
+	String indexdir = GSFile.collectionIndexPath(cluster_name_, index);
+	
+	mgpp_src_.loadIndexData(basedir, indexdir);
+	setStandardQueryParams(params);
+	
+	String query="";
+	if (type.equals("simple")) {
+	    query = parseFieldQueryParams(params);
+	} else if (type.equals("advanced")) {
+	    query = parseAdvancedFieldQueryParams(params);
+	}
+	System.out.println("query="+query);
+	mgpp_src_.runQuery(query);
+	MGPPQueryResult mqr= mgpp_src_.getQueryResult();
+	
+	// get the docnums out, and convert to HASH ids
+	Vector docs = mqr.getDocs();
+	if (docs.size()==0) {
+	    // no docs found
+	    return result;
+	}
+	// create a documentList element
+	Element c = doc_.createElement(GSXML.CONTENT_ELEM);
+	result.appendChild(c);
+	Element document_list = doc_.createElement(GSXML.DOCUMENT_ELEM+GSXML.LIST_MODIFIER);
+	c.appendChild(document_list);
+	// add each document
+	for (int d=0; d<docs.size(); d++) {
+	    long docnum = ((MGPPDocInfo)docs.elementAt(d)).num_;
+	    String id = gdbm_src_.docnum2Oid(docnum);
+	    Node no = GSXML.createDocumentElement(doc_, id);
+	    document_list.appendChild(no);
+	}
+	return result;
+    }
+
+
+
+    // should probably use a list rather than map
+    protected boolean setStandardQueryParams(HashMap params) {
+
+	// set the default ones
+	mgpp_src_.setReturnTerms(true);
+	Set entries = params.entrySet();
+	Iterator i = entries.iterator();
+	while (i.hasNext()) {
+	    Map.Entry m = (Map.Entry)i.next();
+	    String name = (String)m.getKey();
+	    String value = (String)m.getValue();
+	   
+	    if (name.equals(CASE_PARAM)) {
+		boolean val = (value.equals(BOOLEAN_PARAM_ON)?true:false);
+		mgpp_src_.setCase(val);		
+	    } else if (name.equals(STEM_PARAM)) {
+		boolean val = (value.equals(BOOLEAN_PARAM_ON)?true:false);
+		mgpp_src_.setStem(val);
+	    } else if (name.equals(MAXDOCS_PARAM)) {
+		int docs = Integer.parseInt(value);
+		mgpp_src_.setMaxDocs(docs);
+	    } else if (name.equals(LEVEL_PARAM)) {
+		mgpp_src_.setQueryLevel(value);
+	    } else if (name.equals(MATCH_PARAM)) {
+		int mode;
+		if (value.equals(MATCH_PARAM_ALL)) mode=1;
+		else mode=0;
+		mgpp_src_.setMatchMode(mode);
+	    } else if (name.equals(RANK_PARAM)) {
+		if (value.equals(RANK_PARAM_RANK)) {
+		    mgpp_src_.setSortByRank(true);
+		} else if (value.equals(RANK_PARAM_NONE)) {
+		    mgpp_src_.setSortByRank(false);
+		}
+	    } // ignore any others
+	}
+	return true;
+    }
+
+    protected String parseFieldQueryParams(HashMap params) {
+
+	StringBuffer final_query = new StringBuffer(256);
+	String text_line = (String)params.get(FIELD_QUERY_PARAM);
+	String[] texts = text_line.split(",", -1);
+	String field_line = (String)params.get(FIELD_FIELD_PARAM);
+	String[] fields = field_line.split(",", -1);
+	String combine="&";
+	String match = (String)params.get(MATCH_PARAM);
+	if (match.equals(MATCH_PARAM_SOME)) {
+	    combine = "|";
+	}
+	
+	for (int i=0; i<texts.length; i++) {
+
+	    String q = texts[i].trim();
+	    if (!q.equals("")) {
+		addQueryElem(final_query, q, fields[i], combine);
+	    }
+	}
+
+	System.out.println("final query = "+final_query.toString());
+	return final_query.toString();
+    }
+    
+    protected String parseAdvancedFieldQueryParams(HashMap params) {
+
+	StringBuffer final_query = new StringBuffer(256);
+	String text_line = (String)params.get(FIELD_QUERY_PARAM);
+	String[] texts = text_line.split(",", -1);
+	String field_line = (String)params.get(FIELD_FIELD_PARAM);
+	String[] fields = field_line.split(",", -1);
+	String case_line = (String)params.get(FIELD_CASE_PARAM);
+	String[] cases = case_line.split(",", -1);
+	String stem_line = (String)params.get(FIELD_STEM_PARAM);
+	String[] stems = stem_line.split(",", -1);
+	String  combine_line = (String)params.get(FIELD_COMBINE_PARAM);
+	String [] combines = combine_line.split(",", -1);
+	String combine = "&";
+	for (int i=0; i<texts.length; i++) {
+	    if (i==0) {
+		combine = "";
+	    } else {
+		String x = combines[i-1]; // assume first one is missing
+		if (x.equals(FIELD_COMBINE_PARAM_AND)) {
+		    combine = "&";
+		} else if (x.equals(FIELD_COMBINE_PARAM_OR)) {
+		    combine = "|";
+		} else if (x.equals(FIELD_COMBINE_PARAM_NOT)) {
+		    combine = "!";
+		} 
+		
+	    }
+
+	    String q = texts[i].trim();
+	    if (!q.equals("")) {
+		q = addStemAndCase(q, stems[i], cases[i]);
+		addQueryElem(final_query, q, fields[i], combine);
+	    }
+	}
+
+	System.out.println("final query = "+final_query.toString());
+	return final_query.toString();
+    }
+
+    protected void addQueryElem(StringBuffer s, String q, String f, String c) {
+
+	String combine="";
+	if (s.length()>0) {
+	    combine = " "+c+" ";
+	}
+	if (f!="") {
+	    s.append(combine+"["+q+"]:"+f);
+	} else {
+	    s.append(combine+q);
+	}
+    }
+    protected String addStemAndCase(String q, String s, String c) {
+	String mods = "#";
+	if (c.equals("1")) {
+	    mods += "i";
+	} else {
+	    mods += "c";
+	}
+	if (s.equals("1")) {
+	    mods += "s";
+	} else {
+	    mods+= "u";
+	}
+	StringBuffer temp = new StringBuffer();
+	String [] terms = q.split(" ");
+	for (int i=0; i<terms.length; i++) {
+	    String t = terms[i].trim();
+	    
+	    if (!t.equals("") && !t.equals("TX")) {
+		temp.append(" "+t+mods);
+	    }
+	}
+	return temp.toString();
+    }
+
+    protected void printHash(HashMap map) {
+	System.out.println("Map entries are :");
+	Set entries = map.entrySet();
+	Iterator i = entries.iterator();
+	while (i.hasNext()) {
+	    Map.Entry m = (Map.Entry)i.next();
+	    String name = (String)m.getKey();
+	    String value = (String)m.getValue();
+	    System.out.println(name+"="+value);
+	}  
+    }
+
+}
+ 
+
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGRetrieve.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGRetrieve.java	(revision 3649)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGRetrieve.java	(revision 3649)
@@ -0,0 +1,112 @@
+/*
+ *    GS2MGRetrieve.java
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.service;
+
+import org.greenstone.gsdl3.util.*;
+
+import org.w3c.dom.Document; 
+import org.w3c.dom.Node; 
+import org.w3c.dom.Text; 
+import org.w3c.dom.Element; 
+import org.w3c.dom.NodeList; 
+/**
+ *
+ * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+ * @version $Revision$
+ */
+
+public class GS2MGRetrieve
+    extends ServiceRack {
+
+    // the services on offer
+    private static final String DOCUMENT_RETRIEVE_SERVICE = "DocumentRetrieve";
+    private static final String METADATA_RETRIEVE_SERVICE = "MetadataRetrieve";
+    
+
+    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
+    protected Element createServiceDisplay(String service, String lang) {
+	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
+	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
+	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
+
+	Element param;
+
+	return display;
+	
+    }
+
+
+    /** configure this service */
+    public boolean configure(Element info) {
+
+	System.out.println("configuring GS2MGRetrieve");
+
+	Element e = null;
+	// these entries should reflect the build config file - some services may not be available depending on how the colleciton was built.
+	// set up short_service_info_ - for now just has name and type
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, DOCUMENT_RETRIEVE_SERVICE);
+	short_service_info_.appendChild(e);
+
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
+	short_service_info_.appendChild(e);
+
+
+	// set up service_info_map_ - for now, just has the same elements as above
+	// should have full details about each service incl params lists etc.
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, DOCUMENT_RETRIEVE_SERVICE);
+	service_info_map_.put(DOCUMENT_RETRIEVE_SERVICE, e);
+	
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
+	service_info_map_.put(METADATA_RETRIEVE_SERVICE, e);
+
+	return true;
+    }
+  /** retrieve a document */
+    protected Element processDocumentRetrieve(Element request) {
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	result.setAttribute(GSXML.NAME_ATT, DOCUMENT_RETRIEVE_SERVICE);
+	
+	// dummy result
+	Text t = null;
+	t = doc_.createTextNode(DOCUMENT_RETRIEVE_SERVICE+" result... ");
+	result.appendChild(t);
+	return result;
+    }
+
+  /** retrieve metadata */
+    protected Element processMetadataRetrieve(Element request) {
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	result.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
+	
+	// dummy result
+	Text t = null;
+	t = doc_.createTextNode(METADATA_RETRIEVE_SERVICE+" result... ");
+	result.appendChild(t);
+	return result;
+    }
+
+}   
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGSearch.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGSearch.java	(revision 3649)
+++ trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS2MGSearch.java	(revision 3649)
@@ -0,0 +1,88 @@
+/*
+ *    GS2MGSearch.java
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.service;
+
+import org.greenstone.gsdl3.util.*;
+
+import org.w3c.dom.Document; 
+import org.w3c.dom.Node; 
+import org.w3c.dom.Text; 
+import org.w3c.dom.Element; 
+import org.w3c.dom.NodeList; 
+/**
+ *
+ * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
+ * @version $Revision$
+ */
+
+public class GS2MGSearch 
+    extends ServiceRack {
+
+    // the services on offer
+    private static final String TEXT_QUERY_SERVICE = "TextQuery";
+    
+
+    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
+    protected Element createServiceDisplay(String service, String lang) {
+	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
+	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
+	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
+
+	Element param;
+
+	return display;
+	
+    }
+    
+    /** configure this service */
+    public boolean configure(Element info) {
+
+	System.out.println("configuring GS2MGSearch");
+
+	Element e = null;
+	// these entries should reflect the build config file - some services may not be available depending on how the colleciton was built.
+	// set up short_service_info_ - for now just has name and type
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
+	short_service_info_.appendChild(e);
+
+	// set up service_info_map_ - for now, just has the same elements as above
+	// should have full details about each service incl params lists etc.
+	e = doc_.createElement(GSXML.SERVICE_ELEM);
+	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
+	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
+	service_info_map_.put(TEXT_QUERY_SERVICE, e);
+	
+	return true;
+    }
+  /** process a text query */
+    protected Element processTextQuery(Element request) {
+	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
+	result.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
+	
+	// dummy result
+	Text t = null;
+	t = doc_.createTextNode(TEXT_QUERY_SERVICE+" result... ");
+	result.appendChild(t);
+	return result;
+    }
+
+
+}   
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GSDL2ClassifierServices.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GSDL2ClassifierServices.java	(revision 3648)
+++ 	(revision )
@@ -1,247 +1,0 @@
-/*
- *    GSDL2ClassifierServices.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.greenstone.gsdl3.service;
-
-import org.greenstone.gdbm.*;
-import org.greenstone.gsdl3.util.*;
-
-import org.w3c.dom.Document; 
-import org.w3c.dom.Node; 
-import org.w3c.dom.Text; 
-import org.w3c.dom.Element; 
-import org.w3c.dom.NodeList; 
-/**
- * A ServicesImpl class for GSDL2-style Classifiers
- *
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @version $Revision$
- */
-public class GSDL2ClassifierServices 
-    extends ServicesImpl {
-
-    // the services on offer
-    private static final String CLASSIFIER_SERVICE = "ClassifierBrowse";
-
-    /** gdbm wrapper */
-    private GDBMWrapper gdbm_src_=null;
-
-    public GSDL2ClassifierServices() {
-	gdbm_src_ = new GDBMWrapper();
-
-    }
- 
-    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
-    protected Element createServiceDisplay(String service, String lang) {
-	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
-	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
-	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
-
-	Element param;
-
-	return display;
-	
-    }
-
-    /** processes the request */
-    protected Element processService(String name, Element request) {
-
-	if (!name.equals(CLASSIFIER_SERVICE)) {
-	    System.err.println("GSDL2ClassifierServices:should never get here. service type wrong:"+name);
-	return null;
-	}
-	// the response element
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	String from = GSPath.appendLink(cluster_name_, CLASSIFIER_SERVICE);
-	result.setAttribute(GSXML.FROM_ATT, from);
-	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-	Element result_content = doc_.createElement(GSXML.CONTENT_ELEM);
-	result.appendChild(result_content);
-
-	// get the classifier name out of request content - assume only one for now
-	String path = GSXML.CONTENT_ELEM;
-	path = GSPath.appendLink(path, GSXML.RESOURCE_ELEM+GSXML.LIST_MODIFIER);
-	path = GSPath.appendLink(path, GSXML.RESOURCE_ELEM);
-
-	Element elem = (Element)GSXML.getNodeByPath(request, path);
-	String elem_name = elem.getAttribute(GSXML.NAME_ATT);
-	System.out.println("elem name="+elem_name);
-
-	if (OID.needsTranslating(elem_name)) {
-	    System.out.println("translating oid");
-	    elem_name = gdbm_src_.translateOID(elem_name);
-	}
-	// get the info from gdbm db
-	DBInfo info = gdbm_src_.getInfo(elem_name);
-
-	// build up the XML
-	Element classifier = doc_.createElement(GSXML.CLASSIFIER_ELEM);
-	
-	String classifier_name = OID.getTop(elem_name);
-	classifier.setAttribute(GSXML.NAME_ATT, classifier_name);
-	result_content.appendChild(classifier);
-	DBInfo top_info;
-
-	if (elem_name.equals(classifier_name)) { 
-	    top_info = info;
-	} else {
-	    top_info = gdbm_src_.getInfo(classifier_name);
-	}
-
-	// a substitute template - should be read from config file
-	//String extra = "<stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template match='resource' priority='3'><xsl:param name='collName'>coll-name</xsl:param><xsl:variable name='library' select='ancestor::page/config/library_name'/><td><a href='{$library}?a=r&amp;c={$collName}&amp;r={@name}'><img src='interfaces/default/images/book.gif' width='18' height='11' border='0'/></a></td><td>***</td><td><xsl:value-of select='metadataList/metadata[@name=\"Title\"]'/></td></xsl:template></stylesheet>";
-	//Element extra_doc = converter_.getDOM(extra).getDocumentElement();
-	//result.appendChild(doc_.importNode(extra_doc, true));
-	
-	// get the classifier attributes
-	String type = top_info.getInfo("childtype");
-	if (type.equals("VList")) {
-	    
-	    classifier.setAttribute("type", "vertical");
-	    classifier.setAttribute("interleave", "true");
-	    classifier.setAttribute("link", "icon");
-	}
-	else if (type.equals("HList")){
-	    classifier.setAttribute("type", "horizontal");
-	    classifier.setAttribute("interleave", "false");
-	    classifier.setAttribute("link", "name");
-	} else {
-	    System.out.println("unknown type!!! check this");
-	    classifier.setAttribute("type", "vertical");
-	    classifier.setAttribute("interleave", "true");
-	    classifier.setAttribute("link", "icon");
-	}
-
-	Element this_node;
-	if (elem_name.equals(classifier_name)) {
-	    this_node = classifier;
-	} else { // have to build up the parents 
-	    // the current node
-	    this_node = doc_.createElement("node");
-	    this_node.setAttribute("name", elem_name);
-	    type = info.getInfo("childtype");
-	    if (type.equals("VList")) {
-		this_node.setAttribute("type", "vertical");
-	    } else {
-		this_node.setAttribute("type", "horzizontal");
-	    }
-	    String title = info.getInfo("Title");
-	    Element meta_list = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	    GSXML.addMetadata(doc_, meta_list, "Title", title);
-	    this_node.appendChild(meta_list);
-
-	    System.out.println("classifier_name="+classifier_name);
-	    System.out.println("this name="+elem_name);
-	    // the parents
-	    String middle_name = OID.getParent(elem_name);
-	    Element middle_node = this_node;
-	    while (!middle_name.equals(classifier_name)) {
-		System.out.println("middle_name="+middle_name);
-		// add in a new node
-		Element temp_node = doc_.createElement("node");
-		temp_node.setAttribute("name", middle_name);
-		
-		DBInfo i = gdbm_src_.getInfo(middle_name);
-		type = i.getInfo("childtype");
-		if (type.equals("VList")) {
-		    temp_node.setAttribute("type", "vertical");
-		} else {
-		    temp_node.setAttribute("type", "horzizontal");
-		}
-		title = i.getInfo("Title");
-		meta_list = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-		GSXML.addMetadata(doc_, meta_list, "Title", title);
-		temp_node.appendChild(meta_list);
-
-		// link into the tree
-		temp_node.appendChild(middle_node);
-		middle_node = temp_node;
-		middle_name = OID.getParent(middle_name);
-	    }
-	    classifier.appendChild(middle_node);
-	}
-	// get the child nodes
-	String contains = info.getInfo("contains");
-	// replace the " with parent name
-	contains = OID.translateParent(contains, elem_name);
-	String [] children = contains.split(";");
-	for (int i=0; i<children.length; i++) {
-	    String child = children[i];
-	    DBInfo child_info = gdbm_src_.getInfo(child);
-	    String title = child_info.getInfo("Title");
-	    Element node;
-	    if (child.startsWith("HASH")) {
-		// a resource
-		node = doc_.createElement(GSXML.RESOURCE_ELEM);
-	    } else { // a node in the classification
-		node = doc_.createElement("node");
-		
-	    }
-	    
-	    node.setAttribute(GSXML.NAME_ATT, child);
-	    Element meta_list = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
-	    GSXML.addMetadata(doc_, meta_list, "Title", title);
-	    node.appendChild(meta_list);
-	    this_node.appendChild(node);
-	    
-	}
-	
-	return result;
-	
-    }
-    
-
-    /** configure this service */
-    public boolean configure(Element info) {
-
-	System.out.println("configuring GSDL2ClassifierServices");
-
-	Element e = null;
-	// these entries should reflect the build config file - some services may not be available depending on how the colleciton was built.
-	// set up short_service_info_ - for now just has name and type
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
-	short_service_info_.appendChild(e);
-
-	// set up service_info_map_ - for now, just has the same elements as above
-	// should have full details about each service incl params lists etc.
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
-
-	// get the classifier list out of the service info
-	Node classList = GSXML.getChildByTagName(info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
-	e.appendChild(doc_.importNode(classList, true));
-
-	service_info_map_.put(CLASSIFIER_SERVICE, e);
-	
-	if (gdbm_src_.openDatabase(GSFile.GDBMDatabaseFile(site_home_, cluster_name_), GDBMWrapper.READER)) {
-	    return true;
-	}
-	else {
-	    System.err.println("couldn't open gdbm database!");
-	    return false;
-	}
-	
-    }
-
-
-}  
- 
-
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/MGGDBMServices.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/MGGDBMServices.java	(revision 3648)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- *    MGGDBMServices.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.greenstone.gsdl3.service;
-
-import org.greenstone.gsdl3.util.*;
-
-import org.w3c.dom.Document; 
-import org.w3c.dom.Node; 
-import org.w3c.dom.Text; 
-import org.w3c.dom.Element; 
-import org.w3c.dom.NodeList; 
-/**
- *
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @version $Revision$
- */
-
-public class MGGDBMServices 
-    extends ServicesImpl {
-
-    // the services on offer
-    private static final String TEXT_QUERY_SERVICE = "TextQuery";
-    private static final String RESOURCE_RETRIEVE_SERVICE = "ResourceRetrieve";
-    private static final String METADATA_RETRIEVE_SERVICE = "MetadataRetrieve";
-    
-
-    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
-    protected Element createServiceDisplay(String service, String lang) {
-	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
-	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
-	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
-
-	Element param;
-
-	return display;
-	
-    }
-
-    /** passes the request Element to the appropriate service function*/
-    protected Element processService(String name, Element request) {
-	
-	// dont need to check that the service name is  supported for this particular object, because that has been checked by ServicesImpl
-	if (name.equals(TEXT_QUERY_SERVICE)) {
-	    return processTextQuery(request);
-	} else if (name.equals(RESOURCE_RETRIEVE_SERVICE)) {
-	    return processDocRetrieve(request);
-	} else if (name.equals(METADATA_RETRIEVE_SERVICE)) {
-	    return processMetadataRetrieve(request);
-	}
-	
-	System.err.println("MGGDBMServices:should never get here. service type wrong:"+name);
-	return null;
-    }
-  /** configure this service */
-    public boolean configure(Element info) {
-
-	System.out.println("configuring MGGDBMServices");
-
-	Element e = null;
-	// these entries should reflect the build config file - some services may not be available depending on how the colleciton was built.
-	// set up short_service_info_ - for now just has name and type
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, RESOURCE_RETRIEVE_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
-	short_service_info_.appendChild(e);
-
-
-	// set up service_info_map_ - for now, just has the same elements as above
-	// should have full details about each service incl params lists etc.
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
-	service_info_map_.put(TEXT_QUERY_SERVICE, e);
-	
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, RESOURCE_RETRIEVE_SERVICE);
-	service_info_map_.put(RESOURCE_RETRIEVE_SERVICE, e);
-	
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
-	service_info_map_.put(METADATA_RETRIEVE_SERVICE, e);
-
-	return true;
-    }
-  /** process a text query */
-    protected Element processTextQuery(Element request) {
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	result.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
-	
-	// dummy result
-	Text t = null;
-	t = doc_.createTextNode(TEXT_QUERY_SERVICE+" result... ");
-	result.appendChild(t);
-	return result;
-    }
-
-  /** retrieve a document */
-    protected Element processDocRetrieve(Element request) {
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	result.setAttribute(GSXML.NAME_ATT, RESOURCE_RETRIEVE_SERVICE);
-	
-	// dummy result
-	Text t = null;
-	t = doc_.createTextNode(RESOURCE_RETRIEVE_SERVICE+" result... ");
-	result.appendChild(t);
-	return result;
-    }
-
-  /** retrieve metadata */
-    protected Element processMetadataRetrieve(Element request) {
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	result.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
-	
-	// dummy result
-	Text t = null;
-	t = doc_.createTextNode(METADATA_RETRIEVE_SERVICE+" result... ");
-	result.appendChild(t);
-	return result;
-    }
-
-}   
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/MGPPGDBMServices.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/MGPPGDBMServices.java	(revision 3648)
+++ 	(revision )
@@ -1,1074 +1,0 @@
-/*
- *    MGPPGDBMServices.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.greenstone.gsdl3.service;
-
-import org.greenstone.mgpp.*;
-import org.greenstone.gdbm.*;
-import org.greenstone.gsdl3.util.*;
-
-import org.w3c.dom.Document; 
-import org.w3c.dom.Node; 
-import org.w3c.dom.Text; 
-import org.w3c.dom.Element; 
-import org.w3c.dom.NodeList; 
-
-import java.util.HashMap;
-import java.util.Vector;
-import java.util.Set;
-import java.util.Map;
-import java.util.Iterator;
-import java.util.Locale;
-/**
- * A ServicesImpl class for MGPP+GDBM
- *
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @version $Revision$
- * @see ServicesImpl
- */
-
-
-public class MGPPGDBMServices 
-    extends ServicesImpl {
-
-    // these strings must match what is found in the properties file
-    // the services on offer
-    private static final String TEXT_QUERY_SERVICE = "TextQuery";
-    private static final String FIELD_QUERY_SERVICE = "FieldQuery";
-    private static final String ADVANCED_FIELD_QUERY_SERVICE = "AdvancedFieldQuery";
-    private static final String RESOURCE_RETRIEVE_SERVICE = "ResourceRetrieve";
-    private static final String METADATA_RETRIEVE_SERVICE = "MetadataRetrieve";
-
-    // params used
-    private static final String CASE_PARAM = "case";
-    private static final String STEM_PARAM = "stem";
-    private static final String MATCH_PARAM = "matchMode";
-    private static final String MATCH_PARAM_ALL = "all";
-    private static final String MATCH_PARAM_SOME = "some";
-    private static final String INDEX_PARAM = "index";
-    private static final String LEVEL_PARAM = "level";
-    private static final String RANK_PARAM = "sortBy";
-    private static final String RANK_PARAM_RANK = "rank";
-    private static final String RANK_PARAM_NONE = "natural";
-    private static final String MAXDOCS_PARAM = "maxDocs";
-    private static final String BOOLEAN_PARAM_ON = "1";
-    private static final String BOOLEAN_PARAM_OFF = "0";
-    private static final String QUERY_PARAM = "query";
-    private static final String SIMPLE_FIELD_PARAM = "simpleField";
-    private static final String ADVANCED_FIELD_PARAM = "complexField";
-    // more params for field query
-    private static final String FIELD_QUERY_PARAM = "fqv";
-    private static final String FIELD_STEM_PARAM = "fqs";
-    private static final String FIELD_CASE_PARAM = "fqc";
-    private static final String FIELD_FIELD_PARAM = "fqf";
-    private static final String FIELD_COMBINE_PARAM = "fqk";
-    private static final String FIELD_COMBINE_PARAM_AND = "0";
-    private static final String FIELD_COMBINE_PARAM_OR = "1";
-    private static final String FIELD_COMBINE_PARAM_NOT = "2";
-    
-    // elements used in the config file that are specific to this class
-    private static final String DEFAULT_INDEX_ELEM = "defaultIndex";
-    private static final String DEFAULT_LEVEL_ELEM = "defaultLevel";
-    private static final String INDEX_ELEM = "index";
-    private static final String LEVEL_ELEM = "level";
-    
-
-    private MGPPWrapper mgpp_src_=null;
-    private GDBMWrapper gdbm_src_=null;
-    
-    private String default_index_=null;
-    private String default_level_=null;
-
-    private Element config_info_ = null;
-    public MGPPGDBMServices() {
-	mgpp_src_ = new MGPPWrapper();
-	gdbm_src_ = new GDBMWrapper();
-
-    }
-    
-    /** configure this service */
-    public boolean configure(Element info) {
-
-	System.out.println("configuring MGPPGDBMServices");
-	config_info_ = info;
-	// get the general info first
-	// get the default index from <defaultIndex>
-	Element def = (Element)GSXML.getChildByTagName(info, DEFAULT_INDEX_ELEM );
-	if (def !=null) {
-	    default_index_ = def.getAttribute(GSXML.NAME_ATT);
-	}
-	if (default_index_==null||default_index_.equals("")) {
-	    System.err.println("Error: default index not specified!");
-	    return false;
-	}
-
-	// get the default level out of <defaultLevel>
-	def = (Element)GSXML.getChildByTagName(info, DEFAULT_LEVEL_ELEM);
-	if (def !=null) {
-	    default_level_ = def.getAttribute(GSXML.NAME_ATT);
-	}
-	if (default_level_==null||default_level_.equals("")) {
-	    System.err.println("Error: default level not specified!");
-	    return false;
-	}
-	// the default level is also the level which gdbm is expecting
-	mgpp_src_.setReturnLevel(default_level_);
-
-	// set up which services are available for this collection
-	Element e = null;
-	// these entries should reflect the build config file - some services may not be available depending on how the collection was built.
-
-	// set up short_service_info_ - for now just has name and type
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, FIELD_QUERY_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, ADVANCED_FIELD_QUERY_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, RESOURCE_RETRIEVE_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
-	short_service_info_.appendChild(e);
-
-	// set up service_info_map_ - for now, just has the same elements as above
-	// should have full details about each service incl params lists etc.
-	// do the text query one - for now a static list. later use buildcfg.xml values to dynamically change this
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
-	Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	createTextQueryParamList(param_list, false, null);
-	e.appendChild(param_list);
-	service_info_map_.put(TEXT_QUERY_SERVICE, e);
-	
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, FIELD_QUERY_SERVICE);
-	Element param_list1 = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	createFieldQueryParamList(param_list1, false, null);
-	e.appendChild(param_list1);
-	service_info_map_.put(FIELD_QUERY_SERVICE, e);
-	
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, ADVANCED_FIELD_QUERY_SERVICE);
-	Element param_list2 = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	createAdvancedFieldQueryParamList(param_list2, false, null);
-	e.appendChild(param_list2);
-	service_info_map_.put(ADVANCED_FIELD_QUERY_SERVICE, e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, RESOURCE_RETRIEVE_SERVICE);
-	service_info_map_.put(RESOURCE_RETRIEVE_SERVICE, e);
-	
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, METADATA_RETRIEVE_SERVICE);
-	service_info_map_.put(METADATA_RETRIEVE_SERVICE, e);
-
-	if (gdbm_src_.openDatabase(GSFile.GDBMDatabaseFile(site_home_, cluster_name_), GDBMWrapper.READER)) {
-	    return true;
-	}
-	else {
-	    System.err.println("couldn't open gdbm database!");
-	    return false;
-	}
-    }
-  
-    /** this creates all teh params and appends them to param_list.
-     * if display=true it creates the text strings version
-     * otherwise it creates the description version
-     */
-    protected boolean createTextQueryParamList(Element param_list, boolean display, String lang) {
-	Element param;
-
-	// first do index and level params
-
-	// the index info - read from config file
-	Element index_list = (Element)GSXML.getChildByTagName(config_info_, INDEX_ELEM+GSXML.LIST_MODIFIER);
-	NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
-	int len = indexes.getLength();
-	if (len > 1) {
-	    // add level param to list
-	    String [] inds  = new String[len];
-	    for (int i=0; i<len; i++) {
-		inds[i] = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT);
-	    }
-	    if (display) {
-		// use the same index names for now - should get these out of the config info
-		param = GSXML.createParameterDisplay(doc_, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), inds, inds);
-	    } else {
-		param = GSXML.createParameter(doc_, INDEX_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_index_, inds);
-	    }
-	    param_list.appendChild(param);
-	} // else dont need to add it
-
-	// the level info - read from config file
-	Element level_list = (Element)GSXML.getChildByTagName(config_info_, LEVEL_ELEM+GSXML.LIST_MODIFIER);
-	NodeList levels = level_list.getElementsByTagName(LEVEL_ELEM);
-	len = levels.getLength();
-	if (len > 1) {
-	    // add level param to list
-	    String [] levs  = new String[len];
-	    for (int i=0; i<len; i++) {
-		levs[i] = ((Element)levels.item(i)).getAttribute(GSXML.NAME_ATT);
-	    }
-	    if (display) {
-		param =  GSXML.createParameterDisplay(doc_, LEVEL_PARAM, getTextString("param."+LEVEL_PARAM, lang), levs, levs);
-	    } else {
-		param = GSXML.createParameter(doc_, LEVEL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_level_, levs);
-	    }
-	    param_list.appendChild(param);
-	} // else dont need to add it
-	
-	// boolean params
-	if (display) {
-	    String[] bool_ops = {"0", "1"};
-	    String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
-	    param = GSXML.createParameterDisplay(doc_, CASE_PARAM, getTextString("param."+CASE_PARAM, lang),  bool_ops, bool_texts);
-	    param_list.appendChild(param);
-	    param = GSXML.createParameterDisplay(doc_, STEM_PARAM, getTextString("param."+STEM_PARAM, lang),  bool_ops, bool_texts);
-	    param_list.appendChild(param);
-
-	} else {
-	    param = GSXML.createParameter(doc_, CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
-	    param_list.appendChild(param);
-	    param = GSXML.createParameter(doc_, STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
-	    param_list.appendChild(param);
-	}
-
-	// enum params
-	String []vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
-	if (display) {
-	    String []val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)}; 
-
-	    param = GSXML.createParameterDisplay(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), vals, val_texts);
-	} else {
-	    param = GSXML.createParameter(doc_, MATCH_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals);
-	}	
-	param_list.appendChild(param);
-	String [] vals1 = {RANK_PARAM_RANK, RANK_PARAM_NONE };
-	if (display) {
-	    String [] vals1_texts = { getTextString("param."+RANK_PARAM+"."+RANK_PARAM_RANK, lang),
-				  getTextString("param."+RANK_PARAM+"."+RANK_PARAM_NONE, lang)};
-	
-	    param = GSXML.createParameterDisplay(doc_, RANK_PARAM, getTextString("param."+RANK_PARAM, lang), vals1, vals1_texts);
-	} else {
-	    param = GSXML.createParameter(doc_, RANK_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, RANK_PARAM_RANK, vals1 );
-	}
-	param_list.appendChild(param);
-
-	// Integer params
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), null, null);
-	} else {
-	    param = GSXML.createParameter(doc_, MAXDOCS_PARAM, GSXML.PARAM_TYPE_INTEGER, "10", null);
-	}
-	param_list.appendChild(param);
-
-	// for now add the query itself as a param
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), null, null);
-	} else {
-	    param = GSXML.createParameter(doc_, QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
-	}
-	param_list.appendChild(param);
-	
-	return true;
-    }
-    /** this creates all teh params and appends them to param_list.
-     * if display=true it creates the text strings version
-     * otherwise it creates the description version
-     */
-    protected boolean createFieldQueryParamList(Element param_list, boolean display, String lang) {
-	Element param;
-
-	// first do index and level params
-
-	// the index info - read from config file
-//  	Element index_list = (Element)GSXML.getChildByTagName(config_info_, INDEX_ELEM+GSXML.LIST_MODIFIER);
-//  	NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
-//  	int len = indexes.getLength();
-//  	if (len > 1) {
-//  	    // add level param to list
-//  	    String [] inds  = new String[len];
-//  	    for (int i=0; i<len; i++) {
-//  		inds[i] = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT);
-//  	    }
-//  	    if (display) {
-//  		// use the same index names for now - should get these out of the config info
-//  		param = GSXML.createParameterDisplay(doc_, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), inds, inds);
-//  	    } else {
-//  		param = GSXML.createParameter(doc_, INDEX_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_index_, inds);
-//  	    }
-//  	    param_list.appendChild(param);
-//  	} // else dont need to add it
-
-	// the level info - read from config file
-	Element level_list = (Element)GSXML.getChildByTagName(config_info_, LEVEL_ELEM+GSXML.LIST_MODIFIER);
-	NodeList levels = level_list.getElementsByTagName(LEVEL_ELEM);
-	int len = levels.getLength();
-	if (len > 1) {
-	    // add level param to list
-	    String [] levs  = new String[len];
-	    for (int i=0; i<len; i++) {
-		levs[i] = ((Element)levels.item(i)).getAttribute(GSXML.NAME_ATT);
-	    }
-	    if (display) {
-		param =  GSXML.createParameterDisplay(doc_, LEVEL_PARAM, getTextString("param."+LEVEL_PARAM, lang), levs, levs);
-	    } else {
-		param = GSXML.createParameter(doc_, LEVEL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_level_, levs);
-	    }
-	    param_list.appendChild(param);
-	} // else dont need to add it
-	
-	// enum params
-	String []vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
-	if (display) {
-	    String []val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)}; 
-
-	    param = GSXML.createParameterDisplay(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), vals, val_texts);
-	} else {
-	    param = GSXML.createParameter(doc_, MATCH_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals);
-	}	
-	param_list.appendChild(param);
-	String [] vals1 = {RANK_PARAM_RANK, RANK_PARAM_NONE };
-	if (display) {
-	    String [] vals1_texts = { getTextString("param."+RANK_PARAM+"."+RANK_PARAM_RANK, lang),
-				  getTextString("param."+RANK_PARAM+"."+RANK_PARAM_NONE, lang)};
-	
-	    param = GSXML.createParameterDisplay(doc_, RANK_PARAM, getTextString("param."+RANK_PARAM, lang), vals1, vals1_texts);
-	} else {
-	    param = GSXML.createParameter(doc_, RANK_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, RANK_PARAM_RANK, vals1 );
-	}
-	param_list.appendChild(param);
-
-	// boolean params
-	if (display) {
-	    String[] bool_ops = {"0", "1"};
-	    String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
-	    param = GSXML.createParameterDisplay(doc_, FIELD_CASE_PARAM, getTextString("param."+FIELD_CASE_PARAM, lang),  bool_ops, bool_texts);
-	    param_list.appendChild(param);
-	    param = GSXML.createParameterDisplay(doc_, FIELD_STEM_PARAM, getTextString("param."+FIELD_STEM_PARAM, lang),  bool_ops, bool_texts);
-	    param_list.appendChild(param);
-
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
-	    param_list.appendChild(param);
-	    param = GSXML.createParameter(doc_, FIELD_STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
-	    param_list.appendChild(param);
-	}
-
-	// Integer params
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), null, null);
-	} else {
-	    param = GSXML.createParameter(doc_, MAXDOCS_PARAM, GSXML.PARAM_TYPE_INTEGER, "10", null);
-	}
-	param_list.appendChild(param);
-
-	// create a multi param for the fields etc
-	// text box, stem, case, field
-
-	Element multiparam = null;;
-
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, SIMPLE_FIELD_PARAM, "",  null, null);
-	    param_list.appendChild(param);
-	} else {
-	    multiparam = GSXML.createParameter(doc_, SIMPLE_FIELD_PARAM, GSXML.PARAM_TYPE_MULTI, null, null);
-	    multiparam.setAttribute("occurs", "4");
-	    param_list.appendChild(multiparam);
-	}
-	// the components
-	// the text box
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, FIELD_QUERY_PARAM, getTextString("param."+FIELD_QUERY_PARAM, lang), null, null);
-	    param_list.appendChild(param);
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
-	    multiparam.appendChild(param);
-	    
-	}
-	
-	// the field list - should be read from config file
-	String [] vals2 = {"TX", "SU", "TI"};
-	String [] vals2_texts = {"TextOnly", "Subject", "Title"};
-	
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, FIELD_FIELD_PARAM, getTextString("param."+FIELD_FIELD_PARAM, lang), vals2, vals2_texts);
-	    param_list.appendChild(param); 
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_FIELD_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", vals2 );
-	    multiparam.appendChild(param);
-	}
-	
-	return true;
-    }
-
-    protected boolean createAdvancedFieldQueryParamList(Element param_list, boolean display, String lang) {
-	Element param;
-
-	// first do index and level params
-
-	// the index info - read from config file
-//  	Element index_list = (Element)GSXML.getChildByTagName(config_info_, INDEX_ELEM+GSXML.LIST_MODIFIER);
-//  	NodeList indexes = index_list.getElementsByTagName(INDEX_ELEM);
-//  	int len = indexes.getLength();
-//  	if (len > 1) {
-//  	    // add level param to list
-//  	    String [] inds  = new String[len];
-//  	    for (int i=0; i<len; i++) {
-//  		inds[i] = ((Element)indexes.item(i)).getAttribute(GSXML.NAME_ATT);
-//  	    }
-//  	    if (display) {
-//  		// use the same index names for now - should get these out of the config info
-//  		param = GSXML.createParameterDisplay(doc_, INDEX_PARAM, getTextString("param."+INDEX_PARAM, lang), inds, inds);
-//  	    } else {
-//  		param = GSXML.createParameter(doc_, INDEX_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_index_, inds);
-//  	    }
-//  	    param_list.appendChild(param);
-//  	} // else dont need to add it
-
-	// the level info - read from config file
-	Element level_list = (Element)GSXML.getChildByTagName(config_info_, LEVEL_ELEM+GSXML.LIST_MODIFIER);
-	NodeList levels = level_list.getElementsByTagName(LEVEL_ELEM);
-	int len = levels.getLength();
-	if (len > 1) {
-	    // add level param to list
-	    String [] levs  = new String[len];
-	    for (int i=0; i<len; i++) {
-		levs[i] = ((Element)levels.item(i)).getAttribute(GSXML.NAME_ATT);
-	    }
-	    if (display) {
-		param =  GSXML.createParameterDisplay(doc_, LEVEL_PARAM, getTextString("param."+LEVEL_PARAM, lang), levs, levs);
-	    } else {
-		param = GSXML.createParameter(doc_, LEVEL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, default_level_, levs);
-	    }
-	    param_list.appendChild(param);
-	} // else dont need to add it
-	
-//  	// enum params
-//  	String []vals = {MATCH_PARAM_ALL, MATCH_PARAM_SOME};
-//  	if (display) {
-//  	    String []val_texts = {getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_ALL, lang),getTextString("param."+MATCH_PARAM+"."+MATCH_PARAM_SOME, lang)}; 
-
-//  	    param = GSXML.createParameterDisplay(doc_, MATCH_PARAM, getTextString("param."+MATCH_PARAM, lang), vals, val_texts);
-//  	} else {
-//  	    param = GSXML.createParameter(doc_, MATCH_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, MATCH_PARAM_ALL, vals);
-//  	}	
-//  	param_list.appendChild(param);
-
-	String [] vals1 = {RANK_PARAM_RANK, RANK_PARAM_NONE };
-	if (display) {
-	    String [] vals1_texts = { getTextString("param."+RANK_PARAM+"."+RANK_PARAM_RANK, lang),
-				  getTextString("param."+RANK_PARAM+"."+RANK_PARAM_NONE, lang)};
-	
-	    param = GSXML.createParameterDisplay(doc_, RANK_PARAM, getTextString("param."+RANK_PARAM, lang), vals1, vals1_texts);
-	} else {
-	    param = GSXML.createParameter(doc_, RANK_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, RANK_PARAM_RANK, vals1 );
-	}
-	param_list.appendChild(param);
-
-	// Integer params
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, MAXDOCS_PARAM, getTextString("param."+MAXDOCS_PARAM, lang), null, null);
-	} else {
-	    param = GSXML.createParameter(doc_, MAXDOCS_PARAM, GSXML.PARAM_TYPE_INTEGER, "10", null);
-	}
-	param_list.appendChild(param);
-
-	// create a multi param for the fields etc
-	// text box, stem, case, field
-
-	Element multiparam = null;
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, ADVANCED_FIELD_PARAM, "",  null, null);
-	    param_list.appendChild(param);
-	} else {
-	    multiparam = GSXML.createParameter(doc_, ADVANCED_FIELD_PARAM, GSXML.PARAM_TYPE_MULTI, null, null);
-	    multiparam.setAttribute("occurs", "4");
-	    param_list.appendChild(multiparam);
-	}
-	
-	// the components
-
-	//the combiners
-	
-	String []vals = {FIELD_COMBINE_PARAM_AND, FIELD_COMBINE_PARAM_OR, FIELD_COMBINE_PARAM_NOT};
-	if (display) {
-	    String []val_texts = {getTextString("param."+FIELD_COMBINE_PARAM+"."+FIELD_COMBINE_PARAM_AND, lang), getTextString("param."+FIELD_COMBINE_PARAM+"."+FIELD_COMBINE_PARAM_OR, lang), getTextString("param."+FIELD_COMBINE_PARAM+"."+FIELD_COMBINE_PARAM_NOT, lang)}; 
-
-	    param = GSXML.createParameterDisplay(doc_, FIELD_COMBINE_PARAM, "", vals, val_texts);
-	    param_list.appendChild(param);
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_COMBINE_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, FIELD_COMBINE_PARAM_AND, vals);
-	    param.setAttribute(GSXML.PARAM_IGNORE_POS_ATT, "0");
-	    multiparam.appendChild(param);
-	}	
-
-	// the text box
-	if (display) {
-	    param = GSXML.createParameterDisplay(doc_, FIELD_QUERY_PARAM, getTextString("param."+FIELD_QUERY_PARAM, lang), null, null);
-	    param_list.appendChild(param);
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_QUERY_PARAM, GSXML.PARAM_TYPE_STRING, null, null);
-	    multiparam.appendChild(param);
-	    
-	}
-	
-	// boolean params
-	if (display) {
-	    String[] bool_ops = {"0", "1"};
-	    String[] bool_texts = {getTextString("param.boolean.off", lang),getTextString("param.boolean.on", lang)}; 
-	    param = GSXML.createParameterDisplay(doc_, FIELD_CASE_PARAM, getTextString("param."+FIELD_CASE_PARAM, lang),  bool_ops, bool_texts);
-	    param_list.appendChild(param);
-	    param = GSXML.createParameterDisplay(doc_, FIELD_STEM_PARAM, getTextString("param."+FIELD_STEM_PARAM, lang),  bool_ops, bool_texts);
-	    param_list.appendChild(param);
-
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_CASE_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
-	    multiparam.appendChild(param);
-	    param = GSXML.createParameter(doc_, FIELD_STEM_PARAM, GSXML.PARAM_TYPE_BOOLEAN, BOOLEAN_PARAM_ON, null);
-	    multiparam.appendChild(param);
-	}
-
-	// the field list
-	String [] vals2 = {"TX", "SU", "TI"};
-	String [] vals2_texts = {"TextOnly", "Subject", "Title"};
-
-	if (display) {
-	     param = GSXML.createParameterDisplay(doc_, FIELD_FIELD_PARAM, getTextString("param."+FIELD_FIELD_PARAM, lang), vals2, vals2_texts);
-	    param_list.appendChild(param); 
-	} else {
-	    param = GSXML.createParameter(doc_, FIELD_FIELD_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", vals2 );
-	    multiparam.appendChild(param);
-	}
-	
-	return true;
-    }
-    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
-    protected Element createServiceDisplay(String service, String lang) {
-	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
-	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
-	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
-
-	// now need to add in the params
-	if (service.equals(TEXT_QUERY_SERVICE)) {
-	    
-	    createTextQueryParamList(display, true, lang);
-	}
-	// now need to add in the params
-	if (service.equals(FIELD_QUERY_SERVICE)) {
-	    
-	    createFieldQueryParamList(display, true, lang);
-	}
-	// now need to add in the params
-	if (service.equals(ADVANCED_FIELD_QUERY_SERVICE)) {
-	    
-	    createAdvancedFieldQueryParamList(display, true, lang);
-	}
-	return display;
-	
-    }
-
-     
-
-    /** passes the request Element to the appropriate service function*/
-    protected Element processService(String name, Element request) {
-
-	// dont need to check that the service name is  supported for this particular object, because that has been checked by ServicesImpl
-	if (name.equals(TEXT_QUERY_SERVICE)) {
-	    return processTextQuery(request);
-	} else if(name.equals(FIELD_QUERY_SERVICE)) {
-	    return processFieldQuery(request, "simple");
-	} else if(name.equals(ADVANCED_FIELD_QUERY_SERVICE)) {
-	    return processFieldQuery(request, "advanced");
-	} else if (name.equals(RESOURCE_RETRIEVE_SERVICE)) {
-	    return processResourceRetrieve(request);
-	} else if (name.equals(METADATA_RETRIEVE_SERVICE)) {
-	    return processMetadataRetrieve(request);
-	}
-	
-	System.err.println("MGPPGDBMServices:should never get here. service type wrong:"+name);
-	return null;
-	
-	
-    }
-
-    /** process a text query */
-    protected Element processTextQuery(Element request) {
-
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	String from = GSPath.appendLink(cluster_name_, TEXT_QUERY_SERVICE);
-	result.setAttribute(GSXML.FROM_ATT, from);
-	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-	
-	// get param list and content
-	/*Element param_elem=null;
-	Element content_elem=null;
-	Node n = request.getFirstChild();
-	while (n!=null) {
-	  String node_name = n.getNodeName();
-	  if (node_name.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
-	      param_elem = (Element)n;
-	  } else if (node_name.equals(GSXML.CONTENT_ELEM)) {
-	      content_elem = (Element)n;
-	  }
-	  n = n.getNextSibling();
-	}
-
-	if (param_elem==null || content_elem==null) {
-	    System.out.println("bad query request");
-	    return result; // empty result
-	}
-	*/
-
-	// get param list
-	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	if (param_list==null) {
-	    System.err.println("MGPPGDBMServices, TextQuery Error: no param list in request!");
-	    return result; // empty result
-	}
-	/*
-	// get the query string
-	String query = GSXML.getNodeText(content_elem);
-	if (query==null) {
-	    System.out.println("nothing to query");
-	    return result;
-	}
-	*/
-	HashMap params = GSXML.extractParams(param_list);
-	String query = (String)params.get(QUERY_PARAM);
-	if (query == null) {
-	    // nothing to query
-	    return result;
-	}
-	
-	String index = (String)params.get(INDEX_PARAM); 
-	if (index==null) { // if its not present, use the default index
-	    index=default_index_;
-	}
-
-	// now set up the mgpp stuff
-	String basedir = GSFile.collectionBaseDir(site_home_, 
-						  cluster_name_);
-	String indexdir = GSFile.collectionIndexPath(cluster_name_, index);
-
-	mgpp_src_.loadIndexData(basedir, indexdir);
-	setStandardQueryParams(params);
-	
-	mgpp_src_.runQuery(query);
-	MGPPQueryResult mqr= mgpp_src_.getQueryResult();
-	
-	// get the docnums out, and convert to HASH ids
-	Vector docs = mqr.getDocs();
-	if (docs.size()==0) {
-	    // no docs found
-	    return result;
-	}
-	// create a resourceList element
-	Element c = doc_.createElement(GSXML.CONTENT_ELEM);
-	result.appendChild(c);
-	Element resource_list = doc_.createElement(GSXML.RESOURCE_ELEM+GSXML.LIST_MODIFIER);
-	c.appendChild(resource_list);
-	// add each resource
-	for (int d=0; d<docs.size(); d++) {
-	    long docnum = ((MGPPDocInfo)docs.elementAt(d)).num_;
-	    String id = gdbm_src_.docnum2Oid(docnum);
-	    Node no = GSXML.createResourceElement(doc_, id);
-	    resource_list.appendChild(no);
-	}
-	return result;
-    }//processTextQuery
-
-    /** process a fielded query */
-    protected Element processFieldQuery(Element request, String type) {
-	
-	System.out.println("processing Field Query...");
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	String from = GSPath.appendLink(cluster_name_, FIELD_QUERY_SERVICE);
-	result.setAttribute(GSXML.FROM_ATT, from);
-	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-	
-	// get param list
-	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	if (param_list==null) {
-	    System.err.println("MGPPGDBMServices, FieldQuery Error: no param list in request!");
-	    return result; // empty result
-	}
-
-	HashMap params = GSXML.extractAllParams(param_list);
-	printHash(params);
-
-	//check one of the params to see if it is present
-	String test_param = (String)params.get(FIELD_QUERY_PARAM);
-	if (test_param == null) { // no query
-	    return result;
-	}
-
-	
-	/*	String index = (String)params.get(INDEX_PARAM); 
-	if (index==null) { // if its not present, use the default index
-	    index=default_index_;
-	    }*/
-	// for now we are using the default index
-	String index = default_index_;
-	
-	// now set up the mgpp stuff
-	String basedir = GSFile.collectionBaseDir(site_home_, 
-						  cluster_name_);
-	String indexdir = GSFile.collectionIndexPath(cluster_name_, index);
-	
-	mgpp_src_.loadIndexData(basedir, indexdir);
-	setStandardQueryParams(params);
-	
-	String query="";
-	if (type.equals("simple")) {
-	    query = parseFieldQueryParams(params);
-	} else if (type.equals("advanced")) {
-	    query = parseAdvancedFieldQueryParams(params);
-	}
-	System.out.println("query="+query);
-	mgpp_src_.runQuery(query);
-	MGPPQueryResult mqr= mgpp_src_.getQueryResult();
-	
-	// get the docnums out, and convert to HASH ids
-	Vector docs = mqr.getDocs();
-	if (docs.size()==0) {
-	    // no docs found
-	    return result;
-	}
-	// create a resourceList element
-	Element c = doc_.createElement(GSXML.CONTENT_ELEM);
-	result.appendChild(c);
-	Element resource_list = doc_.createElement(GSXML.RESOURCE_ELEM+GSXML.LIST_MODIFIER);
-	c.appendChild(resource_list);
-	// add each resource
-	for (int d=0; d<docs.size(); d++) {
-	    long docnum = ((MGPPDocInfo)docs.elementAt(d)).num_;
-	    String id = gdbm_src_.docnum2Oid(docnum);
-	    Node no = GSXML.createResourceElement(doc_, id);
-	    resource_list.appendChild(no);
-	}
-	return result;
-    }
-
-    /** retrieve a document */
-    protected Element processResourceRetrieve(Element request) {
-
-	// where the mgpp text files are
-	String basedir = GSFile.collectionBaseDir(site_home_, 
-						  cluster_name_);
-	String textdir = GSFile.collectionTextPath(cluster_name_);
-
-	// an empty result
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	String from = GSPath.appendLink(cluster_name_, RESOURCE_RETRIEVE_SERVICE);
-	result.setAttribute(GSXML.FROM_ATT, from);
-	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-	Element result_doc = doc_.createElement(GSXML.CONTENT_ELEM);
-	result.appendChild(result_doc);
-	
-	// get param list and content - this code same as for TextQuery - put
-	// somewhere else?
-	Element param_elem=null;
-	Element content_elem=null;
-	Node n = request.getFirstChild();
-	while (n!=null) {
-	  String node_name = n.getNodeName();
-	  if (node_name.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
-	      param_elem = (Element)n;
-	  } else if (node_name.equals(GSXML.CONTENT_ELEM)) {
-	      content_elem = (Element)n;
-	  }
-	  n = n.getNextSibling();
-	}
-
-	if (param_elem==null || content_elem==null) {
-	    System.out.println("bad query request");
-	    return result; // empty result
-	}
-	
-	HashMap params = GSXML.extractParams(param_elem);
-	String resource_type = (String)params.get("resourceType");
-	if (resource_type==null) {
-	    System.out.println("no resourceType defined, assume 'core'");
-	    // have error? or assume that its core?
-	    resource_type="core";
-	}
-
-	if (resource_type.equals("core")) {
-	    // get docs from mgpp, and possibly associated files too
-	    String level = (String)params.get(LEVEL_PARAM); // level at which to 
-	    // retrieve a doc
-	    if (level==null) {
-		level=default_level_;
-	    }
-	    // whether to just get the doc, or all assoc files too.
-	    String retrieve_extent = (String)params.get("retrieveExtent");
-	    if (retrieve_extent==null) {
-		// assume just the doc
-		retrieve_extent = "docOnly";
-	    }
-
-	    // always get the doc (for now - this may change later)
-	    // get the doc text, and if retrieveExtent = allFiles, get assoc files too	
-	    
-	    String []ids = GSXML.getResourceNameList(content_elem);
-	    for (int j=0; j<ids.length; j++) {
-		long real_num = gdbm_src_.oid2Docnum(ids[j]);
-		System.out.println("getting doc text, basedir="+basedir+", textdir="+textdir+", level="+level+", num="+real_num);
-		String document = mgpp_src_.getDocument(basedir, textdir,  level, real_num);
-	    // for now, stick it in a text node - eventually should be parsed as xml??
-
-		// something funny with the doc - 
-		Element new_doc = GSXML.createResourceElement(doc_, ids[j]);
-		GSXML.addDocText(doc_, new_doc, document);
-		if (retrieve_extent.equals("allFiles")) {
-		    // get the assoc files too
-		}
-		result_doc.appendChild(new_doc);
-	    }
-	    
-	} else if (resource_type.equals("assoc")) {
-	    // get associated files
-	    String assoc_file_dir = (String)params.get("assocfilepath");
-	    if (assoc_file_dir==null) {
-		System.err.println("need assocfilepath to find files");
-		
-	    } else {
-		String []files = GSXML.getResourceNameList(content_elem);
-		for (int j=0; j<files.length; j++) {
-		    Element new_doc = GSXML.createResourceElement(doc_, 
-								  files[j]);
-		    // add the file
-		    result_doc.appendChild(new_doc);
-		}
-	    }
-	} else {
-	    System.out.println("error: resource Type is not legal");
-	}
-	
-	return result;
-
-    }
-
-    /** retrieve metadata */
-    protected Element processMetadataRetrieve(Element request) {
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	String from = GSPath.appendLink(cluster_name_, METADATA_RETRIEVE_SERVICE);
-	result.setAttribute(GSXML.FROM_ATT, from);
-	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-	Element result_content = doc_.createElement(GSXML.CONTENT_ELEM);
-	result.appendChild(result_content);
-	Element resource_list = doc_.createElement(GSXML.RESOURCE_ELEM+GSXML.LIST_MODIFIER);
-	result_content.appendChild(resource_list);
-	// get the metadata
-	
-	Element content = (Element)request.getElementsByTagName(GSXML.CONTENT_ELEM).item(0);
-	if (content==null) {
-	    // error: query had no content!! - should make an error message
-	    return result;
-	}
-	String []metas = GSXML.getMetaNameList(content);
-	String []ids = GSXML.getResourceNameList(content);
-	for (int j=0; j<ids.length; j++) { // for each document
-	    Element doc = GSXML.createResourceElement(doc_, ids[j]);
-	    Element list = GSXML.addMetaList(doc_, doc);
-	    DBInfo info = gdbm_src_.getInfo(ids[j]);
-	    for (int m=0; m<metas.length; m++) {
-		String value = info.getInfo(metas[m]);
-		GSXML.addMetadata(doc_, list, metas[m], value);
-	    }
-	    resource_list.appendChild(doc);
-	}
-	return result;
-    }
-
-    // should probably use a list rather than map
-    protected boolean setStandardQueryParams(HashMap params) {
-
-	// set the default ones
-	mgpp_src_.setReturnTerms(true);
-	Set entries = params.entrySet();
-	Iterator i = entries.iterator();
-	while (i.hasNext()) {
-	    Map.Entry m = (Map.Entry)i.next();
-	    String name = (String)m.getKey();
-	    String value = (String)m.getValue();
-	   
-	    if (name.equals(CASE_PARAM)) {
-		boolean val = (value.equals(BOOLEAN_PARAM_ON)?true:false);
-		mgpp_src_.setCase(val);		
-	    } else if (name.equals(STEM_PARAM)) {
-		boolean val = (value.equals(BOOLEAN_PARAM_ON)?true:false);
-		mgpp_src_.setStem(val);
-	    } else if (name.equals(MAXDOCS_PARAM)) {
-		int docs = Integer.parseInt(value);
-		mgpp_src_.setMaxDocs(docs);
-	    } else if (name.equals(LEVEL_PARAM)) {
-		mgpp_src_.setQueryLevel(value);
-	    } else if (name.equals(MATCH_PARAM)) {
-		int mode;
-		if (value.equals(MATCH_PARAM_ALL)) mode=1;
-		else mode=0;
-		mgpp_src_.setMatchMode(mode);
-	    } else if (name.equals(RANK_PARAM)) {
-		if (value.equals(RANK_PARAM_RANK)) {
-		    mgpp_src_.setSortByRank(true);
-		} else if (value.equals(RANK_PARAM_NONE)) {
-		    mgpp_src_.setSortByRank(false);
-		}
-	    } // ignore any others
-	}
-	return true;
-    }
-
-    protected String parseFieldQueryParams(HashMap params) {
-
-	StringBuffer final_query = new StringBuffer(256);
-	String text_line = (String)params.get(FIELD_QUERY_PARAM);
-	String[] texts = text_line.split(",", -1);
-	String field_line = (String)params.get(FIELD_FIELD_PARAM);
-	String[] fields = field_line.split(",", -1);
-	String combine="&";
-	String match = (String)params.get(MATCH_PARAM);
-	if (match.equals(MATCH_PARAM_SOME)) {
-	    combine = "|";
-	}
-	
-	for (int i=0; i<texts.length; i++) {
-
-	    String q = texts[i].trim();
-	    if (!q.equals("")) {
-		addQueryElem(final_query, q, fields[i], combine);
-	    }
-	}
-
-	System.out.println("final query = "+final_query.toString());
-	return final_query.toString();
-    }
-    
-    protected String parseAdvancedFieldQueryParams(HashMap params) {
-
-	StringBuffer final_query = new StringBuffer(256);
-	String text_line = (String)params.get(FIELD_QUERY_PARAM);
-	String[] texts = text_line.split(",", -1);
-	String field_line = (String)params.get(FIELD_FIELD_PARAM);
-	String[] fields = field_line.split(",", -1);
-	String case_line = (String)params.get(FIELD_CASE_PARAM);
-	String[] cases = case_line.split(",", -1);
-	String stem_line = (String)params.get(FIELD_STEM_PARAM);
-	String[] stems = stem_line.split(",", -1);
-	String  combine_line = (String)params.get(FIELD_COMBINE_PARAM);
-	String [] combines = combine_line.split(",", -1);
-	String combine = "&";
-	for (int i=0; i<texts.length; i++) {
-	    if (i==0) {
-		combine = "";
-	    } else {
-		String x = combines[i-1]; // assume first one is missing
-		if (x.equals(FIELD_COMBINE_PARAM_AND)) {
-		    combine = "&";
-		} else if (x.equals(FIELD_COMBINE_PARAM_OR)) {
-		    combine = "|";
-		} else if (x.equals(FIELD_COMBINE_PARAM_NOT)) {
-		    combine = "!";
-		} 
-		
-	    }
-
-	    String q = texts[i].trim();
-	    if (!q.equals("")) {
-		q = addStemAndCase(q, stems[i], cases[i]);
-		addQueryElem(final_query, q, fields[i], combine);
-	    }
-	}
-
-	System.out.println("final query = "+final_query.toString());
-	return final_query.toString();
-    }
-
-    protected void addQueryElem(StringBuffer s, String q, String f, String c) {
-
-	String combine="";
-	if (s.length()>0) {
-	    combine = " "+c+" ";
-	}
-	if (f!="") {
-	    s.append(combine+"["+q+"]:"+f);
-	} else {
-	    s.append(combine+q);
-	}
-    }
-    protected String addStemAndCase(String q, String s, String c) {
-	String mods = "#";
-	if (c.equals("1")) {
-	    mods += "i";
-	} else {
-	    mods += "c";
-	}
-	if (s.equals("1")) {
-	    mods += "s";
-	} else {
-	    mods+= "u";
-	}
-	StringBuffer temp = new StringBuffer();
-	String [] terms = q.split(" ");
-	for (int i=0; i<terms.length; i++) {
-	    String t = terms[i].trim();
-	    
-	    if (!t.equals("") && !t.equals("TX")) {
-		temp.append(" "+t+mods);
-	    }
-	}
-	return temp.toString();
-    }
-
-    protected void printHash(HashMap map) {
-	System.out.println("Map entries are :");
-	Set entries = map.entrySet();
-	Iterator i = entries.iterator();
-	while (i.hasNext()) {
-	    Map.Entry m = (Map.Entry)i.next();
-	    String name = (String)m.getKey();
-	    String value = (String)m.getValue();
-	    System.out.println(name+"="+value);
-	}  
-    }
-
-}
- 
-
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/PerlBuildServices.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/PerlBuildServices.java	(revision 3648)
+++ 	(revision )
@@ -1,428 +1,0 @@
-/*
- *    PerlBuildServices.java 
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.greenstone.gsdl3.service;
-
-import org.greenstone.gsdl3.util.*;
-
-import org.w3c.dom.Document; 
-import org.w3c.dom.Node; 
-import org.w3c.dom.Text; 
-import org.w3c.dom.Element; 
-import org.w3c.dom.NodeList; 
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.io.File;
-import java.util.Locale;
-
-/**
- * A Services class for building collections
- * provides a wrapper around the old perl scripts
- *
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @version $Revision$
- */
-public class PerlBuildServices 
-    extends ServicesImpl {
-
-    // services offered
-    private static final String NEW_SERVICE = "NewCollection";
-    private static final String IMPORT_SERVICE = "ImportCollection";
-    private static final String BUILD_SERVICE = "BuildCollection";
-    private static final String ACTIVATE_SERVICE = "ActivateCollection";
-    private static final String DELETE_SERVICE = "DeleteCollection";
-    private static final String RELOAD_SERVICE = "ReloadCollection";
-
-    // params used
-    private static final String COL_PARAM = "collection";
-    private static final String NEW_COL_NAME_PARAM = "collectionName";
-    private static final String CREATOR_PARAM = "creator";
-
-    // the list of the collections - store between some method calls
-    private String[] collection_list_ = null;
-
-    /** returns the service list for the subclass */
-    protected Element getServiceList(String lang) {
-	// for now, it is static and there is no lang stuff
-	return short_service_info_;
-    }
-
-    /** returns a specific service description */
-    protected Element getServiceDescription(String service, String lang) {
-	Element descript = (Element)service_info_map_.get(service);
-	// need to add in collection param list
-	if (!service.equals(NEW_SERVICE)) {
-	    Element param_list = (Element) GSXML.getChildByTagName(descript, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	    Element old_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, COL_PARAM);
-	    collection_list_ = getCollectionList();
-	    Element param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, null, collection_list_);
-	    // put at front of the list
-	    param_list.replaceChild(param, old_param);
-	}
-	// for now, create it on the fly - look at caching it later
-	Element display = createServiceDisplay(service, lang);
-	addServiceDisplay(descript, display);
-	return descript;
-	
-    }
-
-    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
-    protected Element createServiceDisplay(String service, String lang) {
-	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
-	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
-	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
-
-	Element param;
-	if (service.equals(NEW_SERVICE)) {
-	    // have the coll name and creator params
-	    param = GSXML.createParameterDisplay(doc_, NEW_COL_NAME_PARAM, getTextString("param."+NEW_COL_NAME_PARAM, lang), null, null);
-	    display.appendChild(param);
-	    param = GSXML.createParameterDisplay(doc_, CREATOR_PARAM, getTextString("param."+CREATOR_PARAM, lang), null, null);
-	    display.appendChild(param);
-	} else {
-	    // have just the coll param
-	    //use the colleciton list already created - this method is only called directly after getServiceDescription()
-	    param = GSXML.createParameterDisplay(doc_, COL_PARAM, getTextString("param."+COL_PARAM, lang), collection_list_, collection_list_);
-	    display.appendChild(param);
-	}	    
-
-	return display;
-	
-    }
-
-     /** passes the request Element to the appropriate service function*/
-    protected Element processService(String name, Element request) {
-
-	String language = request.getAttribute(GSXML.LANG_ATT);
-	// extract the collection out of here
-	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	HashMap params = GSXML.extractParams(param_list);
-	String coll_name = (String)params.get(COL_PARAM);
-	
-	Element response = doc_.createElement(GSXML.RESPONSE_ELEM);
-	response.setAttribute(GSXML.FROM_ATT, name);
-	Element status=null;
-	if (name.equals(NEW_SERVICE)) {
-	    status = newCollection(coll_name, language);
-	} else if (name.equals(IMPORT_SERVICE)) {
-	    status = importCollection(coll_name, language);
-	} else if (name.equals(BUILD_SERVICE)) {
-	    status = buildCollection(coll_name, language);
-	} else if (name.equals(ACTIVATE_SERVICE)) {
-	    status = activateCollection(coll_name, language);
-	} else if (name.equals(DELETE_SERVICE)) {
-	    status = deleteCollection(coll_name, language);
-	} else if (name.equals(RELOAD_SERVICE)) {
-	    status = reloadCollection(coll_name, language);
-	} 
-	
-	if (status !=null) {
-	    response.appendChild(status);
-	    return response;
-	}
-	
-	System.err.println("PerlBuildServices:should never get here. service type wrong:"+name);
-	return null;
-	    
-    }
-
-    /** configure the service module
-     * for now, all services have type=build - need to think about this
-     */
-    public boolean configure(Element info) {
-	System.out.println("configuring PerlBuildServices");
-
-	Element e = null;
-	// hard code in the services for now
-
-	// set up short_service_info_ - for now just has name and type
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, NEW_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, IMPORT_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, BUILD_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, ACTIVATE_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, DELETE_SERVICE);
-	short_service_info_.appendChild(e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, RELOAD_SERVICE);
-	short_service_info_.appendChild(e);
-
-	//e = doc_.createElement(GSXML.SERVICE_ELEM);
-	//e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	//e.setAttribute(GSXML.NAME_ATT, "AddDocument");
-	//short_service_info_.appendChild(e);
-
-	// set up service_info_map_ - for now, just has the same elements as above
-
-	Element param_list; 
-	Element param;
-
-	String lang = Locale.US.toString();
-	
-	// should have full details about each service incl params lists etc.
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, NEW_SERVICE);
-	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	param = GSXML.createParameter(doc_, NEW_COL_NAME_PARAM, GSXML.PARAM_TYPE_STRING, "", null);
-	param_list.appendChild(param);
-	param = GSXML.createParameter(doc_, CREATOR_PARAM, GSXML.PARAM_TYPE_STRING, "", null);
-	param_list.appendChild(param);
-	e.appendChild(param_list);
-	service_info_map_.put(NEW_SERVICE, e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, IMPORT_SERVICE);
-	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
-	param_list.appendChild(param);
-	e.appendChild(param_list);
-	service_info_map_.put(IMPORT_SERVICE, e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, BUILD_SERVICE);
-	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
-	param_list.appendChild(param);
-	e.appendChild(param_list);
-	service_info_map_.put(BUILD_SERVICE, e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, ACTIVATE_SERVICE);
-	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
-	param_list.appendChild(param);
-	e.appendChild(param_list);
-	service_info_map_.put(ACTIVATE_SERVICE, e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, DELETE_SERVICE);
-	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
-	param_list.appendChild(param);
-	e.appendChild(param_list);
-	service_info_map_.put(DELETE_SERVICE, e);
-
-	e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BUILD);
-	e.setAttribute(GSXML.NAME_ATT, RELOAD_SERVICE);
-	param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	param = GSXML.createParameter(doc_, COL_PARAM, GSXML.PARAM_TYPE_ENUM_SINGLE, "", null);
-	param_list.appendChild(param);
-	e.appendChild(param_list);
-	service_info_map_.put(RELOAD_SERVICE, e);
-
-
-	return true;
-    }
-
-    /** creates a new collection using mkcol.pl */
-    protected Element newCollection(String coll_name, String lang) {
-	Element status = doc_.createElement(GSXML.STATUS_ELEM);
-	Text t = doc_.createTextNode("trying to create new coll:"+coll_name);
-	status.appendChild(t);
-	return status;
-    }   
-    
-    /** imports a collection using import.pl */
-    protected Element importCollection(String coll_name, String lang) {
-	Element status = doc_.createElement(GSXML.STATUS_ELEM);
-	Text t = doc_.createTextNode("trying to import coll:"+coll_name);
-	status.appendChild(t);
-	return status;
-    }   
-    /** builds a collection using buildcol.pl */
-    protected Element buildCollection(String coll_name, String lang) {
-	Element status = doc_.createElement(GSXML.STATUS_ELEM);
-	Text t = doc_.createTextNode("trying to build coll:"+coll_name);
-	status.appendChild(t);
-	return status;
-    }   
-    protected Element reloadCollection(String coll_name, String lang) {
-	Element status = doc_.createElement(GSXML.STATUS_ELEM);
-	
-	Element message = doc_.createElement(GSXML.MESSAGE_ELEM);
-	Element request = doc_.createElement(GSXML.REQUEST_ELEM);
-	request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_CONFIGURE);
-	request.setAttribute(GSXML.TO_ATT, "");
-	message.appendChild(request);
-	Element command = doc_.createElement(GSXML.CONFIGURE_ELEM);
-	command.setAttribute(GSXML.TYPE_ATT, GSXML.COLLECTION_ELEM);
-	command.setAttribute(GSXML.NAME_ATT, coll_name);
-	command.setAttribute(GSXML.ACTION_ATT, GSXML.CONFIG_ACTION_ACTIVATE);
-	request.appendChild(command);
-	Element response = router_.process(message); // at the moment, get no info in response so ignore it
-
-	String[] args={coll_name};
-
-	if (response == null) {
-	    Text t = doc_.createTextNode(getTextString("reload.activate_error", args , lang));
-	    status.appendChild(t);
-	    return status;
-	}
-	// if we got here, we have succeeded!
-	Text t = doc_.createTextNode(getTextString("reload.success", args, lang));
-	status.appendChild(t);
-	return status;	
-    }   
-
-    /** activates a collection by removing index, copying building over 
-     * also instructs the MR to activate this new/modified collection
-     * fails if no valid building directory */ 
-    protected Element activateCollection(String coll_name, String lang) {
-	// the return element
-	Element status = doc_.createElement(GSXML.STATUS_ELEM);
-	String[] args={coll_name};
-
-	// check that we have buildcfg.xml in the building directory
-	File coll_build_dir = new File(GSFile.collectionBuildDir(site_home_, coll_name));
-	if (!coll_build_dir.exists()) {
-	    Text t = doc_.createTextNode(getTextString("activate.build_dir_error", args, lang));
-	    status.appendChild(t);
-	    return status;
-	}
-	File coll_build_file = new File(GSFile.collectionBuildConfigFileBuilding(site_home_, coll_name));
-	if (!coll_build_file.exists()) {
-	    Text t = doc_.createTextNode(getTextString("activate.build_config_error", args, lang));
-	    status.appendChild(t);
-	    return status;
-	}
-	
-	
-	File coll_index_dir = new File(GSFile.collectionIndexDir(site_home_, coll_name));
-	if (coll_index_dir.exists()) {
-	    // remove it
-	    if (!GSFile.deleteFile(coll_index_dir)) {
-		Text t = doc_.createTextNode(getTextString("activate.rm_index_error", args, lang));
-		status.appendChild(t);
-		return status;
-	    }
-	}
-	
-	// copy building to index
-	if (!GSFile.moveDirectory(coll_build_dir, coll_index_dir)) {
-	    Text t = doc_.createTextNode(getTextString("activate.rename_building_error", args, lang));
-	    status.appendChild(t);
-	    return status;
-	}
-	
-	// now have to tell the message router
-	return reloadCollection(coll_name, lang);
-
-    }
-    /** deletes a collection - removes the whole directory
-     * also instructs the MR to deactivate this  collection*/ 
-    protected Element deleteCollection(String coll_name, String lang) {
-	Element status = doc_.createElement(GSXML.STATUS_ELEM);
-	
-	String[] args={coll_name};
-	File coll_dir = new File(GSFile.collectionBaseDir(site_home_, coll_name));
-	if (coll_dir.exists()) {
-	    if (!GSFile.deleteFile(coll_dir)) {
-		Text t = doc_.createTextNode(getTextString("delete.delete_error", args, lang));
-		status.appendChild(t);
-		return status;
-	    }
-	    // now tell the MR about it
-
-	    Element message = doc_.createElement(GSXML.MESSAGE_ELEM);
-	    Element request = doc_.createElement(GSXML.REQUEST_ELEM);
-	    request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_CONFIGURE);
-	    request.setAttribute(GSXML.TO_ATT, "");
-	    message.appendChild(request);
-	    Element command = doc_.createElement(GSXML.CONFIGURE_ELEM);
-	    command.setAttribute(GSXML.TYPE_ATT, GSXML.COLLECTION_ELEM);
-	    command.setAttribute(GSXML.NAME_ATT, coll_name);
-	    command.setAttribute(GSXML.ACTION_ATT, GSXML.CONFIG_ACTION_DEACTIVATE);
-	    request.appendChild(command);
-	    
-	    Element response = router_.process(message); // at the moment, get no info in response so ignore it
-	    if (response == null) {
-		Text t = doc_.createTextNode(getTextString("delete.deactivate_error", args, lang));
-		status.appendChild(t);
-		return status;
-	    }
-	}
-	// success   
-       
-	Text t = doc_.createTextNode(getTextString("delete.success", args, lang));
-	status.appendChild(t);
-	return status;
-    }
-
-    protected String[] getCollectionList() {
-	
-	File collectDir = new File(GSFile.collectDir(site_home_));
-	if (!collectDir.exists()) {
-	    System.err.println("couldn't find collect dir: "+collectDir.toString());
-	    return null;
-	}
-	System.out.println("PerlBuildServices: reading thru directory "+collectDir.getPath()+" to find collections.");
-	File[] contents = collectDir.listFiles();
-	int num_colls=0;
-	for (int i=0; i<contents.length;i++) {
-	    if(contents[i].isDirectory() && !contents[i].getName().startsWith("CVS")) {
-		num_colls ++;
-	    }
-	}
-	
-	String[] names= new String[num_colls];
-	
-	for (int i=0, j=0; i<contents.length;i++) {
-	    if(contents[i].isDirectory()) {
-		String colName = contents[i].getName();
-		if (!colName.startsWith("CVS")) {
-		    names[j] = colName;
-		    j++;
-		}
-		
-	    } 
-	}
-	
-	return names;
-	
-    }
-   
-
-}
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/PhindServices.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/PhindServices.java	(revision 3648)
+++ 	(revision )
@@ -1,458 +1,0 @@
-/*
- *    PhindServices.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.greenstone.gsdl3.service;
-
-import org.greenstone.gsdl3.util.*;
-
-import org.greenstone.mgpp.*;
-import org.w3c.dom.Document; 
-import org.w3c.dom.Node; 
-import org.w3c.dom.Element; 
-import org.w3c.dom.Text; 
-
-import java.util.Vector;
-import java.util.HashMap;
-/** 
- * PhindServices - the phind phrase browsing service
- * 
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @version $Revision$
- */
-public class PhindServices 
-    extends ServicesImpl {
-    
-    // the services on offer
-    private static final String PHIND_SERVICE = "PhindApplet";
-
-    private MGPPWrapper mgpp_src_=null;
-    private String basepath_ = null;
-    public PhindServices() {
-	mgpp_src_ = new MGPPWrapper();
-	// set up the default params
-	mgpp_src_.setQueryLevel("Document");
-	mgpp_src_.setReturnLevel("Document");
-	mgpp_src_.setMaxDocs(5);
-	mgpp_src_.setStem(false);
-	mgpp_src_.setCase(true);
-    }
-    /** configure the service module
-     *
-     * @param info a DOM Element containing any config info for the service
-     * @return true if configured
-     */
-    public boolean configure(Element info) {
-
-	System.out.println("configuring PhindServices");
-
-	// set up short_service_info_ - for now just has name and type
-	Element e = doc_.createElement(GSXML.SERVICE_ELEM);
-	e.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	e.setAttribute(GSXML.NAME_ATT, PHIND_SERVICE);
-	short_service_info_.appendChild(e);
-
-	// set up service_info_map_ - we only have one element, and it has
-	// no extra info yet - we are not processing the config info
-	Element f = doc_.createElement(GSXML.SERVICE_ELEM);
-	f.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
-	f.setAttribute(GSXML.NAME_ATT, PHIND_SERVICE);
-
-	// add in the applet info for the phind applet
-	// need to make this dynamic - library names etc
-	// change the applet params - have a single param with the library name
-	// this is left blank at this end, and must be filled in by applet action - if the library name is not needed, this param is left out
-	// phindcgi param now is not complete - library must be prepended to it.
-	String app_info = "<"+GSXML.APPLET_ELEM+" CODEBASE='lib/java' CODE='org.greenstone.applet.phind.Phind.class' ARCHIVE='phind.jar, xercesImpl.jar, gsdl3.jar, jaxp.jar, xml-apis.jar' WIDTH='500' HEIGHT='400'><PARAM NAME='library' VALUE=''/> <PARAM NAME='phindcgi' VALUE='?a=a&amp;sa=r&amp;sn=Phind'/>";
-	app_info +="<PARAM NAME='collection'   VALUE='";
-	app_info += cluster_name_;
-	app_info += "'/> <PARAM NAME='classifier' VALUE='1'/>  <PARAM NAME='orientation'  VALUE='vertical'/> <PARAM NAME='depth' VALUE='2'/> <PARAM NAME='resultorder' VALUE='L,l,E,e,D,d'/> <PARAM NAME='backdrop' VALUE='interfaces/default/images/phindbg1.jpg'/><PARAM NAME='fontsize' VALUE='10'/> <PARAM NAME='blocksize'    VALUE='10'/>The Phind java applet.</"+GSXML.APPLET_ELEM+">";
-	
-	Document dom = converter_.getDOM(app_info);
-	Element app_elem = dom.getDocumentElement();
-	f.appendChild(doc_.importNode(app_elem, true));
-	
-	service_info_map_.put(PHIND_SERVICE, f);
-	
-	return true;
-    }
-
-    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
-    protected Element createServiceDisplay(String service, String lang) {
-	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
-	display.appendChild(GSXML.createTextElement(doc_, GSXML.DISPLAY_NAME_ELEM,  getTextString(service+".name", lang)));
-	display.appendChild(GSXML.createTextElement(doc_,  GSXML.DISPLAY_SUBMIT_ELEM, getTextString(service+".submit", lang)));
-
-	Element param;
-
-	return display;
-	
-    }
-
-    protected Element processService(String name, Element request) {
-	
-	if (!name.equals(PHIND_SERVICE)) {
-	    System.err.println("PhindServices:you have asked for a non-existant service - "+name+"!");
-	    return null;
-	}
-	Element param_elem = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	HashMap params = GSXML.extractParams(param_elem);
-	
-	long first_e = Long.parseLong((String)params.get("pfe"));
-	long last_e = Long.parseLong((String)params.get("ple"));
-	long first_l = Long.parseLong((String)params.get("pfl"));
-	long last_l = Long.parseLong((String)params.get("pll"));
-	long first_d = Long.parseLong((String)params.get("pfd"));
-	long last_d = Long.parseLong((String)params.get("pld"));
-	
-	long phrase;
-	String phrase_str = (String)params.get("ppnum");
-	if (phrase_str == null || phrase_str.equals("")) {
-	    phrase=0;
-	} else {
-	    phrase = Long.parseLong(phrase_str);
-	}
-	String word = (String)params.get("pptext");
-	String phind_index = (String)params.get("pc");
-	// the location of the mgpp database files
-	basepath_ = GSFile.phindBaseDir(site_home_, cluster_name_, phind_index);
-
-	// the result element
-	Element result = doc_.createElement(GSXML.RESPONSE_ELEM);
-	String from = GSPath.appendLink(cluster_name_, "PhindApplet");
-	result.setAttribute(GSXML.FROM_ATT, from);
-	result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-
-	// applet result info must be in appletInfo element
-	Element applet_data = doc_.createElement(GSXML.APPLET_DATA_ELEM);
-	result.appendChild(applet_data);
-	Element phind_data = doc_.createElement("phindData");
-	applet_data.appendChild(phind_data);
-
-
-	// if we dont know the phrase number, look it up
-	if (phrase == 0) {
-	    if (word==null || word.equals("")) {
-		Element error = phindError("no word or phrase");
-		phind_data.appendChild(error);
-		return result;
-	    }
-	    phrase = findPhraseNumberFromWord( word);
-	    System.out.println("phind, term number for "+word+" is "+phrase);
-	}
-	if (phrase==0) {
-	    // the word is not in the collection
-	    // return a phind error string
-	    Element error = phindError("the term "+word+" is not in the collection");
-	    phind_data.appendChild(error);
-	    return result;
-	}
-	
-	// get the phrase data into the phind_data node
-	getPhraseData(phind_data, phrase, first_l, last_l,
-		      first_e, last_e,  first_d, last_d);
-	return result;
-	
-	
-    }// processService
-    
-    protected long findPhraseNumberFromWord(String word) {
-
-	// set the mgpp index data - we are looking up pword
-	mgpp_src_.loadIndexData(basepath_, "pword");
-
-	mgpp_src_.runQuery(word);
-
-	MGPPQueryResult res = mgpp_src_.getQueryResult();
-	Vector docs = res.getDocs();
-	if (docs.size()==0) {
-	    // phrase not found
-	    return 0;
-	}
-	MGPPDocInfo doc = (MGPPDocInfo)docs.firstElement();
-	return doc.num_;
-    }
-
-    protected boolean getPhraseData(Element phind_data,
-				    long phrase, long first_l, long last_l,
-				    long first_e, long last_e, long first_d, 
-				    long last_d) {
-
-	String record = mgpp_src_.getDocument(basepath_, "pdata", "Document",
-					      phrase);
-	if (record.equals("")) {
-	    Element error = phindError("somethings gone wrong - we haven't got a record for phrase number "+phrase);
-	    phind_data.appendChild(error);
-	    return false;
-	}
-	
-	System.out.println("record="+record);
-	// parse the record - its in gordons cryptic form
-	// ":word:tf:ef:df:el:dl:lf:ll"
-	// el: e,e,e
-	// dl: d;f,d;f,
-	// lf and ll may be null
-	// l: type,dest, dest; type,dest,dest
-
-	// ignore everything up to and including first colon (has
-	// <Document>3505: at the start)
-	record = record.substring(record.indexOf(':')+1);
-
-	// split on ':'
-	String [] fields = record.split(":");
-	String word = fields[0];
-	String tf = fields[1];
-	String ef = fields[2];
-	String df = fields[3];
-
-	
-	String expansions = fields[4];
-	String documents = fields[5];
-	String lf = "0";
-	String linklist = "";
-	if (fields.length > 7) {// have thesaurus stuff
-	    lf =fields[6];
-	    linklist = fields[7];
-	}
-	
-	// the phindData attributes and phrase
-	phind_data.setAttribute("id", Long.toString(phrase));
-	phind_data.setAttribute("df", df);
-	phind_data.setAttribute("ef", ef);
-	phind_data.setAttribute("lf", lf);
-	phind_data.setAttribute("tf", tf);
-	GSXML.createTextElement(doc_, "phrase", word);
-
-	addExpansionList(phind_data, expansions, word, ef, first_e, last_e);
-	addDocumentList(phind_data, documents, word, df, first_d, last_d);
-	if (!lf.equals("0")) {
-	    System.out.println("adding thesaurus stuff");
-	    addThesaurusList(phind_data, linklist, word, lf, first_l, last_l);
-	}
-	return true;
-    }
-
-    protected boolean addExpansionList( Element phind_data, String record, 
-				       String word,
-				       String freq,
-				       long first, long last) {
-
-	Element expansion_list = doc_.createElement("expansionList");
-	phind_data.appendChild(expansion_list);
-	expansion_list.setAttribute("length", freq);
-	expansion_list.setAttribute("start", Long.toString(first));
-	expansion_list.setAttribute("end", Long.toString(last));
-
-	// get the list of strings
-	String [] expansions = record.split(",");
-	int length = expansions.length;
-	if (length < last) last = length;
-	for (long i = first; i < last; i++) {
-	    long num  = Long.parseLong(expansions[(int)i]);
-	    Element expansion = getExpansion( num, word);
-	    expansion.setAttribute("num", Long.toString(i));
-	    expansion_list.appendChild(expansion);
-	}
-	return true;
-    }
-    
-    protected Element getExpansion(long phrase_num, 
-				   String orig_phrase) {
-	
-	// look up the phrase in the pdata thingy
-	String record = mgpp_src_.getDocument(basepath_, "pdata", "Document",
-					      phrase_num);
-
-	if (record ==null || record.equals("")) return null;
-
-	// ignore everything up to and including first colon 
-	record = record.substring(record.indexOf(':')+1);
-
-	String [] fields = record.split(":");
-	String phrase = fields[0];
-	String tf = fields[1];
-	//String ef = fields[2]; dont use this
-	String df = fields[3];
-
-	Element expansion = doc_.createElement("expansion");
-	expansion.setAttribute("tf", tf);
-	expansion.setAttribute("df", df);
-	expansion.setAttribute("id", Long.toString(phrase_num));
-
-	// get teh suffix and prefix
-	String [] ends = splitPhraseOnWord(phrase, orig_phrase);
-	if (!ends[0].equals("")) {
-	    expansion.appendChild(GSXML.createTextElement(doc_, "prefix", ends[0]));
-	}
-	if (!ends[1].equals("")) {
-	    expansion.appendChild(GSXML.createTextElement(doc_, "suffix", ends[1]));
-	}
-
-	return expansion;
-
-    }
-
-    protected boolean addDocumentList(Element phind_data, String record, 
-				      String word,
-				      String freq,
-				      long first, long last) {
-
-	Element document_list = doc_.createElement("documentList");
-	phind_data.appendChild(document_list);
-	document_list.setAttribute("length", freq);
-	document_list.setAttribute("start", Long.toString(first));
-	document_list.setAttribute("end", Long.toString(last));
-
-	// get the list of doc,freq
-	String [] doc_freqs = record.split(";");
-	int length = doc_freqs.length;
-	if (length<last) last=length;
-
-	for (long i = first; i < last; i++) {
-	    String doc_elem = doc_freqs[(int)i];
-	    int p = doc_elem.indexOf(',');
-	    long doc_num;
-	    String doc_freq;
-	    if (p == -1) { // there is no freq in the record
-		doc_num =Long.parseLong(doc_elem);
-		doc_freq = "1";
-	    } else {
-		doc_num = Long.parseLong(doc_elem.substring(0,p));
-		doc_freq = doc_elem.substring(p+1);
-	    }
-	    Element document = getDocument( doc_num);
-	    document.setAttribute("freq", doc_freq);
-	    document.setAttribute("num", Long.toString(i));
-	    document_list.appendChild(document);
-	}
-
-	
-	return true;
-    }
-
-
-    protected Element getDocument(long doc_num) {
-	
-	// look up the phrase in the docs thingy
-	String record = mgpp_src_.getDocument(basepath_, "docs", "Document",
-					      doc_num);
-	
-	if (record ==null || record.equals("")) return null;
-	System.out.println("doc record:"+record);
-	
-	// ignore everything up to and including first \t
-	record = record.substring(record.indexOf('\t')+1);
-
-	String [] fields = record.split("\t");
-	String hash = fields[0];
-	String title = fields[1];
-
-	Element d = doc_.createElement("document");
-	d.setAttribute("hash", hash);
-	d.appendChild(GSXML.createTextElement(doc_, "title", title));
-	
-	return d;
-
-    }
-    protected boolean addThesaurusList(Element phind_data, String record,
-				       String word,
-				       String freq,
-				       long first, long last) {
-
-
-	Element thesaurus_list = doc_.createElement("thesaurusList");
-	phind_data.appendChild(thesaurus_list);
-	thesaurus_list.setAttribute("length", freq);
-	thesaurus_list.setAttribute("start", Long.toString(first));
-	thesaurus_list.setAttribute("end", Long.toString(last));
-	
-	System.out.println("record for thesaurus="+record);
-
-	// get the list of type,dest,dest
-	String [] links = record.split(";");
-	int length = links.length;
-	long index = 0;
-	for (int i = 0; i < length; i++) { // go through the entries
-	    String link_info = links[(int)i];
-	    String [] items = link_info.split(",");
-	    // the first entry is teh type
-	    String type = items[0];
-	    for (int j = 1; j<items.length; j++, index++) {
-		if (index >= first && index < last) { // only output the ones we want
-		    long phrase = Long.parseLong(items[j]);
-		    Element t = getThesaurus(phrase);
-		    t.setAttribute("type", type);
-		    thesaurus_list.appendChild(t);
-		}
-	    }
-	}
-
-	return true;
-    }
-
-    protected Element getThesaurus(long phrase_num) {
-
-	// look up the phrase in the pdata thingy
-	String record = mgpp_src_.getDocument(basepath_, "pdata", "Document",
-					      phrase_num);
-
-	if (record ==null || record.equals("")) return null;
-
-	// ignore everything up to and including first colon 
-	record = record.substring(record.indexOf(':')+1);
-
-	String [] fields = record.split(":");
-	String phrase = fields[0];
-	String tf = fields[1];
-	//String ef = fields[2]; dont use this
-	String df = fields[3];
-
-	Element thesaurus = doc_.createElement("thesaurus");
-	thesaurus.setAttribute("tf", tf);
-	thesaurus.setAttribute("df", df);
-	thesaurus.setAttribute("id", Long.toString(phrase_num));
-	thesaurus.appendChild(GSXML.createTextElement(doc_, "phrase", phrase));
-	return thesaurus;
-
-    }
-
-    /** returns an array of two elements - the prefix and the suffix*/
-    protected String [] splitPhraseOnWord(String phrase, String word) {
-	
-	if (word.equals("")) {
-	    
-	    String [] res =  {phrase, ""};
-	    return res;
-	}
-	// use 2 so that we only split on the first occurrance. trailing empty strings should be included 
-	String [] result = phrase.split(word, 2);
-	if (result.length !=2) {
-	    System.out.println("didn't get two substrings!!");
-	}
-	return result;
-	
-    }
-
-    protected Element phindError(String message) {
-	Element e = doc_.createElement("phindError");
-	Text t = doc_.createTextNode(message);
-	e.appendChild(t);
-	return e;
-    }
-    
-}
-
Index: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/ServicesImpl.java
===================================================================
--- trunk/gsdl3/src/java/org/greenstone/gsdl3/service/ServicesImpl.java	(revision 3648)
+++ 	(revision )
@@ -1,271 +1,0 @@
-/*
- *    ServicesImpl.java
- *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.greenstone.gsdl3.service;
-
-// greenstone classes
-import org.greenstone.gsdl3.util.*;
-import org.greenstone.gsdl3.core.*;
-
-// xml classes
-import org.w3c.dom.Node; 
-import org.w3c.dom.NodeList; 
-import org.w3c.dom.Element; 
-import org.w3c.dom.Document; 
-import org.xml.sax.InputSource;
-import javax.xml.parsers.*;
-import org.apache.xpath.XPathAPI;
-
-// general java classes
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.File;
-import java.util.HashMap;
-
-import java.util.ResourceBundle;
-import java.util.Locale;
-
-/**
- * ServicesImpl - abstract base class 
- *
- * A ServicesImpl implements some Service modules -
- * It may provide more than one Service. for eg
- * MGGDBMServicesImpl may support "DocRetrieve", "TextQuery", "MetadataRetrieve" services
- *
- * @author <a href="mailto:kjdon@cs.waikato.ac.nz">Katherine Don</a>
- * @version $Revision$
- */
-public abstract class ServicesImpl 
-    implements ModuleInterface
-{
-
-
-    /** the absolute address of the site home */
-    protected String site_home_ =null;
-    /** the name of the cluster that this service belongs to -
-	if any */ 
-    protected String cluster_name_ = null;
-
-    /** some services can talk back to the message router */
-    protected ModuleInterface router_ = null;
-
-    /** a converter class to create Documents etc */
-    protected XMLConverter converter_ = null;
-
-    /** XML element for describe requests - the container doc */
-    protected Document doc_ = null;
-
-    /** XML element for describe requests - list of supported services */
-    protected Element short_service_info_ = null;
-
-    /** XML element for describe requests - map of service name to full 
-	description */
-    protected HashMap service_info_map_ = null;
-
-    /** sets the cluster name */
-    public void setClusterName(String cluster_name) {
-	cluster_name_ = cluster_name;
-    }
-    /** sets the collect name */
-    public void setCollectionName(String coll_name) {
-	setClusterName(coll_name);
-    }
-    
-    /** sets the site home */
-    public void setSiteHome(String site_home) {
-	site_home_ = site_home;
-    }
-
-    /** sets the message router */
-    public void setMessageRouter(ModuleInterface m) {
-       router_ = m;
-    }
-
-    /** the no-args constructor */
-    public ServicesImpl() {
-	converter_ = new XMLConverter();
-	doc_ = converter_.newDOM();
-	short_service_info_ = doc_.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
-	service_info_map_ = new HashMap();
-    }
-    
-
-    /** configure the service module
-     *
-     * @param info the XML node <servicesImpl name="XXX"/> with name equal
-     * to the class name (of the subclass)
-     *
-     * must initialise short_service_info_ and service_info_map_
-     * @return true if configured ok
-     * must be implemented in subclasses
-     */
-    abstract public boolean configure(Element info); 
-
-    /**
-     * Process an XML document - convenience method that uses Strings rather than Nodes. just calls process(Node).
-     *
-     * @param xml_in the Document to process - a string
-     * @return the resultant document as a string - contains any error messages
-     * @see String
-     */
-    public String process(String xml_in) {
-	
-	Document doc = converter_.getDOM(xml_in);
-	
-	Element res = process(doc.getDocumentElement());
-	return converter_.getString(res);
-	
-    }
-
-    /** process an XML request in DOM form
-     *
-     * @param xml_in the Element node containing the request
-     * should be <message> 
-     * @return an Element with the result XML
-     * @see Element
-     */
-    public Element process(Element message) {
-
-	NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
-	Document mess_doc = message.getOwnerDocument();
-	Element mainResult = doc_.createElement(GSXML.MESSAGE_ELEM);
-	if (requests.getLength()==0) {
-	    // no requests
-	    return mainResult; // for now
-	}
-
-	for (int i=0; i<requests.getLength(); i++) {
-	    Element request = (Element)requests.item(i);
-	
-
-	    String type = request.getAttribute(GSXML.TYPE_ATT);
-	    if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) {
-		Element response = processDescribe(request);
-		if (response !=null) {
-		    mainResult.appendChild(doc_.importNode(response, true));
-		}
-		
-	    } else {
-		// other type of request, must be processed by the subclass - 
-		// send to the service method
-
-		String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));		
-		if (service_info_map_.containsKey(to)) { 
-		    Element response = processService(to, request);
-		    if (response !=null) {
-			mainResult.appendChild(doc_.importNode(response, true));
-		    }
-		} else {
-		    // else error in to field
-		    System.err.println("ServicesImpl describe request: error in 'to' field, to='"+to+"'.");
-		    return null;
-		}
-	    }
-	} // for each request
-
-	return mainResult;
-		
-    }
-
-    /** process method for describe requests 
-     */
-    protected Element processDescribe(Element request) {
-	
-	Element response = doc_.createElement(GSXML.RESPONSE_ELEM);
-	response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
-	
-	String lang = request.getAttribute(GSXML.LANG_ATT);
-	String info = request.getAttribute(GSXML.INFO_ATT);
-	String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
-	
-	if (to.equals("")) { // to="", look at info
-	    if (info.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
-		//response.appendChild(short_service_info_);
-		response.appendChild(getServiceList(lang));
-		return response;
-	    } 
-	    // else error in info field
-	    System.err.println("ServicesImpl describe request: error in 'info' field, info='"+info+"'.");
-	    return null;
-	} 
-
-	// describe a particular service
-	
-	if (service_info_map_.containsKey(to)) {
-	    response.appendChild(getServiceDescription(to, lang));//(Element)service_info_map_.get(to));
-	    return response;
-	}
-	// else error in to field
-	System.err.println("ServicesImpl describe request: error in 'to' field, to='"+to+"'.");
-	return null;
-    
-    }
-    /** process method for specific services - must be implemented by all
-     * subclasses
-     * should implement all services supported by the servicesImpl except
-     * for describe, which is implemented by this base class
-     *
-     */
-    abstract protected Element processService(String service, Element request);
-
-    // the following two should be overwritten for info with any language stuff in it
-    /** returns the service list for the subclass */
-    protected Element getServiceList(String lang) {
-	// for now, it is static and there is no lang stuff
-	return short_service_info_;
-    }
-
-    /** returns a specific service description */
-    protected Element getServiceDescription(String service, String lang) {
-	Element descript = (Element)((Element)service_info_map_.get(service)).cloneNode(true);
-	// for now, create it on the fly - look at caching it later
-	Element display = createServiceDisplay(service, lang);
-	addServiceDisplay(descript, display);
-	return descript;
-    }
-    
-    /** adds the display element into the description - appends to the root for now, but may do something fancy later */
-    protected boolean addServiceDisplay(Element descript, Element display) {
-	if (descript.getOwnerDocument() != display.getOwnerDocument()) {
-	    display = (Element)descript.getOwnerDocument().importNode(display, true);
-	}
-	descript.appendChild(display);
-	return true;
-    }
-    /** creates a display element containing all the text strings needed to display the service page, in the language specified */
-    abstract protected Element createServiceDisplay(String service, String lang);
-    /** overloaded version for no args case */
-    protected String getTextString(String key, String lang) {
-	return getTextString(key, null, lang);
-    }
-    /** getTextString - retrieves a language specific text string for the given
-key and locale
-    */
-    protected String getTextString(String key, String[] args,  String lang) {
-
-	String class_name = getClass().getName();
-	class_name = class_name.substring(class_name.lastIndexOf('.')+1);
-	
-	Dictionary dict = new Dictionary(class_name, lang);
-	String result = dict.get(key, args);
-	if (result == null) { // not found
-	    return "_"+key+"_";
-	}
-	return result;
-    }
-}
