alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * 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 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.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This is a SOAP Monitor Service class. 
 *
 * 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.
 *
 * 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).
 *
 * Each time a socket connection is established, a new 
 * thread is created to handle communications from the 
 * applet.
 *
 * 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 server_socket = 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 (server_socket == null) {
      // Get the server socket port from the init params
      ServletConfig config = super.getServletConfig();
      String port = config.getInitParameter(SOAPMonitorConstants.SOAP_MONITOR_PORT);
      if (port == null) {
        log.error("SOAPMonitorService can't find ServletConfig init parameter 'port'");
        port = "0";
      }
      try {
        // Try to open the server socket
        server_socket = 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);
        server_socket = null;
      }
      if (server_socket != 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 (server_socket != null) {
      try {
        server_socket.close();
      } catch (Exception x) {}
      server_socket = 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 (server_socket != null) {
     port = server_socket.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");
   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=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=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 (server_socket != null) {
        try {
          Socket socket = server_socket.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) {}
      }
    }
  }
}

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.