Changeset 33705


Ignore:
Timestamp:
2019-11-19T14:08:06+13:00 (4 years ago)
Author:
kjdon
Message:

reindented the file, no code changes

File:
1 edited

Legend:

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

    r33700 r33705  
    9090  protected static final String LOGIN_MESSAGE_PARAM = "loginMessage";
    9191  protected static final String REDIRECT_URL_PARAM = "redirectURL";
    92     /** the receptionist to send messages to */
    93     protected Receptionist recept = null;
     92  /** the receptionist to send messages to */
     93  protected Receptionist recept = null;
    9494
    9595  /** We record the library name for later */
    9696  protected String library_name = null;
    97     /** Whether or not client-side XSLT support should be exposed */
    98     protected boolean supports_client_xslt = false;
    99 
    100     /**
    101      * the default language - is specified by setting a servlet param, otherwise
    102      * DEFAULT_LANG is used
    103      */
    104     protected String default_lang = null;
    105     /**
    106      * The default default - used if a default lang is not specified in the
    107      * servlet params
    108      */
    109     protected final String DEFAULT_LANG = "en";
    110 
    111     /**
    112      * the cgi stuff - the Receptionist can add new args to this
    113      *
    114      * its used by the servlet to determine what args to save,
    115      * and to set default values
    116      */
    117     protected GSParams gs_params = null;
    118 
    119     /**
    120      * a hash that contains all the active session IDs mapped to the cached
    121      * items It is updated whenever the whole site or a particular collection is
    122      * reconfigured using the command a=s&sa=c or a=s&sa=c&c=xxx It is in the
    123      * form: sid -> (UserSessionCache object)
    124      */
    125     protected Hashtable<String, UserSessionCache> session_ids_table = new Hashtable<String, UserSessionCache>();
    126 
    127     /**
    128      * the maximum interval that the cached info remains in session_ids_table
    129      * (in seconds) This is set in web.xml
    130      */
    131     protected int session_expiration = 1800;
    132 
    133     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
    134 
    135     /** initialise the servlet */
    136     public void init(ServletConfig config) throws ServletException
     97  /** Whether or not client-side XSLT support should be exposed */
     98  protected boolean supports_client_xslt = false;
     99
     100  /**
     101   * the default language - is specified by setting a servlet param, otherwise
     102   * DEFAULT_LANG is used
     103   */
     104  protected String default_lang = null;
     105  /**
     106   * The default default - used if a default lang is not specified in the
     107   * servlet params
     108   */
     109  protected final String DEFAULT_LANG = "en";
     110
     111  /**
     112   * the cgi stuff - the Receptionist can add new args to this
     113   *
     114   * its used by the servlet to determine what args to save,
     115   * and to set default values
     116   */
     117  protected GSParams gs_params = null;
     118
     119  /**
     120   * a hash that contains all the active session IDs mapped to the cached
     121   * items It is updated whenever the whole site or a particular collection is
     122   * reconfigured using the command a=s&sa=c or a=s&sa=c&c=xxx It is in the
     123   * form: sid -> (UserSessionCache object)
     124   */
     125  protected Hashtable<String, UserSessionCache> session_ids_table = new Hashtable<String, UserSessionCache>();
     126
     127  /**
     128   * the maximum interval that the cached info remains in session_ids_table
     129   * (in seconds) This is set in web.xml
     130   */
     131  protected int session_expiration = 1800;
     132
     133  static Logger logger = Logger.getLogger(org.greenstone.gsdl3.LibraryServlet.class.getName());
     134
     135  /** initialise the servlet */
     136  public void init(ServletConfig config) throws ServletException
     137  {
     138    // always call super.init;
     139    super.init(config);
     140    // disable preferences - does this work anyway??
     141    //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
     142
     143    // Look through all the init params
     144    // these are the ones we are expecting
     145    String interface_name = null;
     146    String useXslt = null;
     147    String sess_expire = null;
     148    String site_name = null;
     149    String recept_name = null;
     150
     151    // may have these instead of site_name
     152    String remote_site_name = null;
     153    String remote_site_type = null;
     154    String remote_site_address = null;
     155
     156    // the stored config params
     157    HashMap<String, Object> config_params = new HashMap<String, Object>();
     158    Enumeration<String> params = config.getInitParameterNames();
     159    while (params.hasMoreElements()) {
     160      String name = params.nextElement();
     161      String value = config.getInitParameter(name);
     162      if (name.equals(GSConstants.LIBRARY_NAME)) {
     163    library_name = value;
     164      } else if (name.equals(GSConstants.INTERFACE_NAME)) {
     165    interface_name = value;
     166      } else if (name.equals(GSConstants.USE_CLIENT_SIDE_XSLT)) {
     167    useXslt = value;
     168      } else if (name.equals(GSConstants.DEFAULT_LANG)) {
     169    this.default_lang = value;
     170      } else if (name.equals(GSXML.SESSION_EXPIRATION)) {
     171    sess_expire = value;
     172      } else if (name.equals(GSConstants.SITE_NAME)) {
     173    site_name = value;
     174      } else if (name.equals(GSConstants.REMOTE_SITE_NAME)) {
     175    remote_site_name = value;
     176      } else if (name.equals(GSConstants.REMOTE_SITE_TYPE)) {
     177    remote_site_type = value;
     178      } else if (name.equals(GSConstants.REMOTE_SITE_ADDRESS)) {
     179    remote_site_address = value;
     180      } else if (name.equals(GSConstants.RECEPTIONIST_CLASS)) {
     181    recept_name = value;
     182      } else {
     183    // If there is a param we are not expecting, just add to the list. That way users can add new servlet params which will go through to the XML source without modifying code.
     184    config_params.put(name, value);
     185      }
     186    }
     187    if (library_name == null || interface_name == null) {
     188         
     189      // must have these
     190      System.err.println("initialisation parameters not all set!");
     191      System.err.println(" you must have libraryname and interfacename");
     192      System.exit(1);
     193    }
     194
     195    // If we don't have a site, then we must be using a Communicator, and all the remote params must be set
     196    if (site_name == null && (remote_site_name == null || remote_site_type == null || remote_site_address == null)) {
     197         
     198      System.err.println("initialisation paramters not all set!");
     199      System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
     200      System.exit(1);
     201    }
     202       
     203    supports_client_xslt = useXslt != null && useXslt.equals("true");
     204    if (sess_expire != null && !sess_expire.equals(""))
     205      {
     206    this.session_expiration = Integer.parseInt(sess_expire);
     207      }
     208    if (this.default_lang == null)
     209      {
     210    // choose english
     211    this.default_lang = DEFAULT_LANG;
     212      }
     213
     214    config_params.put(GSConstants.LIBRARY_NAME, library_name);
     215    config_params.put(GSConstants.INTERFACE_NAME, interface_name);
     216    config_params.put(GSConstants.USE_CLIENT_SIDE_XSLT, supports_client_xslt);
     217
     218    if (site_name != null)
     219      {
     220    config_params.put(GSConstants.SITE_NAME, site_name);
     221      }
     222
     223    // the receptionist -the servlet will talk to this
     224    if (recept_name == null)
     225      {
     226    this.recept = new DefaultReceptionist();
     227      }
     228    else
     229      {
     230    try
     231      {
     232        this.recept = (Receptionist) Class.forName("org.greenstone.gsdl3.core." + recept_name).newInstance();
     233      }
     234    catch (Exception e)
     235      { // cant use this new one, so use normal one
     236        System.err.println("LibraryServlet configure exception when trying to use a new Receptionist " + recept_name + ": " + e.getMessage());
     237        e.printStackTrace();
     238        this.recept = new DefaultReceptionist();
     239      }
     240      }
     241    this.recept.setConfigParams(config_params);
     242
     243    // the params arg thingy
     244
     245    String params_name = (String) config.getInitParameter("params_class");
     246    if (params_name == null)
     247      {
     248    this.gs_params = new GSParams();
     249      }
     250    else
     251      {
     252    try
     253      {
     254        this.gs_params = (GSParams) Class.forName("org.greenstone.gsdl3.util." + params_name).newInstance();
     255      }
     256    catch (Exception e)
     257      {
     258        System.err.println("LibraryServlet configure exception when trying to use a new params thing " + params_name + ": " + e.getMessage());
     259        e.printStackTrace();
     260        this.gs_params = new GSParams();
     261      }
     262      }
     263       
     264    // 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 the Receptionist, and the servlet never talks to it again directly.
     265    if (site_name != null)
     266      {
     267    String mr_name = (String) config.getInitParameter("messagerouter_class");
     268    MessageRouter message_router = null;
     269    if (mr_name == null)
     270      { // just use the normal MR
     271        message_router = new MessageRouter();
     272      }
     273    else
     274      { // try the specified one
     275        try
     276          {
     277        message_router = (MessageRouter) Class.forName("org.greenstone.gsdl3.core." + mr_name).newInstance();
     278          }
     279        catch (Exception e)
     280          { // cant use this new one, so use normal one
     281        System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter " + mr_name + ": " + e.getMessage());
     282        e.printStackTrace();
     283        message_router = new MessageRouter();
     284          }
     285      }
     286
     287    message_router.setSiteName(site_name);
     288    message_router.setLibraryName(library_name);
     289    message_router.setParams(this.gs_params);
     290    message_router.configure();
     291    this.recept.setMessageRouter(message_router);
     292      }
     293    else
     294      {
     295    // TODO: what do we do about params here?
     296    // talking to a remote site, create a communicator
     297    Communicator communicator = null;
     298    // we need to create the XML to configure the communicator
     299    Document doc = XMLConverter.newDOM();
     300    Element site_elem = doc.createElement(GSXML.SITE_ELEM);
     301    site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
     302    site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
     303    site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
     304
     305    if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
     306      {
     307        communicator = new SOAPCommunicator();
     308      }
     309    else
     310      {
     311        System.err.println("LibraryServlet.init Error: invalid Communicator type: " + remote_site_type);
     312        System.exit(1);
     313      }
     314
     315    if (!communicator.configure(site_elem))
     316      {
     317        System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
     318        System.exit(1);
     319      }
     320    this.recept.setMessageRouter(communicator);
     321      }
     322
     323    // pass params to the receptionist
     324    this.recept.setParams(this.gs_params);
     325    this.recept.configure();
     326
     327    //Allow the message router and the document to be accessed from anywhere in this servlet context
     328    this.getServletContext().setAttribute(library_name+"Router", this.recept.getMessageRouter());
     329  }
     330
     331  private void logUsageInfo(HttpServletRequest request, Map<String, String[]> queryMap)
     332  {
     333    String usageInfo = "";
     334
     335    //session-info: get params stored in the session
     336    HttpSession session = request.getSession(true);
     337    Enumeration attributeNames = session.getAttributeNames();
     338    while (attributeNames.hasMoreElements())
     339      {
     340    String name = (String) attributeNames.nextElement();
     341    usageInfo += name + "=" + session.getAttribute(name) + " ";
     342      }
     343
     344    String queryParamStr = "";
     345    if (queryMap != null)
     346      {
     347    Iterator<String> queryIter = queryMap.keySet().iterator();
     348    while (queryIter.hasNext()) {
     349      String q = queryIter.next();
     350      String[] vals = queryMap.get(q);
     351      queryParamStr += q +"="+StringUtils.join(vals, ",")+" ";
     352    }
     353      }
     354    //logged info = general-info + session-info
     355    usageInfo = request.getServletPath() + " " + //serlvet
     356      "[" + queryParamStr.trim()+"]"+" " + // query map params
     357      "session:[" + usageInfo.trim() + "]" + " " + // params stored in a session
     358      request.getRemoteAddr() + " " + //remote address
     359      request.getRequestedSessionId() + " " + //session id
     360      request.getHeader("user-agent") + " "; //the remote brower info
     361
     362    logger.info(usageInfo);
     363
     364  }
     365
     366  public class UserSessionCache implements HttpSessionBindingListener
     367  {
     368    String session_id = "";
     369
     370    /**
     371     * a hash that maps the session ID to a hashtable that maps the
     372     * coll_name to its parameters coll_name -> Hashtable (param_name ->
     373     * param_value)
     374     */
     375    protected Hashtable<String, Hashtable<String, String>> coll_name_params_table = null;
     376
     377    public UserSessionCache(String id, Hashtable<String, Hashtable<String, String>> table)
     378    {
     379      session_id = id;
     380      coll_name_params_table = (table == null) ? new Hashtable() : table;
     381    }
     382
     383    protected void cleanupCache(String coll_name)
     384    {
     385      if (coll_name_params_table.containsKey(coll_name))
    137386    {
    138         // always call super.init;
    139         super.init(config);
    140         // disable preferences - does this work anyway??
    141         //System.setProperty("java.util.prefs.PreferencesFactory", "org.greenstone.gsdl3.util.DisabledPreferencesFactory");
    142 
    143         // Look through all the init params
    144         // these are the ones we are expecting
    145         String interface_name = null;
    146         String useXslt = null;
    147         String sess_expire = null;
    148         String site_name = null;
    149         String recept_name = null;
    150 
    151         // may have these instead of site_name
    152         String remote_site_name = null;
    153         String remote_site_type = null;
    154         String remote_site_address = null;
    155 
    156         // the stored config params
    157         HashMap<String, Object> config_params = new HashMap<String, Object>();
    158         Enumeration<String> params = config.getInitParameterNames();
    159         while (params.hasMoreElements()) {
    160           String name = params.nextElement();
    161           String value = config.getInitParameter(name);
    162           if (name.equals(GSConstants.LIBRARY_NAME)) {
    163             library_name = value;
    164           } else if (name.equals(GSConstants.INTERFACE_NAME)) {
    165             interface_name = value;
    166           } else if (name.equals(GSConstants.USE_CLIENT_SIDE_XSLT)) {
    167             useXslt = value;
    168           } else if (name.equals(GSConstants.DEFAULT_LANG)) {
    169             this.default_lang = value;
    170           } else if (name.equals(GSXML.SESSION_EXPIRATION)) {
    171             sess_expire = value;
    172           } else if (name.equals(GSConstants.SITE_NAME)) {
    173             site_name = value;
    174           } else if (name.equals(GSConstants.REMOTE_SITE_NAME)) {
    175             remote_site_name = value;
    176           } else if (name.equals(GSConstants.REMOTE_SITE_TYPE)) {
    177             remote_site_type = value;
    178           } else if (name.equals(GSConstants.REMOTE_SITE_ADDRESS)) {
    179             remote_site_address = value;
    180           } else if (name.equals(GSConstants.RECEPTIONIST_CLASS)) {
    181             recept_name = value;
    182           } else {
    183             // If there is a param we are not expecting, just add to the list. That way users can add new servlet params which will go through to the XML source without modifying code.
    184             config_params.put(name, value);
     387      coll_name_params_table.remove(coll_name);
     388    }
     389    }
     390
     391    protected Hashtable<String, Hashtable<String, String>> getParamsTable()
     392    {
     393      return coll_name_params_table;
     394    }
     395
     396    public void valueBound(HttpSessionBindingEvent event)
     397    {
     398      // Do nothing
     399    }
     400
     401    // if session cache id removed from session, this triggers this valueUnbound method on the value=this object
     402    public void valueUnbound(HttpSessionBindingEvent event)
     403    {
     404      if (session_ids_table.containsKey(session_id))
     405    {
     406      session_ids_table.remove(session_id);
     407    }
     408    }
     409
     410    public int tableSize()
     411    {
     412      return (coll_name_params_table == null) ? 0 : coll_name_params_table.size();
     413    }
     414  }
     415
     416  public void destroy()
     417  {
     418    recept.cleanUp();
     419  }
     420
     421  public void doGetOrPost(HttpServletRequest request, HttpServletResponse response, Map<String, String[]> queryMap) throws ServletException, IOException
     422  {
     423    logUsageInfo(request, queryMap);
     424
     425    if (queryMap != null)
     426      {
     427    Iterator<String> queryIter = queryMap.keySet().iterator();
     428    boolean redirect = false;
     429    String href = null;
     430    String rl = null;
     431    String el = null;
     432
     433    while (queryIter.hasNext())
     434      {
     435        String q = queryIter.next();
     436        if (q.equals(GSParams.EXTERNAL_LINK_TYPE))
     437          {
     438        el = queryMap.get(q)[0];
     439          }
     440        else if (q.equals(GSParams.HREF))
     441          {
     442        href = queryMap.get(q)[0];
     443        href = StringUtils.replace(href, "%2f", "/");
     444        href = StringUtils.replace(href, "%7e", "~");
     445        href = StringUtils.replace(href, "%3f", "?");
     446        href = StringUtils.replace(href, "%3A", "\\:");
     447          }
     448        else if (q.equals(GSParams.RELATIVE_LINK))
     449          {
     450        rl = queryMap.get(q)[0];
     451          }
     452      }
     453
     454    //if query_string contains "el=direct", an href is specified, and its not a relative link, then the web page will be redirected to the external URl, otherwise a greenstone page with an external URL will be displayed
     455    //"rl=0" this is an external link
     456    //"rl=1" this is an internal link
     457    if ((href != null) && (rl.equals("0")))
     458      {// This is an external link,
     459
     460        if (el.equals("framed"))
     461          {
     462        //TODO **** how best to change to a=p&sa=html&c=collection&url=href
     463        // response.setContentType("text/xml");
     464        //response.sendRedirect("http://localhost:8383/greenstone3/gs3library?a=p&sa=html&c=external&url="+href);
     465          }
     466        else
     467          {
     468        // el = '' or direct
     469        //the web page is re-directed to the external URL (&el=&rl=0&href="http://...")
     470        response.setContentType("text/xml");
     471        response.sendRedirect(href);
     472          }
     473      }
     474      }
     475
     476    // Nested Diagnostic Configurator to identify the client for
     477    HttpSession session = request.getSession(true);
     478    session.setMaxInactiveInterval(session_expiration);
     479    String uid = session.getId();
     480    request.setCharacterEncoding("UTF-8");
     481    response.setContentType("text/html;charset=UTF-8");
     482    PrintWriter out = response.getWriter();
     483
     484    String lang = getFirstParam(GSParams.LANGUAGE, queryMap);
     485    if (lang == null || lang.equals(""))
     486      {
     487    // try the session cached lang
     488    lang = (String) session.getAttribute(GSParams.LANGUAGE);
     489    if (lang == null || lang.equals(""))
     490      {
     491        // still not set, use the default
     492        lang = this.default_lang;
     493      }
     494      }
     495    UserContext userContext = new UserContext();
     496    userContext.setLanguage(lang);
     497    userContext.setUserID(uid);
     498    logger.error("LS new user context");
     499    if (request.getAuthType() != null)
     500      {
     501    //Get the username
     502    userContext.setUsername(request.getUserPrincipal().getName());
     503    logger.error("setting username = "+request.getUserPrincipal().getName());
     504    //Get the groups for the user
     505    Document msg_doc = XMLConverter.newDOM();
     506    Element acquireGroupMessage = msg_doc.createElement(GSXML.MESSAGE_ELEM);
     507    Element acquireGroupRequest = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_PROCESS, "GetUserInformation", userContext);
     508    acquireGroupMessage.appendChild(acquireGroupRequest);
     509
     510    Element paramList = msg_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     511    acquireGroupRequest.appendChild(paramList);
     512    paramList.appendChild(GSXML.createParameter(msg_doc, GSXML.USERNAME_ATT, request.getUserPrincipal().getName()));
     513
     514    Element aquireGroupsResponseMessage = (Element) this.recept.process(acquireGroupMessage);
     515    Element aquireGroupsResponse = (Element) GSXML.getChildByTagName(aquireGroupsResponseMessage, GSXML.RESPONSE_ELEM);
     516    Element param_list = (Element) GSXML.getChildByTagName(aquireGroupsResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     517
     518    if (param_list != null)
     519      {
     520        HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
     521        String groups = (String) params.get("groups");
     522        userContext.setGroups(groups.split(","));
     523      }
     524      }
     525
     526    // set the lang in the session
     527    session.setAttribute(GSParams.LANGUAGE, lang);
     528
     529    String output = getFirstParam(GSParams.OUTPUT, queryMap);
     530    if (output == null || output.equals(""))
     531      {
     532    output = "html"; // uses html by default
     533      }
     534
     535    // If server output, force a switch to traditional interface
     536    //output = (output.equals("server")) ? "html" : output;
     537
     538    // Force change the output mode if client-side XSLT is supported - server vs. client
     539    // BUT only if the library allows client-side transforms   
     540    if (supports_client_xslt)
     541      {
     542    // MUST be done before the xml_message is built
     543    Cookie[] cookies = request.getCookies();
     544    Cookie xsltCookie = null;
     545
     546    // The client has cookies enabled and a value set - use it!
     547    if (cookies != null)
     548      {
     549        for (Cookie c : cookies)
     550          {
     551        if (c.getName().equals("supportsXSLT"))
     552          {
     553            xsltCookie = c;
     554            break;
    185555          }
     556          }
     557        output = (xsltCookie != null && xsltCookie.getValue().equals("true") && output.equals("html")) ? "xsltclient" : output;
     558      }
     559      }
     560
     561    // the request to the receptionist
     562    Document msg_doc = XMLConverter.newDOM();
     563    Element xml_message = msg_doc.createElement(GSXML.MESSAGE_ELEM);
     564    Element xml_request = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
     565    xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
     566
     567    xml_message.appendChild(xml_request);
     568
     569    String action = getFirstParam(GSParams.ACTION, queryMap);
     570    String subaction = getFirstParam(GSParams.SUBACTION, queryMap);
     571    String collection = getFirstParam(GSParams.COLLECTION, queryMap);
     572    String document = getFirstParam(GSParams.DOCUMENT, queryMap);
     573    String service = getFirstParam(GSParams.SERVICE, queryMap);
     574    String specified_cache_key = getFirstParam(GSParams.CACHE_KEY, queryMap);
     575
     576    // We clean up the cache session_ids_table if system
     577    // commands are issued, and also don't need to do caching for these request requests
     578    boolean should_cache = true;
     579    if (action != null && action.equals(GSParams.SYSTEM_ACTION)
     580    && !subaction.equals(GSXML.SYSTEM_TYPE_PING)
     581    && !subaction.equals(GSXML.SYSTEM_TYPE_AUTHENTICATED_PING)) // don't 'clean' anything on a mere ping
     582      {
     583    should_cache = false;
     584
     585    // we may want to remove all collection cache info, or just a specific collection
     586    boolean clean_all = true;
     587    String clean_collection = null;
     588    // system commands are to activate/deactivate stuff
     589    // collection param is in the sc parameter.
     590    // don't like the fact that it is hard coded here
     591    String coll = getFirstParam(GSParams.SYSTEM_CLUSTER, queryMap);
     592    if (coll != null && !coll.equals(""))
     593      {
     594        clean_all = false;
     595        clean_collection = coll;
     596      }
     597    else
     598      {
     599        // check other system types
     600        if (subaction.equals("a") || subaction.equals("d"))
     601          {
     602        String module_name = getFirstParam("sn", queryMap);
     603        if (module_name != null && !module_name.equals(""))
     604          {
     605            clean_all = false;
     606            clean_collection = module_name;
     607          }
     608          }
     609      }
     610    if (clean_all)
     611      {
     612        // TODO
     613        session_ids_table = new Hashtable<String, UserSessionCache>();
     614        session.removeAttribute(GSParams.USER_SESSION_CACHE); // triggers valueUnbound(), which removes the session id from the session_ids_table
     615      }
     616    else
     617      {
     618        // just clean up info for clean_collection
     619        ArrayList<UserSessionCache> cache_list = new ArrayList<UserSessionCache>(session_ids_table.values());
     620        for (int i = 0; i < cache_list.size(); i++)
     621          {
     622        UserSessionCache cache = cache_list.get(i);
     623        cache.cleanupCache(clean_collection);
     624          }
     625
     626      }
     627      }
     628
     629    // cache_key is the collection name, or service name
     630    String cache_key = specified_cache_key;
     631    if (cache_key == null || cache_key.equals(""))
     632      {
     633    cache_key = collection;
     634      }
     635    if (cache_key == null || cache_key.equals(""))
     636      {
     637    cache_key = service;
     638      }
     639       
     640    //clear the collection-specific cache in the session, since we have no way to know whether this page is
     641    //about the same collection as the last page or not.
     642    Enumeration attributeNames = session.getAttributeNames();
     643    while (attributeNames.hasMoreElements())
     644      {
     645    String name = (String) attributeNames.nextElement();
     646    if (!name.equals(GSParams.USER_SESSION_CACHE) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT) && !this.gs_params.isGlobal(name))
     647      {
     648        session.removeAttribute(name);
     649      }
     650      }
     651
     652    UserSessionCache session_cache = null;
     653    Hashtable<String, Hashtable<String, String>> param_table = null;
     654    Hashtable<String, String> table = null;
     655    boolean new_table = false;
     656    String sid = session.getId();
     657    boolean new_session = false;
     658    if (!session_ids_table.containsKey(sid)) {
     659      new_session = true;
     660    }
     661    if (should_cache == true && cache_key != null && !cache_key.equals(""))
     662      {
     663    if (!new_session)
     664      {
     665        session_cache = session_ids_table.get(sid);
     666        param_table = session_cache.getParamsTable();
     667        if (param_table.containsKey(cache_key))
     668          {
     669        table = param_table.get(cache_key);
     670          }
     671        else
     672          {
     673        table = new Hashtable<String, String>();
     674        param_table.put(cache_key, table);
     675        new_table = true;
     676          }
     677      }
     678    else
     679      {
     680             
     681        param_table = new Hashtable<String, Hashtable<String, String>>();
     682        table = new Hashtable<String, String>();
     683        param_table.put(cache_key, table);
     684        session_cache = new UserSessionCache(sid, param_table);
     685        session_ids_table.put(sid, session_cache);
     686        session.setAttribute(GSParams.USER_SESSION_CACHE, session_cache);
     687        new_table = true;
     688      }
     689
     690      }
     691       
     692    // here we add in default params values if need be - if we have a new session, or if we have a new table
     693    // in an existing session
     694    // don't override any existing values
     695    if (new_session || new_table) {
     696
     697      Iterator i = this.gs_params.getParamsWithDefaults().iterator();
     698      while (i.hasNext()) {
     699    String p = (String)i.next();
     700    String v = this.gs_params.getParamDefault(p);
     701    if (this.gs_params.isGlobal(p)) {
     702      //need to add in to session unless its already there
     703      if (session.getAttribute(p) == null) {
     704        session.setAttribute(p, v);
     705      }
     706    } else {
     707      // add to table unless its already there
     708      if (new_table && !table.containsKey(p)) {
     709        table.put(p,v);
     710      }
     711    }
     712           
     713      }
     714    }
     715
     716    if (action == null || action.equals(""))
     717      {
     718    // display the home page  - the default page
     719    xml_request.setAttribute(GSXML.ACTION_ATT, "p");
     720    xml_request.setAttribute(GSXML.SUBACTION_ATT, PageAction.HOME_PAGE);
     721      }
     722    else
     723      {
     724    xml_request.setAttribute(GSXML.ACTION_ATT, action);
     725    if (subaction != null)
     726      {
     727        xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
     728      }
     729      }
     730       
     731    //  create the param list for the greenstone request - includes
     732    // the params from the current request and any others from the saved session
     733    Element xml_param_list = msg_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     734    xml_request.appendChild(xml_param_list);
     735           
     736    if (queryMap.containsKey("s1.collection") || queryMap.containsKey("s1.group")){
     737      table.remove("s1.collection");
     738      table.remove("s1.group");
     739    }
     740    for (String name : queryMap.keySet())
     741      {
     742    if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT))
     743      {// we have already dealt with these
     744
     745        String value = "";
     746        String[] values = queryMap.get(name);
     747        value = values[0];
     748        if (values.length > 1)
     749          {
     750        for (int i = 1; i < values.length; i++)
     751          {
     752            value += "," + values[i];
     753          }
     754          }
     755        // if we need to save the value, then add it to the session/cache table.
     756        // otherwise add directly to the paramList
     757        if (this.gs_params.shouldSave(name)) {
     758          if (this.gs_params.isGlobal(name) || table == null) {
     759        session.setAttribute(name, value);
     760          } else {
     761        table.put(name, value);
     762          }
     763        }
     764        else
     765          {
     766        Element param = msg_doc.createElement(GSXML.PARAM_ELEM);
     767        param.setAttribute(GSXML.NAME_ATT, name);
     768        param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
     769        if (this.gs_params.isSensitive(name)) {
     770          param.setAttribute(GSXML.SENSITIVE_ATT, "true");
    186771        }
    187         if (library_name == null || interface_name == null) {
    188          
    189           // must have these
    190           System.err.println("initialisation parameters not all set!");
    191           System.err.println(" you must have libraryname and interfacename");
    192           System.exit(1);
     772        xml_param_list.appendChild(param);
     773                       
     774          }
     775      }
     776      }
     777    //put everything in the table into the session
     778    if (table != null)
     779      {
     780    Enumeration<String> keys = table.keys();
     781    while (keys.hasMoreElements())
     782      {
     783        String name = keys.nextElement();
     784        session.setAttribute(name, table.get(name));
     785      }
     786      }
     787
     788    // put in all the params from the session cache
     789    Enumeration params = session.getAttributeNames();
     790    while (params.hasMoreElements())
     791      {
     792    String name = (String) params.nextElement();
     793    if (!name.equals(GSParams.USER_SESSION_CACHE) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
     794      {
     795
     796        // lang and uid are stored but we dont want it in the param list cos its already in the request
     797        Element param = msg_doc.createElement(GSXML.PARAM_ELEM);
     798        param.setAttribute(GSXML.NAME_ATT, name);
     799        String value = GSXML.xmlSafe((String) session.getAttribute(name));
     800
     801        // ugly hack to undo : escaping
     802        value = StringUtils.replace(value, "%3A", "\\:");
     803        param.setAttribute(GSXML.VALUE_ATT, value);
     804        xml_param_list.appendChild(param);
     805      }
     806      }
     807   
     808
     809    if (output.equals("json"))
     810      {
     811    response.setContentType("application/json");
     812      }
     813    else if (!output.equals("html") && !output.equals("server") && !output.equals("xsltclient"))
     814      {
     815    response.setContentType("text/xml"); // for now use text
     816      }
     817
     818    //Add custom HTTP headers if requested
     819    String httpHeadersParam = getFirstParam(GSParams.HTTP_HEADER_FIELDS, queryMap);
     820    if (httpHeadersParam != null && httpHeadersParam.length() > 0)
     821      {
     822    Gson gson = new Gson();
     823    Type type = new TypeToken<List<Map<String, String>>>()
     824            {
     825      }.getType();
     826    List<Map<String, String>> httpHeaders = gson.fromJson(httpHeadersParam, type);
     827    if (httpHeaders != null && httpHeaders.size() > 0)
     828      {
     829
     830        for (int j = 0; j < httpHeaders.size(); j++)
     831          {
     832        Map nameValueMap = httpHeaders.get(j);
     833        String name = (String) nameValueMap.get("name");
     834        String value = (String) nameValueMap.get("value");
     835
     836        if (name != null && value != null)
     837          {
     838            response.setHeader(name, value);
     839          }
     840          }
     841      }
     842      }
     843
     844    String requestedURL = request.getRequestURL().toString();
     845    String baseURL = "";
     846    if (requestedURL.indexOf(library_name) != -1)
     847      {
     848    baseURL = requestedURL.substring(0, requestedURL.indexOf(library_name));
     849    xml_request.setAttribute("baseURL", baseURL);
     850      }
     851    String fullURL;
     852    if (request.getQueryString() != null)
     853      {
     854    fullURL = requestedURL + "?" + request.getQueryString();
     855      }
     856    else
     857      {
     858    fullURL = requestedURL;
     859      }
     860
     861    xml_request.setAttribute("remoteAddress", request.getRemoteAddr());
     862    xml_request.setAttribute("fullURL", fullURL.replace("&", "&amp;"));
     863
     864    if (!runSecurityChecks(request, xml_request, userContext, out, baseURL, collection, document, queryMap, lang))
     865      {
     866    return;
     867      }
     868
     869    logger.error("about to process this message");
     870    logger.error(XMLConverter.getPrettyString(xml_message));
     871    Node xml_result = this.recept.process(xml_message);
     872    encodeURLs(xml_result, response);
     873
     874    String xml_string = XMLConverter.getPrettyString(xml_result);
     875       
     876    if (output.equals("json"))
     877      {
     878    try
     879      {
     880        JSONObject json_obj = org.json.XML.toJSONObject(xml_string);
     881
     882        out.println(json_obj.toString());
     883      }
     884    catch (Exception e)
     885      {
     886        e.printStackTrace();
     887        out.println("Error: failed to convert output XML to JSON format");
     888      }
     889      }
     890    else
     891      {
     892    out.println(xml_string);
     893      }
     894
     895    displaySize(session_ids_table);
     896  }
     897
     898  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
     899  {
     900    doGetOrPost(request, response, request.getParameterMap());
     901  } //end of doGet(HttpServletRequest, HttpServletResponse)
     902
     903  private boolean runSecurityChecks(HttpServletRequest request, Element xml_request, UserContext userContext, PrintWriter out, String baseURL, String collection, String document, Map<String, String[]> queryMap, String lang) throws ServletException
     904  {
     905    logger.error("kk in run security");
     906    //Check if we need to login or logout
     907    String username = getFirstParam(GSParams.USERNAME, queryMap);
     908    String password = getFirstParam(GSParams.PASSWORD, queryMap);
     909    String logout = getFirstParam(GSParams.LOGOUT, queryMap);
     910
     911    if (logout != null)
     912      {
     913    request.logout();
     914      }
     915
     916    if (username != null && password != null)
     917      {
     918    logger.error("kk u&p not null");
     919    //We are changing to another user, so log out first
     920    if (request.getAuthType() != null)
     921      {
     922        request.logout();
     923      }
     924
     925    //This try/catch block catches when the login request fails (e.g. The user enters an incorrect password).
     926    try
     927      {
     928        //Try a global login first
     929        password = Authentication.hashPassword(password);
     930        request.login(username, password);
     931      }
     932    catch (Exception ex)
     933      {
     934        try
     935          {
     936        //If the global login fails then try a site-level login
     937        String siteName = (String) this.recept.getConfigParams().get(GSConstants.SITE_NAME);
     938        request.login(siteName + "-" + username, password);
     939          }
     940        catch (Exception exc)
     941          {
     942        //The user entered in either the wrong username or the wrong password
     943        Document loginPageDoc = XMLConverter.newDOM();
     944        Element loginPageMessage = loginPageDoc.createElement(GSXML.MESSAGE_ELEM);
     945        Element loginPageRequest = GSXML.createBasicRequest(loginPageDoc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
     946        loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
     947        loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
     948        loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
     949        loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
     950        loginPageMessage.appendChild(loginPageRequest);
     951
     952        Element paramList = loginPageDoc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     953        loginPageRequest.appendChild(paramList);
     954
     955        Element messageParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
     956        messageParam.setAttribute(GSXML.NAME_ATT, LOGIN_MESSAGE_PARAM);
     957        messageParam.setAttribute(GSXML.VALUE_ATT, getTextString("auth.error.un_or_pw_err", lang));
     958        paramList.appendChild(messageParam);
     959
     960        Element urlParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
     961        urlParam.setAttribute(GSXML.NAME_ATT, REDIRECT_URL_PARAM);
     962        String queryString = "";
     963        if (request.getQueryString() != null)
     964          {
     965            queryString = "?" + request.getQueryString().replace("&", "&amp;");
     966          }
     967        urlParam.setAttribute(GSXML.VALUE_ATT, library_name + queryString);
     968        paramList.appendChild(urlParam);
     969
     970        Node loginPageResponse = this.recept.process(loginPageMessage);
     971        out.println(XMLConverter.getPrettyString(loginPageResponse));
     972
     973        return false;
     974          }
     975      }
     976      }
     977
     978    //If a user is logged in
     979    if (request.getAuthType() != null)
     980      {
     981    logger.error("kk auth type not null "+ request.getAuthType());
     982    Element userInformation = xml_request.getOwnerDocument().createElement(GSXML.USER_INFORMATION_ELEM);
     983    userInformation.setAttribute(GSXML.USERNAME_ATT, request.getUserPrincipal().getName());
     984    logger.error("setting user info username "+request.getUserPrincipal().getName());
     985    Document msg_doc = XMLConverter.newDOM();
     986    Element userInfoMessage = msg_doc.createElement(GSXML.MESSAGE_ELEM);
     987    Element userInfoRequest = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_SECURITY, "GetUserInformation", userContext);
     988    userInfoMessage.appendChild(userInfoRequest);
     989
     990    Element paramList = msg_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     991    userInfoRequest.appendChild(paramList);
     992
     993    Element param = msg_doc.createElement(GSXML.PARAM_ELEM);
     994    param.setAttribute(GSXML.NAME_ATT, GSXML.USERNAME_ATT);
     995    param.setAttribute(GSXML.VALUE_ATT, request.getUserPrincipal().getName());
     996    paramList.appendChild(param);
     997
     998    Element userInformationResponse = (Element) GSXML.getChildByTagName(this.recept.process(userInfoMessage), GSXML.RESPONSE_ELEM);
     999    Element responseParamList = (Element) GSXML.getChildByTagName(userInformationResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     1000    if (responseParamList == null)
     1001      {
     1002        logger.error("Can't get the groups for user " + request.getUserPrincipal().getName());
     1003      }
     1004    else
     1005      {
     1006        HashMap<String, Serializable> responseParams = GSXML.extractParams(responseParamList, true);
     1007        String groups = (String) responseParams.get(GSXML.GROUPS_ATT);
     1008        String editEnabled = (String) responseParams.get("editEnabled");
     1009
     1010        userInformation.setAttribute(GSXML.GROUPS_ATT, groups);
     1011        userInformation.setAttribute(GSXML.EDIT_ENABLED_ATT, (editEnabled != null) ? editEnabled : "false");
     1012        xml_request.appendChild(userInformation);
     1013      }
     1014      }
     1015
     1016    //If we are in a collection-related page then make sure this user is allowed to access it
     1017    if (collection != null && !collection.equals(""))
     1018      {
     1019    logger.error("kk in a coll"+collection);
     1020    //Get the security info for this collection
     1021    Document msg_doc = XMLConverter.newDOM();
     1022    Element securityMessage = msg_doc.createElement(GSXML.MESSAGE_ELEM);
     1023    Element securityRequest = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_SECURITY, collection, userContext);
     1024    securityMessage.appendChild(securityRequest);
     1025    if (document != null && !document.equals(""))
     1026      {
     1027        securityRequest.setAttribute(GSXML.NODE_OID, document);
     1028      }
     1029
     1030    Element securityResponse = (Element) GSXML.getChildByTagName(this.recept.process(securityMessage), GSXML.RESPONSE_ELEM);
     1031    if (securityResponse == null)
     1032      {
     1033        return false;
     1034      }
     1035
     1036    ArrayList<String> groups = GSXML.getGroupsFromSecurityResponse(securityResponse);
     1037
     1038    //If guests are not allowed to access this page then check to see if the user is in a group that is allowed to access the page
     1039    if (!groups.contains(""))
     1040      {
     1041        boolean found = false;
     1042        for (String group : groups)
     1043          {
     1044        if (request.isUserInRole(group))
     1045          {
     1046            found = true;
     1047            break;
     1048          }
     1049          }
     1050
     1051        //The current user is not allowed to access the page so produce a login page
     1052        if (!found)
     1053          {
     1054        logger.error("kk current user not allowed to access");
     1055        Document loginPageDoc = XMLConverter.newDOM();
     1056        Element loginPageMessage = loginPageDoc.createElement(GSXML.MESSAGE_ELEM);
     1057        Element loginPageRequest = GSXML.createBasicRequest(loginPageDoc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
     1058        loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
     1059        loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
     1060        loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
     1061        loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
     1062        loginPageMessage.appendChild(loginPageRequest);
     1063
     1064        Element paramList = loginPageDoc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     1065        loginPageRequest.appendChild(paramList);
     1066
     1067        Element messageParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
     1068        messageParam.setAttribute(GSXML.NAME_ATT, LOGIN_MESSAGE_PARAM);
     1069        if (request.getAuthType() == null)
     1070          {
     1071            messageParam.setAttribute(GSXML.VALUE_ATT, getTextString("auth.error.login", lang));
     1072          }
     1073        else
     1074          {
     1075            messageParam.setAttribute(GSXML.VALUE_ATT, getTextString("auth.error.incorrect_login", lang));
     1076          }
     1077        paramList.appendChild(messageParam);
     1078
     1079        Element urlParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
     1080        urlParam.setAttribute(GSXML.NAME_ATT, REDIRECT_URL_PARAM);
     1081        if (request.getQueryString() != null && request.getQueryString().length() > 0)
     1082          {
     1083            urlParam.setAttribute(GSXML.VALUE_ATT, request.getRequestURL() + "?" + request.getQueryString().replace("&", "&amp;"));
     1084          }
     1085        else
     1086          {
     1087            urlParam.setAttribute(GSXML.VALUE_ATT, request.getRequestURL().toString());
     1088          }
     1089        paramList.appendChild(urlParam);
     1090
     1091        // for debugging purposes, eg adding o=xml to the url
     1092        String output_p = getFirstParam(GSParams.OUTPUT, queryMap);
     1093        if (output_p !=null && !output_p.equals("")) {
     1094          loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, output_p);
    1931095        }
    194 
    195         // If we don't have a site, then we must be using a Communicator, and all the remote params must be set
    196         if (site_name == null && (remote_site_name == null || remote_site_type == null || remote_site_address == null)) {
    197          
    198           System.err.println("initialisation paramters not all set!");
    199           System.err.println("if site_name is not set, then you must have remote_site_name, remote_site_type and remote_site_address set");
    200           System.exit(1);
    201         }
    202        
    203         supports_client_xslt = useXslt != null && useXslt.equals("true");
    204         if (sess_expire != null && !sess_expire.equals(""))
    205         {
    206             this.session_expiration = Integer.parseInt(sess_expire);
    207         }
    208         if (this.default_lang == null)
    209         {
    210             // choose english
    211             this.default_lang = DEFAULT_LANG;
    212         }
    213 
    214         config_params.put(GSConstants.LIBRARY_NAME, library_name);
    215         config_params.put(GSConstants.INTERFACE_NAME, interface_name);
    216         config_params.put(GSConstants.USE_CLIENT_SIDE_XSLT, supports_client_xslt);
    217 
    218         if (site_name != null)
    219         {
    220             config_params.put(GSConstants.SITE_NAME, site_name);
    221         }
    222 
    223         // the receptionist -the servlet will talk to this
    224         if (recept_name == null)
    225         {
    226             this.recept = new DefaultReceptionist();
    227         }
    228         else
    229         {
    230             try
    231             {
    232                 this.recept = (Receptionist) Class.forName("org.greenstone.gsdl3.core." + recept_name).newInstance();
    233             }
    234             catch (Exception e)
    235             { // cant use this new one, so use normal one
    236                 System.err.println("LibraryServlet configure exception when trying to use a new Receptionist " + recept_name + ": " + e.getMessage());
    237                 e.printStackTrace();
    238                 this.recept = new DefaultReceptionist();
    239             }
    240         }
    241         this.recept.setConfigParams(config_params);
    242 
    243         // the params arg thingy
    244 
    245         String params_name = (String) config.getInitParameter("params_class");
    246         if (params_name == null)
    247         {
    248             this.gs_params = new GSParams();
    249         }
    250         else
    251         {
    252             try
    253             {
    254                 this.gs_params = (GSParams) Class.forName("org.greenstone.gsdl3.util." + params_name).newInstance();
    255             }
    256             catch (Exception e)
    257             {
    258                 System.err.println("LibraryServlet configure exception when trying to use a new params thing " + params_name + ": " + e.getMessage());
    259                 e.printStackTrace();
    260                 this.gs_params = new GSParams();
    261             }
    262         }
    263        
    264         // 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 the Receptionist, and the servlet never talks to it again directly.
    265         if (site_name != null)
    266         {
    267             String mr_name = (String) config.getInitParameter("messagerouter_class");
    268             MessageRouter message_router = null;
    269             if (mr_name == null)
    270             { // just use the normal MR
    271                 message_router = new MessageRouter();
    272             }
    273             else
    274             { // try the specified one
    275                 try
    276                 {
    277                     message_router = (MessageRouter) Class.forName("org.greenstone.gsdl3.core." + mr_name).newInstance();
    278                 }
    279                 catch (Exception e)
    280                 { // cant use this new one, so use normal one
    281                     System.err.println("LibraryServlet configure exception when trying to use a new MessageRouter " + mr_name + ": " + e.getMessage());
    282                     e.printStackTrace();
    283                     message_router = new MessageRouter();
    284                 }
    285             }
    286 
    287             message_router.setSiteName(site_name);
    288             message_router.setLibraryName(library_name);
    289             message_router.setParams(this.gs_params);
    290             message_router.configure();
    291             this.recept.setMessageRouter(message_router);
    292         }
    293         else
    294         {
    295           // TODO: what do we do about params here?
    296             // talking to a remote site, create a communicator
    297             Communicator communicator = null;
    298             // we need to create the XML to configure the communicator
    299             Document doc = XMLConverter.newDOM();
    300             Element site_elem = doc.createElement(GSXML.SITE_ELEM);
    301             site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
    302             site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
    303             site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
    304 
    305             if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
    306             {
    307                 communicator = new SOAPCommunicator();
    308             }
    309             else
    310             {
    311                 System.err.println("LibraryServlet.init Error: invalid Communicator type: " + remote_site_type);
    312                 System.exit(1);
    313             }
    314 
    315             if (!communicator.configure(site_elem))
    316             {
    317                 System.err.println("LibraryServlet.init Error: Couldn't configure communicator");
    318                 System.exit(1);
    319             }
    320             this.recept.setMessageRouter(communicator);
    321         }
    322 
    323         // pass params to the receptionist
    324         this.recept.setParams(this.gs_params);
    325         this.recept.configure();
    326 
    327         //Allow the message router and the document to be accessed from anywhere in this servlet context
    328         this.getServletContext().setAttribute(library_name+"Router", this.recept.getMessageRouter());
    329     }
    330 
    331   private void logUsageInfo(HttpServletRequest request, Map<String, String[]> queryMap)
    332     {
    333         String usageInfo = "";
    334 
    335         //session-info: get params stored in the session
    336         HttpSession session = request.getSession(true);
    337         Enumeration attributeNames = session.getAttributeNames();
    338         while (attributeNames.hasMoreElements())
    339         {
    340             String name = (String) attributeNames.nextElement();
    341             usageInfo += name + "=" + session.getAttribute(name) + " ";
    342         }
    343 
    344         String queryParamStr = "";
    345         if (queryMap != null)
    346         {
    347             Iterator<String> queryIter = queryMap.keySet().iterator();
    348             while (queryIter.hasNext()) {
    349               String q = queryIter.next();
    350               String[] vals = queryMap.get(q);
    351               queryParamStr += q +"="+StringUtils.join(vals, ",")+" ";
    352             }
    353         }
    354         //logged info = general-info + session-info
    355         usageInfo = request.getServletPath() + " " + //serlvet
    356           "[" + queryParamStr.trim()+"]"+" " + // query map params
    357           "session:[" + usageInfo.trim() + "]" + " " + // params stored in a session
    358           request.getRemoteAddr() + " " + //remote address
    359           request.getRequestedSessionId() + " " + //session id
    360           request.getHeader("user-agent") + " "; //the remote brower info
    361 
    362         logger.info(usageInfo);
    363 
    364     }
    365 
    366     public class UserSessionCache implements HttpSessionBindingListener
    367     {
    368         String session_id = "";
    369 
    370         /**
    371          * a hash that maps the session ID to a hashtable that maps the
    372          * coll_name to its parameters coll_name -> Hashtable (param_name ->
    373          * param_value)
    374          */
    375         protected Hashtable<String, Hashtable<String, String>> coll_name_params_table = null;
    376 
    377         public UserSessionCache(String id, Hashtable<String, Hashtable<String, String>> table)
    378         {
    379             session_id = id;
    380             coll_name_params_table = (table == null) ? new Hashtable() : table;
    381         }
    382 
    383         protected void cleanupCache(String coll_name)
    384         {
    385             if (coll_name_params_table.containsKey(coll_name))
    386             {
    387                 coll_name_params_table.remove(coll_name);
    388             }
    389         }
    390 
    391         protected Hashtable<String, Hashtable<String, String>> getParamsTable()
    392         {
    393             return coll_name_params_table;
    394         }
    395 
    396         public void valueBound(HttpSessionBindingEvent event)
    397         {
    398             // Do nothing
    399         }
    400 
    401       // if session cache id removed from session, this triggers this valueUnbound method on the value=this object
    402         public void valueUnbound(HttpSessionBindingEvent event)
    403         {
    404             if (session_ids_table.containsKey(session_id))
    405             {
    406                 session_ids_table.remove(session_id);
    407             }
    408         }
    409 
    410         public int tableSize()
    411         {
    412             return (coll_name_params_table == null) ? 0 : coll_name_params_table.size();
    413         }
    414     }
    415 
    416     public void destroy()
    417     {
    418         recept.cleanUp();
    419     }
    420 
    421     public void doGetOrPost(HttpServletRequest request, HttpServletResponse response, Map<String, String[]> queryMap) throws ServletException, IOException
    422     {
    423       logUsageInfo(request, queryMap);
    424 
    425         if (queryMap != null)
    426         {
    427             Iterator<String> queryIter = queryMap.keySet().iterator();
    428             boolean redirect = false;
    429             String href = null;
    430             String rl = null;
    431             String el = null;
    432 
    433             while (queryIter.hasNext())
    434             {
    435                 String q = queryIter.next();
    436                 if (q.equals(GSParams.EXTERNAL_LINK_TYPE))
    437                 {
    438                     el = queryMap.get(q)[0];
    439                 }
    440                 else if (q.equals(GSParams.HREF))
    441                 {
    442                     href = queryMap.get(q)[0];
    443                     href = StringUtils.replace(href, "%2f", "/");
    444                     href = StringUtils.replace(href, "%7e", "~");
    445                     href = StringUtils.replace(href, "%3f", "?");
    446                     href = StringUtils.replace(href, "%3A", "\\:");
    447                 }
    448                 else if (q.equals(GSParams.RELATIVE_LINK))
    449                 {
    450                     rl = queryMap.get(q)[0];
    451                 }
    452             }
    453 
    454             //if query_string contains "el=direct", an href is specified, and its not a relative link, then the web page will be redirected to the external URl, otherwise a greenstone page with an external URL will be displayed
    455             //"rl=0" this is an external link
    456             //"rl=1" this is an internal link
    457             if ((href != null) && (rl.equals("0")))
    458             {// This is an external link,
    459 
    460                 if (el.equals("framed"))
    461                 {
    462                     //TODO **** how best to change to a=p&sa=html&c=collection&url=href
    463                     // response.setContentType("text/xml");
    464                     //response.sendRedirect("http://localhost:8383/greenstone3/gs3library?a=p&sa=html&c=external&url="+href);
    465                 }
    466                 else
    467                 {
    468                     // el = '' or direct
    469                     //the web page is re-directed to the external URL (&el=&rl=0&href="http://...")
    470                     response.setContentType("text/xml");
    471                     response.sendRedirect(href);
    472                 }
    473             }
    474         }
    475 
    476         // Nested Diagnostic Configurator to identify the client for
    477         HttpSession session = request.getSession(true);
    478         session.setMaxInactiveInterval(session_expiration);
    479         String uid = session.getId();
    480         request.setCharacterEncoding("UTF-8");
    481         response.setContentType("text/html;charset=UTF-8");
    482         PrintWriter out = response.getWriter();
    483 
    484         String lang = getFirstParam(GSParams.LANGUAGE, queryMap);
    485         if (lang == null || lang.equals(""))
    486         {
    487             // try the session cached lang
    488             lang = (String) session.getAttribute(GSParams.LANGUAGE);
    489             if (lang == null || lang.equals(""))
    490             {
    491                 // still not set, use the default
    492                 lang = this.default_lang;
    493             }
    494         }
    495         UserContext userContext = new UserContext();
    496         userContext.setLanguage(lang);
    497         userContext.setUserID(uid);
    498         logger.error("LS new user context");
    499         if (request.getAuthType() != null)
    500         {
    501             //Get the username
    502           userContext.setUsername(request.getUserPrincipal().getName());
    503           logger.error("setting username = "+request.getUserPrincipal().getName());
    504             //Get the groups for the user
    505             Document msg_doc = XMLConverter.newDOM();
    506             Element acquireGroupMessage = msg_doc.createElement(GSXML.MESSAGE_ELEM);
    507             Element acquireGroupRequest = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_PROCESS, "GetUserInformation", userContext);
    508             acquireGroupMessage.appendChild(acquireGroupRequest);
    509 
    510             Element paramList = msg_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    511             acquireGroupRequest.appendChild(paramList);
    512             paramList.appendChild(GSXML.createParameter(msg_doc, GSXML.USERNAME_ATT, request.getUserPrincipal().getName()));
    513 
    514             Element aquireGroupsResponseMessage = (Element) this.recept.process(acquireGroupMessage);
    515             Element aquireGroupsResponse = (Element) GSXML.getChildByTagName(aquireGroupsResponseMessage, GSXML.RESPONSE_ELEM);
    516             Element param_list = (Element) GSXML.getChildByTagName(aquireGroupsResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    517 
    518             if (param_list != null)
    519             {
    520                 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
    521                 String groups = (String) params.get("groups");
    522                 userContext.setGroups(groups.split(","));
    523             }
    524         }
    525 
    526         // set the lang in the session
    527         session.setAttribute(GSParams.LANGUAGE, lang);
    528 
    529         String output = getFirstParam(GSParams.OUTPUT, queryMap);
    530         if (output == null || output.equals(""))
    531         {
    532             output = "html"; // uses html by default
    533         }
    534 
    535         // If server output, force a switch to traditional interface
    536         //output = (output.equals("server")) ? "html" : output;
    537 
    538         // Force change the output mode if client-side XSLT is supported - server vs. client
    539         // BUT only if the library allows client-side transforms   
    540         if (supports_client_xslt)
    541         {
    542             // MUST be done before the xml_message is built
    543             Cookie[] cookies = request.getCookies();
    544             Cookie xsltCookie = null;
    545 
    546             // The client has cookies enabled and a value set - use it!
    547             if (cookies != null)
    548             {
    549                 for (Cookie c : cookies)
    550                 {
    551                     if (c.getName().equals("supportsXSLT"))
    552                     {
    553                         xsltCookie = c;
    554                         break;
    555                     }
    556                 }
    557                 output = (xsltCookie != null && xsltCookie.getValue().equals("true") && output.equals("html")) ? "xsltclient" : output;
    558             }
    559         }
    560 
    561         // the request to the receptionist
    562         Document msg_doc = XMLConverter.newDOM();
    563         Element xml_message = msg_doc.createElement(GSXML.MESSAGE_ELEM);
    564         Element xml_request = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
    565         xml_request.setAttribute(GSXML.OUTPUT_ATT, output);
    566 
    567         xml_message.appendChild(xml_request);
    568 
    569         String action = getFirstParam(GSParams.ACTION, queryMap);
    570         String subaction = getFirstParam(GSParams.SUBACTION, queryMap);
    571         String collection = getFirstParam(GSParams.COLLECTION, queryMap);
    572         String document = getFirstParam(GSParams.DOCUMENT, queryMap);
    573         String service = getFirstParam(GSParams.SERVICE, queryMap);
    574         String specified_cache_key = getFirstParam(GSParams.CACHE_KEY, queryMap);
    575 
    576         // We clean up the cache session_ids_table if system
    577         // commands are issued, and also don't need to do caching for these request requests
    578         boolean should_cache = true;
    579         if (action != null && action.equals(GSParams.SYSTEM_ACTION)
    580             && !subaction.equals(GSXML.SYSTEM_TYPE_PING)
    581             && !subaction.equals(GSXML.SYSTEM_TYPE_AUTHENTICATED_PING)) // don't 'clean' anything on a mere ping
    582         {
    583             should_cache = false;
    584 
    585             // we may want to remove all collection cache info, or just a specific collection
    586             boolean clean_all = true;
    587             String clean_collection = null;
    588             // system commands are to activate/deactivate stuff
    589             // collection param is in the sc parameter.
    590             // don't like the fact that it is hard coded here
    591             String coll = getFirstParam(GSParams.SYSTEM_CLUSTER, queryMap);
    592             if (coll != null && !coll.equals(""))
    593             {
    594                 clean_all = false;
    595                 clean_collection = coll;
    596             }
    597             else
    598             {
    599                 // check other system types
    600                 if (subaction.equals("a") || subaction.equals("d"))
    601                 {
    602                     String module_name = getFirstParam("sn", queryMap);
    603                     if (module_name != null && !module_name.equals(""))
    604                     {
    605                         clean_all = false;
    606                         clean_collection = module_name;
    607                     }
    608                 }
    609             }
    610             if (clean_all)
    611             {
    612                 // TODO
    613                 session_ids_table = new Hashtable<String, UserSessionCache>();
    614                 session.removeAttribute(GSParams.USER_SESSION_CACHE); // triggers valueUnbound(), which removes the session id from the session_ids_table
    615             }
    616             else
    617             {
    618                 // just clean up info for clean_collection
    619                 ArrayList<UserSessionCache> cache_list = new ArrayList<UserSessionCache>(session_ids_table.values());
    620                 for (int i = 0; i < cache_list.size(); i++)
    621                 {
    622                     UserSessionCache cache = cache_list.get(i);
    623                     cache.cleanupCache(clean_collection);
    624                 }
    625 
    626             }
    627         }
    628 
    629         // cache_key is the collection name, or service name
    630         String cache_key = specified_cache_key;
    631         if (cache_key == null || cache_key.equals(""))
    632           {
    633             cache_key = collection;
    634           }
    635         if (cache_key == null || cache_key.equals(""))
    636         {
    637             cache_key = service;
    638         }
    639        
    640         //clear the collection-specific cache in the session, since we have no way to know whether this page is
    641         //about the same collection as the last page or not.
    642         Enumeration attributeNames = session.getAttributeNames();
    643         while (attributeNames.hasMoreElements())
    644         {
    645             String name = (String) attributeNames.nextElement();
    646             if (!name.equals(GSParams.USER_SESSION_CACHE) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT) && !this.gs_params.isGlobal(name))
    647             {
    648                 session.removeAttribute(name);
    649             }
    650         }
    651 
    652         UserSessionCache session_cache = null;
    653         Hashtable<String, Hashtable<String, String>> param_table = null;
    654         Hashtable<String, String> table = null;
    655         boolean new_table = false;
    656         String sid = session.getId();
    657         boolean new_session = false;
    658         if (!session_ids_table.containsKey(sid)) {
    659           new_session = true;
    660         }
    661         if (should_cache == true && cache_key != null && !cache_key.equals(""))
    662         {
    663             if (!new_session)
    664             {
    665                 session_cache = session_ids_table.get(sid);
    666                 param_table = session_cache.getParamsTable();
    667                 if (param_table.containsKey(cache_key))
    668                 {
    669                     table = param_table.get(cache_key);
    670                 }
    671                 else
    672                 {
    673                     table = new Hashtable<String, String>();
    674                     param_table.put(cache_key, table);
    675                     new_table = true;
    676                 }
    677             }
    678             else
    679             {
    680              
    681                 param_table = new Hashtable<String, Hashtable<String, String>>();
    682                 table = new Hashtable<String, String>();
    683                 param_table.put(cache_key, table);
    684                 session_cache = new UserSessionCache(sid, param_table);
    685                 session_ids_table.put(sid, session_cache);
    686                 session.setAttribute(GSParams.USER_SESSION_CACHE, session_cache);
    687                 new_table = true;
    688             }
    689 
    690         }
    691        
    692         // here we add in default params values if need be - if we have a new session, or if we have a new table
    693         // in an existing session
    694         // don't override any existing values
    695         if (new_session || new_table) {
    696 
    697           Iterator i = this.gs_params.getParamsWithDefaults().iterator();
    698           while (i.hasNext()) {
    699             String p = (String)i.next();
    700             String v = this.gs_params.getParamDefault(p);
    701               if (this.gs_params.isGlobal(p)) {
    702             //need to add in to session unless its already there
    703             if (session.getAttribute(p) == null) {
    704               session.setAttribute(p, v);
    705             }
    706               } else {
    707             // add to table unless its already there
    708             if (new_table && !table.containsKey(p)) {
    709               table.put(p,v);
    710             }
    711               }
    712            
    713           }
    714             }
    715 
    716         if (action == null || action.equals(""))
    717         {
    718                 // display the home page  - the default page
    719             xml_request.setAttribute(GSXML.ACTION_ATT, "p");
    720             xml_request.setAttribute(GSXML.SUBACTION_ATT, PageAction.HOME_PAGE);
    721         }
    722         else
    723         {
    724             xml_request.setAttribute(GSXML.ACTION_ATT, action);
    725             if (subaction != null)
    726             {
    727                 xml_request.setAttribute(GSXML.SUBACTION_ATT, subaction);
    728             }
    729         }
    730        
    731             //  create the param list for the greenstone request - includes
    732             // the params from the current request and any others from the saved session
    733             Element xml_param_list = msg_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    734             xml_request.appendChild(xml_param_list);
    735            
    736             if (queryMap.containsKey("s1.collection") || queryMap.containsKey("s1.group")){
    737                 table.remove("s1.collection");
    738                 table.remove("s1.group");
    739             }
    740             for (String name : queryMap.keySet())
    741             {
    742                 if (!name.equals(GSParams.ACTION) && !name.equals(GSParams.SUBACTION) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSParams.OUTPUT))
    743                 {// we have already dealt with these
    744 
    745                     String value = "";
    746                     String[] values = queryMap.get(name);
    747                     value = values[0];
    748                     if (values.length > 1)
    749                     {
    750                         for (int i = 1; i < values.length; i++)
    751                         {
    752                             value += "," + values[i];
    753                         }
    754                     }
    755                     // if we need to save the value, then add it to the session/cache table.
    756                     // otherwise add directly to the paramList
    757                     if (this.gs_params.shouldSave(name)) {
    758                       if (this.gs_params.isGlobal(name) || table == null) {
    759                         session.setAttribute(name, value);
    760                       } else {
    761                         table.put(name, value);
    762                       }
    763                     }
    764                     else
    765                     {
    766                         Element param = msg_doc.createElement(GSXML.PARAM_ELEM);
    767                         param.setAttribute(GSXML.NAME_ATT, name);
    768                         param.setAttribute(GSXML.VALUE_ATT, GSXML.xmlSafe(value));
    769                         if (this.gs_params.isSensitive(name)) {
    770                           param.setAttribute(GSXML.SENSITIVE_ATT, "true");
    771                         }
    772                         xml_param_list.appendChild(param);
    773                        
    774                     }
    775                 }
    776             }
    777             //put everything in the table into the session
    778             if (table != null)
    779             {
    780                 Enumeration<String> keys = table.keys();
    781                 while (keys.hasMoreElements())
    782                 {
    783                     String name = keys.nextElement();
    784                     session.setAttribute(name, table.get(name));
    785                 }
    786             }
    787 
    788             // put in all the params from the session cache
    789             Enumeration params = session.getAttributeNames();
    790             while (params.hasMoreElements())
    791             {
    792                 String name = (String) params.nextElement();
    793                 if (!name.equals(GSParams.USER_SESSION_CACHE) && !name.equals(GSParams.LANGUAGE) && !name.equals(GSXML.USER_ID_ATT))
    794                 {
    795 
    796                     // lang and uid are stored but we dont want it in the param list cos its already in the request
    797                     Element param = msg_doc.createElement(GSXML.PARAM_ELEM);
    798                     param.setAttribute(GSXML.NAME_ATT, name);
    799                     String value = GSXML.xmlSafe((String) session.getAttribute(name));
    800 
    801                     // ugly hack to undo : escaping
    802                     value = StringUtils.replace(value, "%3A", "\\:");
    803                     param.setAttribute(GSXML.VALUE_ATT, value);
    804                     xml_param_list.appendChild(param);
    805                 }
    806             }
    807    
    808 
    809         if (output.equals("json"))
    810         {
    811             response.setContentType("application/json");
    812         }
    813         else if (!output.equals("html") && !output.equals("server") && !output.equals("xsltclient"))
    814         {
    815             response.setContentType("text/xml"); // for now use text
    816         }
    817 
    818         //Add custom HTTP headers if requested
    819         String httpHeadersParam = getFirstParam(GSParams.HTTP_HEADER_FIELDS, queryMap);
    820         if (httpHeadersParam != null && httpHeadersParam.length() > 0)
    821         {
    822             Gson gson = new Gson();
    823             Type type = new TypeToken<List<Map<String, String>>>()
    824             {
    825             }.getType();
    826             List<Map<String, String>> httpHeaders = gson.fromJson(httpHeadersParam, type);
    827             if (httpHeaders != null && httpHeaders.size() > 0)
    828             {
    829 
    830                 for (int j = 0; j < httpHeaders.size(); j++)
    831                 {
    832                     Map nameValueMap = httpHeaders.get(j);
    833                     String name = (String) nameValueMap.get("name");
    834                     String value = (String) nameValueMap.get("value");
    835 
    836                     if (name != null && value != null)
    837                     {
    838                         response.setHeader(name, value);
    839                     }
    840                 }
    841             }
    842         }
    843 
    844         String requestedURL = request.getRequestURL().toString();
    845         String baseURL = "";
    846         if (requestedURL.indexOf(library_name) != -1)
    847         {
    848             baseURL = requestedURL.substring(0, requestedURL.indexOf(library_name));
    849             xml_request.setAttribute("baseURL", baseURL);
    850         }
    851         String fullURL;
    852         if (request.getQueryString() != null)
    853         {
    854             fullURL = requestedURL + "?" + request.getQueryString();
    855         }
    856         else
    857         {
    858             fullURL = requestedURL;
    859         }
    860 
    861         xml_request.setAttribute("remoteAddress", request.getRemoteAddr());
    862         xml_request.setAttribute("fullURL", fullURL.replace("&", "&amp;"));
    863 
    864         if (!runSecurityChecks(request, xml_request, userContext, out, baseURL, collection, document, queryMap, lang))
    865         {
    866             return;
    867         }
    868 
    869         logger.error("about to process this message");
    870         logger.error(XMLConverter.getPrettyString(xml_message));
    871         Node xml_result = this.recept.process(xml_message);
    872         encodeURLs(xml_result, response);
    873 
    874         String xml_string = XMLConverter.getPrettyString(xml_result);
    875        
    876         if (output.equals("json"))
    877         {
    878             try
    879             {
    880                 JSONObject json_obj = org.json.XML.toJSONObject(xml_string);
    881 
    882                 out.println(json_obj.toString());
    883             }
    884             catch (Exception e)
    885             {
    886                 e.printStackTrace();
    887                 out.println("Error: failed to convert output XML to JSON format");
    888             }
    889         }
    890         else
    891         {
    892             out.println(xml_string);
    893         }
    894 
    895         displaySize(session_ids_table);
    896     }
    897 
    898     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    899     {
    900         doGetOrPost(request, response, request.getParameterMap());
    901     } //end of doGet(HttpServletRequest, HttpServletResponse)
    902 
    903   private boolean runSecurityChecks(HttpServletRequest request, Element xml_request, UserContext userContext, PrintWriter out, String baseURL, String collection, String document, Map<String, String[]> queryMap, String lang) throws ServletException
    904     {
    905       logger.error("kk in run security");
    906         //Check if we need to login or logout
    907         String username = getFirstParam(GSParams.USERNAME, queryMap);
    908         String password = getFirstParam(GSParams.PASSWORD, queryMap);
    909         String logout = getFirstParam(GSParams.LOGOUT, queryMap);
    910 
    911         if (logout != null)
    912         {
    913             request.logout();
    914         }
    915 
    916         if (username != null && password != null)
    917         {
    918           logger.error("kk u&p not null");
    919             //We are changing to another user, so log out first
    920             if (request.getAuthType() != null)
    921             {
    922                 request.logout();
    923             }
    924 
    925             //This try/catch block catches when the login request fails (e.g. The user enters an incorrect password).
    926             try
    927             {
    928                 //Try a global login first
    929                 password = Authentication.hashPassword(password);
    930                 request.login(username, password);
    931             }
    932             catch (Exception ex)
    933             {
    934                 try
    935                 {
    936                     //If the global login fails then try a site-level login
    937                     String siteName = (String) this.recept.getConfigParams().get(GSConstants.SITE_NAME);
    938                     request.login(siteName + "-" + username, password);
    939                 }
    940                 catch (Exception exc)
    941                 {
    942                     //The user entered in either the wrong username or the wrong password
    943                   Document loginPageDoc = XMLConverter.newDOM();
    944                     Element loginPageMessage = loginPageDoc.createElement(GSXML.MESSAGE_ELEM);
    945                     Element loginPageRequest = GSXML.createBasicRequest(loginPageDoc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
    946                     loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
    947                     loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
    948                     loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
    949                     loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
    950                     loginPageMessage.appendChild(loginPageRequest);
    951 
    952                     Element paramList = loginPageDoc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    953                     loginPageRequest.appendChild(paramList);
    954 
    955                     Element messageParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
    956                     messageParam.setAttribute(GSXML.NAME_ATT, LOGIN_MESSAGE_PARAM);
    957                     messageParam.setAttribute(GSXML.VALUE_ATT, getTextString("auth.error.un_or_pw_err", lang));
    958                     paramList.appendChild(messageParam);
    959 
    960                     Element urlParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
    961                     urlParam.setAttribute(GSXML.NAME_ATT, REDIRECT_URL_PARAM);
    962                     String queryString = "";
    963                     if (request.getQueryString() != null)
    964                     {
    965                         queryString = "?" + request.getQueryString().replace("&", "&amp;");
    966                     }
    967                     urlParam.setAttribute(GSXML.VALUE_ATT, library_name + queryString);
    968                     paramList.appendChild(urlParam);
    969 
    970                     Node loginPageResponse = this.recept.process(loginPageMessage);
    971                     out.println(XMLConverter.getPrettyString(loginPageResponse));
    972 
    973                     return false;
    974                 }
    975             }
    976         }
    977 
    978         //If a user is logged in
    979         if (request.getAuthType() != null)
    980         {
    981           logger.error("kk auth type not null "+ request.getAuthType());
    982           Element userInformation = xml_request.getOwnerDocument().createElement(GSXML.USER_INFORMATION_ELEM);
    983             userInformation.setAttribute(GSXML.USERNAME_ATT, request.getUserPrincipal().getName());
    984             logger.error("setting user info username "+request.getUserPrincipal().getName());
    985             Document msg_doc = XMLConverter.newDOM();
    986             Element userInfoMessage = msg_doc.createElement(GSXML.MESSAGE_ELEM);
    987             Element userInfoRequest = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_SECURITY, "GetUserInformation", userContext);
    988             userInfoMessage.appendChild(userInfoRequest);
    989 
    990             Element paramList = msg_doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    991             userInfoRequest.appendChild(paramList);
    992 
    993             Element param = msg_doc.createElement(GSXML.PARAM_ELEM);
    994             param.setAttribute(GSXML.NAME_ATT, GSXML.USERNAME_ATT);
    995             param.setAttribute(GSXML.VALUE_ATT, request.getUserPrincipal().getName());
    996             paramList.appendChild(param);
    997 
    998             Element userInformationResponse = (Element) GSXML.getChildByTagName(this.recept.process(userInfoMessage), GSXML.RESPONSE_ELEM);
    999             Element responseParamList = (Element) GSXML.getChildByTagName(userInformationResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    1000             if (responseParamList == null)
    1001             {
    1002                 logger.error("Can't get the groups for user " + request.getUserPrincipal().getName());
    1003             }
    1004             else
    1005             {
    1006                 HashMap<String, Serializable> responseParams = GSXML.extractParams(responseParamList, true);
    1007                 String groups = (String) responseParams.get(GSXML.GROUPS_ATT);
    1008                 String editEnabled = (String) responseParams.get("editEnabled");
    1009 
    1010                 userInformation.setAttribute(GSXML.GROUPS_ATT, groups);
    1011                 userInformation.setAttribute(GSXML.EDIT_ENABLED_ATT, (editEnabled != null) ? editEnabled : "false");
    1012                 xml_request.appendChild(userInformation);
    1013             }
    1014         }
    1015 
    1016         //If we are in a collection-related page then make sure this user is allowed to access it
    1017         if (collection != null && !collection.equals(""))
    1018         {
    1019           logger.error("kk in a coll"+collection);
    1020             //Get the security info for this collection
    1021           Document msg_doc = XMLConverter.newDOM();
    1022             Element securityMessage = msg_doc.createElement(GSXML.MESSAGE_ELEM);
    1023             Element securityRequest = GSXML.createBasicRequest(msg_doc, GSXML.REQUEST_TYPE_SECURITY, collection, userContext);
    1024             securityMessage.appendChild(securityRequest);
    1025             if (document != null && !document.equals(""))
    1026             {
    1027                 securityRequest.setAttribute(GSXML.NODE_OID, document);
    1028             }
    1029 
    1030             Element securityResponse = (Element) GSXML.getChildByTagName(this.recept.process(securityMessage), GSXML.RESPONSE_ELEM);
    1031             if (securityResponse == null)
    1032             {
    1033                 return false;
    1034             }
    1035 
    1036             ArrayList<String> groups = GSXML.getGroupsFromSecurityResponse(securityResponse);
    1037 
    1038             //If guests are not allowed to access this page then check to see if the user is in a group that is allowed to access the page
    1039             if (!groups.contains(""))
    1040             {
    1041                 boolean found = false;
    1042                 for (String group : groups)
    1043                 {
    1044                     if (request.isUserInRole(group))
    1045                     {
    1046                         found = true;
    1047                         break;
    1048                     }
    1049                 }
    1050 
    1051                 //The current user is not allowed to access the page so produce a login page
    1052                 if (!found)
    1053                 {
    1054                   logger.error("kk current user not allowed to access");
    1055                   Document loginPageDoc = XMLConverter.newDOM();
    1056                     Element loginPageMessage = loginPageDoc.createElement(GSXML.MESSAGE_ELEM);
    1057                     Element loginPageRequest = GSXML.createBasicRequest(loginPageDoc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
    1058                     loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
    1059                     loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
    1060                     loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
    1061                     loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
    1062                     loginPageMessage.appendChild(loginPageRequest);
    1063 
    1064                     Element paramList = loginPageDoc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    1065                     loginPageRequest.appendChild(paramList);
    1066 
    1067                     Element messageParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
    1068                     messageParam.setAttribute(GSXML.NAME_ATT, LOGIN_MESSAGE_PARAM);
    1069                     if (request.getAuthType() == null)
    1070                     {
    1071                       messageParam.setAttribute(GSXML.VALUE_ATT, getTextString("auth.error.login", lang));
    1072                     }
    1073                     else
    1074                     {
    1075                       messageParam.setAttribute(GSXML.VALUE_ATT, getTextString("auth.error.incorrect_login", lang));
    1076                     }
    1077                     paramList.appendChild(messageParam);
    1078 
    1079                     Element urlParam = loginPageDoc.createElement(GSXML.PARAM_ELEM);
    1080                     urlParam.setAttribute(GSXML.NAME_ATT, REDIRECT_URL_PARAM);
    1081                     if (request.getQueryString() != null && request.getQueryString().length() > 0)
    1082                     {
    1083                         urlParam.setAttribute(GSXML.VALUE_ATT, request.getRequestURL() + "?" + request.getQueryString().replace("&", "&amp;"));
    1084                     }
    1085                     else
    1086                     {
    1087                         urlParam.setAttribute(GSXML.VALUE_ATT, request.getRequestURL().toString());
    1088                     }
    1089                     paramList.appendChild(urlParam);
    1090 
    1091                     // for debugging purposes, eg adding o=xml to the url
    1092                     String output_p = getFirstParam(GSParams.OUTPUT, queryMap);
    1093                     if (output_p !=null && !output_p.equals("")) {
    1094                       loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, output_p);
    1095                     }
    10961096                     
    1097                     logger.error("login page request=");
    1098                     logger.error(XMLConverter.getPrettyString(loginPageMessage));
    1099                     Node loginPageResponse = this.recept.process(loginPageMessage);
    1100                     out.println(XMLConverter.getPrettyString(loginPageResponse));
    1101 
    1102                     return false;
    1103                 }
    1104             }
    1105         }
    1106         logger.error("kk reurned true");
    1107         return true;
    1108     }
     1097        logger.error("login page request=");
     1098        logger.error(XMLConverter.getPrettyString(loginPageMessage));
     1099        Node loginPageResponse = this.recept.process(loginPageMessage);
     1100        out.println(XMLConverter.getPrettyString(loginPageResponse));
     1101
     1102        return false;
     1103          }
     1104      }
     1105      }
     1106    logger.error("kk reurned true");
     1107    return true;
     1108  }
    11091109
    11101110  private String getTextString(String key, String lang) {
     
    11121112 
    11131113  }
    1114     //a debugging method
    1115     private void displaySize(Hashtable<String, UserSessionCache> table)
    1116     {
    1117         if (table == null)
    1118         {
    1119           //logger.info("cached table is null");
    1120             return;
    1121         }
    1122         if (table.size() == 0)
    1123         {
    1124           //logger.info("cached table size is zero");
    1125             return;
    1126         }
    1127         int num_cached_coll = 0;
    1128         ArrayList<UserSessionCache> cache_list = new ArrayList<UserSessionCache>(table.values());
    1129         for (int i = 0; i < cache_list.size(); i++)
    1130         {
    1131             num_cached_coll += cache_list.get(i).tableSize();
    1132         }
    1133         //logger.info("Number of sessions : total number of cached collection info = " + table.size() + " : " + num_cached_coll);
    1134     }
    1135 
    1136     /** merely a debugging method! */
    1137     private String tableToString(Hashtable<String, Hashtable<String, String>> table)
    1138     {
    1139         String str = "";
    1140         Enumeration<String> keys = table.keys();
    1141         while (keys.hasMoreElements())
    1142         {
    1143             String name = keys.nextElement();
    1144             str += name + ", ";
    1145         }
    1146         return str;
    1147     }
    1148 
    1149     /**
    1150     * this goes through each URL and adds in a session id if needed-- its
    1151     * needed if the browser doesn't accept cookies also escapes things if
    1152     * needed
    1153     */
    1154     protected void encodeURLs(Node dataNode, HttpServletResponse response)
    1155     {
    1156         if (dataNode == null)
    1157         {
    1158             return;
    1159         }
    1160 
    1161         Element data = null;
    1162 
    1163         short nodeType = dataNode.getNodeType();
    1164         if (nodeType == Node.DOCUMENT_NODE)
    1165         {
    1166             Document docNode = (Document) dataNode;
    1167             data = docNode.getDocumentElement();
    1168         }
    1169         else
    1170         {
    1171             data = (Element) dataNode;
    1172         }
    1173 
    1174         if (data != null)
    1175         {
    1176 
    1177             // get all the <a> elements
    1178             NodeList hrefs = data.getElementsByTagName("a");
    1179             // Instead of calculating each iteration...
    1180             int hrefscount = hrefs.getLength();
    1181 
    1182             for (int i = 0; hrefs != null && i < hrefscount; i++)
    1183             {
    1184                 Element a = (Element) hrefs.item(i);
    1185                 // ugly hack to get rid of : in the args - interferes with session handling
    1186                 String href = a.getAttribute("href");
    1187                 if (!href.equals(""))
    1188                 {
    1189                     if (href.indexOf("?") != -1)
    1190                     {
    1191                         String[] parts = StringUtils.split(href, "\\?", -1);
    1192                         if (parts.length == 1)
    1193                         {
    1194                             parts[0] = StringUtils.replace(parts[0], ":", "%3A");
    1195                             href = "?" + parts[0];
    1196                         }
    1197                         else
    1198                         {
    1199                             parts[1] = StringUtils.replace(parts[1], ":", "%3A");
    1200                             href = parts[0] + "?" + parts[1];
    1201                         }
    1202 
    1203                     }
    1204                     a.setAttribute("href", response.encodeURL(href));
    1205                 }
    1206             }
    1207 
    1208             // now find any submit bits - get all the <form> elements
    1209             NodeList forms = data.getElementsByTagName("form");
    1210             int formscount = forms.getLength();
    1211             for (int i = 0; forms != null && i < formscount; i++)
    1212             {
    1213                 Element form = (Element) forms.item(i);
    1214                 form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
    1215             }
    1216             // are these the only cases where URLs occur??
    1217             // we should only do this for greenstone urls?
    1218         }
    1219 
    1220     }
    1221 
    1222     protected String getFirstParam(String name, Map<String, String[]> map)
    1223     {
    1224         String[] val = map.get(name);
    1225         if (val == null || val.length == 0)
    1226         {
    1227             return null;
    1228         }
    1229 
    1230         return val[0];
    1231     }
    1232 
    1233     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    1234     {
    1235         //Check if we need to process a file upload
    1236         if (ServletFileUpload.isMultipartContent(request))
    1237         {
    1238             DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
    1239 
    1240             int sizeLimit = System.getProperties().containsKey("servlet.upload.filesize.limit") ? Integer.parseInt(System.getProperty("servlet.upload.filesize.limit")) : 100 * 1024 * 1024;
    1241 
    1242             File tempDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp");
    1243             if (!tempDir.exists())
    1244             {
    1245                 tempDir.mkdirs();
    1246             }
    1247 
    1248             //We want all files to be stored on disk (hence the 0)
    1249             fileItemFactory.setSizeThreshold(0);
    1250             fileItemFactory.setRepository(tempDir);
    1251 
    1252             ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
    1253             uploadHandler.setFileSizeMax(sizeLimit);
    1254 
    1255             HashMap<String, String[]> queryMap = new HashMap<String, String[]>();
    1256             try
    1257             {
    1258                 List items = uploadHandler.parseRequest(request);
    1259                 Iterator iter = items.iterator();
    1260                 while (iter.hasNext())
    1261                 {
    1262                     FileItem current = (FileItem) iter.next();
    1263                     if (current.isFormField())
    1264                     {
    1265                         queryMap.put(current.getFieldName(), new String[] { current.getString() });
    1266                     }
    1267                     else if (current.getName() != null && !current.getName().equals(""))
    1268                     {
    1269                         File file = new File(tempDir, current.getName());
    1270                         current.write(file);
    1271 
    1272                         queryMap.put("md___ex.Filesize", new String[] { "" + file.length() });
    1273                         queryMap.put("md___ex.Filename", new String[] { "" + current.getName() });
    1274                     }
    1275                 }
    1276             }
    1277             catch (Exception e)
    1278             {
    1279                 e.printStackTrace();
    1280             }
    1281 
    1282             doGetOrPost(request, response, queryMap);
    1283         }
    1284         else
    1285         {
    1286             doGetOrPost(request, response, request.getParameterMap());
    1287         }
    1288     }
     1114  //a debugging method
     1115  private void displaySize(Hashtable<String, UserSessionCache> table)
     1116  {
     1117    if (table == null)
     1118      {
     1119    //logger.info("cached table is null");
     1120    return;
     1121      }
     1122    if (table.size() == 0)
     1123      {
     1124    //logger.info("cached table size is zero");
     1125    return;
     1126      }
     1127    int num_cached_coll = 0;
     1128    ArrayList<UserSessionCache> cache_list = new ArrayList<UserSessionCache>(table.values());
     1129    for (int i = 0; i < cache_list.size(); i++)
     1130      {
     1131    num_cached_coll += cache_list.get(i).tableSize();
     1132      }
     1133    //logger.info("Number of sessions : total number of cached collection info = " + table.size() + " : " + num_cached_coll);
     1134  }
     1135
     1136  /** merely a debugging method! */
     1137  private String tableToString(Hashtable<String, Hashtable<String, String>> table)
     1138  {
     1139    String str = "";
     1140    Enumeration<String> keys = table.keys();
     1141    while (keys.hasMoreElements())
     1142      {
     1143    String name = keys.nextElement();
     1144    str += name + ", ";
     1145      }
     1146    return str;
     1147  }
     1148
     1149  /**
     1150  * this goes through each URL and adds in a session id if needed-- its
     1151  * needed if the browser doesn't accept cookies also escapes things if
     1152  * needed
     1153  */
     1154  protected void encodeURLs(Node dataNode, HttpServletResponse response)
     1155  {
     1156    if (dataNode == null)
     1157      {
     1158    return;
     1159      }
     1160
     1161    Element data = null;
     1162
     1163    short nodeType = dataNode.getNodeType();
     1164    if (nodeType == Node.DOCUMENT_NODE)
     1165      {
     1166    Document docNode = (Document) dataNode;
     1167    data = docNode.getDocumentElement();
     1168      }
     1169    else
     1170      {
     1171    data = (Element) dataNode;
     1172      }
     1173
     1174    if (data != null)
     1175      {
     1176
     1177    // get all the <a> elements
     1178    NodeList hrefs = data.getElementsByTagName("a");
     1179    // Instead of calculating each iteration...
     1180    int hrefscount = hrefs.getLength();
     1181
     1182    for (int i = 0; hrefs != null && i < hrefscount; i++)
     1183      {
     1184        Element a = (Element) hrefs.item(i);
     1185        // ugly hack to get rid of : in the args - interferes with session handling
     1186        String href = a.getAttribute("href");
     1187        if (!href.equals(""))
     1188          {
     1189        if (href.indexOf("?") != -1)
     1190          {
     1191            String[] parts = StringUtils.split(href, "\\?", -1);
     1192            if (parts.length == 1)
     1193              {
     1194            parts[0] = StringUtils.replace(parts[0], ":", "%3A");
     1195            href = "?" + parts[0];
     1196              }
     1197            else
     1198              {
     1199            parts[1] = StringUtils.replace(parts[1], ":", "%3A");
     1200            href = parts[0] + "?" + parts[1];
     1201              }
     1202
     1203          }
     1204        a.setAttribute("href", response.encodeURL(href));
     1205          }
     1206      }
     1207
     1208    // now find any submit bits - get all the <form> elements
     1209    NodeList forms = data.getElementsByTagName("form");
     1210    int formscount = forms.getLength();
     1211    for (int i = 0; forms != null && i < formscount; i++)
     1212      {
     1213        Element form = (Element) forms.item(i);
     1214        form.setAttribute("action", response.encodeURL(form.getAttribute("action")));
     1215      }
     1216    // are these the only cases where URLs occur??
     1217    // we should only do this for greenstone urls?
     1218      }
     1219
     1220  }
     1221
     1222  protected String getFirstParam(String name, Map<String, String[]> map)
     1223  {
     1224    String[] val = map.get(name);
     1225    if (val == null || val.length == 0)
     1226      {
     1227    return null;
     1228      }
     1229
     1230    return val[0];
     1231  }
     1232
     1233  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
     1234  {
     1235    //Check if we need to process a file upload
     1236    if (ServletFileUpload.isMultipartContent(request))
     1237      {
     1238    DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
     1239
     1240    int sizeLimit = System.getProperties().containsKey("servlet.upload.filesize.limit") ? Integer.parseInt(System.getProperty("servlet.upload.filesize.limit")) : 100 * 1024 * 1024;
     1241
     1242    File tempDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp");
     1243    if (!tempDir.exists())
     1244      {
     1245        tempDir.mkdirs();
     1246      }
     1247
     1248    //We want all files to be stored on disk (hence the 0)
     1249    fileItemFactory.setSizeThreshold(0);
     1250    fileItemFactory.setRepository(tempDir);
     1251
     1252    ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
     1253    uploadHandler.setFileSizeMax(sizeLimit);
     1254
     1255    HashMap<String, String[]> queryMap = new HashMap<String, String[]>();
     1256    try
     1257      {
     1258        List items = uploadHandler.parseRequest(request);
     1259        Iterator iter = items.iterator();
     1260        while (iter.hasNext())
     1261          {
     1262        FileItem current = (FileItem) iter.next();
     1263        if (current.isFormField())
     1264          {
     1265            queryMap.put(current.getFieldName(), new String[] { current.getString() });
     1266          }
     1267        else if (current.getName() != null && !current.getName().equals(""))
     1268          {
     1269            File file = new File(tempDir, current.getName());
     1270            current.write(file);
     1271
     1272            queryMap.put("md___ex.Filesize", new String[] { "" + file.length() });
     1273            queryMap.put("md___ex.Filename", new String[] { "" + current.getName() });
     1274          }
     1275          }
     1276      }
     1277    catch (Exception e)
     1278      {
     1279        e.printStackTrace();
     1280      }
     1281
     1282    doGetOrPost(request, response, queryMap);
     1283      }
     1284    else
     1285      {
     1286    doGetOrPost(request, response, request.getParameterMap());
     1287      }
     1288  }
    12891289}
Note: See TracChangeset for help on using the changeset viewer.