blob: 67447dc4105dd623c2ea2aa42ec204fe6df7adc5 [file] [log] [blame]
/*
* Copyright 2001,2004 The Apache Software Foundation.
*
* Licensed under the Apache Liusercense, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.axis.utils;
import org.apache.axis.client.AdminClient;
import org.apache.axis.monitor.SOAPMonitorConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.ChangeListener;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.net.URL;
import java.net.MalformedURLException;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
/**
* This is a SOAP Monitor Application class. This class provides
* the user interface for deploying the SOAP monitor service and
* displaying data from the service.
*
* @author Toshiyuki Kimura (toshi@apache.org)
* @author Brian Price (pricebe@us.ibm.com)
*/
public class SOAPMonitor extends JFrame implements ActionListener, ChangeListener {
/**
* Private data
*/
private JPanel main_panel = null;
/**
* Field tabbed_pane
*/
private JTabbedPane tabbed_pane = null;
/**
* Field top_pane
*/
private JTabbedPane top_pane = null;
/**
* Field port
*/
private int port = 5001;
/**
* Field axisHost
*/
private String axisHost = "localhost";
/**
* Field axisPort
*/
private int axisPort = 8080;
/**
* Field axisURL
*/
private String axisURL = null;
/**
* Field pages
*/
private Vector pages = null;
/**
* Field titleStr
*/
private final String titleStr = "SOAP Monitor Administration";
/**
* Field set_panel
*/
private JPanel set_panel = null;
/**
* Field titleLabel
*/
private JLabel titleLabel = null;
/**
* Field add_btn
*/
private JButton add_btn = null;
/**
* Field del_btn
*/
private JButton del_btn = null;
/**
* Field save_btn
*/
private JButton save_btn = null;
/**
* Field login_btn
*/
private JButton login_btn = null;
/**
* Field model1
*/
private DefaultListModel model1 = null;
/**
* Field model2
*/
private DefaultListModel model2 = null;
/**
* Field list1
*/
private JList list1 = null;
/**
* Field list2
*/
private JList list2 = null;
/**
* Field serviceMap
*/
private HashMap serviceMap = null;
/**
* Field originalDoc
*/
private Document originalDoc = null;
/**
* Field axisUser
*/
private static String axisUser = null;
/**
* Field axisPass
*/
private static String axisPass = null;
/**
* Field adminClient
*/
private AdminClient adminClient = new AdminClient();
/**
* Main method for this class
*
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception {
SOAPMonitor soapMonitor = null;
Options opts = new Options(args);
if (opts.isFlagSet('?') > 0) {
System.out.println(
"Usage: SOAPMonitor [-l<url>] [-u<user>] [-w<password>] [-?]");
System.exit(0);
}
// Create an instance
soapMonitor = new SOAPMonitor();
// GET Axis URL.
// The default is "http://localhost:8080/axis/servlet/AxisServlet"
soapMonitor.axisURL = opts.getURL();
URL url = new URL(soapMonitor.axisURL);
soapMonitor.axisHost = url.getHost();
// GET User name & Password
axisUser = opts.getUser();
axisPass = opts.getPassword();
// Login and start application
soapMonitor.doLogin();
}
/**
* Constructor
*/
public SOAPMonitor() {
setTitle("SOAP Monitor Application");
Dimension d = getToolkit().getScreenSize();
setSize(640, 480);
setLocation((d.width - getWidth()) / 2, (d.height - getHeight()) / 2);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
addWindowListener(new MyWindowAdapter());
// Try to use the system look and feel
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
// Create main panel to hold notebook
main_panel = new JPanel();
main_panel.setBackground(Color.white);
main_panel.setLayout(new BorderLayout());
top_pane = new JTabbedPane();
set_panel = new JPanel();
// label for NORTH panel to display the pain title
titleLabel = new JLabel(titleStr);
titleLabel.setFont(new Font("Serif", Font.BOLD, 18));
// list control for WEST panel to list NOT monitored services
model1 = new DefaultListModel();
list1 = new JList(model1);
list1.setFixedCellWidth(250);
JScrollPane scroll1 = new JScrollPane(list1);
// list control for EAST panel to list monitored services
model2 = new DefaultListModel();
list2 = new JList(model2);
list2.setFixedCellWidth(250);
JScrollPane scroll2 = new JScrollPane(list2);
// buttons for CENTER panel to chage the monitoring state
add_btn = new JButton("Turn On [ >> ]");
del_btn = new JButton("[ << ] Turn Off");
JPanel center_panel = new JPanel();
GridBagLayout layout = new GridBagLayout();
center_panel.setLayout(layout);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(10, 10, 10, 10);
layout.setConstraints(add_btn, c);
center_panel.add(add_btn);
c.gridx = 0;
c.gridy = 1;
c.insets = new Insets(10, 10, 10, 10);
layout.setConstraints(del_btn, c);
center_panel.add(del_btn);
// buttons for SOUTH panel
save_btn = new JButton("Save changes");
login_btn = new JButton("Change server");
JPanel south_panel = new JPanel();
layout = new GridBagLayout();
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(10, 10, 10, 10);
layout.setConstraints(save_btn, c);
south_panel.add(save_btn);
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(10, 10, 10, 10);
layout.setConstraints(login_btn, c);
south_panel.add(login_btn);
// set all controls to the border layout
set_panel.setLayout(new BorderLayout(5, 5));
set_panel.add(titleLabel, BorderLayout.NORTH);
set_panel.add(south_panel, BorderLayout.SOUTH);
set_panel.add(scroll1, BorderLayout.WEST);
set_panel.add(scroll2, BorderLayout.EAST);
set_panel.add(center_panel, BorderLayout.CENTER);
// register the Action Listener
add_btn.addActionListener(this);
del_btn.addActionListener(this);
save_btn.addActionListener(this);
login_btn.addActionListener(this);
// set default button state as 'false'
add_btn.setEnabled(false);
del_btn.setEnabled(false);
save_btn.setEnabled(false);
login_btn.setEnabled(false);
top_pane.add("Setting", set_panel);
top_pane.add("Monitoring", main_panel);
getContentPane().add(top_pane);
// Create the notebook
tabbed_pane = new JTabbedPane(JTabbedPane.TOP);
main_panel.add(tabbed_pane, BorderLayout.CENTER);
top_pane.addChangeListener(this);
top_pane.setEnabled(false);
setVisible(true);
}
/**
* Do login process
*
* @return
*/
private boolean doLogin() {
Dimension d = null;
// Login
LoginDlg login = new LoginDlg();
login.show();
if (!login.isLogin()) {
login_btn.setEnabled(true);
return false;
}
login.dispose();
save_btn.setEnabled(false);
login_btn.setEnabled(false);
// Get the axisHost & axisPort to be used
String url_str = login.getURL();
try {
URL url = new URL(url_str);
axisHost = url.getHost();
axisPort = url.getPort();
if (axisPort == -1) {
axisPort = 8080;
}
String axisPath = url.getPath();
axisURL = "http://" + axisHost + ":" + axisPort + axisPath;
} catch (MalformedURLException e) {
JOptionPane pane = new JOptionPane();
String msg = e.toString();
pane.setMessageType(JOptionPane.WARNING_MESSAGE);
pane.setMessage(msg);
pane.setOptions(new String[]{"OK"});
JDialog dlg = pane.createDialog(null, "Login status");
dlg.setVisible(true);
login_btn.setEnabled(true);
return false;
}
titleLabel.setText(titleStr + " for [" + axisHost + ":" + axisPort
+ "]");
final JProgressBar progressBar = new JProgressBar(0, 100);
BarThread stepper = new BarThread(progressBar);
stepper.start();
JFrame progress = new JFrame();
d = new Dimension(250, 50);
progress.setSize(d);
d = getToolkit().getScreenSize();
progress.getContentPane().add(progressBar);
progress.setTitle("Now loading data ...");
progress.setLocation((d.width - progress.getWidth()) / 2,
(d.height - progress.getHeight()) / 2);
progress.show();
// Add notebook page for default host connection
pages = new Vector();
addPage(new SOAPMonitorPage(axisHost));
serviceMap = new HashMap();
originalDoc = getServerWSDD();
model1.clear();
model2.clear();
if (originalDoc != null) {
String ret = null;
NodeList nl = originalDoc.getElementsByTagName("service");
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
NamedNodeMap map = node.getAttributes();
ret = map.getNamedItem("name").getNodeValue();
serviceMap.put(ret, node);
if (!isMonitored(node)) {
model1.addElement((String) ret);
} else {
model2.addElement((String) ret);
}
}
if (model1.size() > 0) {
add_btn.setEnabled(true);
}
if (model2.size() > 0) {
del_btn.setEnabled(true);
}
progress.dispose();
save_btn.setEnabled(true);
login_btn.setEnabled(true);
top_pane.setEnabled(true);
return true;
} else {
progress.dispose();
login_btn.setEnabled(true);
return false;
}
}
/**
* This class is a thred for a JProgressBar.
*/
class BarThread extends Thread {
/**
* Field wait
*/
private int wait = 100;
/**
* Field progressBar
*/
JProgressBar progressBar = null;
/**
* Constructor BarThread
*
* @param bar
*/
public BarThread(JProgressBar bar) {
progressBar = bar;
}
/**
* Method run
*/
public void run() {
int min = progressBar.getMinimum();
int max = progressBar.getMaximum();
Runnable runner = new Runnable() {
public void run() {
int val = progressBar.getValue();
progressBar.setValue(val + 1);
}
};
for (int i = min; i < max; i++) {
try {
SwingUtilities.invokeAndWait(runner);
Thread.sleep(wait);
} catch (InterruptedException ignoredException) {
} catch (InvocationTargetException ignoredException) {
}
}
}
}
/**
* Get the server-config.wsdd as a document to retrieve deployed services
*
* @return
*/
private Document getServerWSDD() {
Document doc = null;
try {
String[] param = new String[]{"-u" + axisUser, "-w" + axisPass,
"-l " + axisURL, "list"};
String ret = adminClient.process(param);
doc = XMLUtils.newDocument(
new ByteArrayInputStream(ret.getBytes()));
} catch (Exception e) {
JOptionPane pane = new JOptionPane();
String msg = e.toString();
pane.setMessageType(JOptionPane.WARNING_MESSAGE);
pane.setMessage(msg);
pane.setOptions(new String[]{"OK"});
JDialog dlg = pane.createDialog(null, "Login status");
dlg.setVisible(true);
}
return doc;
}
/**
* Deploy the specified wsdd to change the monitoring state
*
* @param wsdd
* @return
*/
private boolean doDeploy(Document wsdd) {
String deploy = null;
Options opt = null;
deploy = XMLUtils.DocumentToString(wsdd);
try {
String[] param = new String[]{"-u" + axisUser, "-w" + axisPass,
"-l " + axisURL, ""};
opt = new Options(param);
adminClient.process(opt,
new ByteArrayInputStream(deploy.getBytes()));
} catch (Exception e) {
return false;
}
return true;
}
/**
* Get a new document which has the specified node as the document root
*
* @param target
* @return
*/
private Document getNewDocumentAsNode(Node target) {
Document doc = null;
Node node = null;
try {
doc = XMLUtils.newDocument();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
node = doc.importNode(target, true);
doc.appendChild(node);
return doc;
}
/**
* Add needed nodes for monitoring to the specified node
* <p/>
* TODO: support JAX-RPC type definition (i.e. <handlerInfoChain/>)
*
* @param target
* @return
*/
private Node addMonitor(Node target) {
Document doc = null;
Node node = null;
Node newNode = null;
String ret = null;
NodeList nl = null;
final String reqFlow = "requestFlow";
final String resFlow = "responseFlow";
final String monitor = "soapmonitor";
final String handler = "handler";
final String type = "type";
doc = getNewDocumentAsNode(target);
// Add "responseFlow node
nl = doc.getElementsByTagName(resFlow);
if (nl.getLength() == 0) {
node = doc.getDocumentElement().getFirstChild();
newNode = doc.createElement(resFlow);
doc.getDocumentElement().insertBefore(newNode, node);
}
// Add "requestFlow" node
nl = doc.getElementsByTagName(reqFlow);
if (nl.getLength() == 0) {
node = doc.getDocumentElement().getFirstChild();
newNode = doc.createElement(reqFlow);
doc.getDocumentElement().insertBefore(newNode, node);
}
// Add "handler" node and "soapmonitor" attribute for "requestFlow"
nl = doc.getElementsByTagName(reqFlow);
node = nl.item(0).getFirstChild();
newNode = doc.createElement(handler);
((Element) newNode).setAttribute(type, monitor);
nl.item(0).insertBefore(newNode, node);
// Add "handler" node and "soapmonitor" attribute for "responseFlow"
nl = doc.getElementsByTagName(resFlow);
node = nl.item(0).getFirstChild();
newNode = doc.createElement(handler);
((Element) newNode).setAttribute(type, monitor);
nl.item(0).insertBefore(newNode, node);
return (Node) doc.getDocumentElement();
}
/**
* Remove a few nodes for stoping monitor from the specified node
* <p/>
* TODO: support JAX-RPC type definition (i.e. <handlerInfoChain/>)
*
* @param target
* @return
*/
private Node delMonitor(Node target) {
Document doc = null;
Node node = null;
Node newNode = null;
String ret = null;
NodeList nl = null;
final String reqFlow = "requestFlow";
final String resFlow = "responseFlow";
final String monitor = "soapmonitor";
final String handler = "handler";
final String type = "type";
doc = getNewDocumentAsNode(target);
nl = doc.getElementsByTagName(handler);
int size;
size = nl.getLength();
Node[] removeNode = new Node[size];
if (size > 0) {
newNode = nl.item(0).getParentNode();
}
for (int i = 0; i < size; i++) {
node = nl.item(i);
NamedNodeMap map = node.getAttributes();
ret = map.getNamedItem(type).getNodeValue();
if (ret.equals(monitor)) {
removeNode[i] = node;
}
}
for (int i = 0; i < size; i++) {
Node child = removeNode[i];
if (child != null) {
child.getParentNode().removeChild(child);
}
}
return (Node) doc.getDocumentElement();
}
/**
* Get a boolean value whether the specified node is monitoring or not
*
* @param target
* @return
*/
private boolean isMonitored(Node target) {
Document doc = null;
Node node = null;
String ret = null;
NodeList nl = null;
final String monitor = "soapmonitor";
final String handler = "handler";
final String type = "type";
doc = getNewDocumentAsNode(target);
nl = doc.getElementsByTagName(handler);
for (int i = 0; i < nl.getLength(); i++) {
node = nl.item(i);
NamedNodeMap map = node.getAttributes();
ret = map.getNamedItem(type).getNodeValue();
if (ret.equals(monitor)) {
return true;
} else {
return false;
}
}
return false;
}
/**
* Add a few nodes for authentification
* <p/>
* TODO: support JAX-RPC type definition (i.e. <handlerInfoChain/>)
*
* @param target
* @return
*/
private Node addAuthenticate(Node target) {
Document doc = null;
Node node = null;
Node newNode = null;
String ret = null;
NodeList nl = null;
final String reqFlow = "requestFlow";
final String handler = "handler";
final String type = "type";
final String authentication =
"java:org.apache.axis.handlers.SimpleAuthenticationHandler";
final String authorization =
"java:org.apache.axis.handlers.SimpleAuthorizationHandler";
final String param = "parameter";
final String name = "name";
final String role = "allowedRoles";
final String value = "value";
final String admin = "admin";
boolean authNode = false;
boolean roleNode = false;
doc = getNewDocumentAsNode(target);
// Add "requestFlow" node
nl = doc.getElementsByTagName(reqFlow);
if (nl.getLength() == 0) {
node = doc.getDocumentElement().getFirstChild();
newNode = doc.createElement(reqFlow);
doc.getDocumentElement().insertBefore(newNode, node);
}
// Add "SimpleAuthorizationHandler"
// (i.e. <handler type="java:org.apache.axis.handlers.SimpleAuthorizationHandler"/>)
nl = doc.getElementsByTagName(handler);
for (int i = 0; i < nl.getLength(); i++) {
node = nl.item(i);
NamedNodeMap map = node.getAttributes();
ret = map.getNamedItem(type).getNodeValue();
if (ret.equals(authorization)) {
authNode = true;
break;
}
}
if (!authNode) {
nl = doc.getElementsByTagName(reqFlow);
node = nl.item(0).getFirstChild();
newNode = doc.createElement(handler);
((Element) newNode).setAttribute(type, authorization);
nl.item(0).insertBefore(newNode, node);
}
// Add "SimpleAuthenticationHandler"
// (i.e. <handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>)
authNode = false;
nl = doc.getElementsByTagName(handler);
for (int i = 0; i < nl.getLength(); i++) {
node = nl.item(i);
NamedNodeMap map = node.getAttributes();
ret = map.getNamedItem(type).getNodeValue();
if (ret.equals(authentication)) {
authNode = true;
break;
}
}
if (!authNode) {
nl = doc.getElementsByTagName(reqFlow);
node = nl.item(0).getFirstChild();
newNode = doc.createElement(handler);
((Element) newNode).setAttribute(type, authentication);
nl.item(0).insertBefore(newNode, node);
}
// Add "allowedRoles" (i.e. <parameter name="allowedRoles" value="admin"/> )
nl = doc.getElementsByTagName(param);
for (int i = 0; i < nl.getLength(); i++) {
node = nl.item(i);
NamedNodeMap map = node.getAttributes();
node = map.getNamedItem(name);
if (node != null) {
ret = node.getNodeValue();
if (ret.equals(role)) {
roleNode = true;
break;
}
}
}
if (!roleNode) {
nl = doc.getElementsByTagName(param);
newNode = doc.createElement(param);
((Element) newNode).setAttribute(name, role);
((Element) newNode).setAttribute(value, admin);
doc.getDocumentElement().insertBefore(newNode, nl.item(0));
}
return (Node) doc.getDocumentElement();
}
/**
* Handle the window close event
*/
class MyWindowAdapter extends WindowAdapter {
/**
* Method windowClosing
*
* @param e
*/
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
/**
* Add a page to the notebook
*
* @param pg
*/
private void addPage(SOAPMonitorPage pg) {
tabbed_pane.addTab(" " + pg.getHost() + " ", pg);
pages.addElement(pg);
}
/**
* Del all pages to the notebook
*/
private void delPage() {
tabbed_pane.removeAll();
pages.removeAllElements();
}
/**
* Frame is being displayed
*/
public void start() {
// Tell all pages to start talking to the server
Enumeration e = pages.elements();
while (e.hasMoreElements()) {
SOAPMonitorPage pg = (SOAPMonitorPage) e.nextElement();
if (pg != null) {
pg.start();
}
}
}
/*
* Frame is no longer displayed
*/
/**
* Method stop
*/
public void stop() {
// Tell all pages to stop talking to the server
Enumeration e = pages.elements();
while (e.hasMoreElements()) {
SOAPMonitorPage pg = (SOAPMonitorPage) e.nextElement();
if (pg != null) {
pg.stop();
}
}
}
/**
* This class is for the Login Dialog
*/
class LoginDlg extends JDialog implements ActionListener {
/**
* Field ok_button
*/
private JButton ok_button = null;
/**
* Field cancel_button
*/
private JButton cancel_button = null;
/**
* Field user
*/
private JTextField user = new JTextField(20);
/**
* Field pass
*/
private JPasswordField pass = new JPasswordField(20);
/**
* Field url
*/
private JTextField url = new JTextField(20);
/**
* Field loginState
*/
private boolean loginState = false;
/**
* Constructor (create and layout page)
*/
public LoginDlg() {
setTitle("SOAP Monitor Login");
UIManager.put("Label.font", new Font("Dialog", Font.BOLD, 12));
JPanel panel = new JPanel();
ok_button = new JButton("OK");
ok_button.addActionListener(this);
cancel_button = new JButton("Cancel");
cancel_button.addActionListener(this);
// default URL for AxisServlet
url.setText(axisURL);
JLabel userLabel = new JLabel("User:");
JLabel passLabel = new JLabel("Password:");
JLabel urlLabel = new JLabel("Axis URL:");
userLabel.setHorizontalAlignment(JTextField.RIGHT);
passLabel.setHorizontalAlignment(JTextField.RIGHT);
urlLabel.setHorizontalAlignment(JTextField.RIGHT);
panel.add(userLabel);
panel.add(user);
panel.add(passLabel);
panel.add(pass);
panel.add(urlLabel);
panel.add(url);
panel.add(ok_button);
panel.add(cancel_button);
setContentPane(panel);
user.setText(SOAPMonitor.axisUser);
pass.setText(SOAPMonitor.axisPass);
GridLayout layout = new GridLayout(4, 2);
layout.setHgap(15);
layout.setVgap(5);
panel.setLayout(layout);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setModal(true);
pack();
Dimension d = getToolkit().getScreenSize();
setLocation((d.width - getWidth()) / 2,
(d.height - getHeight()) / 2);
}
/**
* Listener to handle button actions
*
* @param e
*/
public void actionPerformed(ActionEvent e) {
// Check if the user pressed the OK button
if (e.getSource() == ok_button) {
loginState = true;
SOAPMonitor.axisUser = user.getText();
SOAPMonitor.axisPass = new String(pass.getPassword());
this.hide();
} else if (e.getSource() == cancel_button) {
this.dispose();
}
}
/**
* Get the URL of the AxisServlet we are using
*
* @return
*/
public String getURL() {
return url.getText();
}
/**
* Get the login status as a boolean
*
* @return
*/
public boolean isLogin() {
return loginState;
}
}
/**
* This class provides the contents of a notebook page
* representing a server connection.
*/
class SOAPMonitorPage extends JPanel
implements Runnable, ListSelectionListener, ActionListener {
/**
* Status Strings
*/
private final String STATUS_ACTIVE = "The SOAP Monitor is started.";
/**
* Field STATUS_STOPPED
*/
private final String STATUS_STOPPED = "The SOAP Monitor is stopped.";
/**
* Field STATUS_CLOSED
*/
private final String STATUS_CLOSED =
"The server communication has been terminated.";
/**
* Field STATUS_NOCONNECT
*/
private final String STATUS_NOCONNECT =
"The SOAP Monitor is unable to communcate with the server.";
/**
* Private data
*/
private String host = null;
/**
* Field socket
*/
private Socket socket = null;
/**
* Field in
*/
private ObjectInputStream in = null;
/**
* Field out
*/
private ObjectOutputStream out = null;
/**
* Field model
*/
private SOAPMonitorTableModel model = null;
/**
* Field table
*/
private JTable table = null;
/**
* Field scroll
*/
private JScrollPane scroll = null;
/**
* Field list_panel
*/
private JPanel list_panel = null;
/**
* Field list_buttons
*/
private JPanel list_buttons = null;
/**
* Field remove_button
*/
private JButton remove_button = null;
/**
* Field remove_all_button
*/
private JButton remove_all_button = null;
/**
* Field filter_button
*/
private JButton filter_button = null;
/**
* Field details_panel
*/
private JPanel details_panel = null;
/**
* Field details_header
*/
private JPanel details_header = null;
/**
* Field details_soap
*/
private JSplitPane details_soap = null;
/**
* Field details_buttons
*/
private JPanel details_buttons = null;
/**
* Field details_time
*/
private JLabel details_time = null;
/**
* Field details_target
*/
private JLabel details_target = null;
/**
* Field details_status
*/
private JLabel details_status = null;
/**
* Field details_time_value
*/
private JLabel details_time_value = null;
/**
* Field details_target_value
*/
private JLabel details_target_value = null;
/**
* Field details_status_value
*/
private JLabel details_status_value = null;
/**
* Field empty_border
*/
private EmptyBorder empty_border = null;
/**
* Field etched_border
*/
private EtchedBorder etched_border = null;
/**
* Field request_panel
*/
private JPanel request_panel = null;
/**
* Field response_panel
*/
private JPanel response_panel = null;
/**
* Field request_label
*/
private JLabel request_label = null;
/**
* Field response_label
*/
private JLabel response_label = null;
/**
* Field request_text
*/
private SOAPMonitorTextArea request_text = null;
/**
* Field response_text
*/
private SOAPMonitorTextArea response_text = null;
/**
* Field request_scroll
*/
private JScrollPane request_scroll = null;
/**
* Field response_scroll
*/
private JScrollPane response_scroll = null;
/**
* Field layout_button
*/
private JButton layout_button = null;
/**
* Field split
*/
private JSplitPane split = null;
/**
* Field status_area
*/
private JPanel status_area = null;
/**
* Field status_buttons
*/
private JPanel status_buttons = null;
/**
* Field start_button
*/
private JButton start_button = null;
/**
* Field stop_button
*/
private JButton stop_button = null;
/**
* Field status_text
*/
private JLabel status_text = null;
/**
* Field status_text_panel
*/
private JPanel status_text_panel = null;
/**
* Field filter
*/
private SOAPMonitorFilter filter = null;
/**
* Field details_header_layout
*/
private GridBagLayout details_header_layout = null;
/**
* Field details_header_constraints
*/
private GridBagConstraints details_header_constraints = null;
/**
* Field reflow_xml
*/
private JCheckBox reflow_xml = null;
/**
* Constructor (create and layout page)
*
* @param host_name
*/
public SOAPMonitorPage(String host_name) {
host = host_name;
// Set up default filter (show all messages)
filter = new SOAPMonitorFilter();
// Use borders to help improve appearance
etched_border = new EtchedBorder();
// Build top portion of split (list panel)
model = new SOAPMonitorTableModel();
table = new JTable(model);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setRowSelectionInterval(0, 0);
table.setPreferredScrollableViewportSize(new Dimension(600, 96));
table.getSelectionModel().addListSelectionListener(this);
scroll = new JScrollPane(table);
remove_button = new JButton("Remove");
remove_button.addActionListener(this);
remove_button.setEnabled(false);
remove_all_button = new JButton("Remove All");
remove_all_button.addActionListener(this);
filter_button = new JButton("Filter ...");
filter_button.addActionListener(this);
list_buttons = new JPanel();
list_buttons.setLayout(new FlowLayout());
list_buttons.add(remove_button);
list_buttons.add(remove_all_button);
list_buttons.add(filter_button);
list_panel = new JPanel();
list_panel.setLayout(new BorderLayout());
list_panel.add(scroll, BorderLayout.CENTER);
list_panel.add(list_buttons, BorderLayout.SOUTH);
list_panel.setBorder(empty_border);
// Build bottom portion of split (message details)
details_time = new JLabel("Time: ", SwingConstants.RIGHT);
details_target = new JLabel("Target Service: ",
SwingConstants.RIGHT);
details_status = new JLabel("Status: ", SwingConstants.RIGHT);
details_time_value = new JLabel();
details_target_value = new JLabel();
details_status_value = new JLabel();
Dimension preferred_size = details_time.getPreferredSize();
preferred_size.width = 1;
details_time.setPreferredSize(preferred_size);
details_target.setPreferredSize(preferred_size);
details_status.setPreferredSize(preferred_size);
details_time_value.setPreferredSize(preferred_size);
details_target_value.setPreferredSize(preferred_size);
details_status_value.setPreferredSize(preferred_size);
details_header = new JPanel();
details_header_layout = new GridBagLayout();
details_header.setLayout(details_header_layout);
details_header_constraints = new GridBagConstraints();
details_header_constraints.fill = GridBagConstraints.BOTH;
details_header_constraints.weightx = 0.5;
details_header_layout.setConstraints(details_time,
details_header_constraints);
details_header.add(details_time);
details_header_layout.setConstraints(details_time_value,
details_header_constraints);
details_header.add(details_time_value);
details_header_layout.setConstraints(details_target,
details_header_constraints);
details_header.add(details_target);
details_header_constraints.weightx = 1.0;
details_header_layout.setConstraints(details_target_value,
details_header_constraints);
details_header.add(details_target_value);
details_header_constraints.weightx = .5;
details_header_layout.setConstraints(details_status,
details_header_constraints);
details_header.add(details_status);
details_header_layout.setConstraints(details_status_value,
details_header_constraints);
details_header.add(details_status_value);
details_header.setBorder(etched_border);
request_label = new JLabel("SOAP Request", SwingConstants.CENTER);
request_text = new SOAPMonitorTextArea();
request_text.setEditable(false);
request_scroll = new JScrollPane(request_text);
request_panel = new JPanel();
request_panel.setLayout(new BorderLayout());
request_panel.add(request_label, BorderLayout.NORTH);
request_panel.add(request_scroll, BorderLayout.CENTER);
response_label =
new JLabel("SOAP Response", SwingConstants.CENTER);
response_text = new SOAPMonitorTextArea();
response_text.setEditable(false);
response_scroll = new JScrollPane(response_text);
response_panel = new JPanel();
response_panel.setLayout(new BorderLayout());
response_panel.add(response_label, BorderLayout.NORTH);
response_panel.add(response_scroll, BorderLayout.CENTER);
details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
details_soap.setTopComponent(request_panel);
details_soap.setRightComponent(response_panel);
details_soap.setResizeWeight(.5);
details_panel = new JPanel();
layout_button = new JButton("Switch Layout");
layout_button.addActionListener(this);
reflow_xml = new JCheckBox("Reflow XML text");
reflow_xml.addActionListener(this);
details_buttons = new JPanel();
details_buttons.setLayout(new FlowLayout());
details_buttons.add(reflow_xml);
details_buttons.add(layout_button);
details_panel.setLayout(new BorderLayout());
details_panel.add(details_header, BorderLayout.NORTH);
details_panel.add(details_soap, BorderLayout.CENTER);
details_panel.add(details_buttons, BorderLayout.SOUTH);
details_panel.setBorder(empty_border);
// Add the two parts to the age split pane
split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
split.setTopComponent(list_panel);
split.setRightComponent(details_panel);
// Build status area
start_button = new JButton("Start");
start_button.addActionListener(this);
stop_button = new JButton("Stop");
stop_button.addActionListener(this);
status_buttons = new JPanel();
status_buttons.setLayout(new FlowLayout());
status_buttons.add(start_button);
status_buttons.add(stop_button);
status_text = new JLabel();
status_text.setBorder(new BevelBorder(BevelBorder.LOWERED));
status_text_panel = new JPanel();
status_text_panel.setLayout(new BorderLayout());
status_text_panel.add(status_text, BorderLayout.CENTER);
status_text_panel.setBorder(empty_border);
status_area = new JPanel();
status_area.setLayout(new BorderLayout());
status_area.add(status_buttons, BorderLayout.WEST);
status_area.add(status_text_panel, BorderLayout.CENTER);
status_area.setBorder(etched_border);
// Add the split and status area to page
setLayout(new BorderLayout());
add(split, BorderLayout.CENTER);
add(status_area, BorderLayout.SOUTH);
}
/**
* Get the name of the host we are displaying
*
* @return
*/
public String getHost() {
return host;
}
/**
* Set the status text
*
* @param txt
*/
public void setStatus(String txt) {
status_text.setForeground(Color.black);
status_text.setText(" " + txt);
}
/**
* Set the status text to an error
*
* @param txt
*/
public void setErrorStatus(String txt) {
status_text.setForeground(Color.red);
status_text.setText(" " + txt);
}
/**
* Start talking to the server
*/
public void start() {
String codehost = axisHost;
if (socket == null) {
try {
// Open the socket to the server
socket = new Socket(codehost, port);
// Create output stream
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
// Create input stream and start background
// thread to read data from the server
in = new ObjectInputStream(socket.getInputStream());
new Thread(this).start();
} catch (Exception e) {
// Exceptions here are unexpected, but we can't
// really do anything (so just write it to stdout
// in case someone cares and then ignore it)
e.printStackTrace();
setErrorStatus(STATUS_NOCONNECT);
socket = null;
}
} else {
// Already started
}
if (socket != null) {
// Make sure the right buttons are enabled
start_button.setEnabled(false);
stop_button.setEnabled(true);
setStatus(STATUS_ACTIVE);
}
}
/**
* Stop talking to the server
*/
public void stop() {
if (socket != null) {
// Close all the streams and socket
if (out != null) {
try {
out.close();
} catch (IOException ioe) {
}
out = null;
}
if (in != null) {
try {
in.close();
} catch (IOException ioe) {
}
in = null;
}
if (socket != null) {
try {
socket.close();
} catch (IOException ioe) {
}
socket = null;
}
} else {
// Already stopped
}
// Make sure the right buttons are enabled
start_button.setEnabled(true);
stop_button.setEnabled(false);
setStatus(STATUS_STOPPED);
}
/**
* Background thread used to receive data from
* the server.
*/
public void run() {
Long id;
Integer message_type;
String target;
String soap;
SOAPMonitorData data;
int selected;
int row;
boolean update_needed;
while (socket != null) {
try {
// Get the data from the server
message_type = (Integer) in.readObject();
// Process the data depending on its type
switch (message_type.intValue()) {
case SOAPMonitorConstants.SOAP_MONITOR_REQUEST:
// Get the id, target and soap info
id = (Long) in.readObject();
target = (String) in.readObject();
soap = (String) in.readObject();
// Add new request data to the table
data = new SOAPMonitorData(id, target, soap);
model.addData(data);
// If "most recent" selected then update
// the details area if needed
selected = table.getSelectedRow();
if ((selected == 0) && model.filterMatch(data)) {
valueChanged(null);
}
break;
case SOAPMonitorConstants.SOAP_MONITOR_RESPONSE:
// Get the id and soap info
id = (Long) in.readObject();
soap = (String) in.readObject();
data = model.findData(id);
if (data != null) {
update_needed = false;
// Get the selected row
selected = table.getSelectedRow();
// If "most recent", then always
// update details area
if (selected == 0) {
update_needed = true;
}
// If the data being updated is
// selected then update details
row = model.findRow(data);
if ((row != -1) && (row == selected)) {
update_needed = true;
}
// Set the response and update table
data.setSOAPResponse(soap);
model.updateData(data);
// Refresh details area (if needed)
if (update_needed) {
valueChanged(null);
}
}
break;
}
} catch (Exception e) {
// Exceptions are expected here when the
// server communication has been terminated.
if (stop_button.isEnabled()) {
stop();
setErrorStatus(STATUS_CLOSED);
}
}
}
}
/**
* Listener to handle table selection changes
*
* @param e
*/
public void valueChanged(ListSelectionEvent e) {
int row = table.getSelectedRow();
// Check if they selected a specific row
if (row > 0) {
remove_button.setEnabled(true);
} else {
remove_button.setEnabled(false);
}
// Check for "most recent" selection
if (row == 0) {
row = model.getRowCount() - 1;
if (row == 0) {
row = -1;
}
}
if (row == -1) {
// Clear the details panel
details_time_value.setText("");
details_target_value.setText("");
details_status_value.setText("");
request_text.setText("");
response_text.setText("");
} else {
// Show the details for the row
SOAPMonitorData soap = model.getData(row);
details_time_value.setText(soap.getTime());
details_target_value.setText(soap.getTargetService());
details_status_value.setText(soap.getStatus());
if (soap.getSOAPRequest() == null) {
request_text.setText("");
} else {
request_text.setText(soap.getSOAPRequest());
request_text.setCaretPosition(0);
}
if (soap.getSOAPResponse() == null) {
response_text.setText("");
} else {
response_text.setText(soap.getSOAPResponse());
response_text.setCaretPosition(0);
}
}
}
/**
* Listener to handle button actions
*
* @param e
*/
public void actionPerformed(ActionEvent e) {
// Check if the user pressed the remove button
if (e.getSource() == remove_button) {
int row = table.getSelectedRow();
model.removeRow(row);
table.clearSelection();
table.repaint();
valueChanged(null);
}
// Check if the user pressed the remove all button
if (e.getSource() == remove_all_button) {
model.clearAll();
table.setRowSelectionInterval(0, 0);
table.repaint();
valueChanged(null);
}
// Check if the user pressed the filter button
if (e.getSource() == filter_button) {
filter.showDialog();
if (filter.okPressed()) {
// Update the display with new filter
model.setFilter(filter);
table.repaint();
}
}
// Check if the user pressed the start button
if (e.getSource() == start_button) {
start();
}
// Check if the user pressed the stop button
if (e.getSource() == stop_button) {
stop();
}
// Check if the user wants to switch layout
if (e.getSource() == layout_button) {
details_panel.remove(details_soap);
details_soap.removeAll();
if (details_soap.getOrientation()
== JSplitPane.HORIZONTAL_SPLIT) {
details_soap = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
} else {
details_soap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
}
details_soap.setTopComponent(request_panel);
details_soap.setRightComponent(response_panel);
details_soap.setResizeWeight(.5);
details_panel.add(details_soap, BorderLayout.CENTER);
details_panel.validate();
details_panel.repaint();
}
// Check if the user is changing the reflow option
if (e.getSource() == reflow_xml) {
request_text.setReflowXML(reflow_xml.isSelected());
response_text.setReflowXML(reflow_xml.isSelected());
}
}
}
/**
* This class represend the data for a SOAP request/response pair
*/
class SOAPMonitorData {
/**
* Private data
*/
private Long id;
/**
* Field time
*/
private String time;
/**
* Field target
*/
private String target;
/**
* Field soap_request
*/
private String soap_request;
/**
* Field soap_response
*/
private String soap_response;
/**
* Constructor
*
* @param id
* @param target
* @param soap_request
*/
public SOAPMonitorData(Long id, String target, String soap_request) {
this.id = id;
// A null id is used to signal that the "most recent" entry
// is being created.
if (id == null) {
this.time = "Most Recent";
this.target = "---";
this.soap_request = null;
this.soap_response = null;
} else {
this.time =
DateFormat.getTimeInstance().format(new Date());
this.target = target;
this.soap_request = soap_request;
this.soap_response = null;
}
}
/**
* Get the id for the SOAP message
*
* @return
*/
public Long getId() {
return id;
}
/**
* Get the time the SOAP request was received by the application
*
* @return
*/
public String getTime() {
return time;
}
/**
* Get the SOAP request target service name
*
* @return
*/
public String getTargetService() {
return target;
}
/**
* Get the status of the request
*
* @return
*/
public String getStatus() {
String status = "---";
if (id != null) {
status = "Complete";
if (soap_response == null) {
status = "Active";
}
}
return status;
}
/**
* Get the request SOAP contents
*
* @return
*/
public String getSOAPRequest() {
return soap_request;
}
/**
* Set the resposne SOAP contents
*
* @param response
*/
public void setSOAPResponse(String response) {
soap_response = response;
}
/**
* Get the response SOAP contents
*
* @return
*/
public String getSOAPResponse() {
return soap_response;
}
}
/**
* This table model is used to manage the table displayed
* at the top of the page to show all the SOAP messages
* we have received and to control which message details are
* to be displayed on the bottom of the page.
*/
class SOAPMonitorTableModel extends AbstractTableModel {
/**
* Column titles
*/
private final String[] column_names = {"Time", "Target Service",
"Status"};
/**
* Private data
*/
private Vector data;
/**
* Field filter_include
*/
private Vector filter_include;
/**
* Field filter_exclude
*/
private Vector filter_exclude;
/**
* Field filter_active
*/
private boolean filter_active;
/**
* Field filter_complete
*/
private boolean filter_complete;
/**
* Field filter_data
*/
private Vector filter_data;
/**
* Constructor
*/
public SOAPMonitorTableModel() {
data = new Vector();
// Add "most recent" entry to top of table
SOAPMonitorData soap = new SOAPMonitorData(null, null, null);
data.addElement(soap);
filter_include = null;
filter_exclude = null;
filter_active = false;
filter_complete = false;
filter_data = null;
// By default, exclude NotificationService and
// EventViewerService messages
filter_exclude = new Vector();
filter_exclude.addElement("NotificationService");
filter_exclude.addElement("EventViewerService");
filter_data = new Vector();
filter_data.addElement(soap);
}
/**
* Get column count (part of table model interface)
*
* @return
*/
public int getColumnCount() {
return column_names.length;
}
/**
* Get row count (part of table model interface)
*
* @return
*/
public int getRowCount() {
int count = data.size();
if (filter_data != null) {
count = filter_data.size();
}
return count;
}
/**
* Get column name (part of table model interface)
*
* @param col
* @return
*/
public String getColumnName(int col) {
return column_names[col];
}
/**
* Get value at (part of table model interface)
*
* @param row
* @param col
* @return
*/
public Object getValueAt(int row, int col) {
SOAPMonitorData soap;
String value = null;
soap = (SOAPMonitorData) data.elementAt(row);
if (filter_data != null) {
soap = (SOAPMonitorData) filter_data.elementAt(row);
}
switch (col) {
case 0:
value = soap.getTime();
break;
case 1:
value = soap.getTargetService();
break;
case 2:
value = soap.getStatus();
break;
}
return value;
}
/**
* Check if soap data matches filter
*
* @param soap
* @return
*/
public boolean filterMatch(SOAPMonitorData soap) {
boolean match = true;
if (filter_include != null) {
// Check for service match
Enumeration e = filter_include.elements();
match = false;
while (e.hasMoreElements() && !match) {
String service = (String) e.nextElement();
if (service.equals(soap.getTargetService())) {
match = true;
}
}
}
if (filter_exclude != null) {
// Check for service match
Enumeration e = filter_exclude.elements();
while (e.hasMoreElements() && match) {
String service = (String) e.nextElement();
if (service.equals(soap.getTargetService())) {
match = false;
}
}
}
if (filter_active) {
// Check for active status match
if (soap.getSOAPResponse() != null) {
match = false;
}
}
if (filter_complete) {
// Check for complete status match
if (soap.getSOAPResponse() == null) {
match = false;
}
}
// The "most recent" is always a match
if (soap.getId() == null) {
match = true;
}
return match;
}
/**
* Add data to the table as a new row
*
* @param soap
*/
public void addData(SOAPMonitorData soap) {
int row = data.size();
data.addElement(soap);
if (filter_data != null) {
if (filterMatch(soap)) {
row = filter_data.size();
filter_data.addElement(soap);
fireTableRowsInserted(row, row);
}
} else {
fireTableRowsInserted(row, row);
}
}
/**
* Find the data for a given id
*
* @param id
* @return
*/
public SOAPMonitorData findData(Long id) {
SOAPMonitorData soap = null;
for (int row = data.size(); (row > 0) && (soap == null); row--) {
soap = (SOAPMonitorData) data.elementAt(row - 1);
if (soap.getId().longValue() != id.longValue()) {
soap = null;
}
}
return soap;
}
/**
* Find the row in the table for a given message id
*
* @param soap
* @return
*/
public int findRow(SOAPMonitorData soap) {
int row = -1;
if (filter_data != null) {
row = filter_data.indexOf(soap);
} else {
row = data.indexOf(soap);
}
return row;
}
/**
* Remove all messages from the table (but leave "most recent")
*/
public void clearAll() {
int last_row = data.size() - 1;
if (last_row > 0) {
data.removeAllElements();
SOAPMonitorData soap = new SOAPMonitorData(null, null, null);
data.addElement(soap);
if (filter_data != null) {
filter_data.removeAllElements();
filter_data.addElement(soap);
}
fireTableDataChanged();
}
}
/**
* Remove a message from the table
*
* @param row
*/
public void removeRow(int row) {
SOAPMonitorData soap = null;
if (filter_data == null) {
soap = (SOAPMonitorData) data.elementAt(row);
data.remove(soap);
} else {
soap = (SOAPMonitorData) filter_data.elementAt(row);
filter_data.remove(soap);
data.remove(soap);
}
fireTableRowsDeleted(row, row);
}
/**
* Set a new filter
*
* @param filter
*/
public void setFilter(SOAPMonitorFilter filter) {
// Save new filter criteria
filter_include = filter.getFilterIncludeList();
filter_exclude = filter.getFilterExcludeList();
filter_active = filter.getFilterActive();
filter_complete = filter.getFilterComplete();
applyFilter();
}
/**
* Refilter the list of messages
*/
public void applyFilter() {
// Re-filter using new criteria
filter_data = null;
if ((filter_include != null) || (filter_exclude != null)
|| filter_active || filter_complete) {
filter_data = new Vector();
Enumeration e = data.elements();
SOAPMonitorData soap;
while (e.hasMoreElements()) {
soap = (SOAPMonitorData) e.nextElement();
if (filterMatch(soap)) {
filter_data.addElement(soap);
}
}
}
fireTableDataChanged();
}
/**
* Get the data for a row
*
* @param row
* @return
*/
public SOAPMonitorData getData(int row) {
SOAPMonitorData soap = null;
if (filter_data == null) {
soap = (SOAPMonitorData) data.elementAt(row);
} else {
soap = (SOAPMonitorData) filter_data.elementAt(row);
}
return soap;
}
/**
* Update a message
*
* @param soap
*/
public void updateData(SOAPMonitorData soap) {
int row;
if (filter_data == null) {
// No filter, so just fire table updated
row = data.indexOf(soap);
if (row != -1) {
fireTableRowsUpdated(row, row);
}
} else {
// Check if the row was being displayed
row = filter_data.indexOf(soap);
if (row == -1) {
// Row was not displayed, so check for if it
// now needs to be displayed
if (filterMatch(soap)) {
int index = -1;
row = data.indexOf(soap) + 1;
while ((row < data.size()) && (index == -1)) {
index = filter_data.indexOf(data.elementAt(row));
if (index != -1) {
// Insert at this location
filter_data.add(index, soap);
}
row++;
}
if (index == -1) {
// Insert at end
index = filter_data.size();
filter_data.addElement(soap);
}
fireTableRowsInserted(index, index);
}
} else {
// Row was displayed, so check if it needs to
// be updated or removed
if (filterMatch(soap)) {
fireTableRowsUpdated(row, row);
} else {
filter_data.remove(soap);
fireTableRowsDeleted(row, row);
}
}
}
}
}
/**
* Panel with checkbox and list
*/
class ServiceFilterPanel extends JPanel
implements ActionListener, ListSelectionListener, DocumentListener {
/**
* Field service_box
*/
private JCheckBox service_box = null;
/**
* Field filter_list
*/
private Vector filter_list = null;
/**
* Field service_data
*/
private Vector service_data = null;
/**
* Field service_list
*/
private JList service_list = null;
/**
* Field service_scroll
*/
private JScrollPane service_scroll = null;
/**
* Field remove_service_button
*/
private JButton remove_service_button = null;
/**
* Field remove_service_panel
*/
private JPanel remove_service_panel = null;
/**
* Field indent_border
*/
private EmptyBorder indent_border = null;
/**
* Field empty_border
*/
private EmptyBorder empty_border = null;
/**
* Field service_area
*/
private JPanel service_area = null;
/**
* Field add_service_area
*/
private JPanel add_service_area = null;
/**
* Field add_service_field
*/
private JTextField add_service_field = null;
/**
* Field add_service_button
*/
private JButton add_service_button = null;
/**
* Field add_service_panel
*/
private JPanel add_service_panel = null;
/**
* Constructor
*
* @param text
* @param list
*/
public ServiceFilterPanel(String text, Vector list) {
empty_border = new EmptyBorder(5, 5, 0, 5);
indent_border = new EmptyBorder(5, 25, 5, 5);
service_box = new JCheckBox(text);
service_box.addActionListener(this);
service_data = new Vector();
if (list != null) {
service_box.setSelected(true);
service_data = (Vector) list.clone();
}
service_list = new JList(service_data);
service_list.setBorder(new EtchedBorder());
service_list.setVisibleRowCount(5);
service_list.addListSelectionListener(this);
service_list.setEnabled(service_box.isSelected());
service_scroll = new JScrollPane(service_list);
service_scroll.setBorder(new EtchedBorder());
remove_service_button = new JButton("Remove");
remove_service_button.addActionListener(this);
remove_service_button.setEnabled(false);
remove_service_panel = new JPanel();
remove_service_panel.setLayout(new FlowLayout());
remove_service_panel.add(remove_service_button);
service_area = new JPanel();
service_area.setLayout(new BorderLayout());
service_area.add(service_scroll, BorderLayout.CENTER);
service_area.add(remove_service_panel, BorderLayout.EAST);
service_area.setBorder(indent_border);
add_service_field = new JTextField();
add_service_field.addActionListener(this);
add_service_field.getDocument().addDocumentListener(this);
add_service_field.setEnabled(service_box.isSelected());
add_service_button = new JButton("Add");
add_service_button.addActionListener(this);
add_service_button.setEnabled(false);
add_service_panel = new JPanel();
add_service_panel.setLayout(new BorderLayout());
JPanel dummy = new JPanel();
dummy.setBorder(empty_border);
add_service_panel.add(dummy, BorderLayout.WEST);
add_service_panel.add(add_service_button, BorderLayout.EAST);
add_service_area = new JPanel();
add_service_area.setLayout(new BorderLayout());
add_service_area.add(add_service_field, BorderLayout.CENTER);
add_service_area.add(add_service_panel, BorderLayout.EAST);
add_service_area.setBorder(indent_border);
setLayout(new BorderLayout());
add(service_box, BorderLayout.NORTH);
add(service_area, BorderLayout.CENTER);
add(add_service_area, BorderLayout.SOUTH);
setBorder(empty_border);
}
/**
* Get the current list of services
*
* @return
*/
public Vector getServiceList() {
Vector list = null;
if (service_box.isSelected()) {
list = service_data;
}
return list;
}
/**
* Listener to handle button actions
*
* @param e
*/
public void actionPerformed(ActionEvent e) {
// Check if the user changed the service filter option
if (e.getSource() == service_box) {
service_list.setEnabled(service_box.isSelected());
service_list.clearSelection();
remove_service_button.setEnabled(false);
add_service_field.setEnabled(service_box.isSelected());
add_service_field.setText("");
add_service_button.setEnabled(false);
}
// Check if the user pressed the add service button
if ((e.getSource() == add_service_button)
|| (e.getSource() == add_service_field)) {
String text = add_service_field.getText();
if ((text != null) && (text.length() > 0)) {
service_data.addElement(text);
service_list.setListData(service_data);
}
add_service_field.setText("");
add_service_field.requestFocus();
}
// Check if the user pressed the remove service button
if (e.getSource() == remove_service_button) {
Object[] sels = service_list.getSelectedValues();
for (int i = 0; i < sels.length; i++) {
service_data.removeElement(sels[i]);
}
service_list.setListData(service_data);
service_list.clearSelection();
}
}
/**
* Handle changes to the text field
*
* @param e
*/
public void changedUpdate(DocumentEvent e) {
String text = add_service_field.getText();
if ((text != null) && (text.length() > 0)) {
add_service_button.setEnabled(true);
} else {
add_service_button.setEnabled(false);
}
}
/**
* Handle changes to the text field
*
* @param e
*/
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}
/**
* Handle changes to the text field
*
* @param e
*/
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}
/**
* Listener to handle service list selection changes
*
* @param e
*/
public void valueChanged(ListSelectionEvent e) {
if (service_list.getSelectedIndex() == -1) {
remove_service_button.setEnabled(false);
} else {
remove_service_button.setEnabled(true);
}
}
}
/**
* Class for showing the filter dialog
*/
class SOAPMonitorFilter implements ActionListener {
/**
* Private data
*/
private JDialog dialog = null;
/**
* Field panel
*/
private JPanel panel = null;
/**
* Field buttons
*/
private JPanel buttons = null;
/**
* Field ok_button
*/
private JButton ok_button = null;
/**
* Field cancel_button
*/
private JButton cancel_button = null;
/**
* Field include_panel
*/
private ServiceFilterPanel include_panel = null;
/**
* Field exclude_panel
*/
private ServiceFilterPanel exclude_panel = null;
/**
* Field status_panel
*/
private JPanel status_panel = null;
/**
* Field status_box
*/
private JCheckBox status_box = null;
/**
* Field empty_border
*/
private EmptyBorder empty_border = null;
/**
* Field indent_border
*/
private EmptyBorder indent_border = null;
/**
* Field status_options
*/
private JPanel status_options = null;
/**
* Field status_group
*/
private ButtonGroup status_group = null;
/**
* Field status_active
*/
private JRadioButton status_active = null;
/**
* Field status_complete
*/
private JRadioButton status_complete = null;
/**
* Field filter_include_list
*/
private Vector filter_include_list = null;
/**
* Field filter_exclude_list
*/
private Vector filter_exclude_list = null;
/**
* Field filter_active
*/
private boolean filter_active = false;
/**
* Field filter_complete
*/
private boolean filter_complete = false;
/**
* Field ok_pressed
*/
private boolean ok_pressed = false;
/**
* Constructor
*/
public SOAPMonitorFilter() {
// By default, exclude NotificationService and
// EventViewerService messages
filter_exclude_list = new Vector();
filter_exclude_list.addElement("NotificationService");
filter_exclude_list.addElement("EventViewerService");
}
/**
* Get list of services to be included
*
* @return
*/
public Vector getFilterIncludeList() {
return filter_include_list;
}
/**
* Get list of services to be excluded
*
* @return
*/
public Vector getFilterExcludeList() {
return filter_exclude_list;
}
/**
* Check if filter active messages
*
* @return
*/
public boolean getFilterActive() {
return filter_active;
}
/**
* Check if filter complete messages
*
* @return
*/
public boolean getFilterComplete() {
return filter_complete;
}
/**
* Show the filter dialog
*/
public void showDialog() {
empty_border = new EmptyBorder(5, 5, 0, 5);
indent_border = new EmptyBorder(5, 25, 5, 5);
include_panel = new ServiceFilterPanel(
"Include messages based on target service:",
filter_include_list);
exclude_panel = new ServiceFilterPanel(
"Exclude messages based on target service:",
filter_exclude_list);
status_box = new JCheckBox("Filter messages based on status:");
status_box.addActionListener(this);
status_active = new JRadioButton("Active messages only");
status_active.setSelected(true);
status_active.setEnabled(false);
status_complete = new JRadioButton("Complete messages only");
status_complete.setEnabled(false);
status_group = new ButtonGroup();
status_group.add(status_active);
status_group.add(status_complete);
if (filter_active || filter_complete) {
status_box.setSelected(true);
status_active.setEnabled(true);
status_complete.setEnabled(true);
if (filter_complete) {
status_complete.setSelected(true);
}
}
status_options = new JPanel();
status_options.setLayout(new BoxLayout(status_options,
BoxLayout.Y_AXIS));
status_options.add(status_active);
status_options.add(status_complete);
status_options.setBorder(indent_border);
status_panel = new JPanel();
status_panel.setLayout(new BorderLayout());
status_panel.add(status_box, BorderLayout.NORTH);
status_panel.add(status_options, BorderLayout.CENTER);
status_panel.setBorder(empty_border);
ok_button = new JButton("Ok");
ok_button.addActionListener(this);
cancel_button = new JButton("Cancel");
cancel_button.addActionListener(this);
buttons = new JPanel();
buttons.setLayout(new FlowLayout());
buttons.add(ok_button);
buttons.add(cancel_button);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(include_panel);
panel.add(exclude_panel);
panel.add(status_panel);
panel.add(buttons);
dialog = new JDialog();
dialog.setTitle("SOAP Monitor Filter");
dialog.setContentPane(panel);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setModal(true);
dialog.pack();
Dimension d = dialog.getToolkit().getScreenSize();
dialog.setLocation((d.width - dialog.getWidth()) / 2,
(d.height - dialog.getHeight()) / 2);
ok_pressed = false;
dialog.show();
}
/**
* Listener to handle button actions
*
* @param e
*/
public void actionPerformed(ActionEvent e) {
// Check if the user pressed the ok button
if (e.getSource() == ok_button) {
filter_include_list = include_panel.getServiceList();
filter_exclude_list = exclude_panel.getServiceList();
if (status_box.isSelected()) {
filter_active = status_active.isSelected();
filter_complete = status_complete.isSelected();
} else {
filter_active = false;
filter_complete = false;
}
ok_pressed = true;
dialog.dispose();
}
// Check if the user pressed the cancel button
if (e.getSource() == cancel_button) {
dialog.dispose();
}
// Check if the user changed the status filter option
if (e.getSource() == status_box) {
status_active.setEnabled(status_box.isSelected());
status_complete.setEnabled(status_box.isSelected());
}
}
/**
* Check if the user pressed the ok button
*
* @return
*/
public boolean okPressed() {
return ok_pressed;
}
}
/**
* Text panel class that supports XML reflow
*/
class SOAPMonitorTextArea extends JTextArea {
/**
* Private data
*/
private boolean format = false;
/**
* Field original
*/
private String original = "";
/**
* Field formatted
*/
private String formatted = null;
/**
* Constructor
*/
public SOAPMonitorTextArea() {
}
/**
* Override setText to do formatting
*
* @param text
*/
public void setText(String text) {
original = text;
formatted = null;
if (format) {
doFormat();
super.setText(formatted);
} else {
super.setText(original);
}
}
/**
* Turn reflow on or off
*
* @param reflow
*/
public void setReflowXML(boolean reflow) {
format = reflow;
if (format) {
if (formatted == null) {
doFormat();
}
super.setText(formatted);
} else {
super.setText(original);
}
}
/**
* Reflow XML
*/
public void doFormat() {
Vector parts = new Vector();
char[] chars = original.toCharArray();
int index = 0;
int first = 0;
String part = null;
while (index < chars.length) {
// Check for start of tag
if (chars[index] == '<') {
// Did we have data before this tag?
if (first < index) {
part = new String(chars, first, index - first);
part = part.trim();
// Save non-whitespace data
if (part.length() > 0) {
parts.addElement(part);
}
}
// Save the start of tag
first = index;
}
// Check for end of tag
if (chars[index] == '>') {
// Save the tag
part = new String(chars, first, index - first + 1);
parts.addElement(part);
first = index + 1;
}
// Check for end of line
if ((chars[index] == '\n') || (chars[index] == '\r')) {
// Was there data on this line?
if (first < index) {
part = new String(chars, first, index - first);
part = part.trim();
// Save non-whitespace data
if (part.length() > 0) {
parts.addElement(part);
}
}
first = index + 1;
}
index++;
}
// Reflow as XML
StringBuffer buf = new StringBuffer();
Object[] list = parts.toArray();
int indent = 0;
int pad = 0;
index = 0;
while (index < list.length) {
part = (String) list[index];
if (buf.length() == 0) {
// Just add first tag (should be XML header)
buf.append(part);
} else {
// All other parts need to start on a new line
buf.append('\n');
// If we're at an end tag then decrease indent
if (part.startsWith("</")) {
indent--;
}
// Add any indent
for (pad = 0; pad < indent; pad++) {
buf.append(" ");
}
// Add the tag or data
buf.append(part);
// If this is a start tag then increase indent
if (part.startsWith("<") && !part.startsWith("</")
&& !part.endsWith("/>")) {
indent++;
// Check for special <tag>data</tag> case
if ((index + 2) < list.length) {
part = (String) list[index + 2];
if (part.startsWith("</")) {
part = (String) list[index + 1];
if (!part.startsWith("<")) {
buf.append(part);
part = (String) list[index + 2];
buf.append(part);
index = index + 2;
indent--;
}
}
}
}
}
index++;
}
formatted = new String(buf);
}
}
/**
* Listener to handle button actions
*
* @param e
*/
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == add_btn) {
int selected[] = list1.getSelectedIndices();
int len = selected.length - 1;
for (int i = len; i >= 0; i--) {
model2.addElement(model1.getElementAt(selected[i]));
model1.remove(selected[i]);
}
if (model1.size() == 0) {
add_btn.setEnabled(false);
}
if (model2.size() > 0) {
del_btn.setEnabled(true);
}
} else if (obj == del_btn) {
int selected[] = list2.getSelectedIndices();
int len = selected.length - 1;
for (int i = len; i >= 0; i--) {
model1.addElement(model2.getElementAt(selected[i]));
model2.remove(selected[i]);
}
if (model2.size() == 0) {
del_btn.setEnabled(false);
}
if (model1.size() > 0) {
add_btn.setEnabled(true);
}
} else if (obj == login_btn) {
if (doLogin()) {
delPage();
addPage(new SOAPMonitorPage(axisHost));
start();
} else {
add_btn.setEnabled(false);
del_btn.setEnabled(false);
}
} else if (obj == save_btn) {
String service = null;
Node node = null;
Node impNode = null;
Document wsdd = null;
JOptionPane pane = null;
JDialog dlg = null;
String msg = null;
final String title = "Deployment status";
final String deploy = "<deployment name=\"SOAPMonitor\""
+ " xmlns=\"http://xml.apache.org/axis/wsdd/\""
+ " xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">\n"
+ " <handler name=\"soapmonitor\""
+ " type=\"java:org.apache.axis.handlers.SOAPMonitorHandler\" />\n"
+ " </deployment>";
// Create a new wsdd document
try {
wsdd = XMLUtils.newDocument(
new ByteArrayInputStream(deploy.getBytes()));
} catch (Exception ex) {
ex.printStackTrace();
}
Collection col = serviceMap.keySet();
Iterator ite = col.iterator();
// Add all of service nodes to the new wsdd
while (ite.hasNext()) {
service = (String) ite.next();
node = (Node) serviceMap.get(service);
if (model2.contains(service)) {
if (isMonitored(node)) { // It's already been monitored
impNode = wsdd.importNode(node, true);
} else { // It's to be monitored
impNode = wsdd.importNode(addMonitor(node), true);
}
} else {
if (isMonitored(node)) { // It's not to be monitored
impNode = wsdd.importNode(delMonitor(node), true);
} else { // It's not already been monitored
impNode = wsdd.importNode(node, true);
}
}
if (service.equals("AdminService")) {
// Add "SimpleAuthenticationHandler" and "allowedRoles" parameter
// with "admin" as a user account
impNode = wsdd.importNode(addAuthenticate(impNode), true);
}
wsdd.getDocumentElement().appendChild(impNode);
}
// Show the result of deployment
pane = new JOptionPane();
if (doDeploy(wsdd)) {
msg = "The deploy was successful.";
pane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
} else {
msg = "The deploy was NOT successful.";
pane.setMessageType(JOptionPane.WARNING_MESSAGE);
}
pane.setOptions(new String[]{"OK"});
pane.setMessage(msg);
dlg = pane.createDialog(null, title);
dlg.setVisible(true);
}
}
/**
* ChangeListener to handle tab actions
*
* @param e
*/
public void stateChanged( javax.swing.event.ChangeEvent e ){
JTabbedPane tab = (JTabbedPane)e.getSource();
int item = tab.getSelectedIndex();
if (item==1) { // "Monitoring" tab is selected.
start();
} else { // "Setting" tab is selected.
stop();
}
}
}