/*
 * Copyright 2001,2004 The Apache Software Foundation.
 *
 * Licensed under the Apache Liusercense, 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.axis.utils;

import org.apache.axis.client.AdminClient;
import org.apache.axis.monitor.SOAPMonitorConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.ChangeListener;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.net.URL;
import java.net.MalformedURLException;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

/**
 * This is a SOAP Monitor Application class.  This class provides
 * the user interface for deploying the SOAP monitor service and
 * displaying data from the service.
 * 
 * @author Toshiyuki Kimura (toshi@apache.org)
 * @author Brian Price (pricebe@us.ibm.com)
 */
public class SOAPMonitor extends JFrame implements ActionListener, ChangeListener {

    /**
     * Private data
     */
    private JPanel main_panel = null;

    /**
     * Field tabbed_pane
     */
    private JTabbedPane tabbed_pane = null;

    /**
     * Field top_pane
     */
    private JTabbedPane top_pane = null;

    /**
     * Field port
     */
    private int port = 5001;

    /**
     * Field axisHost
     */
    private String axisHost = "localhost";

    /**
     * Field axisPort
     */
    private int axisPort = 8080;

    /**
     * Field axisURL
     */
    private String axisURL = null;

    /**
     * Field pages
     */
    private Vector pages = null;

    /**
     * Field titleStr
     */
    private final String titleStr = "SOAP Monitor Administration";

    /**
     * Field set_panel
     */
    private JPanel set_panel = null;

    /**
     * Field titleLabel
     */
    private JLabel titleLabel = null;

    /**
     * Field add_btn
     */
    private JButton add_btn = null;

    /**
     * Field del_btn
     */
    private JButton del_btn = null;

    /**
     * Field save_btn
     */
    private JButton save_btn = null;

    /**
     * Field login_btn
     */
    private JButton login_btn = null;

    /**
     * Field model1
     */
    private DefaultListModel model1 = null;

    /**
     * Field model2
     */
    private DefaultListModel model2 = null;

    /**
     * Field list1
     */
    private JList list1 = null;

    /**
     * Field list2
     */
    private JList list2 = null;

    /**
     * Field serviceMap
     */
    private HashMap serviceMap = null;

    /**
     * Field originalDoc
     */
    private Document originalDoc = null;

    /**
     * Field axisUser
     */
    private static String axisUser = null;

    /**
     * Field axisPass
     */
    private static String axisPass = null;

    /**
     * Field adminClient
     */
    private AdminClient adminClient = new AdminClient();

    /**
     * Main method for this class
     * 
     * @param args 
     * @throws Exception 
     */
    public static void main(String args[]) throws Exception {
        SOAPMonitor soapMonitor = null;
        Options opts = new Options(args);
        if (opts.isFlagSet('?') > 0) {
            System.out.println(
                    "Usage: SOAPMonitor [-l<url>] [-u<user>] [-w<password>] [-?]");
            System.exit(0);
        }

        // Create an instance
        soapMonitor = new SOAPMonitor();

        // GET Axis URL.
        // The default is "http://localhost:8080/axis/servlet/AxisServlet"
        soapMonitor.axisURL = opts.getURL();
        URL url = new URL(soapMonitor.axisURL);
        soapMonitor.axisHost = url.getHost();

        // GET User name & Password
        axisUser = opts.getUser();
        axisPass = opts.getPassword();

        // Login and start application
        soapMonitor.doLogin();
    }

    /**
     * Constructor
     */
    public SOAPMonitor() {
        setTitle("SOAP Monitor Application");
        Dimension d = getToolkit().getScreenSize();
        setSize(640, 480);
        setLocation((d.width - getWidth()) / 2, (d.height - getHeight()) / 2);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        addWindowListener(new MyWindowAdapter());

        // Try to use the system look and feel
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
        }

        // Create main panel to hold notebook
        main_panel = new JPanel();
        main_panel.setBackground(Color.white);
        main_panel.setLayout(new BorderLayout());
        top_pane = new JTabbedPane();
        set_panel = new JPanel();

        // label for NORTH panel to display the pain title
        titleLabel = new JLabel(titleStr);
        titleLabel.setFont(new Font("Serif", Font.BOLD, 18));

        // list control for WEST panel to list NOT monitored services
        model1 = new DefaultListModel();
        list1 = new JList(model1);
        list1.setFixedCellWidth(250);
        JScrollPane scroll1 = new JScrollPane(list1);

        // list control for EAST panel to list monitored services
        model2 = new DefaultListModel();
        list2 = new JList(model2);
        list2.setFixedCellWidth(250);
        JScrollPane scroll2 = new JScrollPane(list2);

        // buttons for CENTER panel to chage the monitoring state
        add_btn = new JButton("Turn On [ >> ]");
        del_btn = new JButton("[ << ] Turn Off");
        JPanel center_panel = new JPanel();
        GridBagLayout layout = new GridBagLayout();
        center_panel.setLayout(layout);
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(10, 10, 10, 10);
        layout.setConstraints(add_btn, c);
        center_panel.add(add_btn);
        c.gridx = 0;
        c.gridy = 1;
        c.insets = new Insets(10, 10, 10, 10);
        layout.setConstraints(del_btn, c);
        center_panel.add(del_btn);

        // buttons for SOUTH panel
        save_btn = new JButton("Save changes");
        login_btn = new JButton("Change server");
        JPanel south_panel = new JPanel();
        layout = new GridBagLayout();
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(10, 10, 10, 10);
        layout.setConstraints(save_btn, c);
        south_panel.add(save_btn);
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(10, 10, 10, 10);
        layout.setConstraints(login_btn, c);
        south_panel.add(login_btn);

        // set all controls to the border layout
        set_panel.setLayout(new BorderLayout(5, 5));
        set_panel.add(titleLabel, BorderLayout.NORTH);
        set_panel.add(south_panel, BorderLayout.SOUTH);
        set_panel.add(scroll1, BorderLayout.WEST);
        set_panel.add(scroll2, BorderLayout.EAST);
        set_panel.add(center_panel, BorderLayout.CENTER);

        // register the Action Listener
        add_btn.addActionListener(this);
        del_btn.addActionListener(this);
        save_btn.addActionListener(this);
        login_btn.addActionListener(this);

        // set default button state as 'false'
        add_btn.setEnabled(false);
        del_btn.setEnabled(false);
        save_btn.setEnabled(false);
        login_btn.setEnabled(false);
        top_pane.add("Setting", set_panel);
        top_pane.add("Monitoring", main_panel);
        getContentPane().add(top_pane);

        // Create the notebook
        tabbed_pane = new JTabbedPane(JTabbedPane.TOP);
        main_panel.add(tabbed_pane, BorderLayout.CENTER);
        top_pane.addChangeListener(this);
        top_pane.setEnabled(false);
        setVisible(true);
    }

    /**
     * Do login process
     * 
     * @return 
     */
    private boolean doLogin() {
        Dimension d = null;

        // Login
        LoginDlg login = new LoginDlg();
        login.show();
        if (!login.isLogin()) {
            login_btn.setEnabled(true);
            return false;
        }
        login.dispose();
        save_btn.setEnabled(false);
        login_btn.setEnabled(false);

        // Get the axisHost & axisPort to be used
        String url_str = login.getURL();
        try {
            URL url = new URL(url_str);
            axisHost = url.getHost();
            axisPort = url.getPort();
            if (axisPort == -1) {
                axisPort = 8080;
            }
            String axisPath = url.getPath();
            axisURL = "http://" + axisHost + ":" + axisPort + axisPath;
        } catch (MalformedURLException e) {
            JOptionPane pane = new JOptionPane();
            String msg = e.toString();
            pane.setMessageType(JOptionPane.WARNING_MESSAGE);
            pane.setMessage(msg);
            pane.setOptions(new String[]{"OK"});
            JDialog dlg = pane.createDialog(null, "Login status");
            dlg.setVisible(true);
            login_btn.setEnabled(true);
            return false;
        }
        titleLabel.setText(titleStr + " for [" + axisHost + ":" + axisPort
                + "]");
        final JProgressBar progressBar = new JProgressBar(0, 100);
        BarThread stepper = new BarThread(progressBar);
        stepper.start();
        JFrame progress = new JFrame();
        d = new Dimension(250, 50);
        progress.setSize(d);
        d = getToolkit().getScreenSize();
        progress.getContentPane().add(progressBar);
        progress.setTitle("Now loading data ...");
        progress.setLocation((d.width - progress.getWidth()) / 2,
                (d.height - progress.getHeight()) / 2);
        progress.show();

        // Add notebook page for default host connection
        pages = new Vector();
        addPage(new SOAPMonitorPage(axisHost));
        serviceMap = new HashMap();
        originalDoc = getServerWSDD();
        model1.clear();
        model2.clear();
        if (originalDoc != null) {
            String ret = null;
            NodeList nl = originalDoc.getElementsByTagName("service");
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                NamedNodeMap map = node.getAttributes();
                ret = map.getNamedItem("name").getNodeValue();
                serviceMap.put(ret, node);
                if (!isMonitored(node)) {
                    model1.addElement((String) ret);
                } else {
                    model2.addElement((String) ret);
                }
            }
            if (model1.size() > 0) {
                add_btn.setEnabled(true);
            }
            if (model2.size() > 0) {
                del_btn.setEnabled(true);
            }
            progress.dispose();
            save_btn.setEnabled(true);
            login_btn.setEnabled(true);
            top_pane.setEnabled(true);
            return true;
        } else {
            progress.dispose();
            login_btn.setEnabled(true);
            return false;
        }
    }

    /**
     * This class is a thred for a JProgressBar.
     */
    class BarThread extends Thread {

        /**
         * Field wait
         */
        private int wait = 100;

        /**
         * Field progressBar
         */
        JProgressBar progressBar = null;

        /**
         * Constructor BarThread
         * 
         * @param bar 
         */
        public BarThread(JProgressBar bar) {
            progressBar = bar;
        }

        /**
         * Method run
         */
        public void run() {
            int min = progressBar.getMinimum();
            int max = progressBar.getMaximum();
            Runnable runner = new Runnable() {
                public void run() {
                    int val = progressBar.getValue();
                    progressBar.setValue(val + 1);
                }
            };
            for (int i = min; i < max; i++) {
                try {
                    SwingUtilities.invokeAndWait(runner);
                    Thread.sleep(wait);
                } catch (InterruptedException ignoredException) {
                } catch (InvocationTargetException ignoredException) {
                }
            }
        }
    }

    /**
     * Get the server-config.wsdd as a document to retrieve deployed services
     * 
     * @return 
     */
    private Document getServerWSDD() {
        Document doc = null;
        try {
            String[] param = new String[]{"-u" + axisUser, "-w" + axisPass,
                                          "-l " + axisURL, "list"};
            String ret = adminClient.process(param);
            doc = XMLUtils.newDocument(
                    new ByteArrayInputStream(ret.getBytes()));
        } catch (Exception e) {
            JOptionPane pane = new JOptionPane();
            String msg = e.toString();
            pane.setMessageType(JOptionPane.WARNING_MESSAGE);
            pane.setMessage(msg);
            pane.setOptions(new String[]{"OK"});
            JDialog dlg = pane.createDialog(null, "Login status");
            dlg.setVisible(true);
        }
        return doc;
    }

    /**
     * Deploy the specified wsdd to change the monitoring state
     * 
     * @param wsdd 
     * @return 
     */
    private boolean doDeploy(Document wsdd) {
        String deploy = null;
        Options opt = null;
        deploy = XMLUtils.DocumentToString(wsdd);
        try {
            String[] param = new String[]{"-u" + axisUser, "-w" + axisPass,
                                          "-l " + axisURL, ""};
            opt = new Options(param);
            adminClient.process(opt,
                    new ByteArrayInputStream(deploy.getBytes()));
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * Get a new document which has the specified node as the document root
     * 
     * @param target 
     * @return 
     */
    private Document getNewDocumentAsNode(Node target) {
        Document doc = null;
        Node node = null;
        try {
            doc = XMLUtils.newDocument();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        node = doc.importNode(target, true);
        doc.appendChild(node);
        return doc;
    }

    /**
     * Add needed nodes for monitoring to the specified node
     * <p/>
     * TODO: support JAX-RPC type definition (i.e. <handlerInfoChain/>)
     * 
     * @param target 
     * @return 
     */
    private Node addMonitor(Node target) {
        Document doc = null;
        Node node = null;
        Node newNode = null;
        String ret = null;
        NodeList nl = null;
        final String reqFlow = "requestFlow";
        final String resFlow = "responseFlow";
        final String monitor = "soapmonitor";
        final String handler = "handler";
        final String type = "type";
        doc = getNewDocumentAsNode(target);

        // Add "responseFlow node
        nl = doc.getElementsByTagName(resFlow);
        if (nl.getLength() == 0) {
            node = doc.getDocumentElement().getFirstChild();
            newNode = doc.createElement(resFlow);
            doc.getDocumentElement().insertBefore(newNode, node);
        }

        // Add "requestFlow" node
        nl = doc.getElementsByTagName(reqFlow);
        if (nl.getLength() == 0) {
            node = doc.getDocumentElement().getFirstChild();
            newNode = doc.createElement(reqFlow);
            doc.getDocumentElement().insertBefore(newNode, node);
        }

        // Add "handler" node and "soapmonitor" attribute for "requestFlow"
        nl = doc.getElementsByTagName(reqFlow);
        node = nl.item(0).getFirstChild();
        newNode = doc.createElement(handler);
        ((Element) newNode).setAttribute(type, monitor);
        nl.item(0).insertBefore(newNode, node);

        // Add "handler" node and "soapmonitor" attribute for "responseFlow"
        nl = doc.getElementsByTagName(resFlow);
        node = nl.item(0).getFirstChild();
        newNode = doc.createElement(handler);
        ((Element) newNode).setAttribute(type, monitor);
        nl.item(0).insertBefore(newNode, node);
        
        return (Node) doc.getDocumentElement();
    }

    /**
     * Remove a few nodes for stoping monitor from the specified node
     * <p/>
     * TODO: support JAX-RPC type definition (i.e. <handlerInfoChain/>)
     * 
     * @param target 
     * @return 
     */
    private Node delMonitor(Node target) {
        Document doc = null;
        Node node = null;
        Node newNode = null;
        String ret = null;
        NodeList nl = null;
        final String reqFlow = "requestFlow";
        final String resFlow = "responseFlow";
        final String monitor = "soapmonitor";
        final String handler = "handler";
        final String type = "type";
        doc = getNewDocumentAsNode(target);
        nl = doc.getElementsByTagName(handler);
        int size;
        size = nl.getLength();
        Node[] removeNode = new Node[size];
        if (size > 0) {
            newNode = nl.item(0).getParentNode();
        }
        for (int i = 0; i < size; i++) {
            node = nl.item(i);
            NamedNodeMap map = node.getAttributes();
            ret = map.getNamedItem(type).getNodeValue();
            if (ret.equals(monitor)) {
                removeNode[i] = node;
            }
        }
        for (int i = 0; i < size; i++) {
            Node child = removeNode[i];
            if (child != null) {
                child.getParentNode().removeChild(child);
            }
        }

        return (Node) doc.getDocumentElement();
    }

    /**
     * Get a boolean value whether the specified node is monitoring or not
     * 
     * @param target 
     * @return 
     */
    private boolean isMonitored(Node target) {
        Document doc = null;
        Node node = null;
        String ret = null;
        NodeList nl = null;
        final String monitor = "soapmonitor";
        final String handler = "handler";
        final String type = "type";
        doc = getNewDocumentAsNode(target);
        nl = doc.getElementsByTagName(handler);
        for (int i = 0; i < nl.getLength(); i++) {
            node = nl.item(i);
            NamedNodeMap map = node.getAttributes();
            ret = map.getNamedItem(type).getNodeValue();
            if (ret.equals(monitor)) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * Add a few nodes for authentification
     * <p/>
     * TODO: support JAX-RPC type definition (i.e. <handlerInfoChain/>)
     * 
     * @param target 
     * @return 
     */
    private Node addAuthenticate(Node target) {
        Document doc = null;
        Node node = null;
        Node newNode = null;
        String ret = null;
        NodeList nl = null;
        final String reqFlow = "requestFlow";
        final String handler = "handler";
        final String type = "type";
        final String authentication =
                "java:org.apache.axis.handlers.SimpleAuthenticationHandler";
        final String authorization =
                "java:org.apache.axis.handlers.SimpleAuthorizationHandler";
        final String param = "parameter";
        final String name = "name";
        final String role = "allowedRoles";
        final String value = "value";
        final String admin = "admin";
        boolean authNode = false;
        boolean roleNode = false;
        doc = getNewDocumentAsNode(target);

        // Add "requestFlow" node
        nl = doc.getElementsByTagName(reqFlow);
        if (nl.getLength() == 0) {
            node = doc.getDocumentElement().getFirstChild();
            newNode = doc.createElement(reqFlow);
            doc.getDocumentElement().insertBefore(newNode, node);
        }

        // Add "SimpleAuthorizationHandler"
        // (i.e. <handler type="java:org.apache.axis.handlers.SimpleAuthorizationHandler"/>)
        nl = doc.getElementsByTagName(handler);
        for (int i = 0; i < nl.getLength(); i++) {
            node = nl.item(i);
            NamedNodeMap map = node.getAttributes();
            ret = map.getNamedItem(type).getNodeValue();
            if (ret.equals(authorization)) {
                authNode = true;
                break;
            }
        }
        if (!authNode) {
            nl = doc.getElementsByTagName(reqFlow);
            node = nl.item(0).getFirstChild();
            newNode = doc.createElement(handler);
            ((Element) newNode).setAttribute(type, authorization);
            nl.item(0).insertBefore(newNode, node);
        }        

        // Add "SimpleAuthenticationHandler"
        // (i.e. <handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>)
        authNode = false;
        nl = doc.getElementsByTagName(handler);
        for (int i = 0; i < nl.getLength(); i++) {
            node = nl.item(i);
            NamedNodeMap map = node.getAttributes();
            ret = map.getNamedItem(type).getNodeValue();
            if (ret.equals(authentication)) {
                authNode = true;
                break;
            }
        }
        if (!authNode) {
            nl = doc.getElementsByTagName(reqFlow);
            node = nl.item(0).getFirstChild();
            newNode = doc.createElement(handler);
            ((Element) newNode).setAttribute(type, authentication);
            nl.item(0).insertBefore(newNode, node);
        }

        // Add "allowedRoles" (i.e. <parameter name="allowedRoles" value="admin"/> )
        nl = doc.getElementsByTagName(param);
        for (int i = 0; i < nl.getLength(); i++) {
            node = nl.item(i);
            NamedNodeMap map = node.getAttributes();
            node = map.getNamedItem(name);
            if (node != null) {
                ret = node.getNodeValue();
                if (ret.equals(role)) {
                    roleNode = true;
                    break;
                }
            }
        }
        if (!roleNode) {
            nl = doc.getElementsByTagName(param);
            newNode = doc.createElement(param);
            ((Element) newNode).setAttribute(name, role);
            ((Element) newNode).setAttribute(value, admin);
            doc.getDocumentElement().insertBefore(newNode, nl.item(0));
        }
        return (Node) doc.getDocumentElement();
    }

    /**
     * Handle the window close event
     */
    class MyWindowAdapter extends WindowAdapter {

        /**
         * Method windowClosing
         * 
         * @param e 
         */
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }

    /**
     * Add a page to the notebook
     * 
     * @param pg 
     */
    private void addPage(SOAPMonitorPage pg) {
        tabbed_pane.addTab("  " + pg.getHost() + "  ", pg);
        pages.addElement(pg);
    }

    /**
     * Del all pages to the notebook
     */
    private void delPage() {
        tabbed_pane.removeAll();
        pages.removeAllElements();
    }

    /**
     * Frame is being displayed
     */
    public void start() {
        // Tell all pages to start talking to the server
        Enumeration e = pages.elements();
        while (e.hasMoreElements()) {
            SOAPMonitorPage pg = (SOAPMonitorPage) e.nextElement();
            if (pg != null) {
                pg.start();
            }
        }
    }

    /*
     * Frame is no longer displayed
     */

    /**
     * Method stop
     */
    public void stop() {
        // Tell all pages to stop talking to the server
        Enumeration e = pages.elements();
        while (e.hasMoreElements()) {
            SOAPMonitorPage pg = (SOAPMonitorPage) e.nextElement();
            if (pg != null) {
                pg.stop();
            }
        }
    }

    /**
     * This class is for the Login Dialog
     */
    class LoginDlg extends JDialog implements ActionListener {

        /**
         * Field ok_button
         */
        private JButton ok_button = null;

        /**
         * Field cancel_button
         */
        private JButton cancel_button = null;

        /**
         * Field user
         */
        private JTextField user = new JTextField(20);

        /**
         * Field pass
         */
        private JPasswordField pass = new JPasswordField(20);

        /**
         * Field url
         */
        private JTextField url = new JTextField(20);

        /**
         * Field loginState
         */
        private boolean loginState = false;

        /**
         * Constructor (create and layout page)
         */
        public LoginDlg() {
            setTitle("SOAP Monitor Login");
            UIManager.put("Label.font", new Font("Dialog", Font.BOLD, 12));
            JPanel panel = new JPanel();
            ok_button = new JButton("OK");
            ok_button.addActionListener(this);
            cancel_button = new JButton("Cancel");
            cancel_button.addActionListener(this);

            // default URL for AxisServlet
            url.setText(axisURL);
            JLabel userLabel = new JLabel("User:");
            JLabel passLabel = new JLabel("Password:");
            JLabel urlLabel = new JLabel("Axis URL:");
            userLabel.setHorizontalAlignment(JTextField.RIGHT);
            passLabel.setHorizontalAlignment(JTextField.RIGHT);
            urlLabel.setHorizontalAlignment(JTextField.RIGHT);
            panel.add(userLabel);
            panel.add(user);
            panel.add(passLabel);
            panel.add(pass);
            panel.add(urlLabel);
            panel.add(url);
            panel.add(ok_button);
            panel.add(cancel_button);
            setContentPane(panel);
            user.setText(SOAPMonitor.axisUser);
            pass.setText(SOAPMonitor.axisPass);
            GridLayout layout = new GridLayout(4, 2);
            layout.setHgap(15);
            layout.setVgap(5);
            panel.setLayout(layout);
            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            setModal(true);
            pack();
            Dimension d = getToolkit().getScreenSize();
            setLocation((d.width - getWidth()) / 2,
                    (d.height - getHeight()) / 2);
        }

        /**
         * Listener to handle button actions
         * 
         * @param e 
         */
        public void actionPerformed(ActionEvent e) {
            // Check if the user pressed the OK button
            if (e.getSource() == ok_button) {
                loginState = true;
                SOAPMonitor.axisUser = user.getText();
                SOAPMonitor.axisPass = new String(pass.getPassword());
                this.hide();
            } else if (e.getSource() == cancel_button) {
                this.dispose();
            }
        }

        /**
         * Get the URL of the AxisServlet we are using
         * 
         * @return 
         */
        public String getURL() {
            return url.getText();
        }

        /**
         * Get the login status as a boolean
         * 
         * @return 
         */
        public boolean isLogin() {
            return loginState;
        }
    }

    /**
     * This class provides the contents of a notebook page
     * representing a server connection.
     */
    class SOAPMonitorPage extends JPanel
            implements Runnable, ListSelectionListener, ActionListener {

        /**
         * Status Strings
         */
        private final String STATUS_ACTIVE = "The SOAP Monitor is started.";

        /**
         * Field STATUS_STOPPED
         */
        private final String STATUS_STOPPED = "The SOAP Monitor is stopped.";

        /**
         * Field STATUS_CLOSED
         */
        private final String STATUS_CLOSED =
                "The server communication has been terminated.";

        /**
         * Field STATUS_NOCONNECT
         */
        private final String STATUS_NOCONNECT =
                "The SOAP Monitor is unable to communcate with the server.";

        /**
         * Private data
         */
        private String host = null;

        /**
         * Field socket
         */
        private Socket socket = null;

        /**
         * Field in
         */
        private ObjectInputStream in = null;

        /**
         * Field out
         */
        private ObjectOutputStream out = null;

        /**
         * Field model
         */
        private SOAPMonitorTableModel model = null;

        /**
         * Field table
         */
        private JTable table = null;

        /**
         * Field scroll
         */
        private JScrollPane scroll = null;

        /**
         * Field list_panel
         */
        private JPanel list_panel = null;

        /**
         * Field list_buttons
         */
        private JPanel list_buttons = null;

        /**
         * Field remove_button
         */
        private JButton remove_button = null;

        /**
         * Field remove_all_button
         */
        private JButton remove_all_button = null;

        /**
         * Field filter_button
         */
        private JButton filter_button = null;

        /**
         * Field details_panel
         */
        private JPanel details_panel = null;

        /**
         * Field details_header
         */
        private JPanel details_header = null;

        /**
         * Field details_soap
         */
        private JSplitPane details_soap = null;

        /**
         * Field details_buttons
         */
        private JPanel details_buttons = null;

        /**
         * Field details_time
         */
        private JLabel details_time = null;

        /**
         * Field details_target
         */
        private JLabel details_target = null;

        /**
         * Field details_status
         */
        private JLabel details_status = null;

        /**
         * Field details_time_value
         */
        private JLabel details_time_value = null;

        /**
         * Field details_target_value
         */
        private JLabel details_target_value = null;

        /**
         * Field details_status_value
         */
        private JLabel details_status_value = null;

        /**
         * Field empty_border
         */
        private EmptyBorder empty_border = null;

        /**
         * Field etched_border
         */
        private EtchedBorder etched_border = null;

        /**
         * Field request_panel
         */
        private JPanel request_panel = null;

        /**
         * Field response_panel
         */
        private JPanel response_panel = null;

        /**
         * Field request_label
         */
        private JLabel request_label = null;

        /**
         * Field response_label
         */
        private JLabel response_label = null;

        /**
         * Field request_text
         */
        private SOAPMonitorTextArea request_text = null;

        /**
         * Field response_text
         */
        private SOAPMonitorTextArea response_text = null;

        /**
         * Field request_scroll
         */
        private JScrollPane request_scroll = null;

        /**
         * Field response_scroll
         */
        private JScrollPane response_scroll = null;

        /**
         * Field layout_button
         */
        private JButton layout_button = null;

        /**
         * Field split
         */
        private JSplitPane split = null;

        /**
         * Field status_area
         */
        private JPanel status_area = null;

        /**
         * Field status_buttons
         */
        private JPanel status_buttons = null;

        /**
         * Field start_button
         */
        private JButton start_button = null;

        /**
         * Field stop_button
         */
        private JButton stop_button = null;

        /**
         * Field status_text
         */
        private JLabel status_text = null;

        /**
         * Field status_text_panel
         */
        private JPanel status_text_panel = null;

        /**
         * Field filter
         */
        private SOAPMonitorFilter filter = null;

        /**
         * Field details_header_layout
         */
        private GridBagLayout details_header_layout = null;

        /**
         * Field details_header_constraints
         */
        private GridBagConstraints details_header_constraints = null;

        /**
         * Field reflow_xml
         */
        private JCheckBox reflow_xml = null;

        /**
         * Constructor (create and layout page)
         * 
         * @param host_name 
         */
        public SOAPMonitorPage(String host_name) {
            host = host_name;

            // Set up default filter (show all messages)
            filter = new SOAPMonitorFilter();

            // Use borders to help improve appearance
            etched_border = new EtchedBorder();

            // Build top portion of split (list panel)
            model = new SOAPMonitorTableModel();
            table = new JTable(model);
            table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            table.setRowSelectionInterval(0, 0);
            table.setPreferredScrollableViewportSize(new Dimension(600, 96));
            table.getSelectionModel().addListSelectionListener(this);
            scroll = new JScrollPane(table);
            remove_button = new JButton("Remove");
            remove_button.addActionListener(this);
            remove_button.setEnabled(false);
            remove_all_button = new JButton("Remove All");
            remove_all_button.addActionListener(this);
            filter_button = new JButton("Filter ...");
            filter_button.addActionListener(this);
            list_buttons = new JPanel();
            list_buttons.setLayout(new FlowLayout());
            list_buttons.add(remove_button);
            list_buttons.add(remove_all_button);
            list_buttons.add(filter_button);
            list_panel = new JPanel();
            list_panel.setLayout(new BorderLayout());
            list_panel.add(scroll, BorderLayout.CENTER);
            list_panel.add(list_buttons, BorderLayout.SOUTH);
            list_panel.setBorder(empty_border);

            // Build bottom portion of split (message details)
            details_time = new JLabel("Time: ", SwingConstants.RIGHT);
            details_target = new JLabel("Target Service: ",
                    SwingConstants.RIGHT);
            details_status = new JLabel("Status: ", SwingConstants.RIGHT);
            details_time_value = new JLabel();
            details_target_value = new JLabel();
            details_status_value = new JLabel();
            Dimension preferred_size = details_time.getPreferredSize();
            preferred_size.width = 1;
            details_time.setPreferredSize(preferred_size);
            details_target.setPreferredSize(preferred_size);
            details_status.setPreferredSize(preferred_size);
            details_time_value.setPreferredSize(preferred_size);
            details_target_value.setPreferredSize(preferred_size);
            details_status_value.setPreferredSize(preferred_size);
            details_header = new JPanel();
            details_header_layout = new GridBagLayout();
            details_header.setLayout(details_header_layout);
            details_header_constraints = new GridBagConstraints();
            details_header_constraints.fill = GridBagConstraints.BOTH;
            details_header_constraints.weightx = 0.5;
            details_header_layout.setConstraints(details_time,
                    details_header_constraints);
            details_header.add(details_time);
            details_header_layout.setConstraints(details_time_value,
                    details_header_constraints);
            details_header.add(details_time_value);
            details_header_layout.setConstraints(details_target,
                    details_header_constraints);
            details_header.add(details_target);
            details_header_constraints.weightx = 1.0;
            details_header_layout.setConstraints(details_target_value,
                    details_header_constraints);
            details_header.add(details_target_value);
            details_header_constraints.weightx = .5;
            details_header_layout.setConstraints(details_status,
                    details_header_constraints);
            details_header.add(details_status);
            details_header_layout.setConstraints(details_status_value,
                    details_header_constraints);
            details_header.add(details_status_value);
            details_header.setBorder(etched_border);
            request_label = new JLabel("SOAP Request", SwingConstants.CENTER);
            request_text = new SOAPMonitorTextArea();
            request_text.setEditable(false);
            request_scroll = new JScrollPane(request_text);
            request_panel = new JPanel();
            request_panel.setLayout(new BorderLayout());
            request_panel.add(request_label, BorderLayout.NORTH);
            request_panel.add(request_scroll, BorderLayout.CENTER);
            response_label =
                    new JLabel("SOAP Response", SwingConstants.CENTER);
            response_text = new SOAPMonitorTextArea();
            response_text.setEditable(false);
            response_scroll = new JScrollPane(response_text);
            response_panel = new JPanel();
            response_panel.setLayout(new BorderLayout());
            response_panel.add(response_label, BorderLayout.NORTH);
            response_panel.add(response_scroll, BorderLayout.CENTER);
            details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
            details_soap.setTopComponent(request_panel);
            details_soap.setRightComponent(response_panel);
            details_soap.setResizeWeight(.5);
            details_panel = new JPanel();
            layout_button = new JButton("Switch Layout");
            layout_button.addActionListener(this);
            reflow_xml = new JCheckBox("Reflow XML text");
            reflow_xml.addActionListener(this);
            details_buttons = new JPanel();
            details_buttons.setLayout(new FlowLayout());
            details_buttons.add(reflow_xml);
            details_buttons.add(layout_button);
            details_panel.setLayout(new BorderLayout());
            details_panel.add(details_header, BorderLayout.NORTH);
            details_panel.add(details_soap, BorderLayout.CENTER);
            details_panel.add(details_buttons, BorderLayout.SOUTH);
            details_panel.setBorder(empty_border);

            // Add the two parts to the age split pane
            split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
            split.setTopComponent(list_panel);
            split.setRightComponent(details_panel);

            // Build status area
            start_button = new JButton("Start");
            start_button.addActionListener(this);
            stop_button = new JButton("Stop");
            stop_button.addActionListener(this);
            status_buttons = new JPanel();
            status_buttons.setLayout(new FlowLayout());
            status_buttons.add(start_button);
            status_buttons.add(stop_button);
            status_text = new JLabel();
            status_text.setBorder(new BevelBorder(BevelBorder.LOWERED));
            status_text_panel = new JPanel();
            status_text_panel.setLayout(new BorderLayout());
            status_text_panel.add(status_text, BorderLayout.CENTER);
            status_text_panel.setBorder(empty_border);
            status_area = new JPanel();
            status_area.setLayout(new BorderLayout());
            status_area.add(status_buttons, BorderLayout.WEST);
            status_area.add(status_text_panel, BorderLayout.CENTER);
            status_area.setBorder(etched_border);

            // Add the split and status area to page
            setLayout(new BorderLayout());
            add(split, BorderLayout.CENTER);
            add(status_area, BorderLayout.SOUTH);
        }

        /**
         * Get the name of the host we are displaying
         * 
         * @return 
         */
        public String getHost() {
            return host;
        }

        /**
         * Set the status text
         * 
         * @param txt 
         */
        public void setStatus(String txt) {
            status_text.setForeground(Color.black);
            status_text.setText("  " + txt);
        }

        /**
         * Set the status text to an error
         * 
         * @param txt 
         */
        public void setErrorStatus(String txt) {
            status_text.setForeground(Color.red);
            status_text.setText("  " + txt);
        }

        /**
         * Start talking to the server
         */
        public void start() {
            String codehost = axisHost;
            if (socket == null) {
                try {
                    // Open the socket to the server
                    socket = new Socket(codehost, port);

                    // Create output stream
                    out = new ObjectOutputStream(socket.getOutputStream());
                    out.flush();

                    // Create input stream and start background
                    // thread to read data from the server
                    in = new ObjectInputStream(socket.getInputStream());
                    new Thread(this).start();
                } catch (Exception e) {
                    // Exceptions here are unexpected, but we can't
                    // really do anything (so just write it to stdout
                    // in case someone cares and then ignore it)
                    e.printStackTrace();
                    setErrorStatus(STATUS_NOCONNECT);
                    socket = null;
                }
            } else {
                // Already started
            }
            if (socket != null) {
                // Make sure the right buttons are enabled
                start_button.setEnabled(false);
                stop_button.setEnabled(true);
                setStatus(STATUS_ACTIVE);
            }
        }

        /**
         * Stop talking to the server
         */
        public void stop() {
            if (socket != null) {
                // Close all the streams and socket
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException ioe) {
                    }
                    out = null;
                }
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException ioe) {
                    }
                    in = null;
                }
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException ioe) {
                    }
                    socket = null;
                }
            } else {
                // Already stopped
            }

            // Make sure the right buttons are enabled
            start_button.setEnabled(true);
            stop_button.setEnabled(false);
            setStatus(STATUS_STOPPED);
        }

        /**
         * Background thread used to receive data from
         * the server.
         */
        public void run() {
            Long id;
            Integer message_type;
            String target;
            String soap;
            SOAPMonitorData data;
            int selected;
            int row;
            boolean update_needed;
            while (socket != null) {
                try {
                    // Get the data from the server
                    message_type = (Integer) in.readObject();

                    // Process the data depending on its type
                    switch (message_type.intValue()) {
                        case SOAPMonitorConstants.SOAP_MONITOR_REQUEST:

                            // Get the id, target and soap info
                            id = (Long) in.readObject();
                            target = (String) in.readObject();
                            soap = (String) in.readObject();

                            // Add new request data to the table
                            data = new SOAPMonitorData(id, target, soap);
                            model.addData(data);

                            // If "most recent" selected then update
                            // the details area if needed
                            selected = table.getSelectedRow();
                            if ((selected == 0) && model.filterMatch(data)) {
                                valueChanged(null);
                            }
                            break;
                        case SOAPMonitorConstants.SOAP_MONITOR_RESPONSE:

                            // Get the id and soap info
                            id = (Long) in.readObject();
                            soap = (String) in.readObject();
                            data = model.findData(id);
                            if (data != null) {
                                update_needed = false;

                                // Get the selected row
                                selected = table.getSelectedRow();

                                // If "most recent", then always
                                // update details area
                                if (selected == 0) {
                                    update_needed = true;
                                }

                                // If the data being updated is
                                // selected then update details
                                row = model.findRow(data);
                                if ((row != -1) && (row == selected)) {
                                    update_needed = true;
                                }

                                // Set the response and update table
                                data.setSOAPResponse(soap);
                                model.updateData(data);

                                // Refresh details area (if needed)
                                if (update_needed) {
                                    valueChanged(null);
                                }
                            }
                            break;
                    }
                } catch (Exception e) {
                    // Exceptions are expected here when the
                    // server communication has been terminated.
                    if (stop_button.isEnabled()) {
                        stop();
                        setErrorStatus(STATUS_CLOSED);
                    }
                }
            }
        }

        /**
         * Listener to handle table selection changes
         * 
         * @param e 
         */
        public void valueChanged(ListSelectionEvent e) {
            int row = table.getSelectedRow();

            // Check if they selected a specific row
            if (row > 0) {
                remove_button.setEnabled(true);
            } else {
                remove_button.setEnabled(false);
            }

            // Check for "most recent" selection
            if (row == 0) {
                row = model.getRowCount() - 1;
                if (row == 0) {
                    row = -1;
                }
            }
            if (row == -1) {
                // Clear the details panel
                details_time_value.setText("");
                details_target_value.setText("");
                details_status_value.setText("");
                request_text.setText("");
                response_text.setText("");
            } else {
                // Show the details for the row
                SOAPMonitorData soap = model.getData(row);
                details_time_value.setText(soap.getTime());
                details_target_value.setText(soap.getTargetService());
                details_status_value.setText(soap.getStatus());
                if (soap.getSOAPRequest() == null) {
                    request_text.setText("");
                } else {
                    request_text.setText(soap.getSOAPRequest());
                    request_text.setCaretPosition(0);
                }
                if (soap.getSOAPResponse() == null) {
                    response_text.setText("");
                } else {
                    response_text.setText(soap.getSOAPResponse());
                    response_text.setCaretPosition(0);
                }
            }
        }

        /**
         * Listener to handle button actions
         * 
         * @param e 
         */
        public void actionPerformed(ActionEvent e) {
            // Check if the user pressed the remove button
            if (e.getSource() == remove_button) {
                int row = table.getSelectedRow();
                model.removeRow(row);
                table.clearSelection();
                table.repaint();
                valueChanged(null);
            }

            // Check if the user pressed the remove all button
            if (e.getSource() == remove_all_button) {
                model.clearAll();
                table.setRowSelectionInterval(0, 0);
                table.repaint();
                valueChanged(null);
            }

            // Check if the user pressed the filter button
            if (e.getSource() == filter_button) {
                filter.showDialog();
                if (filter.okPressed()) {
                    // Update the display with new filter
                    model.setFilter(filter);
                    table.repaint();
                }
            }

            // Check if the user pressed the start button
            if (e.getSource() == start_button) {
                start();
            }

            // Check if the user pressed the stop button
            if (e.getSource() == stop_button) {
                stop();
            }

            // Check if the user wants to switch layout
            if (e.getSource() == layout_button) {
                details_panel.remove(details_soap);
                details_soap.removeAll();
                if (details_soap.getOrientation()
                        == JSplitPane.HORIZONTAL_SPLIT) {
                    details_soap = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
                } else {
                    details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
                }
                details_soap.setTopComponent(request_panel);
                details_soap.setRightComponent(response_panel);
                details_soap.setResizeWeight(.5);
                details_panel.add(details_soap, BorderLayout.CENTER);
                details_panel.validate();
                details_panel.repaint();
            }

            // Check if the user is changing the reflow option
            if (e.getSource() == reflow_xml) {
                request_text.setReflowXML(reflow_xml.isSelected());
                response_text.setReflowXML(reflow_xml.isSelected());
            }
        }
    }

    /**
     * This class represend the data for a SOAP request/response pair
     */
    class SOAPMonitorData {

        /**
         * Private data
         */
        private Long id;

        /**
         * Field time
         */
        private String time;

        /**
         * Field target
         */
        private String target;

        /**
         * Field soap_request
         */
        private String soap_request;

        /**
         * Field soap_response
         */
        private String soap_response;

        /**
         * Constructor
         * 
         * @param id           
         * @param target       
         * @param soap_request 
         */
        public SOAPMonitorData(Long id, String target, String soap_request) {
            this.id = id;

            // A null id is used to signal that the "most recent" entry
            // is being created.
            if (id == null) {
                this.time = "Most Recent";
                this.target = "---";
                this.soap_request = null;
                this.soap_response = null;
            } else {
                this.time =
                        DateFormat.getTimeInstance().format(new Date());
                this.target = target;
                this.soap_request = soap_request;
                this.soap_response = null;
            }
        }

        /**
         * Get the id for the SOAP message
         * 
         * @return 
         */
        public Long getId() {
            return id;
        }

        /**
         * Get the time the SOAP request was received by the application
         * 
         * @return 
         */
        public String getTime() {
            return time;
        }

        /**
         * Get the SOAP request target service name
         * 
         * @return 
         */
        public String getTargetService() {
            return target;
        }

        /**
         * Get the status of the request
         * 
         * @return 
         */
        public String getStatus() {
            String status = "---";
            if (id != null) {
                status = "Complete";
                if (soap_response == null) {
                    status = "Active";
                }
            }
            return status;
        }

        /**
         * Get the request SOAP contents
         * 
         * @return 
         */
        public String getSOAPRequest() {
            return soap_request;
        }

        /**
         * Set the resposne SOAP contents
         * 
         * @param response 
         */
        public void setSOAPResponse(String response) {
            soap_response = response;
        }

        /**
         * Get the response SOAP contents
         * 
         * @return 
         */
        public String getSOAPResponse() {
            return soap_response;
        }
    }

    /**
     * This table model is used to manage the table displayed
     * at the top of the page to show all the SOAP messages
     * we have received and to control which message details are
     * to be displayed on the bottom of the page.
     */
    class SOAPMonitorTableModel extends AbstractTableModel {

        /**
         * Column titles
         */
        private final String[] column_names = {"Time", "Target Service",
                                               "Status"};

        /**
         * Private data
         */
        private Vector data;

        /**
         * Field filter_include
         */
        private Vector filter_include;

        /**
         * Field filter_exclude
         */
        private Vector filter_exclude;

        /**
         * Field filter_active
         */
        private boolean filter_active;

        /**
         * Field filter_complete
         */
        private boolean filter_complete;

        /**
         * Field filter_data
         */
        private Vector filter_data;

        /**
         * Constructor
         */
        public SOAPMonitorTableModel() {
            data = new Vector();

            // Add "most recent" entry to top of table
            SOAPMonitorData soap = new SOAPMonitorData(null, null, null);
            data.addElement(soap);
            filter_include = null;
            filter_exclude = null;
            filter_active = false;
            filter_complete = false;
            filter_data = null;

            // By default, exclude NotificationService and
            // EventViewerService messages
            filter_exclude = new Vector();
            filter_exclude.addElement("NotificationService");
            filter_exclude.addElement("EventViewerService");
            filter_data = new Vector();
            filter_data.addElement(soap);
        }

        /**
         * Get column count (part of table model interface)
         * 
         * @return 
         */
        public int getColumnCount() {
            return column_names.length;
        }

        /**
         * Get row count (part of table model interface)
         * 
         * @return 
         */
        public int getRowCount() {
            int count = data.size();
            if (filter_data != null) {
                count = filter_data.size();
            }
            return count;
        }

        /**
         * Get column name (part of table model interface)
         * 
         * @param col 
         * @return 
         */
        public String getColumnName(int col) {
            return column_names[col];
        }

        /**
         * Get value at (part of table model interface)
         * 
         * @param row 
         * @param col 
         * @return 
         */
        public Object getValueAt(int row, int col) {
            SOAPMonitorData soap;
            String value = null;
            soap = (SOAPMonitorData) data.elementAt(row);
            if (filter_data != null) {
                soap = (SOAPMonitorData) filter_data.elementAt(row);
            }
            switch (col) {
                case 0:
                    value = soap.getTime();
                    break;
                case 1:
                    value = soap.getTargetService();
                    break;
                case 2:
                    value = soap.getStatus();
                    break;
            }
            return value;
        }

        /**
         * Check if soap data matches filter
         * 
         * @param soap 
         * @return 
         */
        public boolean filterMatch(SOAPMonitorData soap) {
            boolean match = true;
            if (filter_include != null) {
                // Check for service match
                Enumeration e = filter_include.elements();
                match = false;
                while (e.hasMoreElements() && !match) {
                    String service = (String) e.nextElement();
                    if (service.equals(soap.getTargetService())) {
                        match = true;
                    }
                }
            }
            if (filter_exclude != null) {
                // Check for service match
                Enumeration e = filter_exclude.elements();
                while (e.hasMoreElements() && match) {
                    String service = (String) e.nextElement();
                    if (service.equals(soap.getTargetService())) {
                        match = false;
                    }
                }
            }
            if (filter_active) {
                // Check for active status match
                if (soap.getSOAPResponse() != null) {
                    match = false;
                }
            }
            if (filter_complete) {
                // Check for complete status match
                if (soap.getSOAPResponse() == null) {
                    match = false;
                }
            }

            // The "most recent" is always a match
            if (soap.getId() == null) {
                match = true;
            }
            return match;
        }

        /**
         * Add data to the table as a new row
         * 
         * @param soap 
         */
        public void addData(SOAPMonitorData soap) {
            int row = data.size();
            data.addElement(soap);
            if (filter_data != null) {
                if (filterMatch(soap)) {
                    row = filter_data.size();
                    filter_data.addElement(soap);
                    fireTableRowsInserted(row, row);
                }
            } else {
                fireTableRowsInserted(row, row);
            }
        }

        /**
         * Find the data for a given id
         * 
         * @param id 
         * @return 
         */
        public SOAPMonitorData findData(Long id) {
            SOAPMonitorData soap = null;
            for (int row = data.size(); (row > 0) && (soap == null); row--) {
                soap = (SOAPMonitorData) data.elementAt(row - 1);
                if (soap.getId().longValue() != id.longValue()) {
                    soap = null;
                }
            }
            return soap;
        }

        /**
         * Find the row in the table for a given message id
         * 
         * @param soap 
         * @return 
         */
        public int findRow(SOAPMonitorData soap) {
            int row = -1;
            if (filter_data != null) {
                row = filter_data.indexOf(soap);
            } else {
                row = data.indexOf(soap);
            }
            return row;
        }

        /**
         * Remove all messages from the table (but leave "most recent")
         */
        public void clearAll() {
            int last_row = data.size() - 1;
            if (last_row > 0) {
                data.removeAllElements();
                SOAPMonitorData soap = new SOAPMonitorData(null, null, null);
                data.addElement(soap);
                if (filter_data != null) {
                    filter_data.removeAllElements();
                    filter_data.addElement(soap);
                }
                fireTableDataChanged();
            }
        }

        /**
         * Remove a message from the table
         * 
         * @param row 
         */
        public void removeRow(int row) {
            SOAPMonitorData soap = null;
            if (filter_data == null) {
                soap = (SOAPMonitorData) data.elementAt(row);
                data.remove(soap);
            } else {
                soap = (SOAPMonitorData) filter_data.elementAt(row);
                filter_data.remove(soap);
                data.remove(soap);
            }
            fireTableRowsDeleted(row, row);
        }

        /**
         * Set a new filter
         * 
         * @param filter 
         */
        public void setFilter(SOAPMonitorFilter filter) {
            // Save new filter criteria
            filter_include = filter.getFilterIncludeList();
            filter_exclude = filter.getFilterExcludeList();
            filter_active = filter.getFilterActive();
            filter_complete = filter.getFilterComplete();
            applyFilter();
        }

        /**
         * Refilter the list of messages
         */
        public void applyFilter() {
            // Re-filter using new criteria
            filter_data = null;
            if ((filter_include != null) || (filter_exclude != null)
                    || filter_active || filter_complete) {
                filter_data = new Vector();
                Enumeration e = data.elements();
                SOAPMonitorData soap;
                while (e.hasMoreElements()) {
                    soap = (SOAPMonitorData) e.nextElement();
                    if (filterMatch(soap)) {
                        filter_data.addElement(soap);
                    }
                }
            }
            fireTableDataChanged();
        }

        /**
         * Get the data for a row
         * 
         * @param row 
         * @return 
         */
        public SOAPMonitorData getData(int row) {
            SOAPMonitorData soap = null;
            if (filter_data == null) {
                soap = (SOAPMonitorData) data.elementAt(row);
            } else {
                soap = (SOAPMonitorData) filter_data.elementAt(row);
            }
            return soap;
        }

        /**
         * Update a message
         * 
         * @param soap 
         */
        public void updateData(SOAPMonitorData soap) {
            int row;
            if (filter_data == null) {
                // No filter, so just fire table updated
                row = data.indexOf(soap);
                if (row != -1) {
                    fireTableRowsUpdated(row, row);
                }
            } else {
                // Check if the row was being displayed
                row = filter_data.indexOf(soap);
                if (row == -1) {
                    // Row was not displayed, so check for if it
                    // now needs to be displayed
                    if (filterMatch(soap)) {
                        int index = -1;
                        row = data.indexOf(soap) + 1;
                        while ((row < data.size()) && (index == -1)) {
                            index = filter_data.indexOf(data.elementAt(row));
                            if (index != -1) {
                                // Insert at this location
                                filter_data.add(index, soap);
                            }
                            row++;
                        }
                        if (index == -1) {
                            // Insert at end
                            index = filter_data.size();
                            filter_data.addElement(soap);
                        }
                        fireTableRowsInserted(index, index);
                    }
                } else {
                    // Row was displayed, so check if it needs to
                    // be updated or removed
                    if (filterMatch(soap)) {
                        fireTableRowsUpdated(row, row);
                    } else {
                        filter_data.remove(soap);
                        fireTableRowsDeleted(row, row);
                    }
                }
            }
        }
    }

    /**
     * Panel with checkbox and list
     */
    class ServiceFilterPanel extends JPanel
            implements ActionListener, ListSelectionListener, DocumentListener {

        /**
         * Field service_box
         */
        private JCheckBox service_box = null;

        /**
         * Field filter_list
         */
        private Vector filter_list = null;

        /**
         * Field service_data
         */
        private Vector service_data = null;

        /**
         * Field service_list
         */
        private JList service_list = null;

        /**
         * Field service_scroll
         */
        private JScrollPane service_scroll = null;

        /**
         * Field remove_service_button
         */
        private JButton remove_service_button = null;

        /**
         * Field remove_service_panel
         */
        private JPanel remove_service_panel = null;

        /**
         * Field indent_border
         */
        private EmptyBorder indent_border = null;

        /**
         * Field empty_border
         */
        private EmptyBorder empty_border = null;

        /**
         * Field service_area
         */
        private JPanel service_area = null;

        /**
         * Field add_service_area
         */
        private JPanel add_service_area = null;

        /**
         * Field add_service_field
         */
        private JTextField add_service_field = null;

        /**
         * Field add_service_button
         */
        private JButton add_service_button = null;

        /**
         * Field add_service_panel
         */
        private JPanel add_service_panel = null;

        /**
         * Constructor
         * 
         * @param text 
         * @param list 
         */
        public ServiceFilterPanel(String text, Vector list) {
            empty_border = new EmptyBorder(5, 5, 0, 5);
            indent_border = new EmptyBorder(5, 25, 5, 5);
            service_box = new JCheckBox(text);
            service_box.addActionListener(this);
            service_data = new Vector();
            if (list != null) {
                service_box.setSelected(true);
                service_data = (Vector) list.clone();
            }
            service_list = new JList(service_data);
            service_list.setBorder(new EtchedBorder());
            service_list.setVisibleRowCount(5);
            service_list.addListSelectionListener(this);
            service_list.setEnabled(service_box.isSelected());
            service_scroll = new JScrollPane(service_list);
            service_scroll.setBorder(new EtchedBorder());
            remove_service_button = new JButton("Remove");
            remove_service_button.addActionListener(this);
            remove_service_button.setEnabled(false);
            remove_service_panel = new JPanel();
            remove_service_panel.setLayout(new FlowLayout());
            remove_service_panel.add(remove_service_button);
            service_area = new JPanel();
            service_area.setLayout(new BorderLayout());
            service_area.add(service_scroll, BorderLayout.CENTER);
            service_area.add(remove_service_panel, BorderLayout.EAST);
            service_area.setBorder(indent_border);
            add_service_field = new JTextField();
            add_service_field.addActionListener(this);
            add_service_field.getDocument().addDocumentListener(this);
            add_service_field.setEnabled(service_box.isSelected());
            add_service_button = new JButton("Add");
            add_service_button.addActionListener(this);
            add_service_button.setEnabled(false);
            add_service_panel = new JPanel();
            add_service_panel.setLayout(new BorderLayout());
            JPanel dummy = new JPanel();
            dummy.setBorder(empty_border);
            add_service_panel.add(dummy, BorderLayout.WEST);
            add_service_panel.add(add_service_button, BorderLayout.EAST);
            add_service_area = new JPanel();
            add_service_area.setLayout(new BorderLayout());
            add_service_area.add(add_service_field, BorderLayout.CENTER);
            add_service_area.add(add_service_panel, BorderLayout.EAST);
            add_service_area.setBorder(indent_border);
            setLayout(new BorderLayout());
            add(service_box, BorderLayout.NORTH);
            add(service_area, BorderLayout.CENTER);
            add(add_service_area, BorderLayout.SOUTH);
            setBorder(empty_border);
        }

        /**
         * Get the current list of services
         * 
         * @return 
         */
        public Vector getServiceList() {
            Vector list = null;
            if (service_box.isSelected()) {
                list = service_data;
            }
            return list;
        }

        /**
         * Listener to handle button actions
         * 
         * @param e 
         */
        public void actionPerformed(ActionEvent e) {
            // Check if the user changed the service filter option
            if (e.getSource() == service_box) {
                service_list.setEnabled(service_box.isSelected());
                service_list.clearSelection();
                remove_service_button.setEnabled(false);
                add_service_field.setEnabled(service_box.isSelected());
                add_service_field.setText("");
                add_service_button.setEnabled(false);
            }

            // Check if the user pressed the add service button
            if ((e.getSource() == add_service_button)
                    || (e.getSource() == add_service_field)) {
                String text = add_service_field.getText();
                if ((text != null) && (text.length() > 0)) {
                    service_data.addElement(text);
                    service_list.setListData(service_data);
                }
                add_service_field.setText("");
                add_service_field.requestFocus();
            }

            // Check if the user pressed the remove service button
            if (e.getSource() == remove_service_button) {
                Object[] sels = service_list.getSelectedValues();
                for (int i = 0; i < sels.length; i++) {
                    service_data.removeElement(sels[i]);
                }
                service_list.setListData(service_data);
                service_list.clearSelection();
            }
        }

        /**
         * Handle changes to the text field
         * 
         * @param e 
         */
        public void changedUpdate(DocumentEvent e) {
            String text = add_service_field.getText();
            if ((text != null) && (text.length() > 0)) {
                add_service_button.setEnabled(true);
            } else {
                add_service_button.setEnabled(false);
            }
        }

        /**
         * Handle changes to the text field
         * 
         * @param e 
         */
        public void insertUpdate(DocumentEvent e) {
            changedUpdate(e);
        }

        /**
         * Handle changes to the text field
         * 
         * @param e 
         */
        public void removeUpdate(DocumentEvent e) {
            changedUpdate(e);
        }

        /**
         * Listener to handle service list selection changes
         * 
         * @param e 
         */
        public void valueChanged(ListSelectionEvent e) {
            if (service_list.getSelectedIndex() == -1) {
                remove_service_button.setEnabled(false);
            } else {
                remove_service_button.setEnabled(true);
            }
        }
    }

    /**
     * Class for showing the filter dialog
     */
    class SOAPMonitorFilter implements ActionListener {

        /**
         * Private data
         */
        private JDialog dialog = null;

        /**
         * Field panel
         */
        private JPanel panel = null;

        /**
         * Field buttons
         */
        private JPanel buttons = null;

        /**
         * Field ok_button
         */
        private JButton ok_button = null;

        /**
         * Field cancel_button
         */
        private JButton cancel_button = null;

        /**
         * Field include_panel
         */
        private ServiceFilterPanel include_panel = null;

        /**
         * Field exclude_panel
         */
        private ServiceFilterPanel exclude_panel = null;

        /**
         * Field status_panel
         */
        private JPanel status_panel = null;

        /**
         * Field status_box
         */
        private JCheckBox status_box = null;

        /**
         * Field empty_border
         */
        private EmptyBorder empty_border = null;

        /**
         * Field indent_border
         */
        private EmptyBorder indent_border = null;

        /**
         * Field status_options
         */
        private JPanel status_options = null;

        /**
         * Field status_group
         */
        private ButtonGroup status_group = null;

        /**
         * Field status_active
         */
        private JRadioButton status_active = null;

        /**
         * Field status_complete
         */
        private JRadioButton status_complete = null;

        /**
         * Field filter_include_list
         */
        private Vector filter_include_list = null;

        /**
         * Field filter_exclude_list
         */
        private Vector filter_exclude_list = null;

        /**
         * Field filter_active
         */
        private boolean filter_active = false;

        /**
         * Field filter_complete
         */
        private boolean filter_complete = false;

        /**
         * Field ok_pressed
         */
        private boolean ok_pressed = false;

        /**
         * Constructor
         */
        public SOAPMonitorFilter() {
            // By default, exclude NotificationService and
            // EventViewerService messages
            filter_exclude_list = new Vector();
            filter_exclude_list.addElement("NotificationService");
            filter_exclude_list.addElement("EventViewerService");
        }

        /**
         * Get list of services to be included
         * 
         * @return 
         */
        public Vector getFilterIncludeList() {
            return filter_include_list;
        }

        /**
         * Get list of services to be excluded
         * 
         * @return 
         */
        public Vector getFilterExcludeList() {
            return filter_exclude_list;
        }

        /**
         * Check if filter active messages
         * 
         * @return 
         */
        public boolean getFilterActive() {
            return filter_active;
        }

        /**
         * Check if filter complete messages
         * 
         * @return 
         */
        public boolean getFilterComplete() {
            return filter_complete;
        }

        /**
         * Show the filter dialog
         */
        public void showDialog() {
            empty_border = new EmptyBorder(5, 5, 0, 5);
            indent_border = new EmptyBorder(5, 25, 5, 5);
            include_panel = new ServiceFilterPanel(
                    "Include messages based on target service:",
                    filter_include_list);
            exclude_panel = new ServiceFilterPanel(
                    "Exclude messages based on target service:",
                    filter_exclude_list);
            status_box = new JCheckBox("Filter messages based on status:");
            status_box.addActionListener(this);
            status_active = new JRadioButton("Active messages only");
            status_active.setSelected(true);
            status_active.setEnabled(false);
            status_complete = new JRadioButton("Complete messages only");
            status_complete.setEnabled(false);
            status_group = new ButtonGroup();
            status_group.add(status_active);
            status_group.add(status_complete);
            if (filter_active || filter_complete) {
                status_box.setSelected(true);
                status_active.setEnabled(true);
                status_complete.setEnabled(true);
                if (filter_complete) {
                    status_complete.setSelected(true);
                }
            }
            status_options = new JPanel();
            status_options.setLayout(new BoxLayout(status_options,
                    BoxLayout.Y_AXIS));
            status_options.add(status_active);
            status_options.add(status_complete);
            status_options.setBorder(indent_border);
            status_panel = new JPanel();
            status_panel.setLayout(new BorderLayout());
            status_panel.add(status_box, BorderLayout.NORTH);
            status_panel.add(status_options, BorderLayout.CENTER);
            status_panel.setBorder(empty_border);
            ok_button = new JButton("Ok");
            ok_button.addActionListener(this);
            cancel_button = new JButton("Cancel");
            cancel_button.addActionListener(this);
            buttons = new JPanel();
            buttons.setLayout(new FlowLayout());
            buttons.add(ok_button);
            buttons.add(cancel_button);
            panel = new JPanel();
            panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
            panel.add(include_panel);
            panel.add(exclude_panel);
            panel.add(status_panel);
            panel.add(buttons);
            dialog = new JDialog();
            dialog.setTitle("SOAP Monitor Filter");
            dialog.setContentPane(panel);
            dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            dialog.setModal(true);
            dialog.pack();
            Dimension d = dialog.getToolkit().getScreenSize();
            dialog.setLocation((d.width - dialog.getWidth()) / 2,
                    (d.height - dialog.getHeight()) / 2);
            ok_pressed = false;
            dialog.show();
        }

        /**
         * Listener to handle button actions
         * 
         * @param e 
         */
        public void actionPerformed(ActionEvent e) {
            // Check if the user pressed the ok button
            if (e.getSource() == ok_button) {
                filter_include_list = include_panel.getServiceList();
                filter_exclude_list = exclude_panel.getServiceList();
                if (status_box.isSelected()) {
                    filter_active = status_active.isSelected();
                    filter_complete = status_complete.isSelected();
                } else {
                    filter_active = false;
                    filter_complete = false;
                }
                ok_pressed = true;
                dialog.dispose();
            }

            // Check if the user pressed the cancel button
            if (e.getSource() == cancel_button) {
                dialog.dispose();
            }

            // Check if the user changed the status filter option
            if (e.getSource() == status_box) {
                status_active.setEnabled(status_box.isSelected());
                status_complete.setEnabled(status_box.isSelected());
            }
        }

        /**
         * Check if the user pressed the ok button
         * 
         * @return 
         */
        public boolean okPressed() {
            return ok_pressed;
        }
    }

    /**
     * Text panel class that supports XML reflow
     */
    class SOAPMonitorTextArea extends JTextArea {

        /**
         * Private data
         */
        private boolean format = false;

        /**
         * Field original
         */
        private String original = "";

        /**
         * Field formatted
         */
        private String formatted = null;

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

        /**
         * Override setText to do formatting
         * 
         * @param text 
         */
        public void setText(String text) {
            original = text;
            formatted = null;
            if (format) {
                doFormat();
                super.setText(formatted);
            } else {
                super.setText(original);
            }
        }

        /**
         * Turn reflow on or off
         * 
         * @param reflow 
         */
        public void setReflowXML(boolean reflow) {
            format = reflow;
            if (format) {
                if (formatted == null) {
                    doFormat();
                }
                super.setText(formatted);
            } else {
                super.setText(original);
            }
        }

        /**
         * Reflow XML
         */
        public void doFormat() {
            Vector parts = new Vector();
            char[] chars = original.toCharArray();
            int index = 0;
            int first = 0;
            String part = null;
            while (index < chars.length) {
                // Check for start of tag
                if (chars[index] == '<') {
                    // Did we have data before this tag?
                    if (first < index) {
                        part = new String(chars, first, index - first);
                        part = part.trim();

                        // Save non-whitespace data
                        if (part.length() > 0) {
                            parts.addElement(part);
                        }
                    }

                    // Save the start of tag
                    first = index;
                }

                // Check for end of tag
                if (chars[index] == '>') {
                    // Save the tag
                    part = new String(chars, first, index - first + 1);
                    parts.addElement(part);
                    first = index + 1;
                }

                // Check for end of line
                if ((chars[index] == '\n') || (chars[index] == '\r')) {
                    // Was there data on this line?
                    if (first < index) {
                        part = new String(chars, first, index - first);
                        part = part.trim();

                        // Save non-whitespace data
                        if (part.length() > 0) {
                            parts.addElement(part);
                        }
                    }
                    first = index + 1;
                }
                index++;
            }

            // Reflow as XML
            StringBuffer buf = new StringBuffer();
            Object[] list = parts.toArray();
            int indent = 0;
            int pad = 0;
            index = 0;
            while (index < list.length) {
                part = (String) list[index];
                if (buf.length() == 0) {
                    // Just add first tag (should be XML header)
                    buf.append(part);
                } else {
                    // All other parts need to start on a new line
                    buf.append('\n');

                    // If we're at an end tag then decrease indent
                    if (part.startsWith("</")) {
                        indent--;
                    }

                    // Add any indent
                    for (pad = 0; pad < indent; pad++) {
                        buf.append("  ");
                    }

                    // Add the tag or data
                    buf.append(part);

                    // If this is a start tag then increase indent
                    if (part.startsWith("<") && !part.startsWith("</")
                            && !part.endsWith("/>")) {
                        indent++;

                        // Check for special <tag>data</tag> case
                        if ((index + 2) < list.length) {
                            part = (String) list[index + 2];
                            if (part.startsWith("</")) {
                                part = (String) list[index + 1];
                                if (!part.startsWith("<")) {
                                    buf.append(part);
                                    part = (String) list[index + 2];
                                    buf.append(part);
                                    index = index + 2;
                                    indent--;
                                }
                            }
                        }
                    }
                }
                index++;
            }
            formatted = new String(buf);
        }
    }

    /**
     * Listener to handle button actions
     * 
     * @param e 
     */
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if (obj == add_btn) {
            int selected[] = list1.getSelectedIndices();
            int len = selected.length - 1;
            for (int i = len; i >= 0; i--) {
                model2.addElement(model1.getElementAt(selected[i]));
                model1.remove(selected[i]);
            }
            if (model1.size() == 0) {
                add_btn.setEnabled(false);
            }
            if (model2.size() > 0) {
                del_btn.setEnabled(true);
            }
        } else if (obj == del_btn) {
            int selected[] = list2.getSelectedIndices();
            int len = selected.length - 1;
            for (int i = len; i >= 0; i--) {
                model1.addElement(model2.getElementAt(selected[i]));
                model2.remove(selected[i]);
            }
            if (model2.size() == 0) {
                del_btn.setEnabled(false);
            }
            if (model1.size() > 0) {
                add_btn.setEnabled(true);
            }
        } else if (obj == login_btn) {
            if (doLogin()) {
                delPage();
                addPage(new SOAPMonitorPage(axisHost));
                start();
            } else {
                add_btn.setEnabled(false);
                del_btn.setEnabled(false);
            }
        } else if (obj == save_btn) {
            String service = null;
            Node node = null;
            Node impNode = null;
            Document wsdd = null;
            JOptionPane pane = null;
            JDialog dlg = null;
            String msg = null;
            final String title = "Deployment status";
            final String deploy = "<deployment name=\"SOAPMonitor\""
              + " xmlns=\"http://xml.apache.org/axis/wsdd/\""
              + " xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">\n"
              + " <handler name=\"soapmonitor\""
              + " type=\"java:org.apache.axis.handlers.SOAPMonitorHandler\" />\n"
              + " </deployment>";

            // Create a new wsdd document
            try {
                wsdd = XMLUtils.newDocument(
                        new ByteArrayInputStream(deploy.getBytes()));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            Collection col = serviceMap.keySet();
            Iterator ite = col.iterator();

            // Add all of service nodes to the new wsdd
            while (ite.hasNext()) {
                service = (String) ite.next();
                node = (Node) serviceMap.get(service);
                if (model2.contains(service)) {
                    if (isMonitored(node)) {    // It's already been monitored
                        impNode = wsdd.importNode(node, true);
                    } else {                    // It's to be monitored
                        impNode = wsdd.importNode(addMonitor(node), true);
                    }
                } else {
                    if (isMonitored(node)) {    // It's not to be monitored
                        impNode = wsdd.importNode(delMonitor(node), true);
                    } else {                    // It's not already been monitored
                        impNode = wsdd.importNode(node, true);
                    }
                }
                if (service.equals("AdminService")) {
                    // Add "SimpleAuthenticationHandler" and "allowedRoles" parameter
                    // with "admin" as a user account
                    impNode = wsdd.importNode(addAuthenticate(impNode), true);
                }
                wsdd.getDocumentElement().appendChild(impNode);
            }

            // Show the result of deployment
            pane = new JOptionPane();
            if (doDeploy(wsdd)) {
                msg = "The deploy was successful.";
                pane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
            } else {
                msg = "The deploy was NOT successful.";
                pane.setMessageType(JOptionPane.WARNING_MESSAGE);
            }
            pane.setOptions(new String[]{"OK"});
            pane.setMessage(msg);
            dlg = pane.createDialog(null, title);
            dlg.setVisible(true);
        }
    }

    /**
     * ChangeListener to handle tab actions
     * 
     * @param e 
     */
    public void stateChanged( javax.swing.event.ChangeEvent e ){
        JTabbedPane tab = (JTabbedPane)e.getSource();
        int item = tab.getSelectedIndex();
        if (item==1) { // "Monitoring" tab is selected.
            start();
        } else {       // "Setting" tab is selected.
            stop();
        }
    }
}
