/*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache JMeter" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache JMeter", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.jmeter.protocol.http.proxy.gui;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.functions.ValueReplacer;
import org.apache.jmeter.gui.GuiPackage;
import org.apache.jmeter.gui.JMeterGUIComponent;
import org.apache.jmeter.gui.NamePanel;
import org.apache.jmeter.gui.util.MenuFactory;
import org.apache.jmeter.gui.util.PowerTableModel;
import org.apache.jmeter.protocol.http.proxy.ProxyControl;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.util.JMeterUtils;
/****************************************
* Title: Jakarta-JMeter Description: Copyright: Copyright (c) 2001 Company:
* Apache
*
*@author Michael Stover
*@created $Date: 2002/08/28 15:53:00 $
*@version 1.0
***************************************/
public class ProxyControlGui extends JPanel implements JMeterGUIComponent, ActionListener,
KeyListener,FocusListener
{
NamePanel namePanel;
JTextField portField;
ProxyControl model;
JTable excludeTable;
PowerTableModel excludeModel;
JTable includeTable;
PowerTableModel includeModel;
JButton addExclude,deleteExclude,addInclude,deleteInclude;
JButton stop, start,restart;
private final static String STOP = "stop";
private final static String START = "start";
private final static String RESTART = "restart";
private final static String ADD_INCLUDE = "add_include";
private final static String ADD_EXCLUDE = "add_exclude";
private final static String DELETE_INCLUDE = "delete_include";
private final static String DELETE_EXCLUDE = "delete_exclude";
private final static String INCLUDE_COL = JMeterUtils.getResString("patterns_to_include");
private final static String EXCLUDE_COL = JMeterUtils.getResString("patterns_to_exclude");
/****************************************
* !ToDo (Constructor description)
***************************************/
public ProxyControlGui()
{
namePanel = new NamePanel();
setName(getStaticLabel());
init();
}
public JPopupMenu createPopupMenu()
{
return MenuFactory.getDefaultTimerMenu();
}
public TestElement createTestElement()
{
ProxyControl element = new ProxyControl();
element.setProperty(TestElement.NAME,getName());
element.setPort(Integer.parseInt(portField.getText()));
setIncludeListInProxyControl(element);
setExcludeListInProxyControl(element);
element.setProperty(TestElement.GUI_CLASS, this.getClass().getName());
element.setProperty(TestElement.TEST_CLASS, element.getClass().getName());
return element;
}
private void setIncludeListInProxyControl(ProxyControl element) {
List includeList = getDataList(includeModel,INCLUDE_COL);
element.setIncludeList(includeList);
}
private void setExcludeListInProxyControl(ProxyControl element)
{
List excludeList = getDataList(excludeModel,EXCLUDE_COL);
element.setExcludeList(excludeList);
}
private List getDataList(PowerTableModel model,String colName) {
String[] dataArray = model.getData().getColumn(colName);
List list = new LinkedList();
for(int i = 0;i < dataArray.length;i++)
{
list.add(dataArray[i]);
}
return list;
}
public void setName(String name)
{
super.setName(name);
namePanel.setName(name);
}
public String getName()
{
return namePanel.getName();
}
public String getStaticLabel()
{
return JMeterUtils.getResString("proxy_title");
}
public Collection getMenuCategories()
{
return Arrays.asList(new String[]{MenuFactory.NON_TEST_ELEMENTS});
}
public void configure(TestElement element)
{
ProxyControl el = (ProxyControl)element;
setName(element.getProperty(TestElement.NAME).toString());
portField.setText(element.getProperty(ProxyControl.PORT).toString());
populateTable(includeModel,el.getIncludePatterns().iterator());
populateTable(excludeModel,el.getExcludePatterns().iterator());
}
private void populateTable(PowerTableModel model,Iterator iter) {
while(iter.hasNext())
{
model.addRow(new Object[]{iter.next()});
}
}
public void focusLost(FocusEvent e)
{
try
{
((JTable)e.getSource()).getCellEditor().stopCellEditing();
}
catch(Exception err)
{
}
}
public void focusGained(FocusEvent e)
{
}
/****************************************
* !ToDo (Method description)
*
*@param action !ToDo (Parameter description)
***************************************/
public void actionPerformed(ActionEvent action)
{
String command = action.getActionCommand();
if(command.equals(STOP))
{
model.stopProxy();
stop.setEnabled(false);
start.setEnabled(true);
model = null;
}
else if(command.equals(START))
{
model = (ProxyControl)createTestElement();
startProxy();
}
else if(command.equals(RESTART))
{
model.stopProxy();
model = (ProxyControl)createTestElement();
startProxy();
}
else if(command.equals(this.ADD_EXCLUDE))
{
excludeModel.addNewRow();
excludeModel.fireTableDataChanged();
if(model != null)
enableRestart();
}
else if(command.equals(this.ADD_INCLUDE))
{
includeModel.addNewRow();
includeModel.fireTableDataChanged();
enableRestart();
}
else if(command.equals(this.DELETE_EXCLUDE))
{
excludeModel.removeRow(excludeTable.getSelectedRow());
excludeModel.fireTableDataChanged();
enableRestart();
}
else if(command.equals(this.DELETE_INCLUDE))
{
includeModel.removeRow(includeTable.getSelectedRow());
includeModel.fireTableDataChanged();
enableRestart();
}
}
private void startProxy()
{
ValueReplacer replacer = GuiPackage.getInstance().getReplacer();
try
{
replacer.replaceValues(model);
model.startProxy();
start.setEnabled(false);
stop.setEnabled(true);
restart.setEnabled(false);
}
catch (InvalidVariableException e)
{
JOptionPane.showMessageDialog(this,JMeterUtils.getResString(
"invalid_variables"),"Error",JOptionPane.ERROR_MESSAGE);
}
}
private void enableRestart()
{
if(model != null)
{
restart.setEnabled(true);
}
}
/****************************************
* !ToDo (Method description)
*
*@param e !ToDo (Parameter description)
***************************************/
public void keyPressed(KeyEvent e) { }
/****************************************
* !ToDo (Method description)
*
*@param e !ToDo (Parameter description)
***************************************/
public void keyTyped(KeyEvent e) { }
/****************************************
* !ToDo (Method description)
*
*@param e !ToDo (Parameter description)
***************************************/
public void keyReleased(KeyEvent e)
{
String fieldName = e.getComponent().getName();
if(fieldName.equals(ProxyControl.PORT))
{
try
{
Integer.parseInt(portField.getText());
}
catch(NumberFormatException nfe)
{
if(portField.getText().length() > 0)
{
JOptionPane.showMessageDialog(this, "You must enter a valid number",
"Invalid data", JOptionPane.WARNING_MESSAGE);
// Right now, the cleanest thing to do is simply clear the
// entire text field. We do not want to set the text to
// the default because that would be confusing to the user.
// For example, the user typed "5t" instead of "56". After
// the user closes the error dialog, the text would change
// from "5t" to "1". A litle confusing. If anything, it
// should display just "5". Future enhancement...
portField.setText("");
}
}
}
}
private void init()
{
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = gbc.WEST;
gbc.fill = gbc.BOTH;
gbc.gridheight = 1;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
// MAIN PANEL
JPanel mainPanel = new JPanel();
add(mainPanel,gbc.clone());
Border margin = new EmptyBorder(10, 10, 5, 10);
mainPanel.setBorder(margin);
mainPanel.setLayout(new GridBagLayout());
//gbc.fill = gbc.NONE;
gbc.weighty = 0;
// TITLE
JLabel panelTitleLabel = new JLabel(JMeterUtils.getResString("proxy_title"));
Font curFont = panelTitleLabel.getFont();
int curFontSize = curFont.getSize();
curFontSize += 4;
panelTitleLabel.setFont(new Font(curFont.getFontName(), curFont.getStyle(), curFontSize));
mainPanel.add(panelTitleLabel,gbc.clone());
gbc.gridy++;
// NAME
mainPanel.add(namePanel,gbc.clone());
gbc.gridy++;
mainPanel.add(createPortPanel(),gbc.clone());
gbc.gridy++;
gbc.fill = gbc.BOTH;
gbc.weighty = .5;
mainPanel.add(createIncludePanel(),gbc.clone());
gbc.gridy++;
mainPanel.add(createExcludePanel(),gbc.clone());
gbc.gridy++;
gbc.fill = gbc.NONE;
gbc.weighty = 0;
mainPanel.add(createControls(),gbc.clone());
}
private JPanel createControls()
{
JPanel panel = new JPanel();
start = new JButton(JMeterUtils.getResString("start"));
start.addActionListener(this);
start.setActionCommand(START);
stop = new JButton(JMeterUtils.getResString("stop"));
stop.addActionListener(this);
stop.setActionCommand(STOP);
restart = new JButton(JMeterUtils.getResString("restart"));
restart.addActionListener(this);
restart.setActionCommand(RESTART);
panel.add(start);
panel.add(stop);
panel.add(restart);
start.setEnabled(true);
stop.setEnabled(false);
restart.setEnabled(false);
return panel;
}
private JPanel createPortPanel()
{
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(new JLabel(JMeterUtils.getResString("port")));
portField = new JTextField(8);
portField.setName(ProxyControl.PORT);
portField.addKeyListener(this);
portField.setText("8080");
panel.add(portField);
panel.revalidate();
return panel;
}
private JPanel createIncludePanel()
{
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
JMeterUtils.getResString("patterns_to_include")));
includeTable = new JTable();
includeModel = new PowerTableModel(new String[]{INCLUDE_COL},
new Class[]{String.class});
JScrollPane scroller = new JScrollPane(includeTable);
scroller.setBackground(panel.getBackground());
includeTable.setModel(includeModel);
addInclude = new JButton(JMeterUtils.getResString("add"));
deleteInclude = new JButton(JMeterUtils.getResString("delete"));
addInclude.setActionCommand(ADD_INCLUDE);
deleteInclude.setActionCommand(DELETE_INCLUDE);
addInclude.addActionListener(this);
deleteInclude.addActionListener(this);
panel.add(scroller,BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.add(addInclude);
buttonPanel.add(deleteInclude);
panel.add(buttonPanel,BorderLayout.SOUTH);
includeTable.addFocusListener(this);
return panel;
}
private JPanel createExcludePanel()
{
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
JMeterUtils.getResString("patterns_to_exclude")));
excludeTable = new JTable();
excludeModel = new PowerTableModel(new String[]{EXCLUDE_COL},
new Class[]{String.class});
JScrollPane scroller = new JScrollPane(excludeTable);
scroller.setBackground(panel.getBackground());
excludeTable.setModel(excludeModel);
addExclude = new JButton(JMeterUtils.getResString("add"));
deleteExclude = new JButton(JMeterUtils.getResString("delete"));
addExclude.setActionCommand(ADD_EXCLUDE);
deleteExclude.setActionCommand(DELETE_EXCLUDE);
addExclude.addActionListener(this);
deleteExclude.addActionListener(this);
panel.add(scroller,BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.add(addExclude);
buttonPanel.add(deleteExclude);
panel.add(buttonPanel,BorderLayout.SOUTH);
excludeTable.addFocusListener(this);
return panel;
}
}