org.apache.axis2.soapmonitor.servlet.SOAPMonitorService.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.axis2.soapmonitor.servlet.SOAPMonitorService.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.soapmonitor.servlet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;

/**
 * This is a SOAP Monitor Service class.
 * <p/>
 * During the HTTP server startup, the servlet init method
 * is invoked.  This allows the code to open a server
 * socket that will be used to communicate with running
 * applets.
 * <p/>
 * When an HTTP GET request is received, the servlet
 * dynamically produces an HTML document to load the SOAP
 * monitor applet and supply the port number being used by
 * the server socket (so the applet will know how to
 * connect back to the server).
 * <p/>
 * Each time a socket connection is established, a new
 * thread is created to handle communications from the
 * applet.
 * <p/>
 * The publishMethod routine is invoked by the SOAP monitor
 * handler when a SOAP message request or response is
 * detected.  The information about the SOAP message is
 * then forwared to all current socket connections for
 * display by the applet.
 */

public class SOAPMonitorService extends HttpServlet {

    /**
     * Private data
     */
    private static ServerSocket serverSocket = null;
    private static Vector connections = null;

    private static final Log log = LogFactory.getLog(SOAPMonitorService.class);

    /**
     * Constructor
     */
    public SOAPMonitorService() {
    }

    /**
     * Publish a SOAP message to listeners
     */
    public static void publishMessage(Long id, Integer type, String target, String soap) {
        if (connections != null) {
            Enumeration e = connections.elements();
            while (e.hasMoreElements()) {
                ConnectionThread ct = (ConnectionThread) e.nextElement();
                ct.publishMessage(id, type, target, soap);
            }
        }
    }

    /**
     * Servlet initialiation
     */
    public void init() throws ServletException {
        if (connections == null) {
            // Create vector to hold connection information
            connections = new Vector();
        }
        if (serverSocket == null) {
            // Get the server socket port from the init params
            ServletConfig config = super.getServletConfig();
            String hostName = config.getInitParameter(SOAPMonitorConstants.SOAP_MONITOR_HOST_NAME);
            String port = config.getInitParameter(SOAPMonitorConstants.SOAP_MONITOR_PORT);
            if (port == null) {
                log.error("SOAPMonitorService can't find ServletConfig init parameter 'port'");
                port = "0";
            }
            try {
                if (hostName != null) {
                    serverSocket = new ServerSocket(Integer.parseInt(port), 50, InetAddress.getByName(hostName));
                } else {
                    serverSocket = new ServerSocket(Integer.parseInt(port));
                }
            } catch (Exception ex) {
                // Let someone know we could not open the socket
                log.error("Unable to open server socket using port: " + port);
                log.error(ex.getMessage(), ex);
                // Fail as loudly as possible for those without logging configured
                config.getServletContext().log("Unable to open server socket using port " + port + ":", ex);
                serverSocket = null;
            }
            if (serverSocket != null) {
                // Start the server socket thread
                new Thread(new ServerSocketThread()).start();
            }
        }
    }

    /**
     * Servlet termination
     */
    public void destroy() {
        // End all connection threads
        Enumeration e = connections.elements();
        while (e.hasMoreElements()) {
            ConnectionThread ct = (ConnectionThread) e.nextElement();
            ct.close();
        }
        // End main server socket thread
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (Exception x) {
            }
            serverSocket = null;
        }
    }

    /**
     * HTTP GET request
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        // Create HTML to load the SOAP monitor applet
        int port = 0;
        if (serverSocket != null) {
            port = serverSocket.getLocalPort();
            log.debug("Sending param to SOAP monitor applet as port: " + port);
        }
        response.setContentType("text/html");
        response.getWriter().println("<html>");
        response.getWriter().println("<head>");
        response.getWriter().println("<title>SOAP Monitor</title>");
        response.getWriter().println("</head>");
        response.getWriter().println("<body>");
        response.getWriter().println(
                "<object classid=\"clsid:8AD9C840-044E-11D1-B3E9-00805F499D93\" width=100% height=100% codebase=\"http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0\">");
        response.getWriter()
                .println("<param name=code value=org.apache.axis2.soapmonitor.applet.SOAPMonitorApplet.class>");
        response.getWriter().println("<param name=\"type\" value=\"application/x-java-applet;version=1.3\">");
        response.getWriter().println("<param name=\"scriptable\" value=\"false\">");
        response.getWriter().println("<param name=\"port\" value=\"" + port + "\">");
        response.getWriter().println("<comment>");
        response.getWriter().println(
                "<embed type=\"application/x-java-applet;version=1.3\" code=org.apache.axis2.soapmonitor.applet.SOAPMonitorApplet.class width=100% height=100% port=\""
                        + port
                        + "\" scriptable=false pluginspage=\"http://java.sun.com/products/plugin/1.3/plugin-install.html\">");
        response.getWriter().println("<noembed>");
        response.getWriter().println("</comment>");
        response.getWriter().println("</noembed>");
        response.getWriter().println("</embed>");
        response.getWriter().println("</object>");
        response.getWriter().println("</body>");
        response.getWriter().println("</html>");
    }

    /**
     * Thread class for handling the server socket
     */
    class ServerSocketThread implements Runnable {

        /**
         * Thread for handling the server socket
         */
        public void run() {
            // Wait for socket connections
            while (serverSocket != null) {
                try {
                    Socket socket = serverSocket.accept();
                    new Thread(new ConnectionThread(socket)).start();
                } catch (IOException ioe) {
                }
            }
        }
    }

    /**
     * Thread class for handling socket connections
     */
    class ConnectionThread implements Runnable {

        private Socket socket = null;
        private ObjectInputStream in = null;
        private ObjectOutputStream out = null;
        private boolean closed = false;

        /**
         * Constructor
         */
        public ConnectionThread(Socket s) {
            socket = s;
            try {
                // Use object streams for input and output
                //
                // NOTE: We need to be sure to create and flush the
                // output stream first because the ObjectOutputStream
                // constructor writes a header to the stream that is
                // needed by the ObjectInputStream on the other end
                out = new ObjectOutputStream(socket.getOutputStream());
                out.flush();
                in = new ObjectInputStream(socket.getInputStream());
            } catch (Exception e) {
            }
            // Add the connection to our list
            synchronized (connections) {
                connections.addElement(this);
            }
        }

        /**
         * Close the socket connection
         */
        public void close() {
            closed = true;
            try {
                socket.close();
            } catch (IOException ioe) {
            }
        }

        /**
         * Thread to handle the socket connection
         */
        public void run() {
            try {
                while (!closed) {
                    Object o = in.readObject();
                }
            } catch (Exception e) {
            }
            // Cleanup connection list
            synchronized (connections) {
                connections.removeElement(this);
            }
            // Cleanup I/O streams
            if (out != null) {
                try {
                    out.close();
                } catch (IOException ioe) {
                }
                out = null;
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ioe) {
                }
                in = null;
            }
            // Be sure the socket is closed
            close();
        }

        /**
         * Publish SOAP message information
         */
        public synchronized void publishMessage(Long id, Integer message_type, String target, String soap) {
            // If we have a valid output stream, then
            // send the data to the applet
            if (out != null) {
                try {
                    switch (message_type.intValue()) {
                    case SOAPMonitorConstants.SOAP_MONITOR_REQUEST:
                        out.writeObject(message_type);
                        out.writeObject(id);
                        out.writeObject(target);
                        out.writeObject(soap);
                        out.flush();
                        break;
                    case SOAPMonitorConstants.SOAP_MONITOR_RESPONSE:
                        out.writeObject(message_type);
                        out.writeObject(id);
                        out.writeObject(soap);
                        out.flush();
                        break;
                    }
                } catch (Exception e) {
                }
            }
        }
    }
}