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

What this is

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

Other links

The source code

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

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;

import org.apache.axis2.soapmonitor.servlet.SOAPMonitorConstants;

/**
 * This is a SOAP Mointor Applet class.  This class provides
 * the user interface for displaying data from the SOAP
 * monitor service.
 */
public class SOAPMonitorApplet extends JApplet {

    /**
     * Private data
     */
    private JPanel      main_panel = null;
    private JTabbedPane tabbed_pane = null;
    private int         port = 0;
    private Vector      pages = null;

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

    /**
     * Applet initialization
     */
    public void init() {
        // Get the port to be used
        String port_str = getParameter("port");
        if (port_str != null) {
            port = Integer.parseInt(port_str);
        }
        // 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());
        setContentPane(main_panel);
        // Create the notebook
        tabbed_pane = new JTabbedPane(JTabbedPane.TOP);
        main_panel.add(tabbed_pane,BorderLayout.CENTER);
        // Add notebook page for default host connection
        pages = new Vector();
        addPage(new SOAPMonitorPage(getCodeBase().getHost()));
    }

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

    /** 
     * Applet 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();
            }
        }
    }

    /*
     * Applet is no longer displayed
     */
    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();
            }
        }
    }

    /**
     * Applet cleanup
     */
    public void destroy() {
        tabbed_pane = null;
        main_panel = null;
    }

    /**
     * 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.";
        private final String STATUS_STOPPED   = "The SOAP Monitor is stopped.";
        private final String STATUS_CLOSED    = "The server communication has been terminated.";
        private final String STATUS_NOCONNECT = "The SOAP Monitor is unable to communcate with the server.";

        /**
         * Private data
         */
        private String                host = null;
        private Socket                socket = null;
        private ObjectInputStream     in = null;
        private ObjectOutputStream    out = null;
        private SOAPMonitorTableModel model = null;
        private JTable                table = null;
        private JScrollPane           scroll = null;
        private JPanel                list_panel = null;
        private JPanel                list_buttons = null;
        private JButton               remove_button = null;
        private JButton               remove_all_button = null;
        private JButton               filter_button = null;
        private JPanel                details_panel = null;
        private JPanel                details_header = null;
        private JSplitPane            details_soap = null;
        private JPanel                details_buttons = null;
        private JLabel                details_time = null;
        private JLabel                details_target = null;
        private JLabel                details_status = null;
        private JLabel                details_time_value = null;
        private JLabel                details_target_value = null;
        private JLabel                details_status_value = null;
        private EmptyBorder           empty_border = null;
        private EtchedBorder          etched_border = null;
        private JPanel                request_panel = null;
        private JPanel                response_panel = null;
        private JLabel                request_label = null;
        private JLabel                response_label = null;
        private SOAPMonitorTextArea   request_text = null;
        private SOAPMonitorTextArea   response_text = null;
        private JScrollPane           request_scroll = null;
        private JScrollPane           response_scroll = null;
        private JButton               layout_button = null;
        private JSplitPane            split = null;
        private JPanel                status_area = null;
        private JPanel                status_buttons = null;
        private JButton               start_button = null;
        private JButton               stop_button = null;
        private JLabel                status_text = null;
        private JPanel                status_text_panel = null;
        private SOAPMonitorFilter     filter = null;
        private GridBagLayout         details_header_layout = null;
        private GridBagConstraints    details_header_constraints = null;
        private JCheckBox             reflow_xml = null;

        /**
         * Constructor (create and layout page)
         */
        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
         */
        public String getHost() {
            return host;
        }

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

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

        /**
         * Start talking to the server
         */
        public void start() {
            String codehost = getCodeBase().getHost();
            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)
                    System.out.println("Exception! "+e.toString());
                    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
         */
        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
         */
        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;
        private String  time;
        private String  target;
        private String  soap_request;
        private String  soap_response;

        /**
         * Constructor
         */
        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
         */
        public Long getId() {
            return id;
        }

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

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

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

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

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

        /**
         * Get the response SOAP contents
         */
        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;
        private Vector  filter_include;
        private Vector  filter_exclude;
        private boolean filter_active;
        private boolean filter_complete;
        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)
         */
        public int getColumnCount() {
            return column_names.length;
        }
        
        /**
         * Get row count (part of table model interface)
         */
        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)
         */
        public String getColumnName(int col) {
            return column_names[col];
        }

        /**
         * Get value at (part of table model interface)
         */
        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 
         */
        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
         */
        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
         */
        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
         */
        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
         */
        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
         */
        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
         */
        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
         */
        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 {

        private JCheckBox    service_box = null;
        private Vector       filter_list = null;
        private Vector       service_data = null;
        private JList        service_list = null;
        private JScrollPane  service_scroll = null;
        private JButton      remove_service_button = null;
        private JPanel       remove_service_panel = null;
        private EmptyBorder  indent_border = null;
        private EmptyBorder  empty_border = null;
        private JPanel       service_area = null;
        private JPanel       add_service_area = null;
        private JTextField   add_service_field = null;
        private JButton      add_service_button = null;
        private JPanel       add_service_panel = null;

        /**
         * Constructor
         */
        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
         */
        public Vector getServiceList() {
            Vector list = null;
            if (service_box.isSelected()) {
                list = service_data;
            }
            return list;
        }

        /**
         * Listener to handle button actions
         */
        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
         */
        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
         */
        public void insertUpdate(DocumentEvent e) {
            changedUpdate(e);
        }

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

        /**
         * Listener to handle service list selection changes
         */
        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;
        private JPanel             panel = null;
        private JPanel             buttons = null;
        private JButton            ok_button = null;
        private JButton            cancel_button = null;
        private ServiceFilterPanel include_panel = null;
        private ServiceFilterPanel exclude_panel = null;
        private JPanel             status_panel = null;
        private JCheckBox          status_box = null;
        private EmptyBorder  empty_border = null;
        private EmptyBorder  indent_border = null;
        private JPanel             status_options = null;
        private ButtonGroup        status_group = null;
        private JRadioButton       status_active = null;
        private JRadioButton       status_complete = null;
        private Vector             filter_include_list = null;
        private Vector             filter_exclude_list = null;
        private boolean            filter_active = false;
        private boolean            filter_complete = false;
        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
         */
        public Vector getFilterIncludeList() {
            return filter_include_list;
        }

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

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

        /**
         * Check if filter complete messages
         */
        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
         */
        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
         */
        public boolean okPressed() {
            return ok_pressed;
        }
    }

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

        /**
         * Private data
         */
        private boolean format = false;
        private String  original = "";
        private String  formatted = null; 

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

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

        /**
         * Turn reflow on or off
         */
        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 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);
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

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

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