Changeset 14498


Ignore:
Timestamp:
2007-09-06T18:08:23+12:00 (14 years ago)
Author:
xiao
Message:

modify to make the session caching collection-specific.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • greenstone3/trunk/src/java/org/greenstone/gsdl3/LibraryServlet.java

    r13273 r14498  
    1212import javax.servlet.http.*;
    1313import java.util.Enumeration;
     14import java.util.ArrayList;
    1415import java.util.HashMap;
    1516import java.io.File;
    16 
     17import java.util.Hashtable;
    1718import org.apache.log4j.*;
     19
    1820
    1921/** a servlet to serve the greenstone library - we are using servlets instead
     
    2224 * are loaded. Each time a request comes in to the servlet, the session()
    2325 * method is called in a new thread (calls doGet/doPut etc)
    24  * takes the a=p&p=home type args and builds a simple request to send to 
     26 * takes the a=p&p=home type args and builds a simple request to send to
    2527 * its receptionist, which returns a result in html, cos output=html
    2628 * is set in the request
     29 *
     30 * 18/Jul/07 xiao
     31 * modify to make the cached parameters collection-specific.
     32 * Most of the work is done in doGet(), except adding an inner class UserSessionCache.
     33 *
    2734 * @see Receptionist
    2835 */
    2936public class LibraryServlet extends HttpServlet {
    30    
    31     /** the receptionist to send messages to */
    32     protected Receptionist recept=null;
    33     /** the default language - is specified by setting a servlet param,
    34      * otherwise DEFAULT_LANG is used*/
    35     protected String default_lang= null;
    36     /** The default default - used if a default lang is not specified
    37      * in the servlet params */
    38     protected final String DEFAULT_LANG = "en";
    39     /** container Document to create XML Nodes */
    40     protected Document doc=null;   
    41     /** a converter class to parse XML and create Docs */
    42     protected XMLConverter converter=null;
    43     /** the cgi stuff - the Receptionist can add new args to this
    44      * its used by the servlet to determine what args to save */
    45     protected GSParams params = null;
    46 
    47     /** 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. */
    48     protected int next_user_id = 0;
    49 
    50     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
    51 
    52     /** initialise the servlet
     37 
     38  /** the receptionist to send messages to */
     39  protected Receptionist recept=null;
     40  /** the default language - is specified by setting a servlet param,
     41   * otherwise DEFAULT_LANG is used*/
     42  protected String default_lang= null;
     43  /** The default default - used if a default lang is not specified
     44   * in the servlet params */
     45  protected final String DEFAULT_LANG = "en";
     46  /** container Document to create XML Nodes */
     47  protected Document doc=null;
     48  /** a converter class to parse XML and create Docs */
     49  protected XMLConverter converter=null;
     50  /** the cgi stuff - the Receptionist can add new args to this
     51   *
     52   * its used by the servlet to determine what args to save */
     53  protected GSParams params = null;
     54 
     55  /** 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. */
     56  protected int next_user_id = 0;
     57
     58  /** a hash that contains all the active session IDs mapped to the cached items
     59   *  It is updated whenever the whole site or a particular collection is reconfigured
     60   *  using the command a=s&sa=c or a=s&sa=c&c=xxx
     61   *  It is in the form: sid -> (UserSessionCache object)
     62   */
     63  protected Hashtable session_ids_table = new Hashtable();
     64  //this name is combined with the collection name and used for caching
     65  protected String valid_site_name = "";
     66 
     67  /** the maximum interval that the cached info remains in session_ids_table (in seconds)
     68   *  This is set in web.xml
     69   */
     70  protected int session_expiration = 1800;
     71 
     72  static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
     73 
     74  /** initialise the servlet
     75   */
     76  public void init(ServletConfig config) throws ServletException {
     77    // always call super.init;
     78    super.init(config);
     79    // disable preferences - does this work anyway??
     80    //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
     81   
     82   
     83    String library_name = config.getInitParameter(GSConstants.LIBRARY_NAME);
     84    String gsdl3_home = config.getInitParameter(GSConstants.GSDL3_HOME);
     85    String interface_name = config.getInitParameter(GSConstants.INTERFACE_NAME);
     86    this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG);
     87    String sess_expire = config.getInitParameter(GSXML.SESSION_EXPIRATION);
     88    if (sess_expire != null && !sess_expire.equals("")) {
     89        this.session_expiration = Integer.parseInt(sess_expire);
     90    }
     91   
     92    if (library_name == null || interface_name ==null) {
     93      // must have this
     94      System.err.println("initialisation parameters not all set!");
     95      System.err.println(" you must have libraryname and interfacename");
     96      System.exit(1);
     97    }
     98   
     99    String site_name = config.getInitParameter(GSConstants.SITE_NAME);
     100    String remote_site_name = null;
     101    String remote_site_type = null;
     102    String remote_site_address = null;
     103   
     104    if (site_name == null) {
     105      // no site, try for communicator
     106      remote_site_name = config.getInitParameter("remote_site_name");
     107      remote_site_type = config.getInitParameter("remote_site_type");
     108      remote_site_address = config.getInitParameter("remote_site_address");
     109      if (remote_site_name == null || remote_site_type == null || remote_site_address == null) {
     110        System.err.println("initialisation paramters not all set!");
     111        System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
     112        System.exit(1);
     113      }
     114    }
     115    valid_site_name = (site_name != null)? site_name : remote_site_name;
     116   
     117    if (this.default_lang == null) {
     118      // choose english
     119      this.default_lang = DEFAULT_LANG;
     120    }
     121   
     122    HashMap config_params = new HashMap();
     123   
     124    config_params.put(GSConstants.LIBRARY_NAME, library_name);
     125    config_params.put(GSConstants.INTERFACE_NAME, interface_name);
     126    if (site_name != null) {
     127      config_params.put(GSConstants.SITE_NAME, site_name);
     128    }
     129    this.converter = new XMLConverter();
     130    this.doc = this.converter.newDOM();
     131   
     132    // the receptionist -the servlet will talk to this
     133    String recept_name = (String)config.getInitParameter("receptionist_class");
     134    if (recept_name == null) {
     135      this.recept = new DefaultReceptionist();
     136    } else {
     137      try {
     138        this.recept = (Receptionist)Class.forName("org.greenstone.gsdl3.core."+recept_name).newInstance();
     139      } catch (Exception e) { // cant use this new one, so use normal one
     140        System.err.println("LibraryServlet configure exception when trying to use a new Receptionist "+recept_name+": "+e.getMessage());
     141        e.printStackTrace();
     142        this.recept = new DefaultReceptionist();
     143      }
     144    }
     145    this.recept.setConfigParams(config_params);
     146   
     147    // the receptionist uses a MessageRouter or Communicator to send its requests to. We either create a MessageRouter here for the designated site (if site_name set), or we create a Communicator for a remote site. The is given to teh Receptionist, and the servlet never talks to it again.directly.
     148    if (site_name != null) {
     149      String mr_name = (String)config.getInitParameter("messagerouter_class");
     150      MessageRouter message_router = null;
     151      if (mr_name == null) { // just use the normal MR
     152        message_router = new MessageRouter();
     153      } else { // try the specified one
     154        try {
     155          message_router = (MessageRouter)Class.forName("org.greenstone.gsdl3.core."+mr_name).newInstance();
     156        } catch (Exception e) { // cant use this new one, so use normal one
     157          System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter "+mr_name+": "+e.getMessage());
     158          e.printStackTrace();
     159          message_router = new MessageRouter();
     160        }
     161      }
     162     
     163      message_router.setSiteName(site_name);
     164      message_router.configure();
     165      this.recept.setMessageRouter(message_router);
     166    } else {
     167      // talking to a remote site, create a communicator
     168      Communicator communicator = null;
     169      // we need to create the XML to configure the communicator
     170      Element site_elem = this.doc.createElement(GSXML.SITE_ELEM);
     171      site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
     172      site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
     173      site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
     174     
     175      if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA)) {
     176        communicator = new SOAPCommunicator();
     177      } else {
     178        System.err.println("LibraryServlet.init Error: invalid Communicator type: "+remote_site_type);
     179        System.exit(1);
     180      }
     181     
     182      if (!communicator.configure(site_elem)) {
     183        System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
     184        System.exit(1);
     185      }
     186      this.recept.setMessageRouter(communicator);
     187    }
     188   
     189    // the params arg thingy
     190   
     191    String params_name = (String)config.getInitParameter("params_class");
     192    if (params_name == null) {
     193      this.params = new GSParams();
     194    } else {
     195      try {
     196        this.params = (GSParams)Class.forName("org.greenstone.gsdl3.util."+params_name).newInstance();
     197      } catch (Exception e) {
     198        System.err.println("LibraryServlet configure exception when trying to use a new params thing "+params_name+": "+e.getMessage());
     199        e.printStackTrace();
     200        this.params = new GSParams();
     201      }
     202    }
     203    // pass it to the receptionist
     204    this.recept.setParams(this.params);
     205    this.recept.configure();
     206   
     207  }
     208 
     209 
     210  private void logUsageInfo(HttpServletRequest request){
     211    String usageInfo = "";
     212   
     213    //session-info: get params stored in the session
     214    HttpSession session = request.getSession(true);
     215    Enumeration attributeNames = session.getAttributeNames();
     216    while(attributeNames.hasMoreElements()) {
     217      String name = (String)attributeNames.nextElement();
     218      usageInfo +=name+"="+session.getAttribute(name)+" ";
     219    }
     220   
     221    //logged info = general-info + session-info
     222    usageInfo =
     223      request.getServletPath()+" "+ //serlvet
     224      "["+request.getQueryString()+"]" +" "+ //the query string
     225      "["+usageInfo.trim()+"]" +" "+ // params stored in a session
     226      request.getRemoteAddr()+" "+   //remote address
     227      request.getRequestedSessionId()+" "+ //session id
     228      request.getHeader("user-agent")+" "; //the remote brower info
     229   
     230    logger.info(usageInfo);
     231   
     232  }
     233 
     234  public class UserSessionCache implements HttpSessionBindingListener {
     235
     236    String session_id = "";
     237   
     238    /** a hash that maps the session ID to a hashtable that maps the coll_name to its parameters
     239     *  coll_name -> Hashtable (param_name -> param_value)
    53240     */
    54     public void init(ServletConfig config) throws ServletException {
    55     // always call super.init;
    56     super.init(config);
    57     // disable preferences - does this work anyway??
    58     //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
    59 
    60    
    61     String library_name = config.getInitParameter(GSConstants.LIBRARY_NAME);
    62     String gsdl3_home = config.getInitParameter(GSConstants.GSDL3_HOME);
    63     String interface_name = config.getInitParameter(GSConstants.INTERFACE_NAME);
    64     this.default_lang = config.getInitParameter(GSConstants.DEFAULT_LANG);
    65 
    66     if (library_name == null || interface_name ==null) {
    67         // must have this
    68         System.err.println("initialisation parameters not all set!");
    69         System.err.println(" you must have libraryname and interfacename");
    70         System.exit(1);
     241    protected Hashtable coll_name_params_table = null;
     242   
     243    public UserSessionCache(String id, Hashtable table) {
     244      session_id = id;     
     245      coll_name_params_table = (table == null)? new Hashtable() : table;     
     246    }
     247
     248    protected void cleanupCache(String coll_name) {
     249      if (coll_name_params_table.containsKey(coll_name)) {
     250          coll_name_params_table.remove(coll_name);
     251      }
     252    }
     253    protected Hashtable getParamsTable() {
     254        return coll_name_params_table;
     255    }
     256    public void valueBound(HttpSessionBindingEvent event) {
     257    // Do nothing
     258    }
     259
     260    public void valueUnbound(HttpSessionBindingEvent event) {
     261      if(session_ids_table.containsKey(session_id)) {
     262        session_ids_table.remove(session_id);
     263      }
     264    }
     265    public int tableSize() {
     266        return (coll_name_params_table == null)? 0 : coll_name_params_table.size();
     267    }
     268  }
     269 
     270  public void doGet (HttpServletRequest request,
     271    HttpServletResponse response)
     272    throws ServletException, IOException {
     273    logUsageInfo (request);
     274    //logger.info("---------------------------------------------------");
     275    // Nested Diagnostic Configurator to identify the client for
     276   
     277    HttpSession session = request.getSession (true);
     278    String uid = (String)session.getAttribute (GSXML.USER_ID_ATT);
     279    if (uid ==null) {
     280      uid = ""+getNextUserId ();
     281      session.setAttribute (GSXML.USER_ID_ATT, uid);
     282    }
     283    request.setCharacterEncoding ("UTF-8");
     284    response.setContentType ("text/html;charset=UTF-8");
     285    PrintWriter out = response.getWriter ();
     286   
     287    String lang = request.getParameter (GSParams.LANGUAGE);
     288    if (lang==null || lang.equals ("")) {
     289      // try the session cached lang
     290      lang = (String)session.getAttribute (GSParams.LANGUAGE);
     291      if (lang==null || lang.equals ("")) {
     292        // still not set, use the default
     293        lang = this.default_lang;
     294      }
     295    }
     296   
     297    // set the lang in the session
     298    session.setAttribute (GSParams.LANGUAGE, lang);
     299   
     300    String output = request.getParameter (GSParams.OUTPUT);
     301    if (output==null || output.equals ("")) {
     302      output = "html"; // uses html by default
     303    }
     304   
     305    // the request to the receptionist
     306    Element xml_message = this.doc.createElement (GSXML.MESSAGE_ELEM);
     307    Element xml_request = GSXML.createBasicRequest (this.doc, GSXML.REQUEST_TYPE_PAGE, "", lang, uid);
     308    xml_request.setAttribute (GSXML.OUTPUT_ATT, output);
     309    xml_message.appendChild (xml_request);
     310   
     311    String action = request.getParameter (GSParams.ACTION);
     312    String subaction = request.getParameter (GSParams.SUBACTION);
     313    String collection = request.getParameter(GSParams.COLLECTION);
     314
     315    //specifically we clean up the cache session_ids_table if the two reconfigure command
     316    //are issued: a=s&sa=c and a=s&sa=c&c=coll_name, in which case there is no caching action to be taken
     317    boolean should_cache = true;
     318    if(action != null && action.equals(GSParams.SYSTEM)
     319            && subaction != null && subaction.equals(GSParams.CONFIGURE)) {
     320        if (collection == null || collection.equals("")) {
     321            //user reconfiugred the whole site, clean up all cached info
     322            //logger.info("clear cache for the whole site.");
     323            session_ids_table = new Hashtable();
     324           
     325        } else {
     326            //clean up all cache info related to the collection
     327            //logger.info("clear cache for collection: " + collection);
     328            ArrayList cache_list = new ArrayList(session_ids_table.values());
     329            for (int i=0; i<cache_list.size(); i++) {
     330                UserSessionCache cache = (UserSessionCache)cache_list.get(i);
     331                cache.cleanupCache(collection);
     332            }
     333        }
     334        should_cache = false;
    71335    }
    72336
    73     String site_name = config.getInitParameter(GSConstants.SITE_NAME);
    74     String remote_site_name = null;
    75     String remote_site_type = null;
    76     String remote_site_address = null;
    77    
    78     if (site_name == null) {
    79         // no site, try for communicator
    80         remote_site_name = config.getInitParameter("remote_site_name");
    81         remote_site_type = config.getInitParameter("remote_site_type");
    82         remote_site_address = config.getInitParameter("remote_site_address");
    83         if (remote_site_name == null || remote_site_type == null || remote_site_address == null) {
    84         System.err.println("initialisation paramters not all set!");
    85         System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
    86         System.exit(1);
    87         }
    88     }
    89    
    90     if (this.default_lang == null) {
    91         // choose english
    92         this.default_lang = DEFAULT_LANG;
    93     }
    94    
    95     HashMap config_params = new HashMap();
    96    
    97     config_params.put(GSConstants.LIBRARY_NAME, library_name);
    98     config_params.put(GSConstants.INTERFACE_NAME, interface_name);
    99     if (site_name != null) {
    100         config_params.put(GSConstants.SITE_NAME, site_name);
    101     }
    102     this.converter = new XMLConverter();
    103     this.doc = this.converter.newDOM();
    104    
    105     // the receptionist -the servlet will talk to this
    106     String recept_name = (String)config.getInitParameter("receptionist_class");
    107     if (recept_name == null) {
    108         this.recept = new DefaultReceptionist();
    109     } else {
    110         try {
    111         this.recept = (Receptionist)Class.forName("org.greenstone.gsdl3.core."+recept_name).newInstance();
    112         } catch (Exception e) { // cant use this new one, so use normal one
    113         System.err.println("LibraryServlet configure exception when trying to use a new Receptionist "+recept_name+": "+e.getMessage());
    114         e.printStackTrace();
    115         this.recept = new DefaultReceptionist();
    116         }
    117     }
    118     this.recept.setConfigParams(config_params);
    119 
    120     // the receptionist uses a MessageRouter or Communicator to send its requests to. We either create a MessageRouter here for the designated site (if site_name set), or we create a Communicator for a remote site. The is given to teh Receptionist, and the servlet never talks to it again.directly.
    121     if (site_name != null) {
    122         String mr_name = (String)config.getInitParameter("messagerouter_class");
    123         MessageRouter message_router = null;
    124         if (mr_name == null) { // just use the normal MR
    125         message_router = new MessageRouter();
    126         } else { // try the specified one
    127         try {
    128             message_router = (MessageRouter)Class.forName("org.greenstone.gsdl3.core."+mr_name).newInstance();
    129         } catch (Exception e) { // cant use this new one, so use normal one
    130             System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter "+mr_name+": "+e.getMessage());
    131             e.printStackTrace();
    132             message_router = new MessageRouter();
    133         }   
    134         }
    135        
    136         message_router.setSiteName(site_name);
    137         message_router.configure();
    138         this.recept.setMessageRouter(message_router);
    139     } else {
    140         // talking to a remote site, create a communicator
    141         Communicator communicator = null;
    142         // we need to create the XML to configure the communicator
    143         Element site_elem = this.doc.createElement(GSXML.SITE_ELEM);
    144         site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
    145         site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
    146         site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
    147 
    148         if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA)) {
    149         communicator = new SOAPCommunicator();
    150         } else {
    151         System.err.println("LibraryServlet.init Error: invalid Communicator type: "+remote_site_type);
    152         System.exit(1);
    153         }
    154        
    155         if (!communicator.configure(site_elem)) {
    156         System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
    157         System.exit(1);
    158         }
    159         this.recept.setMessageRouter(communicator);
    160     }
    161    
    162     // the params arg thingy
    163    
    164     String params_name = (String)config.getInitParameter("params_class");
    165     if (params_name == null) {
    166         this.params = new GSParams();
    167     } else {
    168         try {
    169         this.params = (GSParams)Class.forName("org.greenstone.gsdl3.util."+params_name).newInstance();
    170         } catch (Exception e) {
    171         System.err.println("LibraryServlet configure exception when trying to use a new params thing "+params_name+": "+e.getMessage());
    172         e.printStackTrace();
    173         this.params = new GSParams();
    174         }
    175     }
    176     // pass it to the receptionist
    177     this.recept.setParams(this.params);
    178     this.recept.configure();
    179    
    180     }
    181 
    182 
    183     private void logUsageInfo(HttpServletRequest request){
    184     String usageInfo = "";
    185 
    186     //session-info: get params stored in the session
    187     HttpSession session = request.getSession(true);
    188         Enumeration attributeNames = session.getAttributeNames();
    189     while(attributeNames.hasMoreElements()) {
    190         String name = (String)attributeNames.nextElement();
    191         usageInfo +=name+"="+session.getAttribute(name)+" ";
    192     }
    193    
    194     //logged info = general-info + session-info
    195     usageInfo =
    196         request.getServletPath()+" "+ //serlvet
    197         "["+request.getQueryString()+"]" +" "+ //the query string
    198         "["+usageInfo.trim()+"]" +" "+ // params stored in a session
    199         request.getRemoteAddr()+" "+   //remote address                 
    200         request.getRequestedSessionId()+" "+ //session id
    201         request.getHeader("user-agent")+" "; //the remote brower info                     
    202                          
    203     logger.info(usageInfo);
    204 
    205     }
    206 
    207        
    208     public void doGet(HttpServletRequest request,
    209               HttpServletResponse response)
    210     throws ServletException, IOException {
    211 
    212     logUsageInfo(request);
    213          
    214     // Nested Diagnostic Configurator to identify the client for
    215        
    216     HttpSession session = request.getSession(true);
    217         String uid = (String)session.getAttribute(GSXML.USER_ID_ATT);
    218     if (uid ==null) {
    219         uid = ""+getNextUserId();
    220         session.setAttribute(GSXML.USER_ID_ATT, uid);
    221     }
    222     request.setCharacterEncoding("UTF-8");
    223     response.setContentType("text/html;charset=UTF-8");
    224     PrintWriter out = response.getWriter();
    225 
    226     String lang = request.getParameter(GSParams.LANGUAGE);
    227     if (lang==null || lang.equals("")) {
    228         // try the session cached lang
    229         lang = (String)session.getAttribute(GSParams.LANGUAGE);
    230         if (lang==null || lang.equals("")) {
    231         // still not set, use the default
    232         lang = this.default_lang;
    233         }
    234     }
    235    
    236     // set the lang in the session
    237     session.setAttribute(GSParams.LANGUAGE, lang);
    238 
    239     String output = request.getParameter(GSParams.OUTPUT);
    240     if (output==null || output.equals("")) {
    241         output = "html"; // uses html by default
    242     }
    243 
    244     // the request to the receptionist 
    245     Element xml_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    246     Element xml_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", lang, uid);
    247     xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
    248     xml_message.appendChild(xml_request);
    249    
    250    
    251     String action = request.getParameter(GSParams.ACTION);
    252     String subaction = request.getParameter(GSParams.SUBACTION);
    253     if (action==null || action.equals("")) {
    254         // should we do all the following stuff if using default page?
    255         // display the home page  - the default page
    256         action = "p";
    257         subaction = PageAction.HOME_PAGE;
    258         xml_request.setAttribute(GSXML.ACTION_ATT, action);
    259         xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
    260        
    261     } else {
    262    
    263         xml_request.setAttribute(GSXML.ACTION_ATT, action);
    264         if (subaction != null) {
    265         xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
    266         }
    267 
    268         //  create the param list for the greenstone request - includes
    269         // the params from the current request and any others from the saved session
    270         Element xml_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
    271         xml_request.appendChild(xml_param_list);
    272        
    273         Enumeration params = request.getParameterNames();
    274         while(params.hasMoreElements()) {
    275         String name = (String)params.nextElement();
    276         if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT)) {// we have already dealt with these
    277             String value="";
    278             String [] values = request.getParameterValues(name);
    279             value = values[0];
    280             if (values.length > 1) {
    281             for (int i=1; i< values.length; i++) {
    282                 value += ","+values[i];
    283             }
    284             }
    285             // either add it to the param list straight away, or save it to the session and add it later
    286             if (this.params.shouldSave(name)) {         
    287             session.setAttribute(name, value);
    288             } else {
    289             Element param = this.doc.createElement(GSXML.PARAM_ELEM);
    290             param.setAttribute(GSXML.NAME_ATT, name);
    291             param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
    292             xml_param_list.appendChild(param);
    293             }
     337    //  logger.info("should_cache= " + should_cache);
     338    //clear the collection-specific cache in the session, since we have no way to know whether this session is
     339    //about the same collection as the last session or not.
     340    Enumeration attributeNames = session.getAttributeNames();
     341    while(attributeNames.hasMoreElements()) {
     342        String name = (String)attributeNames.nextElement();
     343        if (!name.equals (GSXML.USER_SESSION_CACHE_ATT)
     344                && !name.equals (GSParams.LANGUAGE)
     345                && !name.equals (GSXML.USER_ID_ATT)) {
     346            session.removeAttribute(name);
     347        }
     348    }
     349   
     350    UserSessionCache session_cache = null;
     351    Hashtable param_table = null;   
     352    Hashtable table = null;
     353    String sid = session.getId();
     354    if (should_cache == true && collection != null && !collection.equals("")) {
     355        String key_str = valid_site_name + collection;
     356        if (session_ids_table.containsKey(sid)) {
     357            session_cache = (UserSessionCache)session_ids_table.get(sid);
     358            param_table = session_cache.getParamsTable();
     359            logger.info("collections in table: " + tableToString(param_table));
     360                if (param_table.containsKey(key_str)) {
     361                    //logger.info("existing table: " + collection);
     362                    table = (Hashtable)param_table.get(key_str);
     363                } else {
     364                    table = new Hashtable();
     365                    param_table.put(key_str, table);
     366                    //logger.info("new table: " + collection);
     367                }
     368        } else {
     369            param_table = new Hashtable();
     370            table = new Hashtable();
     371            param_table.put(key_str, table);
     372            session_cache = new UserSessionCache(sid, param_table);
     373            session_ids_table.put(sid, session_cache);
     374            //logger.info("new session id");
     375        }
     376    }
     377
     378    if (action==null || action.equals ("")) {
     379      // should we do all the following stuff if using default page?
     380      // display the home page  - the default page
     381      action = "p";
     382      subaction = PageAction.HOME_PAGE;
     383     
     384      xml_request.setAttribute (GSXML.ACTION_ATT, action);
     385      xml_request.setAttribute (GSXML.SUBACTION_ATT, subaction);
     386     
     387    } else {
     388     
     389      xml_request.setAttribute (GSXML.ACTION_ATT, action);
     390      if (subaction != null) {
     391        xml_request.setAttribute (GSXML.SUBACTION_ATT, subaction);
     392      }
     393     
     394      //  create the param list for the greenstone request - includes
     395      // the params from the current request and any others from the saved session
     396      Element xml_param_list = this.doc.createElement (GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
     397      xml_request.appendChild (xml_param_list);
     398     
     399      Enumeration params = request.getParameterNames ();
     400      while(params.hasMoreElements ()) {
     401        String name = (String)params.nextElement ();
     402        if (!name.equals (GSParams.ACTION)
     403                && !name.equals (GSParams.SUBACTION)
     404                && !name.equals (GSParams.LANGUAGE)
     405                && !name.equals (GSParams.OUTPUT)) {// we have already dealt with these
     406          String value="";
     407          String [] values = request.getParameterValues (name);
     408          value = values[0];
     409          if (values.length > 1) {
     410            for (int i=1; i< values.length; i++) {
     411              value += ","+values[i];
     412            }
     413          }
     414          // either add it to the param list straight away, or save it to the session and add it later
     415          if (this.params.shouldSave (name)) {
     416              if (table != null) {             
     417                  table.put(name, value);                   
     418              }
     419          } else {
     420            Element param = this.doc.createElement (GSXML.PARAM_ELEM);
     421            param.setAttribute (GSXML.NAME_ATT, name);
     422            param.setAttribute (GSXML.VALUE_ATT, GSXML.xmlSafe (value));
     423            xml_param_list.appendChild (param);
     424          }
     425        }
     426      }
     427      //put everything in the table into the session
     428      if (table != null) {
     429          Enumeration keys = table.keys ();
     430          while(keys.hasMoreElements ()) {
     431              String name = (String)keys.nextElement();
     432              session.setAttribute(name, (String)table.get(name));
     433          }
     434      }
     435     
     436      // put in all the params from the session cache
     437      params = session.getAttributeNames ();
     438      while(params.hasMoreElements ()) {
     439        String name = (String)params.nextElement ();
     440       
     441        if ( !name.equals (GSXML.USER_SESSION_CACHE_ATT)
     442                && !name.equals (GSParams.LANGUAGE)
     443                && !name.equals (GSXML.USER_ID_ATT)) {
     444        // lang and uid are stored but we dont want it in the param list cos its already in the request
     445          Element param = this.doc.createElement (GSXML.PARAM_ELEM);
     446          param.setAttribute (GSXML.NAME_ATT, name);
     447          String value =  GSXML.xmlSafe ((String)session.getAttribute (name));
     448          // ugly hack to undo : escaping
     449          value = value.replaceAll ("%3A", "\\:");
     450          param.setAttribute (GSXML.VALUE_ATT,value);
     451          xml_param_list.appendChild (param);
     452        }
     453      }
     454       
     455      //now set the UserSessionCache object into the session with its life expectancy
     456      if (session_cache != null) {
     457          session.setAttribute(GSXML.USER_SESSION_CACHE_ATT, session_cache);
     458          session.setMaxInactiveInterval(session_expiration);
     459      }
     460    }
     461   
     462    if (!output.equals ("html")) {
     463      response.setContentType ("text/xml"); // for now use text
     464    }
     465   
     466    //GSXML.printXMLNode(xml_message);
     467   
     468    Element xml_result = this.recept.process (xml_message);
     469    encodeURLs (xml_result, response);
     470    out.println (this.converter.getPrettyString (xml_result));
     471   
     472    displaySize(session_ids_table);
     473  }
     474  //a debugging method
     475  private void displaySize(Hashtable table) {
     476      if(table == null) {
     477          logger.info("cached table is null");
     478          return;
     479      }
     480      if (table.size() == 0) {
     481          logger.info("cached table size is zero");
     482          return;
     483      }
     484      int num_cached_coll = 0;
     485        ArrayList cache_list = new ArrayList(table.values());
     486        for (int i=0; i<cache_list.size(); i++) {
     487            num_cached_coll += ((UserSessionCache)cache_list.get(i)).tableSize();           
    294488        }
    295         }
    296        
    297         // put in all the params from the session cache
    298         params = session.getAttributeNames();
    299         while(params.hasMoreElements()) {
    300         String name = (String)params.nextElement();
    301        
    302         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
    303            
    304             Element param = this.doc.createElement(GSXML.PARAM_ELEM);
    305             param.setAttribute(GSXML.NAME_ATT, name);
    306             String value =  GSXML.xmlSafe((String)session.getAttribute(name));
    307             // ugly hack to undo : escaping
    308             value = value.replaceAll("%3A", "\\:");
    309             param.setAttribute(GSXML.VALUE_ATT,value);
    310             xml_param_list.appendChild(param);
    311         }
    312         }
    313 
    314    
    315     }
    316    
    317     if (!output.equals("html")) {
    318         response.setContentType("text/xml"); // for now use text
    319     }
    320 
    321     //GSXML.printXMLNode(xml_message); 
    322 
    323     Element xml_result = this.recept.process(xml_message);
    324     encodeURLs(xml_result, response);
    325     out.println(this.converter.getPrettyString(xml_result));
    326     }
    327 
    328     /** this goes through each URL and adds in a session id if needed--
    329      * its needed if the browser doesn't accept cookies
    330      * also escapes things if needed
    331      */
    332     protected void encodeURLs(Element data, HttpServletResponse response) {
    333    
    334     if (data == null) {
    335         return;
    336     }
    337     // get all the <a> elements
    338     NodeList hrefs = data.getElementsByTagName("a");
    339     for (int i=0; i<hrefs.getLength(); i++) {
    340         Element a = (Element)hrefs.item(i);
    341         // ugly hack to get rid of : in the args - interferes with session handling
    342         String href = a.getAttribute("href");
    343         if (!href.equals("")) {
    344         if (href.indexOf("?")!=-1) {
    345             String[] parts = href.split("\\?", -1);
    346             parts[1]=parts[1].replaceAll(":", "%3A");
    347             href = parts[0]+"?"+parts[1];
    348         }
    349         a.setAttribute("href", response.encodeURL(href));
    350         }
    351     }
    352    
    353     // now find any submit bits - get all the <form> elements
    354     NodeList forms = data.getElementsByTagName("form");
    355     for (int i=0; i<forms.getLength(); i++) {
    356         Element form = (Element)forms.item(i);
    357         form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
    358     }
    359     // are these the only cases where URLs occur??
    360     // we should only do this for greenstone urls?
    361    
    362     }
    363 
    364     synchronized protected int getNextUserId() {
    365     next_user_id++;
    366     return next_user_id;
    367     }
    368 
    369     public void doPost(HttpServletRequest request,
    370               HttpServletResponse response)
    371     throws ServletException, IOException {
    372     doGet(request,response);
    373 
    374     }
     489      logger.info("Number of sessions : total number of cached collection info = " + table.size() + " : " + num_cached_coll);
     490  } 
     491  /** merely a debugging method! */
     492  private String tableToString(Hashtable table) {
     493     String str = "";
     494     Enumeration keys = table.keys ();
     495     while(keys.hasMoreElements ()) {
     496      String name = (String)keys.nextElement();
     497      str += name + ", ";
     498     }
     499     return str;
     500  }
     501
     502  /** this goes through each URL and adds in a session id if needed--
     503   * its needed if the browser doesn't accept cookies
     504   * also escapes things if needed
     505   */
     506  protected void encodeURLs(Element data, HttpServletResponse response) {
     507   
     508    if (data == null) {
     509      return;
     510    }
     511    // get all the <a> elements
     512    NodeList hrefs = data.getElementsByTagName("a");
     513    for (int i=0; i<hrefs.getLength(); i++) {
     514      Element a = (Element)hrefs.item(i);
     515      // ugly hack to get rid of : in the args - interferes with session handling
     516      String href = a.getAttribute("href");
     517      if (!href.equals("")) {
     518        if (href.indexOf("?")!=-1) {
     519          String[] parts = href.split("\\?", -1);
     520          parts[1]=parts[1].replaceAll(":", "%3A");
     521          href = parts[0]+"?"+parts[1];
     522        }
     523        a.setAttribute("href", response.encodeURL(href));
     524      }
     525    }
     526   
     527    // now find any submit bits - get all the <form> elements
     528    NodeList forms = data.getElementsByTagName("form");
     529    for (int i=0; i<forms.getLength(); i++) {
     530      Element form = (Element)forms.item(i);
     531      form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
     532    }
     533    // are these the only cases where URLs occur??
     534    // we should only do this for greenstone urls?
     535   
     536  }
     537 
     538  synchronized protected int getNextUserId() {
     539    next_user_id++;
     540    return next_user_id;
     541  }
     542 
     543  public void doPost(HttpServletRequest request,
     544    HttpServletResponse response)
     545    throws ServletException, IOException {
     546    doGet(request,response);
     547   
     548  }
    375549}
Note: See TracChangeset for help on using the changeset viewer.