/***********************************************************************
*
* $CVSHeader$
*
* This file is part of WebScarab, an Open Web Application Security
* Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2004 Rogan Dawes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source
* ==============
*
* Source for this application is maintained at Sourceforge.net, a
* repository for free software projects.
*
* For details, please see http://www.sourceforge.net/projects/owasp
*
*/
/*
* SummaryPanel.java
*
* Created on December 16, 2003, 10:35 AM
*/
package org.owasp.webscarab.ui.swing;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import javax.swing.Action;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.TableModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.owasp.webscarab.model.ConversationID;
import org.owasp.webscarab.model.FilteredUrlModel;
import org.owasp.webscarab.model.FrameworkModel;
import org.owasp.webscarab.model.HttpUrl;
import org.owasp.webscarab.util.swing.ColumnDataModel;
import org.owasp.webscarab.util.swing.JTreeTable;
import org.owasp.webscarab.util.swing.TableSorter;
/**
*
* @author rdawes
*/
public class SummaryPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = -653352257745170107L;
private FrameworkModel _model;
private UrlFilteredConversationModel _conversationModel;
private FilteredUrlModel _urlModel;
private JTreeTable _urlTreeTable;
private ArrayList<Action> _urlActions = new ArrayList<Action>();
private HttpUrl _treeURL = null;
private TableSorter _conversationTableSorter;
private ConversationTableModel _conversationTableModel;
private UrlTreeTableModelAdapter _urlTreeTableModel;
private ArrayList<Action> _conversationActions = new ArrayList<Action>();
private HashMap<String, ColumnDataModel<HttpUrl>> _urlColumns = new HashMap<String, ColumnDataModel<HttpUrl>>();
/** Creates new form SummaryPanel */
public SummaryPanel(FrameworkModel model) {
_model = model;
_conversationModel = new UrlFilteredConversationModel(_model,
_model.getConversationModel());
// FIXME this is the wrong place for this, I think?
_urlModel = new FilteredUrlModel(model.getUrlModel()) {
protected boolean shouldFilter(HttpUrl url) {
return _model.getUrlProperty(url, "METHODS") == null;
}
};
initComponents();
initTree();
addTreeListeners();
initTable();
addTableListeners();
addConversationActions(new Action[] { new ShowConversationAction(
_conversationModel) });
}
private void initTree() {
_urlTreeTableModel = new UrlTreeTableModelAdapter(_urlModel);
_urlTreeTable = new JTreeTable(_urlTreeTableModel);
_urlTreeTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
_urlTreeTable.setDefaultRenderer(
Boolean.class,
new EnabledBooleanTableCellRenderer());
System.out.println(_urlTreeTable.getDefaultRenderer(Boolean.class));
ColumnWidthTracker.getTracker("UrlTree").addTable(_urlTreeTable);
ColumnDataModel<HttpUrl> cdm = new ColumnDataModel<HttpUrl>("Methods", String.class) {
public Object getValue(HttpUrl key) {
if (_model == null)
return null;
return _model.getUrlProperty(key, "METHODS");
}
};
_urlColumns.put("METHODS", cdm);
_urlTreeTableModel.addColumn(cdm);
cdm = new ColumnDataModel<HttpUrl>("Status", String.class) {
public Object getValue(HttpUrl key) {
if (_model == null)
return null;
return _model.getUrlProperty(key, "STATUS");
}
};
_urlColumns.put("STATUS", cdm);
_urlTreeTableModel.addColumn(cdm);
JTree urlTree = _urlTreeTable.getTree();
urlTree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
urlTree.setRootVisible(false);
urlTree.setShowsRootHandles(true);
urlTree.setCellRenderer(new UrlTreeRenderer());
treeScrollPane.setViewportView(_urlTreeTable);
}
private void addTreeListeners() {
// Listen for when the selection changes.
// We use this to set the selected URLInfo for each action, and
// to filter the conversation list
final JTree urlTree = _urlTreeTable.getTree();
urlTree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
TreePath selection = urlTree.getSelectionPath();
_treeURL = null;
if (selection != null) {
Object o = selection.getLastPathComponent();
if (o instanceof HttpUrl) {
_treeURL = (HttpUrl) o;
}
}
if (treeCheckBox.isSelected()) {
_conversationModel.setUrl(_treeURL);
}
synchronized (_urlActions) {
for (int i = 0; i < _urlActions.size(); i++) {
Action action = _urlActions.get(i);
action.putValue("URL", _treeURL);
}
}
}
});
_urlTreeTable.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger() && _urlActions.size() > 0) {
int row = _urlTreeTable.rowAtPoint(e.getPoint());
_urlTreeTable.getSelectionModel().setSelectionInterval(row,
row);
urlPopupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
}
public void addUrlActions(Action[] actions) {
if (actions == null)
return;
for (int i = 0; i < actions.length; i++) {
_urlActions.add(actions[i]);
}
for (int i = 0; i < actions.length; i++) {
urlPopupMenu.add(new JMenuItem(actions[i]));
}
}
public void addUrlColumns(ColumnDataModel<HttpUrl>[] columns) {
if (columns == null)
return;
for (int i = 0; i < columns.length; i++) {
_urlTreeTableModel.addColumn(columns[i]);
}
}
private void initTable() {
_conversationTableModel = new ConversationTableModel(_conversationModel);
ColumnWidthTracker.getTracker("ConversationTable").addTable(
conversationTable);
_conversationTableSorter = new TableSorter(_conversationTableModel,
conversationTable.getTableHeader());
conversationTable.setModel(_conversationTableSorter);
conversationTable.setDefaultRenderer(
Boolean.class,
new EnabledBooleanTableCellRenderer());
conversationTable.setDefaultRenderer(Date.class, new DateRenderer());
}
private void addTableListeners() {
// This listener updates the registered actions with the selected
// Conversation
conversationTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting())
return;
int row = conversationTable.getSelectedRow();
TableModel tm = conversationTable.getModel();
ConversationID id = null;
if (row > -1)
id = (ConversationID) tm.getValueAt(row, 0); // UGLY
// hack!
// FIXME!!!!
synchronized (_conversationActions) {
for (int i = 0; i < _conversationActions.size(); i++) {
Action action = _conversationActions.get(i);
action.putValue("CONVERSATION", id);
action.putValue("COMPONENT", conversationTable);
}
}
}
});
conversationTable.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
int row = conversationTable.rowAtPoint(e.getPoint());
conversationTable.getSelectionModel().setSelectionInterval(row,
row);
if (e.isPopupTrigger() && _conversationActions.size() > 0) {
conversationPopupMenu.show(e.getComponent(), e.getX(),
e.getY());
}
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2
&& e.getButton() == MouseEvent.BUTTON1) {
if (_conversationActions.size() > 0) {
Action action = _conversationActions.get(0);
ActionEvent evt = new ActionEvent(conversationTable, 0,
(String) action
.getValue(Action.ACTION_COMMAND_KEY));
if (action.isEnabled()) {
action.actionPerformed(evt);
}
}
}
}
});
}
public void addConversationActions(Action[] actions) {
if (actions == null)
return;
for (int i = 0; i < actions.length; i++) {
_conversationActions.add(actions[i]);
}
for (int i = 0; i < actions.length; i++) {
conversationPopupMenu.add(new JMenuItem(actions[i]));
}
}
public void addConversationColumns(ColumnDataModel<ConversationID>[] columns) {
if (columns == null)
return;
for (int i = 0; i < columns.length; i++) {
_conversationTableModel.addColumn(columns[i]);
}
_conversationTableSorter.setSortingStatus(0, TableSorter.DESCENDING);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed"
// desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
urlPopupMenu = new javax.swing.JPopupMenu();
conversationPopupMenu = new javax.swing.JPopupMenu();
summarySplitPane = new javax.swing.JSplitPane();
urlPanel = new javax.swing.JPanel();
treeCheckBox = new javax.swing.JCheckBox();
treeScrollPane = new javax.swing.JScrollPane();
conversationScrollPane = new javax.swing.JScrollPane();
conversationTable = new javax.swing.JTable();
urlPopupMenu.setLabel("URL Actions");
conversationPopupMenu.setLabel("Conversation Actions");
setLayout(new java.awt.BorderLayout());
summarySplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
summarySplitPane.setResizeWeight(0.5);
summarySplitPane.setOneTouchExpandable(true);
urlPanel.setLayout(new java.awt.GridBagLayout());
urlPanel.setMinimumSize(new java.awt.Dimension(283, 100));
urlPanel.setPreferredSize(new java.awt.Dimension(264, 100));
treeCheckBox.setText("Tree Selection filters conversation list");
treeCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
treeCheckBoxActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
urlPanel.add(treeCheckBox, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
urlPanel.add(treeScrollPane, gridBagConstraints);
summarySplitPane.setLeftComponent(urlPanel);
conversationTable.setModel(new javax.swing.table.DefaultTableModel(
new Object[][] {
}, new String[] {
}));
conversationTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
conversationTable.setCellSelectionEnabled(true);
conversationScrollPane.setViewportView(conversationTable);
summarySplitPane.setRightComponent(conversationScrollPane);
add(summarySplitPane, java.awt.BorderLayout.CENTER);
}// </editor-fold>//GEN-END:initComponents
private void treeCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_treeCheckBoxActionPerformed
if (treeCheckBox.isSelected() && _treeURL != null) {
_conversationModel.setUrl(_treeURL);
} else {
_conversationModel.setUrl(null);
}
}// GEN-LAST:event_treeCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPopupMenu conversationPopupMenu;
private javax.swing.JScrollPane conversationScrollPane;
private javax.swing.JTable conversationTable;
private javax.swing.JSplitPane summarySplitPane;
private javax.swing.JCheckBox treeCheckBox;
private javax.swing.JScrollPane treeScrollPane;
private javax.swing.JPanel urlPanel;
private javax.swing.JPopupMenu urlPopupMenu;
// End of variables declaration//GEN-END:variables
}