/* * Copyright 2001,2004 The Apache Software Foundation. * * Licensed 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.axis.monitor.SOAPMonitorConstants; /** * This is a SOAP Mointor Applet class. This class provides * the user interface for displaying data from the SOAP * monitor service. * * @author Brian Price (pricebe@us.ibm.com) * */ 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</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); } } }