/*
* ====================================================================
* 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.ejb.jndi.config.gui;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.border.*;
import java.awt.event.*;
import javax.naming.InitialContext;
import java.awt.*;
import java.util.*;
import java.lang.reflect.Field;
import org.apache.jmeter.control.TestPlan;
import org.apache.jmeter.engine.ReflectionJMeterEngine;
import org.apache.jmeter.gui.GuiPackage;
import org.apache.jmeter.gui.ModelSupported;
import org.apache.jmeter.gui.NamePanel;
import org.apache.jmeter.gui.VerticalLayout;
import org.apache.jmeter.config.gui.ArgumentsPanel;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.ejb.jndi.config.MethodConfig;
import org.apache.jmeter.ejb.jndi.config.MethodConfigUserObject;
import org.apache.jmeter.ejb.jndi.config.MethodConfigUserObjectException;
import org.apache.log4j.Category;
/**
* Provides the gui interface to configure remote method execution
* @author Khor Soon Hin
* @version 1.0
* @created 2001 Dec 24
* @modified 2001 Dec 30
*/
public class MethodConfigGui extends JPanel implements ModelSupported,
ActionListener, TreeSelectionListener
{
private static Category catClass = Category.getInstance(
MethodConfigGui.class.getName());
protected static final String REFLECT = "MethodConfigGui.reflect";
protected static final String INVOKE = "MethodConfigGui.invoke";
protected static final String STRING_CLASS = "java.lang.String";
protected JComboBox methodHomeNameBox;
protected JComboBox methodRemoteNameBox;
protected JComboBox remoteInterfaceBox;
protected DefaultMutableTreeNode rootHome;
protected DefaultMutableTreeNode rootRemote;
protected DefaultTreeModel treeModelHome;
protected DefaultTreeModel treeModelRemote;
protected NamePanel namePanel;
protected JPanel methodHomeNamePanel;
protected JPanel methodHomeParmsPanel;
protected JPanel remoteInterfaceListPanel;
protected JPanel methodRemoteNamePanel;
protected JPanel methodRemoteParmsPanel;
protected JPanel controlPanel;
protected JButton actionButton;
protected JTree jTreeHome;
protected JTree jTreeRemote;
protected boolean displayName;
protected MethodConfig model;
protected Frame frame;
// The frame is required because the JDialog we create must be modal
// and to be modal it must be modal relative to a frame. We want
// the dialog boxes to be modal so that user must fill them up before
// they can do anything with jmeter
public MethodConfigGui()
{
displayName = true;
}
public MethodConfigGui(boolean displayName)
{
this.displayName = displayName;
}
//----- ModelSupported interface : start -----
public void setModel(Object model)
{
this.model = (MethodConfig)model;
init();
}
public void updateGui()
{
catClass.debug("Start : updateGui1");
System.out.println("updateGui1");
// the method name box will always be displayed regardless of the state
// of the MethodConfig of this gui
String methodName = model.getMethodHomeName();
catClass.debug("updateGui1 : home method name - " + methodName);
String[] strings = model.getMethodHomeList();
setupPullDown(methodHomeNameBox, methodName, strings);
// if methodName is null set the home method to be the first entry
// as setup in the home method name JComboBox by setupPullDown
// This is to ensure that if the user does not change the JComboBox
// the first value is set anyway.
if(methodName == null && strings != null)
{
model.setMethodHomeName(strings[0]);
}
// if the state of the MethodConfig of this gui after
// MethodConfig.METHOD_GET_HOME_NAMES, display panel to get
// parms of the selected method
int childCount = treeModelHome.getChildCount(rootHome);
if(catClass.isDebugEnabled())
{
catClass.debug("updateGui1 : state - " + model.getState());
catClass.debug("updateGui1 : METHOD_GET_HOME_NAMES");
catClass.debug("updateGui1 : rootHome child count - " + childCount);
}
// if model is in state after getting home method name AND
// rootHome(method) has no child(parms set) yet then get them
if(model.getState() > MethodConfig.METHOD_GET_HOME_PARMS &&
childCount == 0)
{
catClass.debug("updateGui1 : METHOD_GET_HOME_PARMS");
rootHome.setUserObject(model.getMethodHomeName());
// methodParmsPanel.setVisible(true);
// get all the parms
Class[] parmTypes = model.getMethodHomeParms();
// add all the parms into a JTree
for(int i = 0 ;i < parmTypes.length; i++)
{
catClass.debug("updateGui1 : parmType #" + i + " - " + parmTypes[i]);
recurseParm(parmTypes[i], rootHome, i, treeModelHome);
}
// if the chosen method has no parms then updating the value of
// root node with the method name doesn't seem to trigger a redraw of
// the tree so call treeDidChange()
if(parmTypes.length == 0)
{
jTreeHome.treeDidChange();
}
}
// if model is in state after getting home method name and
// all home method parms gave been obtained then get list of
// remote interfaces
if(model.getState() > MethodConfig.METHOD_SELECT_REMOTE_INTERFACE)
{
catClass.debug("METHOD_SELECT_REMOTE_INTERFACE");
// remoteInterfaceType is the remote interface selected by the user
// remoteInterfaces contains the list of remote interfaces returned
// by home method
Object remoteInterfaceType = model.getRemoteInterfaceType();
String interfaceName = null;
if(remoteInterfaceType != null)
{
interfaceName = remoteInterfaceType.toString();
}
ArrayList remoteInterfaces = (ArrayList)model.getRemoteInterfaceList();
if(catClass.isDebugEnabled())
{
catClass.debug("updateGui1 : remote interfaces - " + remoteInterfaces);
catClass.debug("updateGui1 : remoteInterfacesType - " +
remoteInterfaces.getClass());
}
// prepare variable strings to contain a list of all the names of
// the remote interfaces
Object[] remoteInterfacesArray = remoteInterfaces.toArray();
strings = new String[remoteInterfacesArray.length];
for(int i = 0; i < remoteInterfacesArray.length; i++)
{
strings[i] = remoteInterfacesArray[i].toString();
}
setupPullDown(remoteInterfaceBox, interfaceName,
strings);
// if interfaceName is null set the remote interface to be the first
// entry as setup in the remote interface name JComboBox by setupPullDown.
// This is to ensure that if the user does not change the JComboBox
// the first value is set anyway.
if(interfaceName == null && remoteInterfacesArray != null)
{
model.setRemoteInterfaceType(remoteInterfacesArray[0]);
}
}
// if model is in state after user selects the list of remote interface
// then get a list of remote method names
if(model.getState() > MethodConfig.METHOD_GET_REMOTE_NAMES)
{
catClass.debug("METHOD_GET_REMOTE_NAMES");
methodName = model.getMethodRemoteName();
catClass.debug("updateGui1 : remote method name - " + methodName);
strings = model.getMethodRemoteList();
setupPullDown(methodRemoteNameBox, methodName, strings);
childCount = treeModelRemote.getChildCount(rootRemote);
if(catClass.isDebugEnabled())
{
catClass.debug("updateGui1 : rootRemote child count - " + childCount);
}
}
// if model is in state after getting remote interface AND
// rootRemote(method) has no child(parms set) yet then get them
if(model.getState() > MethodConfig.METHOD_GET_REMOTE_PARMS &&
childCount == 0)
{
catClass.debug("METHOD_GET_REMOTE_PARMS");
rootRemote.setUserObject(model.getMethodRemoteName());
// methodParmsPanel.setVisible(true);
// get all the parms
Class[] parmTypes = model.getMethodRemoteParms();
// add all the parms into a JTree
for(int i = 0 ;i < parmTypes.length; i++)
{
catClass.debug("updateGui1 : parmType #" + i + " - " + parmTypes[i]);
recurseParm(parmTypes[i], rootHome, i, treeModelHome);
}
// if the chosen method has no parms then updating the value of
// root node with the method name doesn't seem to trigger a redraw of
// the tree so call treeDidChange()
if(parmTypes.length == 0)
{
jTreeRemote.treeDidChange();
}
}
// if the state of the MethodConfig of this gui is
// MethodConfig.METHOD_GET_HOME_PARMS, display panel
if(displayName)
{
namePanel.updateGui();
}
catClass.debug("End : updateGui1");
}
//----- ModelSupported interface : end -----
protected void init()
{
catClass.info("Start : init1");
// The frame is required because the JDialog we create must be modal
// and to be modal it must be modal relative to a frame. We want
// the dialog boxes to be modal so that user must fill them up before
// they can do anything with jmeter
GuiPackage guiPkg = GuiPackage.getInstance();
frame = guiPkg.getMainFrame();
model.setState(MethodConfig.METHOD_GET_HOME_NAMES);
model.setGui(this);
methodHomeNameBox = new JComboBox();
methodHomeNameBox.setEditable(false);
methodHomeNameBox.setAlignmentX(Component.LEFT_ALIGNMENT);
methodHomeNameBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
catClass.debug(
"actionPerformed1 : Home name method JComboBox changed");
// change in method name so do the following
JComboBox comboBox = (JComboBox)e.getSource();
String method = (String)methodHomeNameBox.getSelectedItem();
model.setMethodHomeName(method);
model.setState(MethodConfig.METHOD_GET_HOME_PARMS);
resetHomeMethodParms();
resetRemoteInterfaceList();
resetRemoteMethodName();
resetRemoteMethodParms();
// methodParmsPanel.setVisible(false);
actionButton.setText(
JMeterUtils.getResString("jndi_method_button_reflect"));
updateGui();
}
});
remoteInterfaceBox = new JComboBox();
remoteInterfaceBox.setEditable(false);
remoteInterfaceBox.setAlignmentX(Component.LEFT_ALIGNMENT);
remoteInterfaceBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
catClass.debug(
"actionPerformed1 : Remote Interface JComboBox changed");
JComboBox comboBox = (JComboBox)e.getSource();
String interfaceName = (String)remoteInterfaceBox.getSelectedItem();
// compare interface selected with the ones in the remote interface
// list and store the corresponding object in MethodConfig
ArrayList remoteInterfaceList =
(ArrayList)model.getRemoteInterfaceList();
if(remoteInterfaceList != null)
{
Object[] remoteInterfaceListArray = remoteInterfaceList.toArray();
int i = 0;
boolean found = false;
String remoteInterfaceListName = null;
Object selectedInterface = null;
while(i < remoteInterfaceListArray.length && !found)
{
remoteInterfaceListName = remoteInterfaceListArray[i].toString();
if(remoteInterfaceListName.equals(interfaceName))
{
found = true;
selectedInterface = remoteInterfaceListArray[i];
}
i++;
}
model.setRemoteInterfaceType(selectedInterface);
model.setState(MethodConfig.METHOD_GET_REMOTE_NAMES);
}
resetRemoteMethodName();
resetRemoteMethodParms();
// methodParmsPanel.setVisible(false);
actionButton.setText(
JMeterUtils.getResString("jndi_method_button_reflect"));
updateGui();
}
});
methodRemoteNameBox = new JComboBox();
methodRemoteNameBox.setEditable(false);
methodRemoteNameBox.setAlignmentX(Component.LEFT_ALIGNMENT);
methodRemoteNameBox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
catClass.debug(
"actionPerformed1 : Remote method name JComboBox changed");
// change in method name so do the following
JComboBox comboBox = (JComboBox)e.getSource();
String method = (String)methodRemoteNameBox.getSelectedItem();
model.setMethodRemoteName(method);
model.setState(MethodConfig.METHOD_GET_REMOTE_PARMS);
resetRemoteMethodParms();
// methodParmsPanel.setVisible(false);
actionButton.setText(
JMeterUtils.getResString("jndi_method_button_reflect"));
updateGui();
}
});
//rootHome = new DefaultMutableTreeNode("Root");
//treeModelHome = new DefaultTreeModel(rootHome);
this.setLayout(new VerticalLayout(5, VerticalLayout.LEFT,
VerticalLayout.TOP));
JPanel mainPanel = new JPanel();
Border margin = new EmptyBorder(10, 10, 5, 10);
mainPanel.setBorder(margin);
mainPanel.setLayout(new VerticalLayout(5, VerticalLayout.LEFT));
// title
JLabel panelTitleLabel = new JLabel(
JMeterUtils.getResString("jndi_method_title"));
Font curFont = panelTitleLabel.getFont();
int curFontSize = curFont.getSize();
curFontSize += 4;
panelTitleLabel.setFont(new Font(curFont.getFontName(),
curFont.getStyle(), curFontSize));
mainPanel.add(panelTitleLabel);
// name
namePanel = new NamePanel(model);
mainPanel.add(namePanel);
// method properties
JPanel jndiPanel = new JPanel();
jndiPanel.setLayout(new VerticalLayout(5, VerticalLayout.LEFT));
jndiPanel.setBorder(BorderFactory.createTitledBorder(
JMeterUtils.getResString("jndi_method_name")));
methodHomeNamePanel = getMethodHomeNamePanel();
methodHomeParmsPanel = getMethodHomeParmsPanel();
remoteInterfaceListPanel = getRemoteInterfaceListPanel();
methodRemoteNamePanel= getMethodRemoteNamePanel();
methodRemoteParmsPanel = getMethodRemoteParmsPanel();
jndiPanel.add(methodHomeNamePanel);
jndiPanel.add(methodHomeParmsPanel);
jndiPanel.add(remoteInterfaceListPanel);
jndiPanel.add(methodRemoteNamePanel);
jndiPanel.add(methodRemoteParmsPanel);
controlPanel = new JPanel();
actionButton = new JButton(
JMeterUtils.getResString("jndi_method_button_reflect"));
actionButton.addActionListener(this);
actionButton.setActionCommand(REFLECT);
controlPanel.add(actionButton);
jndiPanel.add(controlPanel);
mainPanel.add(jndiPanel);
this.add(mainPanel);
//methodHomeParmsPanel.setVisible(false);
catClass.info("End : init1");
}
/**
* Given a parameter type of a method, this method will find out
* if the parm type is a primitive. If so, it'll just add the parm type
* as a node into the tree model (used to store all parm types of the method).
* If however, the parm type is not a primitive, then the parm type will be
* further recursed i.e. a reflection of all the fields is obtained
* and each of which will be examined to determined if they are primitives.
* For those which are primitives, they'll be added to the tree model
* and those otherwise will be further recursed.
*
* @param parmType the parmType of a method which will be examined
* @param parentNode the node under which the parmType will be added to
* @param childIndex the index of the this parmType if it were to be added
* under the parent node
*/
protected void recurseParm(Class parmType, DefaultMutableTreeNode parentNode,
int childIndex, DefaultTreeModel treeModel)
{
catClass.debug("Start - recurseParm1");
DefaultMutableTreeNode node = new DefaultMutableTreeNode(parmType);
treeModel.insertNodeInto(node, parentNode, childIndex);
System.out.println("recurseParm1 - parent : " + parentNode);
System.out.println("recurseParm1 - parent : " + treeModel.getChildCount(parentNode));
System.out.println("recurseParm1 - child : " + treeModel.getChildCount(node));
if(parmType.isPrimitive())
{
// if parmType is primitive then no need to recurse the parm
}
else if(parmType.getName().equals(STRING_CLASS))
{
// consider String as a primitive i.e. there is not need to recurse parm
}
else if(parmType.isArray())
{
// if parmType is array then need to handle differently
}
else
{
// if parmType is NOT primitive then need to recurse the parm since
// it's an object.
// to recurse the object, use reflections to get all fields
Field[] fields = parmType.getFields();
for(int i = 0; i < fields.length; i++)
{
Class fieldClass = fields[i].getType();
catClass.debug("recurseParm1 : field #" + i + " - " + fieldClass);
recurseParm(fieldClass, node, i, treeModel);
}
}
catClass.debug("End - recurseParm1");
}
protected JPanel getMethodHomeNamePanel()
{
catClass.info("Start : getMethodHomeNamePanel1");
JPanel panel = new JPanel();
panel.add(new JLabel(JMeterUtils.getResString("jndi_method_home_name")));
String methodName = model.getMethodHomeName();
if(methodName != null)
{
methodHomeNameBox.setSelectedItem(methodName);
}
panel.add(methodHomeNameBox);
catClass.info("End : getMethodHomeNamePanel1");
return panel;
}
protected JPanel getRemoteInterfaceListPanel()
{
catClass.info("Start : getRemoteInterfaceListPanel1");
JPanel panel = new JPanel();
panel.add(new JLabel(JMeterUtils.getResString(
"jndi_method_remote_interface_list")));
Object remoteInterfaceType = model.getRemoteInterfaceType();
if(remoteInterfaceType != null)
{
remoteInterfaceBox.setSelectedItem(remoteInterfaceType.toString());
}
panel.add(remoteInterfaceBox);
catClass.info("End : getRemoteInterfaceListPanel1");
return panel;
}
protected JPanel getMethodRemoteNamePanel()
{
catClass.info("Start : getMethodRemoteNamePanel1");
JPanel panel = new JPanel();
panel.add(new JLabel(JMeterUtils.getResString("jndi_method_remote_name")));
String methodName = model.getMethodRemoteName();
if(methodName != null)
{
methodRemoteNameBox.setSelectedItem(methodName);
}
panel.add(methodRemoteNameBox);
catClass.info("End : getMethodRemoteNamePanel1");
return panel;
}
protected JPanel getMethodHomeParmsPanel()
{
catClass.info("Start : getMethodHomeParmsPanel1");
JPanel panel = new JPanel();
panel.add(new JLabel(JMeterUtils.getResString("jndi_method_home_parms")));
rootHome = new DefaultMutableTreeNode("Root");
treeModelHome = new DefaultTreeModel(rootHome);
jTreeHome = new JTree(treeModelHome);
jTreeHome.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
jTreeHome.addTreeSelectionListener(this);
jTreeHome.setPreferredSize(new Dimension(200, 50));
JPanel jTreePanel = new JPanel();
jTreePanel.add(jTreeHome);
panel.add(jTreePanel);
// set mouse listener to listen for double clicks
MouseListener ml = new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
TreePath selPath = jTreeHome.getPathForLocation(e.getX(), e.getY());
if(e.getClickCount() == 2)
{
System.out.println("Double clicked on - " + selPath.getLastPathComponent());
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)selPath.getLastPathComponent();
int childCount = node.getChildCount();
// if node is a leaf and has a parent (i.e. not root)
// then node is a parm which needs a value so pop out
// dialog for user to fill in
if(childCount == 0 && node.getParent() != null)
{
System.out.println("Pop!!!");
Object userObject = node.getUserObject();
Class type = null;
if(userObject instanceof Class)
{
type = (Class)userObject;
}
else if(userObject instanceof MethodConfigUserObject)
{
type = (Class)((MethodConfigUserObject)userObject).getType();
}
MethodConfigDialog dialog = new MethodConfigDialog(frame, type);
dialog.pack();
dialog.setVisible(true);
MethodConfigUserObject input = dialog.getValidatedInput();
System.out.println("input - " + input);
if(input != null)
{
node.setUserObject(input);
}
}
}
}
};
jTreeHome.addMouseListener(ml);
catClass.info("End : getMethodHomeParmsPanel1");
return panel;
}
protected JPanel getMethodRemoteParmsPanel()
{
catClass.info("Start : getMethodRemoteParmsPanel1");
JPanel panel = new JPanel();
panel.add(new JLabel(JMeterUtils.getResString("jndi_method_remote_parms")));
rootRemote = new DefaultMutableTreeNode("Root");
treeModelRemote = new DefaultTreeModel(rootRemote);
jTreeRemote = new JTree(treeModelRemote);
jTreeRemote.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
jTreeRemote.addTreeSelectionListener(this);
jTreeRemote.setPreferredSize(new Dimension(200, 50));
JPanel jTreePanel = new JPanel();
jTreePanel.add(jTreeRemote);
panel.add(jTreePanel);
// set mouse listener to listen for double clicks
MouseListener ml = new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
TreePath selPath = jTreeRemote.getPathForLocation(e.getX(), e.getY());
if(e.getClickCount() == 2)
{
System.out.println("Double clicked on - " + selPath.getLastPathComponent());
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)selPath.getLastPathComponent();
int childCount = node.getChildCount();
if(childCount == 0)
{
System.out.println("Pop!!!");
Object userObject = node.getUserObject();
Class type = null;
if(userObject instanceof Class)
{
type = (Class)userObject;
}
else if(userObject instanceof MethodConfigUserObject)
{
type = (Class)((MethodConfigUserObject)userObject).getType();
}
MethodConfigDialog dialog = new MethodConfigDialog(frame, type);
dialog.pack();
dialog.setVisible(true);
MethodConfigUserObject input = dialog.getValidatedInput();
System.out.println("input - " + input);
if(input != null)
{
node.setUserObject(input);
}
}
}
}
};
jTreeRemote.addMouseListener(ml);
catClass.info("End : getMethodHomeParmsPanel1");
return panel;
}
public MethodConfig getModel()
{
return model;
}
/**
* Caller needs to be able to get Method Parms for both the Home Method
* and Remote Method. Based on the state this method will call
* <code>getMethodParmsValues</code> witht the appropriate root. NOTE :
* parms for Home and Remote Methods are stored under different roots.
*/
public Object[] getMethodParmsValues(int state)
throws MethodConfigUserObjectException
{
Object[] objects = null;
if(state == MethodConfig.METHOD_INVOKE_HOME)
{
objects = getMethodParmsValues(rootHome);
}
else if(state == MethodConfig.METHOD_INVOKE_REMOTE)
{
objects = getMethodParmsValues(rootRemote);
}
return objects;
}
public Object[] getMethodParmsValues(DefaultMutableTreeNode root)
throws MethodConfigUserObjectException
{
catClass.info("Start : getMethodParmsValues1");
// go through jTree to get all arguments
int childCount = root.getChildCount();
Object[] parmsValues = new Object[childCount];
for(int i = 0; i < childCount; i++)
{
parmsValues[i] = formObject((DefaultMutableTreeNode)
treeModelHome.getChild(root, i));
}
catClass.info("End : getMethodParmsValues1");
return parmsValues;
}
protected Object formObject(DefaultMutableTreeNode node)
throws MethodConfigUserObjectException
{
catClass.info("Start : formObject1");
Object obj = node.getUserObject();
Object returnVal = null;
if(obj instanceof MethodConfigUserObject)
{
// then node contains a primitive so just get the object
MethodConfigUserObject userObject = (MethodConfigUserObject)obj;
returnVal = userObject.getObject();
if(catClass.isDebugEnabled())
{
catClass.debug("formObject1 : primitive - " + userObject);
}
}
else if(obj instanceof Class)
{
// there are cases when the tree node will contain only class
// and not MethodConfigUserObject -
// 1. its value has not been input by the user but it's a primitive
// 2. it's not a primitive but an object
Class type = (Class)obj;
if(type.isPrimitive())
{
// it's a primitive but the user has not input a value for it
String errorStr = type.getName() +
" is a primitive with uninitialized values";
catClass.error("formObject1 : " + errorStr);
throw new MethodConfigUserObjectException(errorStr);
}
else
{
// then node is an object which contains other primitives
if(catClass.isDebugEnabled())
{
catClass.debug("formObject1 : Creating object - " + type);
}
int childCount = node.getChildCount();
Object[] constituents = new Object[childCount];
for(int i = 0; i < childCount; i++)
{
constituents[i] = formObject((DefaultMutableTreeNode)
treeModelHome.getChild(node, i));
}
// get the fields of the class
// gather all constituents to form object
Field[] fields = type.getFields();
try
{
for(int i = 0; i < constituents.length; i++)
{
catClass.debug("formObject1 : setting - " + fields[i].getName());
catClass.debug("formObject1 : to value - " + constituents[i]
+ " of - " + constituents[i].getClass());
returnVal = type.newInstance();
fields[i].set(returnVal, constituents[i]);
}
}
catch(IllegalAccessException e)
{
catClass.error(e);
throw new MethodConfigUserObjectException(e.getMessage());
}
catch(InstantiationException e)
{
catClass.error(e);
throw new MethodConfigUserObjectException(e.getMessage());
}
}
}
catClass.info("End : formObject1");
return returnVal;
}
/**
* Sets up the pull-down menus to contain all the <code>String</code>s
* passed in as well as displaying the user's selection.
*
* @param methodNameBox the <code>JComboBox</code> to be manipulated
* @param methodName the user's selection
* @param strings the list of <code>String</code>s to be added
* into the <code>JComboBox</code>
*/
protected void setupPullDown(JComboBox methodNameBox, String methodName,
String[] strings)
{
catClass.info("Start : setupPullDown1");
// if the list is empty then try to fill it
if(methodNameBox.getItemCount() == 0)
{
if(strings != null)
{
for(int i = 0; i < strings.length; i++)
{
catClass.debug("setupPullDown1 : adding method - " + strings[i]);
methodNameBox.addItem(strings[i]);
}
}
}
// change the methodBox selected item only if there's a change in the
// methodName to avoid triggering actionPerformed each time
String methodNameBoxSelected =
(String)methodNameBox.getSelectedItem();
if((methodName != null) && !methodName.equals(methodNameBoxSelected))
{
methodNameBox.setSelectedItem(methodName);
}
catClass.info("End : setupPullDown1");
}
/**
* Resets the home method parms. This method will be called when the user
* makes any changes which requires the resetting the method home parms
* e.g. when user decides to call another home method.
*/
protected void resetHomeMethodParms()
{
catClass.info("Start : resetHomeMethodParms1");
// remove all parms of the old method
int totalChild = rootHome.getChildCount();
for(int i = 0; i < totalChild; i++)
{
// the child to be removed will always be 0 'cos as the child
// is removed the nth node will become (n-1)th
treeModelHome.removeNodeFromParent(
(DefaultMutableTreeNode)rootHome.getChildAt(0));
}
rootHome.setUserObject("Root");
catClass.info("End : resetHomeMethodParms1");
}
/**
* Resets the remote interface list returned by the home method. This method
* will be called when the user makes any changes which requires the
* remote interface list to be modified e.g. when user decides to call
* another home method.
*/
protected void resetRemoteInterfaceList()
{
catClass.info("Start : resetRemoteInterfaceList1");
model.setRemoteInterfaceList(null);
model.setRemoteInterfaceType(null);
remoteInterfaceBox.removeAllItems();
catClass.info("End : resetRemoteInterfaceList1");
}
/**
* Resets the selected remote interface. This method will be called when
* the user makes any changes which requires the resetting the selected
* remote interface e.g. when user decides to call another home method,
* when the user decides to change the remote interface to be executed.
*/
protected void resetRemoteMethodName()
{
catClass.info("Start : resetRemoteMethodName1");
model.setMethodRemoteName(null);
methodRemoteNameBox.removeAllItems();
catClass.info("End : resetRemoteMethodName1");
}
/**
* Resets the remote method parms. This method will be called when the user
* makes any changes which requires the resetting the method remote parms
* e.g. when user decides to call another home method, when user changes the
* remote interface to be executed, when user changes the remote method
* to be run.
*/
protected void resetRemoteMethodParms()
{
catClass.info("Start : resetRemoteMethodParms1");
// remove all parms of the old method
int totalChild = rootRemote.getChildCount();
for(int i = 0; i < totalChild; i++)
{
// the child to be removed will always be 0 'cos as the child
// is removed the nth node will become (n-1)th
treeModelRemote.removeNodeFromParent(
(DefaultMutableTreeNode)rootRemote.getChildAt(0));
}
rootRemote.setUserObject("Root");
catClass.info("End : resetRemoteMethodParms1");
}
//----- ActionListener interface : start -----
public void actionPerformed(ActionEvent e)
{
String command = e.getActionCommand();
ReflectionJMeterEngine engine = null;
GuiPackage guiPackage = null;
if(catClass.isDebugEnabled())
{
catClass.debug("actionPerformed1 : command - " + command);
}
if(command.equals(REFLECT))
{
guiPackage = GuiPackage.getInstance();
Collection groups = TestPlan.createTestPlan(null).compileTestPlan();
engine = new ReflectionJMeterEngine();
for(Iterator i = groups.iterator(); i.hasNext();)
{
ThreadGroup tg = (ThreadGroup)i.next();
if(catClass.isDebugEnabled())
{
catClass.debug("actionPerformed1 : threadgroup - " + tg);
}
engine.addThreadGroup(tg);
}
guiPackage.getMainFrame().setRunning(true);
model.setReflectionStatus(true);
engine.runTest();
guiPackage.getMainFrame().setRunning(false);
model.setReflectionStatus(false);
updateGui();
}
if(command.equals(INVOKE))
{
}
}
//----- ActionListener interface : end -----
//----- TreeSelectionListener interface : start -----
public void valueChanged(TreeSelectionEvent e)
{
catClass.debug("Start : valueChanged1");
catClass.debug("End : valueChanged1");
}
//----- TreeSelectionListener interface : end -----
}