/* * ServiceRack.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; import java.lang.reflect.Method; /** * ServiceRack - abstract base class for services * * A ServiceRack provides one or more Services. * This base class implements the process method. *Each service is invoked * by a method called process which takes one parameter - the xml request Element, and returns an XML response Element. * for example, the TextQuery service would be invoked by * processTextQuery(Element request) * * @author Katherine Don * @version $Revision: 9874 $ */ public abstract class ServiceRack implements ModuleInterface { /** the absolute address of the site home */ protected String site_home =null; /** the http address of the site home */ protected String site_http_address =null; /** the name of the cluster (or collection) 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; /** the original config info - if need to store it */ protected Element config_info = null; /** XML element for describe requests - the container doc */ protected Document doc = null; /** XML element for describe requests - list of supported services - this is static */ protected Element short_service_info = null; /** XML element for stylesheet requests - map of service name to format elem */ protected HashMap format_info_map = null; /** sets the cluster name */ public void setClusterName(String cluster_name) { this.cluster_name = cluster_name; } /** sets the collect name */ public void setCollectionName(String coll_name) { setClusterName(coll_name); } public void cleanUp() {} /** sets the site home */ public void setSiteHome(String site_home) { this.site_home = site_home; } /** sets the site http address */ public void setSiteAddress(String site_address) { this.site_http_address = site_address; } /** sets the message router */ public void setMessageRouter(ModuleInterface m) { this.router = m; } /** the no-args constructor */ public ServiceRack() { this.converter = new XMLConverter(); this.doc = this.converter.newDOM(); this.short_service_info = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER); this.format_info_map = new HashMap(); } /** configure the service module * * @param info the XML node with name equal * to the class name (of the subclass) * * must configure short_service_info_ and service_info_map_ * @return true if configured ok * must be implemented in subclasses */ public boolean configure(Element info) { return configure(info, null); } abstract public boolean configure(Element info, Element extra_info); /** * Process an XML document - convenience method that uses Strings rather than Elements. just calls process(Element). * * @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 = this.converter.getDOM(xml_in); if (doc == null) { System.err.println("ServiceRack.process(String) Error: Couldn't parse request"); System.err.println(xml_in); return null; } Element res = process(doc.getDocumentElement()); return this.converter.getString(res); } /** process an XML request in DOM form * * @param xml_in the Element node containing the request * should be * @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 = this.doc.createElement(GSXML.MESSAGE_ELEM); if (requests.getLength()==0) { // no requests return mainResult; // empty message for now } for (int i=0; i