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