org.openlaszlo.servlets.HistoryServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.openlaszlo.servlets.HistoryServlet.java

Source

/******************************************************************************
 * HistoryServlet.java
 *****************************************************************************/
/* J_LZ_COPYRIGHT_BEGIN *******************************************************
* Copyright 2001-2004 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* J_LZ_COPYRIGHT_END *********************************************************/
package org.openlaszlo.servlets;

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.ServletConfig.*;
import org.apache.log4j.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.util.*;

public class HistoryServlet extends HttpServlet {
    public class MyGetMethod extends GetMethod {
        protected void addCookieRequestHeader(HttpState s, HttpConnection c) {

        }
    }

    private static Logger mLogger = Logger.getLogger(HistoryServlet.class);

    /** Connection Manager */
    private static MultiThreadedHttpConnectionManager mConnectionMgr = new MultiThreadedHttpConnectionManager();

    private List mHistory = new LinkedList();

    private String mURL = "http://localhost:8080/lps-pc/examples/history/history.lzx";

    /** Request counter */
    private int mRequestCounter = 1;

    private static final int TYPE_UNKNOWN = 0;
    private static final int TYPE_MESSAGE = 1;
    private static final int TYPE_HISTORY = 2;
    private static final int TYPE_USERDISCONNECT = 3;

    private static final String DEFAULT_MAX_CONNECTIONS = "1000";
    private static final String DEFAULT_HISTORY_LENGTH = "10";
    private static final String DEFAULT_AGENT_NAME = "history";
    private static final String DEFAULT_AGENT_GROUP = "history";
    private static final String DEFAULT_CLIENT_DATASET = "history";

    private int mHistoryLength;
    private String mAgentURL;
    private String mAgentGroup;
    private String mClientDataset;

    private String getInitParameter(ServletConfig config, String name, String defaultValue) {
        String value = config.getInitParameter(name);
        mLogger.debug("web.xml value for " + name + " is " + value);
        return (value != null ? value : defaultValue);
    }

    /** Initialize servlet.
     * @param config configuration file object */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        try {
            String maxConns = getInitParameter(config, "MAX_CONNECTIONS", DEFAULT_MAX_CONNECTIONS);
            mConnectionMgr.setMaxConnectionsPerHost(Integer.parseInt(maxConns));

            String len = getInitParameter(config, "HISTORY_LENGTH", DEFAULT_HISTORY_LENGTH);
            mHistoryLength = Integer.parseInt(len);

            mAgentURL = getInitParameter(config, "AGENT_URL", DEFAULT_AGENT_NAME);
            mAgentGroup = getInitParameter(config, "AGENT_GROUP", DEFAULT_AGENT_GROUP);
            mClientDataset = getInitParameter(config, "CLIENT_DATASET", DEFAULT_CLIENT_DATASET);

        } catch (Exception e) {
            throw new ServletException(e.getMessage());
        }
    }

    /**
     * @param req @see HttpServletRequest
     * @param res @see HttpServletResponse
     */
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        // Set up logger NDC

        int requestID;
        synchronized (this) {
            requestID = mRequestCounter++;
        }

        NDC.push(req.getRemoteAddr() + " " + (requestID));

        try {
            _doGet(req, res);
        } finally {

            mLogger.debug("Request " + requestID + " finished");
            NDC.pop();
            NDC.remove();
        }

    }

    /**
     * @param req @see HttpServletRequest
     * @param res @see HttpServletResponse
     */
    private void _doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        res.setContentType("text/xml");

        String xml = req.getParameter("xml");
        if (xml == null || xml.equals("")) {
            mLogger.warn("no xml");
            doHelp(req, res, "no xml");
            return;
        }
        mLogger.debug("xml is " + xml);

        try {
            SAXBuilder builder = new SAXBuilder();
            Document document = builder.build(new StringReader(xml));

            switch (peekAtType(document)) {
            case TYPE_MESSAGE:
                doSaveMessage(req, res, document);
                break;
            case TYPE_HISTORY:
                doSendHistory(req, res, document);
                break;
            case TYPE_USERDISCONNECT:
                mLogger.debug("got 'userdisconnect' from server");
                break;
            default:
                doHelp(req, res, "default");
                break;
            }

        } catch (JDOMException e) {
            mLogger.warn("JDOMException: " + e.getMessage());
        }
    }

    private void doHelp(HttpServletRequest req, HttpServletResponse res, String xxx) {
        ServletOutputStream out = null;
        try {
            out = res.getOutputStream();

            out.println("<!-- " + xxx + " -->");

            out.println("<help>");
            out.println("You must pass in an xml query parameter (?xml=...).  ");
            out.println("The following are valid xml values.");

            out.println("<xml description=\"Save message.\" >");
            out.println("<resultset>");
            out.println("<root dset=\"message\"><from name=\"aName\" />messageText</root>");
            out.println("</resultset>");
            out.println("</xml>");

            out.println("<xml description=\"Get message history.\" >");
            out.println("<resultset>");
            out.println("<root><history/></root>");
            out.println("</resultset>");
            out.println("</xml>");

            out.println("<xml description=\"LPS push of client disconnect.\" >");
            out.println("<resultset>");
            out.println("<root dset=\"__LPSUSERDISCONNECT\">username</root>");
            out.println("</resultset>");
            out.println("</xml>");

            out.println("</help>");
            out.flush();
        } catch (IOException e) {
            mLogger.info("IOException: " + e.getMessage());
        } finally {
            close(out);
        }
    }

    private void doSaveMessage(HttpServletRequest req, HttpServletResponse res, Document doc) {
        mLogger.debug("doSaveMessage()");
        if (mHistory.size() == mHistoryLength) {
            mHistory.remove(0);
        }
        String message = doc.getRootElement().getChild("root").getText();
        mHistory.add(message);

        ServletOutputStream out = null;
        try {
            out = res.getOutputStream();
            out.println("<status message=\"message saved\" />");
            out.flush();
        } catch (IOException e) {
            mLogger.info("IOException: " + e.getMessage());
        } finally {
            close(out);
        }
    }

    private String getXMLHistory() {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < mHistory.size(); i++) {
            buf.append("<message>").append((String) mHistory.get(i)).append("</message>\n");
        }
        return buf.toString();
    }

    private void doSendHistory(HttpServletRequest req, HttpServletResponse res, Document doc) {
        mLogger.info("doSendHistory");
        Element el = doc.getRootElement().getChild("root").getChild("history");

        ServletOutputStream out = null;
        GetMethod request = null;
        String status = null;
        String body = null;
        try {
            out = res.getOutputStream();

            request = new MyGetMethod();

            String url = mURL + "?lzt=agentmessage" + "&url=" + URLEncoder.encode(mAgentURL) + "&group="
                    + mAgentGroup + "&to=*&range=user" + "&dset=" + mClientDataset + "&msg="
                    + URLEncoder.encode(getXMLHistory());

            mLogger.debug("url: " + url);
            URI uri = new URI(url.toCharArray());
            HostConfiguration hcfg = new HostConfiguration();
            hcfg.setHost(uri);

            String path = uri.getEscapedPath();
            String query = uri.getEscapedQuery();

            mLogger.debug("path: " + path);
            mLogger.debug("query: " + query);

            request.setPath(path);
            request.setQueryString(query);

            HttpClient htc = new HttpClient(mConnectionMgr);
            htc.setHostConfiguration(hcfg);
            int rc = htc.executeMethod(hcfg, request);

            status = HttpStatus.getStatusText(rc);
            if (status == null) {
                status = "" + rc;
            }
            mLogger.debug("remote response status: " + status);

            body = request.getResponseBodyAsString();

            mLogger.debug("response body: " + body);
        } catch (HttpRecoverableException e) {
            mLogger.debug("HttpRecoverableException: " + e.getMessage());
            sendError(out, "<status message=\"HttpRecoverableException " + e.getMessage() + "\" />");
        } catch (HttpException e) {
            mLogger.debug("HttpException: " + e.getMessage());
            sendError(out, "<status message=\"HttpException " + e.getMessage() + "\" />");
        } catch (IOException e) {
            mLogger.debug("IOException: " + e.getMessage());
            sendError(out, "<status message=\"IOException " + e.getMessage() + "\" />");
        } finally {
            if (request != null) {
                request.releaseConnection();
            }
        }

        try {
            if (status != null && status.equals("OK")) {
                out.println("<status message=\"ok\">" + (body != null ? body : "") + "</status>");
            } else {
                out.println("<status message=\"" + mURL + "?lzt=agentmessage" + " " + status + "\" />");
            }
            out.flush();
        } catch (IOException e) {
            mLogger.debug("Client IOException");
            // ignore client ioexception
        } finally {
            close(out);
        }
    }

    private void sendError(ServletOutputStream out, String error) {
        try {
            out.println(error);
        } catch (IOException e) {
        }
    }

    private int peekAtType(Document doc) throws JDOMException {

        Element el = doc.getRootElement().getChild("root");
        if (el == null)
            return TYPE_UNKNOWN;

        String dset = el.getAttributeValue("dset");
        if (dset != null && dset.equals("__LPSUSERDISCONNECT")) {
            return TYPE_USERDISCONNECT;
        } else if (dset != null && dset.equals("message") && el.getChild("from") != null) {
            return TYPE_MESSAGE;
        } else if (el.getChild("history") != null) {
            return TYPE_HISTORY;
        }

        return TYPE_UNKNOWN;
    }

    private void close(OutputStream out) {
        try {
            if (out != null)
                out.close();
        } catch (IOException e) {
        }
    }
}