Index: /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/DefaultReceptionist.java
===================================================================
--- /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/DefaultReceptionist.java	(revision 4258)
+++ /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/DefaultReceptionist.java	(revision 4258)
@@ -0,0 +1,61 @@
+package org.greenstone.gsdl3.core;
+
+import org.greenstone.gsdl3.util.*;
+import org.greenstone.gsdl3.action.*;
+// XML classes
+import org.w3c.dom.Node; 
+import org.w3c.dom.NodeList; 
+import org.w3c.dom.Document; 
+import org.w3c.dom.Element; 
+
+// other java classes
+import java.io.File;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+/** The default greenstone receptionist - needs some extra info for each page
+ * @see WebReceptionist
+ */
+public class DefaultReceptionist extends WebReceptionist {
+    
+    protected void addExtraInfo(Element page) {
+	// we want to add in the collection description for each page - cos
+	// our default xslt needs this.
+	super.addExtraInfo(page);
+	
+	Element page_request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
+	System.out.println("add extra info, page request="+this.converter.getString(page_request));
+	// is a collection defined?
+	Element param_list = (Element)GSXML.getChildByTagName(page_request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	if (param_list==null) { // must be the original home page
+	    return;
+	}
+	Element coll_param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, this.cgi.COLLECTION_ARG);
+	if (coll_param == null) {
+	    return;
+	}
+	String action = page_request.getAttribute(GSXML.ACTION_ATT);
+	if (action.equals("p")) {
+	    return;
+	}
+	// we have a collection, and we are not page action. get the coll description
+	
+	String collection = coll_param.getAttribute(GSXML.VALUE_ATT);
+	String lang = page_request.getAttribute(GSXML.LANG_ATT);
+	Element coll_about_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
+	Element coll_about_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE,  collection, lang);
+	coll_about_message.appendChild(coll_about_request);
+	
+	Element coll_about_response_message = this.mr.process(coll_about_message);
+	Element coll_about_response = (Element)GSXML.getChildByTagName(coll_about_response_message, GSXML.RESPONSE_ELEM);
+	Element coll_description = (Element)GSXML.getChildByTagName(coll_about_response, GSXML.COLLECTION_ELEM);
+	if (coll_description==null) { // may be a cluster
+	    coll_description = (Element)GSXML.getChildByTagName(coll_about_response, GSXML.CLUSTER_ELEM);
+	}
+	if (coll_description != null) {
+	    Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
+	    page_response.appendChild(this.doc.importNode(coll_description, true));
+	}
+    }
+}
+
Index: /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/NZDLReceptionist.java
===================================================================
--- /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/NZDLReceptionist.java	(revision 4257)
+++ /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/NZDLReceptionist.java	(revision 4258)
@@ -14,129 +14,31 @@
 import java.util.Enumeration;
 
-/** core class for web interface generation. Receives requests consisting
- * of an xml representation of cgi args, and returns the page of data - in 
- * html by default. The requests are processed by the appropriate action class
- * This is a new version of the Receptionist for the nzdl interface
- * @see Action
+/** 
+ * This is a new version of the Receptionist for the NZDL interface
+ * the interface requires a lot more info for each page
+ * @see DefaultReceptionist
  */
-public class NZDLReceptionist extends Receptionist {
+public class NZDLReceptionist extends DefaultReceptionist {
+    
+    protected void addExtraInfo(Element page) {
+	System.out.println("the  page before adding extra info is");
+	System.out.println(this.converter.getPrettyString(page));
 
-    // if we want to use different actions, overwrite this method
-    //public void configure() {
-    //}
+	super.addExtraInfo(page);
 
-    /** process - produce a page of data in response to a request 
-     * if something goes wrong, it returns null - 
-     * TODO:  return a suitable message to the user */
-    public Element process(Element message) {
-
-	// get the request out of the message - assume that there is only one
-	Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
-	if (request == null) {
-	    System.err.println("Receptionist Error: message had no request!");
-	    return null; 
-	}
-	// check that the request type is correct
-	String type = request.getAttribute(GSXML.TYPE_ATT); // returns "" if no att of this name
-	if (!type.equals(GSXML.REQUEST_TYPE_CGI)) {
-	    // now Receptionist forwards non-cgi requests straight to the MR, and returns the responses
-	    System.err.println("Receptionist: request type is not '"+GSXML.REQUEST_TYPE_CGI+"', but it is '"+type+"', so forwarding the message to the MR!");
-	    // process teh whole message - mr needs <message> tags, and 
-	    // in this case, there may be more than one request in the message
-	    return mr_.process(message);
-	}	
-	// work out which action to pass to
-	String action = request.getAttribute(GSXML.ACTION_ATT);
-	if (action.equals("")) {
-	    System.err.println("Receptionist Error: no action specified in the request!");
-	    return null;
-	}
-	// convert cgi short names to long names in the param list
-	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	if (param_list!=null) {
-	    if (!cgi_.paramListToLongNames(param_list)) {
-		System.err.println("Receptionist Error: couldn't convert short names to long names in the param list!");
-		return null;
-	    }
-	}
-	
-	// find the  appropriate action	 - may need to load a new one
-	Action a = (Action)action_map_.get(action);
-	String action_name=null;
-	if (a==null) { // not in the map yet
-	    // try to load a new action
-	    try {
-		action_name = action.substring(0,1).toUpperCase()+action.substring(1)+"Action";
-		Action ac = (Action)Class.forName("org.greenstone.gsdl3.action."+action_name).newInstance();
-		ac.setConfigVars(config_);
-		ac.setMessageRouter(mr_);
-		ac.setCGI(cgi_);
-		ac.configure();
-		action_map_.put(action, ac);
-		a = ac;
-	    } catch (Exception e) {
-		
-		System.err.println("Receptionist Error: a new action ("+action_name+") was specified and it couldn't be created. Error message:"+e.getMessage());
-		return null;
-	    }
+	// this gets the collection info
+	Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
+	Element collection_info = (Element)GSXML.getChildByTagName(page_response, GSXML.COLLECTION_ELEM);
+	if (collection_info== null) {
+	    return;
 	}
 
-	// add in the  system stuff - display and config - this all goes into 
-	// a pageExtra element
-	Document message_doc = message.getOwnerDocument();
-	Element page_extra = message_doc.createElement(GSXML.PAGE_EXTRA_ELEM);
-	message.appendChild(page_extra);
-	String lang = request.getAttribute(GSXML.LANG_ATT);
-	Element display = getDisplayElement(lang);
-	page_extra.appendChild(message_doc.importNode(display, true));
-	page_extra.appendChild(message_doc.importNode(config_.config_xml_, true));
-
-	// create the nzdl page extra
-	// check for collection
-	if (param_list != null) {
-	    HashMap params = GSXML.extractParams(param_list, false);
-	    String collection = (String)params.get(GSCGI.COLLECTION_ARG);
-	    if (collection != null && !collection.equals("")) {
-		addNZDLPageExtra(page_extra, lang, collection);
-	    }
-	}
-	    //message.appendChild(message_doc.importNode(getPageExtra(lang, collection), true));
-	  
-	    //} else {
-	    //message.appendChild(message_doc.createElement("pageExtra"));
-	    // } 
-	    //} else {
-	    //  message.appendChild(message_doc.createElement("pageExtra"));
-	    //}
-	
-	Element page = a.process(message);
-	return page;
-	
-    }
-
-    //protected Element getPageExtra(String lang, String collection) {
-    protected void addNZDLPageExtra(Element page_extra, String lang, 
-				    String collection) {
-	
-	Document doc = page_extra.getOwnerDocument();
-
-	// get the coll description to see whatservices are available
-	Element info_message = doc_.createElement(GSXML.MESSAGE_ELEM);
-	Element info_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_DESCRIBE, collection, lang);
-	Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	info_request.appendChild(param_list);
-	
-	Element param = GSXML.createParameter(doc_,GSXML.SUBSET_PARAM, GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
-	param_list.appendChild(param);
-	info_message.appendChild(info_request);
-
-	Element info_response = mr_.process(info_message);
-
-	//System.out.println("NZDLrecept: coll response = "+converter_.getPrettyString(info_response));
-	Element service_list = (Element)GSXML.getNodeByPath(info_response, "response/collection/serviceList");
-	
-	Element phrase_service = GSXML.getNamedElement(service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, "PhindApplet");
-	if (phrase_service !=null) {
-	    page_extra.appendChild(doc.importNode(phrase_service, false));
+	String collection = collection_info.getAttribute("name"); // should we take this from the request instead??
+	// look through services and see if classifier one is present - need to
+	// get the list of classifiers
+	Element service_list = (Element)GSXML.getChildByTagName(collection_info, GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
+	if (service_list == null) {
+	    // something weird has gone wrong
+	    return;
 	}
 
@@ -145,21 +47,21 @@
 	    return; // no browsing stuff
 	}
-
+	String lang = page.getAttribute(GSXML.LANG_ATT);
 	// find the list of classifiers
-	info_message = doc_.createElement(GSXML.MESSAGE_ELEM);
+	Element info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
 	String to = GSPath.appendLink(collection, "ClassifierBrowse");
-	info_request = GSXML.createBasicRequest(doc_, GSXML.REQUEST_TYPE_DESCRIBE, to, lang); 
+	Element info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang); 
 	info_message.appendChild(info_request);
-		
-	info_response = (Element) mr_.process(info_message);
-
-	classifier_service = (Element)GSXML.getNodeByPath(info_response, "response/service");
 	
-	page_extra.appendChild(doc.importNode(classifier_service, true));
+	Element info_response = (Element) this.mr.process(info_message);
+	String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.SERVICE_ELEM);
+	Element classifier_service_info = (Element)GSXML.getNodeByPath(info_response, path);
+	// add all the children into the classifier service element
+	GSXML.copyAllChildren(classifier_service, classifier_service_info);
+	System.out.println("the final page before transforming is");
+	System.out.println(this.converter.getPrettyString(page));
 	return;
+    }
 	
-	
-    }
-
 }
     
Index: /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/Receptionist.java
===================================================================
--- /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/Receptionist.java	(revision 4257)
+++ /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/Receptionist.java	(revision 4258)
@@ -14,7 +14,7 @@
 import java.util.Enumeration;
 
-/** core class for web interface generation. Receives requests consisting
- * of an xml representation of cgi args, and returns the page of data - in 
- * html by default. The requests are processed by the appropriate action class
+/** the most basic Receptionist, used for interface generation. 
+ * Receives requests consisting
+ * of an xml representation of cgi args, and returns the page of data. The requests are processed by the appropriate action class
  *
  * @see Action
@@ -23,31 +23,28 @@
 
     /** the set up variables */
-    protected ConfigVars config_=null;
-
-    /** the cgi args converter */
-    protected GSCGI cgi_ = null;
+    /// this is web specific - perhaps use an interface so diff types (web/java app) can use diff classes
+    protected ConfigVars config=null;
 
     /** container Document to create XML Nodes */
-    protected Document doc_=null; 
+    protected Document doc=null; 
    
     /** a converter class to parse XML and create Docs */
-    protected XMLConverter converter_=null;
-
-    /** the message router that the actions will talk to */
-    protected ModuleInterface mr_=null;
+    protected XMLConverter converter=null;
+
+    /** the message router that the Receptionist and Actions will talk to */
+    protected ModuleInterface mr=null;
 
     /** the list of actions */
-    protected HashMap action_map_=null;
-
+    protected HashMap action_map=null;
+    
     public Receptionist() {
-	converter_ = new XMLConverter();
-	doc_ = converter_.newDOM();
-	action_map_= new HashMap();
-	cgi_ = new GSCGI();
-    }
- 
+	this.converter = new XMLConverter();
+	this.doc = this.converter.newDOM();
+	this.action_map= new HashMap();
+    }
+    
     /** the set up vars must be set before configure called*/
     public void setConfigVars(ConfigVars config) {
-	config_ = config;
+	this.config = config;
     }
 
@@ -55,5 +52,5 @@
      * configured before  being passed to the receptionist*/
     public void setMessageRouter(ModuleInterface m) {
-       mr_ = m;
+       this.mr = m;
     }
 
@@ -61,65 +58,41 @@
     public boolean configure() {
 
-	if (config_==null) {
+	if (this.config==null) {
 	    System.err.println("Receptionist Error: config variables must be set before calling configure");
 	    return false;
 	}
-	if (mr_==null) {	   
+	if (this.mr==null) {	   
 	    System.err.println("Receptionist Error: message router must be set  before calling configure");
 	    return false;
 	}
 
-	// add in the default actions - others can be dynamically 
-	// loaded as needed
-	// if you want an action to have a short name it needs to go here
-	Action a = new PageAction();
-	a.setConfigVars(config_);
-	a.setMessageRouter(mr_);
-	a.setCGI(cgi_);
-	a.configure();
-	action_map_.put("p", a);
-
-	a = new QueryAction();
-	a.setConfigVars(config_);
-	a.setCGI(cgi_);
-	a.setMessageRouter(mr_);
-	a.configure();
-	action_map_.put("q", a);
-
-  	a = new BrowseAction();
-  	a.setConfigVars(config_);
- 	a.setCGI(cgi_);
- 	a.setMessageRouter(mr_);
-  	a.configure();
-  	action_map_.put("b", a);
-
-	a = new DocumentAction();
-	a.setConfigVars(config_);
-	a.setCGI(cgi_);
-	a.setMessageRouter(mr_);
-	a.configure();
-	action_map_.put("d", a);
-
-	a = new AppletAction();
-	a.setConfigVars(config_);
-	a.setCGI(cgi_);
-	a.setMessageRouter(mr_);
-	a.configure();
-	action_map_.put("a", a);
-	
-	a = new ProcessAction();
-	a.setConfigVars(config_);
-	a.setCGI(cgi_);
-	a.setMessageRouter(mr_);
-	a.configure();
-	action_map_.put("pr", a);
-
-	a = new SystemAction();
-	a.setConfigVars(config_);
-	a.setCGI(cgi_);
-	a.setMessageRouter(mr_);
-	a.configure();
-	action_map_.put("s", a);
-
+	// find the config file containing a list of actions
+	File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(this.config.gsdl3_home_, this.config.interface_name_)));
+	if (!interface_config_file.exists()) {
+	    System.err.println("Receptionist: interface config file: "+interface_config_file.getPath()+" not found!");
+	    return false;
+	}
+	
+	Element config_doc = this.converter.getDOM(interface_config_file).getDocumentElement();
+	Element action_list = (Element)GSXML.getChildByTagName(config_doc, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
+	NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
+
+	for (int i=0; i<actions.getLength(); i++) {
+	    Element action = (Element) actions.item(i);
+	    String class_name = action.getAttribute("class");
+	    String action_name = action.getAttribute("name");
+	    Action ac = null;
+	    try {
+		ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
+	    } catch (Exception e) {
+		System.out.println("couldn't load in action "+class_name);
+		e.printStackTrace();
+		continue;
+	    }
+	    ac.setConfigVars(this.config);
+	    ac.setMessageRouter(this.mr);
+	    ac.configure();
+	    this.action_map.put(action_name, ac);
+	}
 
 	return true;
@@ -128,7 +101,7 @@
     public String process(String xml_in) {
 
-	Element message = converter_.getDOM(xml_in).getDocumentElement();
+	Element message = this.converter.getDOM(xml_in).getDocumentElement();
 	Element page = process(message);
-	return converter_.getString(page);
+	return this.converter.getString(page);
     }
 
@@ -144,12 +117,12 @@
 	    return null; 
 	}
-	// check that the request type is correct
+	// check the request type 
 	String type = request.getAttribute(GSXML.TYPE_ATT); // returns "" if no att of this name
-	if (!type.equals(GSXML.REQUEST_TYPE_CGI)) {
+	if (!type.equals(GSXML.REQUEST_TYPE_CGI)) { // should use a diff name??
 	    // now Receptionist forwards non-cgi requests straight to the MR, and returns the responses
 	    System.err.println("Receptionist: request type is not '"+GSXML.REQUEST_TYPE_CGI+"', but it is '"+type+"', so forwarding the message to the MR!");
-	    // process teh whole message - mr needs <message> tags, and 
+	    // process the whole message - mr needs <message> tags, and 
 	    // in this case, there may be more than one request in the message
-	    return mr_.process(message);
+	    return this.mr.process(message);
 	}	
 	// work out which action to pass to
@@ -159,15 +132,7 @@
 	    return null;
 	}
-	// convert cgi short names to long names in the param list
-	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	if (param_list!=null) {
-	    if (!cgi_.paramListToLongNames(param_list)) {
-		System.err.println("Receptionist Error: couldn't convert short names to long names in the param list!");
-		return null;
-	    }
-	}
-	
-	// pass request to appropriate action	
-	Action a = (Action)action_map_.get(action);
+	
+	// find the  appropriate action	
+	Action a = (Action)this.action_map.get(action);
 	String action_name=null;
 	if (a==null) { // not in the map yet
@@ -176,9 +141,8 @@
 		action_name = action.substring(0,1).toUpperCase()+action.substring(1)+"Action";
 		Action ac = (Action)Class.forName("org.greenstone.gsdl3.action."+action_name).newInstance();
-		ac.setConfigVars(config_);
-		ac.setMessageRouter(mr_);
-		ac.setCGI(cgi_);
+		ac.setConfigVars(this.config);
+		ac.setMessageRouter(this.mr);
 		ac.configure();
-		action_map_.put(action, ac);
+		this.action_map.put(action, ac);
 		a = ac;
 	    } catch (Exception e) {
@@ -189,39 +153,50 @@
 	}
 
-	// add in the  system stuff - display and config - this all goes into 
-	// a pageExtra element
-	Document message_doc = message.getOwnerDocument();
-	Element page_extra = message_doc.createElement(GSXML.PAGE_EXTRA_ELEM);
-	message.appendChild(page_extra);
-	String lang = request.getAttribute(GSXML.LANG_ATT);
-	Element display = getDisplayElement(lang);
-	page_extra.appendChild(message_doc.importNode(display, true));
-	page_extra.appendChild(message_doc.importNode(config_.config_xml_, true));
-
-	Element page = a.process(message);
+	// transform the request in some way
+	preProcessRequest(request);
+	// set up the page
+	Element page = this.doc.createElement(GSXML.PAGE_ELEM);
+	// do we need this??
+	page.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
+	
+	// get the page data from the action
+	Element action_response = a.process(message);
+
+	boolean response_only=false;
+	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	if (param_list != null) {
+	    Element param = GSXML.getNamedElement(param_list, GSXML.PARAM_ELEM, GSXML.NAME_ATT, "ro");
+	    if (param != null) {
+		String value = param.getAttribute("value");
+		if (value.equals("1")) {
+		    response_only = true;
+		}
+	    }
+	}
+	if (response_only) {
+	    // only the response from the action is sent back
+	    return action_response;
+	}
+	
+	// the request is part of the page
+	page.appendChild(GSXML.duplicateWithNewName(this.doc, request, GSXML.PAGE_REQUEST_ELEM, true));
+	// add the response too
+	Element page_response = GSXML.duplicateWithNewName(this.doc, (Element)GSXML.getChildByTagName(action_response, GSXML.RESPONSE_ELEM), GSXML.PAGE_RESPONSE_ELEM, true);
+	page.appendChild(page_response);
+
+	// transform the result in some way
+	Element resulting_page = postProcessPage(page);
+	return resulting_page;
+	
+    }
+
+    protected void preProcessRequest(Element request) {
+	return;
+    }
+
+    protected Element postProcessPage(Element page) {
 	return page;
-	
-    }
-
-    /** returns an xml element containing all the text strings 
-     * needed for an interface 
-     * currently only uses the current interface - should add in 
-     * needed ones from the default interface if current != default */
-    protected Element getDisplayElement(String lang) {
-
-	Element display = doc_.createElement(GSXML.DISPLAY_ELEM);
-	// looks for properties files based on interface name
-	String resource_name = "interface_"+config_.interface_name_;
-
-	Dictionary dict = new Dictionary(resource_name, lang);
-	Enumeration enum = dict.getKeys();
-	while (enum.hasMoreElements()) {
-	    String key = (String)enum.nextElement();
-	    String value = dict.get(key);
-	    Element e = GSXML.createTextElement(doc_, key, value);
-	    display.appendChild(e);
-	}
-	return display;
-    }
+    }
+    
 
 }
Index: /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java
===================================================================
--- /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java	(revision 4258)
+++ /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java	(revision 4258)
@@ -0,0 +1,198 @@
+package org.greenstone.gsdl3.core;
+
+import org.greenstone.gsdl3.util.*;
+import org.greenstone.gsdl3.action.*;
+// XML classes
+import org.w3c.dom.Node; 
+import org.w3c.dom.NodeList; 
+import org.w3c.dom.Document; 
+import org.w3c.dom.Element; 
+
+// other java classes
+import java.io.File;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+/** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting
+ * of an xml representation of cgi args, and returns the page of data - in 
+ * html by default. The requests are processed by the appropriate action class
+ *
+ * @see Action
+ */
+public class TransformingReceptionist extends Receptionist{
+    
+    /** the list of xslt to use for actions */
+    protected HashMap xslt_map = null;
+    
+    /** a transformer class to transform xml using xslt */
+    protected XMLTransformer transformer=null;
+
+    public TransformingReceptionist() {
+	super();
+	this.xslt_map = new HashMap();
+	this.transformer = new XMLTransformer();
+    }
+    
+    /** configures the receptionist - overwrite this to set up the xslt map*/
+    public boolean configure() {
+	
+	if (this.config==null) {
+	    System.err.println("Receptionist Error: config variables must be set before calling configure");
+	    return false;
+	}
+	if (this.mr==null) {	   
+	    System.err.println("Receptionist Error: message router must be set  before calling configure");
+	    return false;
+	}
+	
+	// find the config file containing a list of actions
+	File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(this.config.gsdl3_home_, this.config.interface_name_)));
+	if (!interface_config_file.exists()) {
+	    System.err.println("TransformingReceptionist: interface config file: "+interface_config_file.getPath()+" not found!");
+	    return false;
+	}
+	
+	Element config_doc = this.converter.getDOM(interface_config_file).getDocumentElement();
+	Element action_list = (Element)GSXML.getChildByTagName(config_doc, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER);
+	NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM);
+
+	for (int i=0; i<actions.getLength(); i++) {
+	    Element action = (Element) actions.item(i);
+	    String class_name = action.getAttribute("class");
+	    String action_name = action.getAttribute("name");
+	    Action ac = null;
+	    try {
+		ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance();
+	    } catch (Exception e) {
+		System.out.println("couldn't load in action "+class_name);
+		e.printStackTrace();
+		continue;
+	    }
+	    ac.setConfigVars(this.config);
+	    ac.setMessageRouter(this.mr);
+	    ac.configure();
+	    this.action_map.put(action_name, ac);
+
+	    // now do the xslt map
+	    String xslt = action.getAttribute("xslt");
+	    if (!xslt.equals("")) {
+		this.xslt_map.put(action_name, xslt);
+	    }
+	    NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM);
+	    for (int j=0; j<subactions.getLength(); j++) {
+		Element subaction = (Element)subactions.item(j);
+		String subname = subaction.getAttribute(GSXML.NAME_ATT);
+		String subxslt = subaction.getAttribute("xslt");
+		
+		String map_key = action_name+":"+subname;
+		System.out.println("adding in to xslt map, "+map_key+"->"+subxslt);
+		this.xslt_map.put(map_key, subxslt);
+	    }
+	    
+	   
+	}
+
+	return true;
+    }
+
+
+    protected Element postProcessPage(Element page) {
+	
+	// might need to add some data to the page
+	addExtraInfo(page);
+	// transform the page using xslt
+	Element transformed_page = transformPage(page);
+	
+	return transformed_page;
+    }
+    
+    /** adds in the config stuff and interface display stuff - 
+     * needed by the xslt
+     */
+    protected void addExtraInfo(Element page) {
+	Element page_extra = this.doc.createElement(GSXML.PAGE_EXTRA_ELEM);
+	page.appendChild(page_extra);
+	String lang = ((Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM)).getAttribute(GSXML.LANG_ATT);
+	Element display = getDisplayElement(lang);
+	page_extra.appendChild(this.doc.importNode(display, true));
+	page_extra.appendChild(this.doc.importNode(this.config.config_xml_, true));
+	
+	return;
+    }
+
+    /** transform teh page using xslt
+     * we need to get any format element out of teh page and add it to the xslt
+     * before transforming */
+    protected Element transformPage(Element page) {
+
+	Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);
+	String action = request.getAttribute("action");
+	String subaction = request.getAttribute("subaction");
+	String xslt_file = getXSLTFileName(action, subaction);
+	if (xslt_file==null) {
+	    // cant transform the page - return null or the original?
+	    System.err.println(" cant find the xslt file needed, so returning the original page!");
+	    return page;
+	}
+	Document style_doc = this.converter.getDOM(new File(xslt_file));
+
+	// look for the format element in the page response
+	Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
+	Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
+	if (format_elem != null) {
+	    page_response.removeChild(format_elem);
+	    
+	    // need to transform the format info
+	    String stylesheet_file = GSFile.stylesheetFile(this.config, "config_format.xsl");
+	    Document stylesheet = this.converter.getDOM(new File(stylesheet_file));
+	    Element new_format = (Element)this.transformer.transform(stylesheet, format_elem);
+	    // add it in to the main stylesheet
+	    GSXSLT.mergeStylesheets(style_doc, new_format);
+	    System.out.println("the converted stylesheet is:");
+	    System.out.println(this.converter.getPrettyString(style_doc.getDocumentElement()));
+	}
+	
+	GSXSLT.absoluteIncludePaths(style_doc, this.config);
+	return (Element)this.transformer.transform(style_doc, page);          
+    }
+
+    protected String getXSLTFileName(String action, String subaction) {
+
+	String name = null;
+	if (!subaction.equals("")) {
+	    String key = action+":"+subaction;
+	    name = (String) this.xslt_map.get(key);
+	}
+	// try the action by itself
+	if (name==null) {
+	    name = (String) this.xslt_map.get(action);
+	}
+	// now find the absolute path
+	String stylesheet = GSFile.stylesheetFile(this.config, name);
+	if (stylesheet==null) {
+	    System.out.println("cant find stylesheet for "+name);
+	}
+	return stylesheet;
+    }
+    /** returns an xml element containing all the text strings 
+     * needed for an interface 
+     * currently only uses the current interface - should add in 
+     * needed ones from the default interface if current != default */
+    protected Element getDisplayElement(String lang) {
+
+	Element display = this.doc.createElement(GSXML.DISPLAY_ELEM);
+	// looks for properties files based on interface name
+	String resource_name = "interface_"+this.config.interface_name_;
+
+	Dictionary dict = new Dictionary(resource_name, lang);
+	Enumeration enum = dict.getKeys();
+	while (enum.hasMoreElements()) {
+	    String key = (String)enum.nextElement();
+	    String value = dict.get(key);
+	    Element e = GSXML.createTextElement(this.doc, key, value);
+	    display.appendChild(e);
+	}
+	return display;
+    }
+
+}
Index: /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/WebReceptionist.java
===================================================================
--- /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/WebReceptionist.java	(revision 4258)
+++ /trunk/gsdl3/src/java/org/greenstone/gsdl3/core/WebReceptionist.java	(revision 4258)
@@ -0,0 +1,62 @@
+package org.greenstone.gsdl3.core;
+
+import org.greenstone.gsdl3.util.*;
+import org.greenstone.gsdl3.action.*;
+// XML classes
+import org.w3c.dom.Node; 
+import org.w3c.dom.NodeList; 
+import org.w3c.dom.Document; 
+import org.w3c.dom.Element; 
+
+// other java classes
+import java.io.File;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+/** core class for web interface generation. Receives requests consisting
+ * of an xml representation of cgi args, and returns the page of data - in 
+ * html by default. The requests are processed by the appropriate action class
+ *
+ * @see Action
+ */
+public class WebReceptionist extends TransformingReceptionist {
+
+    /** the set up variables */
+
+    /** the cgi args converter */
+    protected GSCGI cgi = null;
+
+    public void setCGI(GSCGI cgi) {
+	this.cgi=cgi;
+    }
+    
+    protected void preProcessRequest(Element request) {
+	// convert cgi short names to long names in the param list
+	Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	if (param_list!=null) {
+	    if (!this.cgi.paramListToLongNames(param_list)) {
+		System.err.println("Receptionist Error: couldn't convert short names to long names in the param list!");
+		
+	    }
+	}
+    }
+
+    // need to modify some param lists
+    protected Element transformPage(Element page) {
+	
+	Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM);
+	// look for a service description
+	Element service = (Element)GSXML.getChildByTagName(page_response, GSXML.SERVICE_ELEM);
+	if (service != null) {
+	    // look for a param-list
+	    Element param_list = (Element)GSXML.getChildByTagName(service, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	    if (param_list != null) {
+
+		// add in cgi short names
+		this.cgi.paramListAddShortNames(param_list);
+	    }
+	}
+	return super.transformPage(page);
+    }
+
+}
