package org.greenstone.gsdl3; import org.greenstone.gsdl3.core.*; import org.greenstone.gsdl3.util.*; import org.greenstone.gsdl3.action.PageAction; // used to get the default action import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Enumeration; import java.util.HashMap; import java.io.File; /** a servlet to serve the greenstone library - we are using servlets instead * of cgi * the init method is called only once - the first time the servlet classes * are loaded. Each time a request comes in to the servlet, the session() * method is called in a new thread (calls doGet/doPut etc) * takes the a=p&p=home type args and builds a simple request to send to * its receptionist, which returns a result in html, cos output=html * is set in the request * @see Receptionist */ public class LibraryServlet extends HttpServlet { /** the receptionist to send messages to */ protected Receptionist recept=null; /** the default language - is specified by setting a servlet param, * otherwise DEFAULT_LANG is used*/ protected String default_lang= null; /** The default default - used if a default lang is not specified * in the servlet params */ protected final String DEFAULT_LANG = "en"; /** container Document to create XML Nodes */ protected Document doc=null; /** a converter class to parse XML and create Docs */ protected XMLConverter converter=null; /** the cgi stuff - the Receptionist can add new args to this * its used by the servlet to determine what args to save */ //protected GSCGI cgi = null; protected GSParams params = null; /** user id - new one per session. This doesn't work if session state is saved between restarts - this requires this value to be saved too. */ protected int next_user_id = 0; /** initialise the servlet */ public void init(ServletConfig config) throws ServletException { // always call super.init; super.init(config); // disable preferences - does this work anyway?? //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory"); String library_name = config.getInitParameter(GSConstants.LIBRARY_NAME); String gsdl3_home = config.getInitParameter(GSConstants.GSDL3_HOME); String site_name = config.getInitParameter(GSConstants.SITE_NAME); String interface_name = config.getInitParameter(GSConstants.INTERFACE_NAME); this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG); if (library_name == null || gsdl3_home == null || site_name ==null || interface_name ==null) { // must have this System.err.println("initialisation parameters not all set!"); System.err.println(" you must have libraryname, gsdl3home, sitename, interfacename"); System.exit(1); } if (this.default_lang == null) { // choose english this.default_lang = DEFAULT_LANG; } HashMap config_params = new HashMap(); config_params.put(GSConstants.LIBRARY_NAME, library_name); config_params.put(GSConstants.GSDL3_HOME, gsdl3_home); config_params.put(GSConstants.SITE_NAME, site_name); config_params.put(GSConstants.INTERFACE_NAME, interface_name); this.converter = new XMLConverter(); this.doc = this.converter.newDOM(); // now try and create MR and recpt // new message router - create it and pass reference to recept. // the servlet wont use this directly String mr_name = (String)config.getInitParameter("messagerouter_class"); MessageRouter message_router = null; if (mr_name == null) { // just use the normal MR message_router = new MessageRouter(); } else { // try the specified one try { message_router = (MessageRouter)Class.forName("org.greenstone.gsdl3.core."+mr_name).newInstance(); } catch (Exception e) { // cant use this new one, so use normal one System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter "+mr_name+": "+e.getMessage()); e.printStackTrace(); message_router = new MessageRouter(); } } message_router.setSiteHome(GSFile.siteHome(gsdl3_home, site_name)); message_router.configure(); // the receptionist -the servlet will talk to this String recept_name = (String)config.getInitParameter("receptionist_class"); if (recept_name == null) { this.recept = new DefaultReceptionist(); } else { try { this.recept = (Receptionist)Class.forName("org.greenstone.gsdl3.core."+recept_name).newInstance(); } catch (Exception e) { // cant use this new one, so use normal one System.err.println("LibraryServlet configure exception when trying to use a new Receptionist "+recept_name+": "+e.getMessage()); e.printStackTrace(); this.recept = new DefaultReceptionist(); } } this.recept.setConfigParams(config_params); this.recept.setMessageRouter(message_router); // the params arg thingy String params_name = (String)config.getInitParameter("params_class"); if (params_name == null) { this.params = new GSParams(); } else { try { this.params = (GSParams)Class.forName("org.greenstone.gsdl3.util."+params_name).newInstance(); } catch (Exception e) { System.err.println("LibraryServlet configure exception when trying to use a new params thing "+params_name+": "+e.getMessage()); e.printStackTrace(); this.params = new GSParams(); } } // pass it to the receptionist this.recept.setParams(this.params); this.recept.configure(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(true); String uid = (String)session.getAttribute(GSXML.USER_ID_ATT); if (uid ==null) { uid = ""+getNextUserId(); session.setAttribute(GSXML.USER_ID_ATT, uid); } request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String lang = request.getParameter(GSParams.LANGUAGE); if (lang==null || lang.equals("")) { // try the session cached lang lang = (String)session.getAttribute(GSParams.LANGUAGE); if (lang==null || lang.equals("")) { // still not set, use the default lang = this.default_lang; } } // set the lang in the session session.setAttribute(GSParams.LANGUAGE, lang); String output = request.getParameter(GSParams.OUTPUT); if (output==null || output.equals("")) { output = "html"; // uses html by default } // the request to the receptionist Element xml_message = this.doc.createElement(GSXML.MESSAGE_ELEM); Element xml_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", lang, uid); xml_request.setAttribute(GSXML.OUTPUT_ATT, output); xml_message.appendChild(xml_request); String action = request.getParameter(GSParams.ACTION); String subaction = request.getParameter(GSParams.SUBACTION); if (action==null || action.equals("")) { // should we do all the following stuff if using default page? // display the home page - the default page action = "p"; subaction = PageAction.HOME_PAGE; xml_request.setAttribute(GSXML.ACTION_ATT, action); xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction); } else { xml_request.setAttribute(GSXML.ACTION_ATT, action); if (subaction != null) { xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction); } // create the param list for the greenstone request - includes // the params from the current request and any others from the saved session Element xml_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); xml_request.appendChild(xml_param_list); Enumeration params = request.getParameterNames(); while(params.hasMoreElements()) { String name = (String)params.nextElement(); if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT)) {// we have already dealt with these String value=""; String [] values = request.getParameterValues(name); value = values[0]; if (values.length > 1) { for (int i=1; i< values.length; i++) { value += ","+values[i]; } } // either add it to the param list straight away, or save it to the session and add it later if (this.params.shouldSave(name)) { session.setAttribute(name, value); } else { Element param = this.doc.createElement(GSXML.PARAM_ELEM); param.setAttribute(GSXML.NAME_ATT, name); param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value)); xml_param_list.appendChild(param); } } } // put in all the params from the session cache params = session.getAttributeNames(); while(params.hasMoreElements()) { String name = (String)params.nextElement(); if ( !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT)) { // lang and uid are stored but we dont want it in the param list cos its already in the request Element param = this.doc.createElement(GSXML.PARAM_ELEM); param.setAttribute(GSXML.NAME_ATT, name); param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe((String)session.getAttribute(name))); xml_param_list.appendChild(param); } } } if (!output.equals("html")) { response.setContentType("text/xml"); // for now use text } Element xml_result = this.recept.process(xml_message); encodeURLs(xml_result, response); out.println(this.converter.getPrettyString(xml_result)); } /** this goes through each URL and adds in a session id if needed-- * its needed if the browser doesn't accept cookies */ protected void encodeURLs(Element data, HttpServletResponse response) { if (data == null) { return; } // get all the elements NodeList hrefs = data.getElementsByTagName("a"); for (int i=0; i elements NodeList forms = data.getElementsByTagName("form"); for (int i=0; i