1 // $Header: /home/cvs/jakarta-jmeter/src/protocol/jndi/config/gui/MethodConfigGui.java,v 1.6 2004/02/13 02:40:53 sebb Exp $ 2 /* 3 * Copyright 2001-2004 The Apache Software Foundation. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.ejb.jndi.config.gui; 20 import java.awt.Component; 21 import java.awt.Dimension; 22 import java.awt.Font; 23 import java.awt.Frame; 24 import java.awt.event.ActionEvent; 25 import java.awt.event.ActionListener; 26 import java.awt.event.MouseAdapter; 27 import java.awt.event.MouseEvent; 28 import java.awt.event.MouseListener; 29 import java.lang.reflect.Field; 30 import java.util.ArrayList; 31 import java.util.Collection; 32 import java.util.Iterator; 33 import javax.swing.BorderFactory; 34 import javax.swing.JButton; 35 import javax.swing.JComboBox; 36 import javax.swing.JLabel; 37 import javax.swing.JPanel; 38 import javax.swing.JTree; 39 import javax.swing.border.Border; 40 import javax.swing.border.EmptyBorder; 41 import javax.swing.event.TreeSelectionEvent; 42 import javax.swing.event.TreeSelectionListener; 43 import javax.swing.tree.DefaultMutableTreeNode; 44 import javax.swing.tree.DefaultTreeModel; 45 import javax.swing.tree.TreePath; 46 import javax.swing.tree.TreeSelectionModel; 47 import org.apache.jmeter.gui.GuiPackage; 48 import org.apache.jmeter.gui.NamePanel; 49 import org.apache.jmeter.gui.util.VerticalLayout; 50 import org.apache.jmeter.testelement.TestPlan; 51 import org.apache.jmeter.threads.ThreadGroup; 52 import org.apache.jmeter.util.JMeterUtils; 53 import org.apache.jorphan.logging.LoggingManager; 54 import org.apache.log.Logger; 55 /** 56 * Provides the gui interface to configure remote method execution 57 * @author Khor Soon Hin 58 * @version $Revision: 1.6 $ Last Updated: $Date: 2004/02/13 02:40:53 $ 59 * Created 2001 Dec 24 60 */ 61 public class MethodConfigGui 62 extends JPanel 63 implements ModelSupported, ActionListener, TreeSelectionListener 64 { 65 transient private static Logger log = LoggingManager.getLoggerForClass(); 66 protected static final String REFLECT = "MethodConfigGui.reflect"; 67 protected static final String INVOKE = "MethodConfigGui.invoke"; 68 protected static final String STRING_CLASS = "java.lang.String"; 69 protected JComboBox methodHomeNameBox; 70 protected JComboBox methodRemoteNameBox; 71 protected JComboBox remoteInterfaceBox; 72 protected DefaultMutableTreeNode rootHome; 73 protected DefaultMutableTreeNode rootRemote; 74 protected DefaultTreeModel treeModelHome; 75 protected DefaultTreeModel treeModelRemote; 76 protected NamePanel namePanel; 77 protected JPanel methodHomeNamePanel; 78 protected JPanel methodHomeParmsPanel; 79 protected JPanel remoteInterfaceListPanel; 80 protected JPanel methodRemoteNamePanel; 81 protected JPanel methodRemoteParmsPanel; 82 protected JPanel controlPanel; 83 protected JButton actionButton; 84 protected JTree jTreeHome; 85 protected JTree jTreeRemote; 86 protected boolean displayName; 87 protected MethodConfig model; 88 protected Frame frame; 89 // The frame is required because the JDialog we create must be modal 90 // and to be modal it must be modal relative to a frame. We want 91 // the dialog boxes to be modal so that user must fill them up before 92 // they can do anything with jmeter 93 public MethodConfigGui() 94 { 95 displayName = true; 96 } 97 public MethodConfigGui(boolean displayName) 98 { 99 this.displayName = displayName; 100 } 101 //----- ModelSupported interface : start ----- 102 public void setModel(Object model) 103 { 104 this.model = (MethodConfig) model; 105 init(); 106 } 107 public void updateGui() 108 { 109 log.debug("Start : updateGui1"); 110 log.info("updateGui1"); 111 // the method name box will always be displayed regardless of the state 112 // of the MethodConfig of this gui 113 String methodName = model.getMethodHomeName(); 114 log.debug("updateGui1 : home method name - " + methodName); 115 String[] strings = model.getMethodHomeList(); 116 setupPullDown(methodHomeNameBox, methodName, strings); 117 // if methodName is null set the home method to be the first entry 118 // as setup in the home method name JComboBox by setupPullDown 119 // This is to ensure that if the user does not change the JComboBox 120 // the first value is set anyway. 121 if (methodName == null && strings != null) 122 { 123 model.setMethodHomeName(strings[0]); 124 } 125 // if the state of the MethodConfig of this gui after 126 // MethodConfig.METHOD_GET_HOME_NAMES, display panel to get 127 // parms of the selected method 128 int childCount = treeModelHome.getChildCount(rootHome); 129 if (log.isDebugEnabled()) 130 { 131 log.debug("updateGui1 : state - " + model.getState()); 132 log.debug("updateGui1 : METHOD_GET_HOME_NAMES"); 133 log.debug("updateGui1 : rootHome child count - " + childCount); 134 } 135 // if model is in state after getting home method name AND 136 // rootHome(method) has no child(parms set) yet then get them 137 if (model.getState() > MethodConfig.METHOD_GET_HOME_PARMS 138 && childCount == 0) 139 { 140 log.debug("updateGui1 : METHOD_GET_HOME_PARMS"); 141 rootHome.setUserObject(model.getMethodHomeName()); 142 // methodParmsPanel.setVisible(true); 143 // get all the parms 144 Class[] parmTypes = model.getMethodHomeParms(); 145 // add all the parms into a JTree 146 for (int i = 0; i < parmTypes.length; i++) 147 { 148 log.debug("updateGui1 : parmType #" + i + " - " + parmTypes[i]); 149 recurseParm(parmTypes[i], rootHome, i, treeModelHome); 150 } 151 // if the chosen method has no parms then updating the value of 152 // root node with the method name doesn't seem to trigger a redraw of 153 // the tree so call treeDidChange() 154 if (parmTypes.length == 0) 155 { 156 jTreeHome.treeDidChange(); 157 } 158 } 159 // if model is in state after getting home method name and 160 // all home method parms gave been obtained then get list of 161 // remote interfaces 162 if (model.getState() > MethodConfig.METHOD_SELECT_REMOTE_INTERFACE) 163 { 164 log.debug("METHOD_SELECT_REMOTE_INTERFACE"); 165 // remoteInterfaceType is the remote interface selected by the user 166 // remoteInterfaces contains the list of remote interfaces returned 167 // by home method 168 Object remoteInterfaceType = model.getRemoteInterfaceType(); 169 String interfaceName = null; 170 if (remoteInterfaceType != null) 171 { 172 interfaceName = remoteInterfaceType.toString(); 173 } 174 ArrayList remoteInterfaces = (ArrayList) model.getRemoteInterfaceList(); 175 if (log.isDebugEnabled()) 176 { 177 log.debug("updateGui1 : remote interfaces - " + remoteInterfaces); 178 log.debug( 179 "updateGui1 : remoteInterfacesType - " + remoteInterfaces.getClass()); 180 } 181 // prepare variable strings to contain a list of all the names of 182 // the remote interfaces 183 Object[] remoteInterfacesArray = remoteInterfaces.toArray(); 184 strings = new String[remoteInterfacesArray.length]; 185 for (int i = 0; i < remoteInterfacesArray.length; i++) 186 { 187 strings[i] = remoteInterfacesArray[i].toString(); 188 } 189 setupPullDown(remoteInterfaceBox, interfaceName, strings); 190 // if interfaceName is null set the remote interface to be the first 191 // entry as setup in the remote interface name JComboBox by setupPullDown. 192 // This is to ensure that if the user does not change the JComboBox 193 // the first value is set anyway. 194 if (interfaceName == null && remoteInterfacesArray != null) 195 { 196 model.setRemoteInterfaceType(remoteInterfacesArray[0]); 197 } 198 } 199 // if model is in state after user selects the list of remote interface 200 // then get a list of remote method names 201 if (model.getState() > MethodConfig.METHOD_GET_REMOTE_NAMES) 202 { 203 log.debug("METHOD_GET_REMOTE_NAMES"); 204 methodName = model.getMethodRemoteName(); 205 log.debug("updateGui1 : remote method name - " + methodName); 206 strings = model.getMethodRemoteList(); 207 setupPullDown(methodRemoteNameBox, methodName, strings); 208 childCount = treeModelRemote.getChildCount(rootRemote); 209 if (log.isDebugEnabled()) 210 { 211 log.debug("updateGui1 : rootRemote child count - " + childCount); 212 } 213 } 214 // if model is in state after getting remote interface AND 215 // rootRemote(method) has no child(parms set) yet then get them 216 if (model.getState() > MethodConfig.METHOD_GET_REMOTE_PARMS 217 && childCount == 0) 218 { 219 log.debug("METHOD_GET_REMOTE_PARMS"); 220 rootRemote.setUserObject(model.getMethodRemoteName()); 221 // methodParmsPanel.setVisible(true); 222 // get all the parms 223 Class[] parmTypes = model.getMethodRemoteParms(); 224 // add all the parms into a JTree 225 for (int i = 0; i < parmTypes.length; i++) 226 { 227 log.debug("updateGui1 : parmType #" + i + " - " + parmTypes[i]); 228 recurseParm(parmTypes[i], rootHome, i, treeModelHome); 229 } 230 // if the chosen method has no parms then updating the value of 231 // root node with the method name doesn't seem to trigger a redraw of 232 // the tree so call treeDidChange() 233 if (parmTypes.length == 0) 234 { 235 jTreeRemote.treeDidChange(); 236 } 237 } 238 // if the state of the MethodConfig of this gui is 239 // MethodConfig.METHOD_GET_HOME_PARMS, display panel 240 if (displayName) 241 { 242 namePanel.updateGui(); 243 } 244 log.debug("End : updateGui1"); 245 } 246 //----- ModelSupported interface : end ----- 247 protected void init() 248 { 249 log.info("Start : init1"); 250 // The frame is required because the JDialog we create must be modal 251 // and to be modal it must be modal relative to a frame. We want 252 // the dialog boxes to be modal so that user must fill them up before 253 // they can do anything with jmeter 254 GuiPackage guiPkg = GuiPackage.getInstance(); 255 frame = guiPkg.getMainFrame(); 256 model.setState(MethodConfig.METHOD_GET_HOME_NAMES); 257 model.setGui(this); 258 methodHomeNameBox = new JComboBox(); 259 methodHomeNameBox.setEditable(false); 260 methodHomeNameBox.setAlignmentX(Component.LEFT_ALIGNMENT); 261 methodHomeNameBox.addActionListener(new ActionListener() 262 { 263 public void actionPerformed(ActionEvent e) 264 { 265 log.debug("actionPerformed1 : Home name method JComboBox changed"); 266 // change in method name so do the following 267 JComboBox comboBox = (JComboBox) e.getSource(); 268 String method = (String) methodHomeNameBox.getSelectedItem(); 269 model.setMethodHomeName(method); 270 model.setState(MethodConfig.METHOD_GET_HOME_PARMS); 271 resetHomeMethodParms(); 272 resetRemoteInterfaceList(); 273 resetRemoteMethodName(); 274 resetRemoteMethodParms(); 275 // methodParmsPanel.setVisible(false); 276 actionButton.setText( 277 JMeterUtils.getResString("jndi_method_button_reflect")); 278 updateGui(); 279 } 280 }); 281 remoteInterfaceBox = new JComboBox(); 282 remoteInterfaceBox.setEditable(false); 283 remoteInterfaceBox.setAlignmentX(Component.LEFT_ALIGNMENT); 284 remoteInterfaceBox.addActionListener(new ActionListener() 285 { 286 public void actionPerformed(ActionEvent e) 287 { 288 log.debug("actionPerformed1 : Remote Interface JComboBox changed"); 289 JComboBox comboBox = (JComboBox) e.getSource(); 290 String interfaceName = (String) remoteInterfaceBox.getSelectedItem(); 291 // compare interface selected with the ones in the remote interface 292 // list and store the corresponding object in MethodConfig 293 ArrayList remoteInterfaceList = 294 (ArrayList) model.getRemoteInterfaceList(); 295 if (remoteInterfaceList != null) 296 { 297 Object[] remoteInterfaceListArray = remoteInterfaceList.toArray(); 298 int i = 0; 299 boolean found = false; 300 String remoteInterfaceListName = null; 301 Object selectedInterface = null; 302 while (i < remoteInterfaceListArray.length && !found) 303 { 304 remoteInterfaceListName = remoteInterfaceListArray[i].toString(); 305 if (remoteInterfaceListName.equals(interfaceName)) 306 { 307 found = true; 308 selectedInterface = remoteInterfaceListArray[i]; 309 } 310 i++; 311 } 312 model.setRemoteInterfaceType(selectedInterface); 313 model.setState(MethodConfig.METHOD_GET_REMOTE_NAMES); 314 } 315 resetRemoteMethodName(); 316 resetRemoteMethodParms(); 317 // methodParmsPanel.setVisible(false); 318 actionButton.setText( 319 JMeterUtils.getResString("jndi_method_button_reflect")); 320 updateGui(); 321 } 322 }); 323 methodRemoteNameBox = new JComboBox(); 324 methodRemoteNameBox.setEditable(false); 325 methodRemoteNameBox.setAlignmentX(Component.LEFT_ALIGNMENT); 326 methodRemoteNameBox.addActionListener(new ActionListener() 327 { 328 public void actionPerformed(ActionEvent e) 329 { 330 log.debug("actionPerformed1 : Remote method name JComboBox changed"); 331 // change in method name so do the following 332 JComboBox comboBox = (JComboBox) e.getSource(); 333 String method = (String) methodRemoteNameBox.getSelectedItem(); 334 model.setMethodRemoteName(method); 335 model.setState(MethodConfig.METHOD_GET_REMOTE_PARMS); 336 resetRemoteMethodParms(); 337 // methodParmsPanel.setVisible(false); 338 actionButton.setText( 339 JMeterUtils.getResString("jndi_method_button_reflect")); 340 updateGui(); 341 } 342 }); 343 //rootHome = new DefaultMutableTreeNode("Root"); 344 //treeModelHome = new DefaultTreeModel(rootHome); 345 this.setLayout( 346 new VerticalLayout(5, VerticalLayout.LEFT, VerticalLayout.TOP)); 347 JPanel mainPanel = new JPanel(); 348 Border margin = new EmptyBorder(10, 10, 5, 10); 349 mainPanel.setBorder(margin); 350 mainPanel.setLayout(new VerticalLayout(5, VerticalLayout.LEFT)); 351 // title 352 JLabel panelTitleLabel = 353 new JLabel(JMeterUtils.getResString("jndi_method_title")); 354 Font curFont = panelTitleLabel.getFont(); 355 int curFontSize = curFont.getSize(); 356 curFontSize += 4; 357 panelTitleLabel.setFont( 358 new Font(curFont.getFontName(), curFont.getStyle(), curFontSize)); 359 mainPanel.add(panelTitleLabel); 360 // name 361 namePanel = new NamePanel(model); 362 mainPanel.add(namePanel); 363 // method properties 364 JPanel jndiPanel = new JPanel(); 365 jndiPanel.setLayout(new VerticalLayout(5, VerticalLayout.LEFT)); 366 jndiPanel.setBorder( 367 BorderFactory.createTitledBorder( 368 JMeterUtils.getResString("jndi_method_name"))); 369 methodHomeNamePanel = getMethodHomeNamePanel(); 370 methodHomeParmsPanel = getMethodHomeParmsPanel(); 371 remoteInterfaceListPanel = getRemoteInterfaceListPanel(); 372 methodRemoteNamePanel = getMethodRemoteNamePanel(); 373 methodRemoteParmsPanel = getMethodRemoteParmsPanel(); 374 jndiPanel.add(methodHomeNamePanel); 375 jndiPanel.add(methodHomeParmsPanel); 376 jndiPanel.add(remoteInterfaceListPanel); 377 jndiPanel.add(methodRemoteNamePanel); 378 jndiPanel.add(methodRemoteParmsPanel); 379 controlPanel = new JPanel(); 380 actionButton = 381 new JButton(JMeterUtils.getResString("jndi_method_button_reflect")); 382 actionButton.addActionListener(this); 383 actionButton.setActionCommand(REFLECT); 384 controlPanel.add(actionButton); 385 jndiPanel.add(controlPanel); 386 mainPanel.add(jndiPanel); 387 this.add(mainPanel); 388 //methodHomeParmsPanel.setVisible(false); 389 log.info("End : init1"); 390 } 391 /** 392 * Given a parameter type of a method, this method will find out 393 * if the parm type is a primitive. If so, it'll just add the parm type 394 * as a node into the tree model (used to store all parm types of the method). 395 * If however, the parm type is not a primitive, then the parm type will be 396 * further recursed i.e. a reflection of all the fields is obtained 397 * and each of which will be examined to determined if they are primitives. 398 * For those which are primitives, they'll be added to the tree model 399 * and those otherwise will be further recursed. 400 * 401 * @param parmType the parmType of a method which will be examined 402 * @param parentNode the node under which the parmType will be added to 403 * @param childIndex the index of the this parmType if it were to be added 404 * under the parent node 405 */ 406 protected void recurseParm( 407 Class parmType, 408 DefaultMutableTreeNode parentNode, 409 int childIndex, 410 DefaultTreeModel treeModel) 411 { 412 log.debug("Start - recurseParm1"); 413 DefaultMutableTreeNode node = new DefaultMutableTreeNode(parmType); 414 treeModel.insertNodeInto(node, parentNode, childIndex); 415 log.info("recurseParm1 - parent : " + parentNode); 416 log.info("recurseParm1 - parent : " + treeModel.getChildCount(parentNode)); 417 log.info("recurseParm1 - child : " + treeModel.getChildCount(node)); 418 if (parmType.isPrimitive()) 419 { 420 // if parmType is primitive then no need to recurse the parm 421 } 422 else if (parmType.getName().equals(STRING_CLASS)) 423 { 424 // consider String as a primitive i.e. there is not need to recurse parm 425 } 426 else if (parmType.isArray()) 427 { 428 // if parmType is array then need to handle differently 429 } 430 else 431 { 432 // if parmType is NOT primitive then need to recurse the parm since 433 // it's an object. 434 // to recurse the object, use reflections to get all fields 435 Field[] fields = parmType.getFields(); 436 for (int i = 0; i < fields.length; i++) 437 { 438 Class fieldClass = fields[i].getType(); 439 log.debug("recurseParm1 : field #" + i + " - " + fieldClass); 440 recurseParm(fieldClass, node, i, treeModel); 441 } 442 } 443 log.debug("End - recurseParm1"); 444 } 445 protected JPanel getMethodHomeNamePanel() 446 { 447 log.info("Start : getMethodHomeNamePanel1"); 448 JPanel panel = new JPanel(); 449 panel.add(new JLabel(JMeterUtils.getResString("jndi_method_home_name"))); 450 String methodName = model.getMethodHomeName(); 451 if (methodName != null) 452 { 453 methodHomeNameBox.setSelectedItem(methodName); 454 } 455 panel.add(methodHomeNameBox); 456 log.info("End : getMethodHomeNamePanel1"); 457 return panel; 458 } 459 protected JPanel getRemoteInterfaceListPanel() 460 { 461 log.info("Start : getRemoteInterfaceListPanel1"); 462 JPanel panel = new JPanel(); 463 panel.add( 464 new JLabel( 465 JMeterUtils.getResString("jndi_method_remote_interface_list"))); 466 Object remoteInterfaceType = model.getRemoteInterfaceType(); 467 if (remoteInterfaceType != null) 468 { 469 remoteInterfaceBox.setSelectedItem(remoteInterfaceType.toString()); 470 } 471 panel.add(remoteInterfaceBox); 472 log.info("End : getRemoteInterfaceListPanel1"); 473 return panel; 474 } 475 protected JPanel getMethodRemoteNamePanel() 476 { 477 log.info("Start : getMethodRemoteNamePanel1"); 478 JPanel panel = new JPanel(); 479 panel.add(new JLabel(JMeterUtils.getResString("jndi_method_remote_name"))); 480 String methodName = model.getMethodRemoteName(); 481 if (methodName != null) 482 { 483 methodRemoteNameBox.setSelectedItem(methodName); 484 } 485 panel.add(methodRemoteNameBox); 486 log.info("End : getMethodRemoteNamePanel1"); 487 return panel; 488 } 489 protected JPanel getMethodHomeParmsPanel() 490 { 491 log.info("Start : getMethodHomeParmsPanel1"); 492 JPanel panel = new JPanel(); 493 panel.add(new JLabel(JMeterUtils.getResString("jndi_method_home_parms"))); 494 rootHome = new DefaultMutableTreeNode("Root"); 495 treeModelHome = new DefaultTreeModel(rootHome); 496 jTreeHome = new JTree(treeModelHome); 497 jTreeHome.getSelectionModel().setSelectionMode( 498 TreeSelectionModel.SINGLE_TREE_SELECTION); 499 jTreeHome.addTreeSelectionListener(this); 500 jTreeHome.setPreferredSize(new Dimension(200, 50)); 501 JPanel jTreePanel = new JPanel(); 502 jTreePanel.add(jTreeHome); 503 panel.add(jTreePanel); 504 // set mouse listener to listen for double clicks 505 MouseListener ml = new MouseAdapter() 506 { 507 public void mousePressed(MouseEvent e) 508 { 509 TreePath selPath = jTreeHome.getPathForLocation(e.getX(), e.getY()); 510 if (e.getClickCount() == 2) 511 { 512 log.info("Double clicked on - " + selPath.getLastPathComponent()); 513 DefaultMutableTreeNode node = 514 (DefaultMutableTreeNode) selPath.getLastPathComponent(); 515 int childCount = node.getChildCount(); 516 // if node is a leaf and has a parent (i.e. not root) 517 // then node is a parm which needs a value so pop out 518 // dialog for user to fill in 519 if (childCount == 0 && node.getParent() != null) 520 { 521 log.info("Pop!!!"); 522 Object userObject = node.getUserObject(); 523 Class type = null; 524 if (userObject instanceof Class) 525 { 526 type = (Class) userObject; 527 } 528 else if (userObject instanceof MethodConfigUserObject) 529 { 530 type = (Class) ((MethodConfigUserObject) userObject).getType(); 531 } 532 MethodConfigDialog dialog = new MethodConfigDialog(frame, type); 533 dialog.pack(); 534 dialog.setVisible(true); 535 MethodConfigUserObject input = dialog.getValidatedInput(); 536 log.info("input - " + input); 537 if (input != null) 538 { 539 node.setUserObject(input); 540 } 541 } 542 } 543 } 544 }; 545 jTreeHome.addMouseListener(ml); 546 log.info("End : getMethodHomeParmsPanel1"); 547 return panel; 548 } 549 protected JPanel getMethodRemoteParmsPanel() 550 { 551 log.info("Start : getMethodRemoteParmsPanel1"); 552 JPanel panel = new JPanel(); 553 panel.add(new JLabel(JMeterUtils.getResString("jndi_method_remote_parms"))); 554 rootRemote = new DefaultMutableTreeNode("Root"); 555 treeModelRemote = new DefaultTreeModel(rootRemote); 556 jTreeRemote = new JTree(treeModelRemote); 557 jTreeRemote.getSelectionModel().setSelectionMode( 558 TreeSelectionModel.SINGLE_TREE_SELECTION); 559 jTreeRemote.addTreeSelectionListener(this); 560 jTreeRemote.setPreferredSize(new Dimension(200, 50)); 561 JPanel jTreePanel = new JPanel(); 562 jTreePanel.add(jTreeRemote); 563 panel.add(jTreePanel); 564 // set mouse listener to listen for double clicks 565 MouseListener ml = new MouseAdapter() 566 { 567 public void mousePressed(MouseEvent e) 568 { 569 TreePath selPath = jTreeRemote.getPathForLocation(e.getX(), e.getY()); 570 if (e.getClickCount() == 2) 571 { 572 log.info("Double clicked on - " + selPath.getLastPathComponent()); 573 DefaultMutableTreeNode node = 574 (DefaultMutableTreeNode) selPath.getLastPathComponent(); 575 int childCount = node.getChildCount(); 576 if (childCount == 0) 577 { 578 log.info("Pop!!!"); 579 Object userObject = node.getUserObject(); 580 Class type = null; 581 if (userObject instanceof Class) 582 { 583 type = (Class) userObject; 584 } 585 else if (userObject instanceof MethodConfigUserObject) 586 { 587 type = (Class) ((MethodConfigUserObject) userObject).getType(); 588 } 589 MethodConfigDialog dialog = new MethodConfigDialog(frame, type); 590 dialog.pack(); 591 dialog.setVisible(true); 592 MethodConfigUserObject input = dialog.getValidatedInput(); 593 log.info("input - " + input); 594 if (input != null) 595 { 596 node.setUserObject(input); 597 } 598 } 599 } 600 } 601 }; 602 jTreeRemote.addMouseListener(ml); 603 log.info("End : getMethodHomeParmsPanel1"); 604 return panel; 605 } 606 public MethodConfig getModel() 607 { 608 return model; 609 } 610 /** 611 * Caller needs to be able to get Method Parms for both the Home Method 612 * and Remote Method. Based on the state this method will call 613 * <code>getMethodParmsValues</code> witht the appropriate root. NOTE : 614 * parms for Home and Remote Methods are stored under different roots. 615 */ 616 public Object[] getMethodParmsValues(int state) 617 throws MethodConfigUserObjectException 618 { 619 Object[] objects = null; 620 if (state == MethodConfig.METHOD_INVOKE_HOME) 621 { 622 objects = getMethodParmsValues(rootHome); 623 } 624 else if (state == MethodConfig.METHOD_INVOKE_REMOTE) 625 { 626 objects = getMethodParmsValues(rootRemote); 627 } 628 return objects; 629 } 630 public Object[] getMethodParmsValues(DefaultMutableTreeNode root) 631 throws MethodConfigUserObjectException 632 { 633 log.info("Start : getMethodParmsValues1"); 634 // go through jTree to get all arguments 635 int childCount = root.getChildCount(); 636 Object[] parmsValues = new Object[childCount]; 637 for (int i = 0; i < childCount; i++) 638 { 639 parmsValues[i] = 640 formObject((DefaultMutableTreeNode) treeModelHome.getChild(root, i)); 641 } 642 log.info("End : getMethodParmsValues1"); 643 return parmsValues; 644 } 645 protected Object formObject(DefaultMutableTreeNode node) 646 throws MethodConfigUserObjectException 647 { 648 log.info("Start : formObject1"); 649 Object obj = node.getUserObject(); 650 Object returnVal = null; 651 if (obj instanceof MethodConfigUserObject) 652 { 653 // then node contains a primitive so just get the object 654 MethodConfigUserObject userObject = (MethodConfigUserObject) obj; 655 returnVal = userObject.getObject(); 656 if (log.isDebugEnabled()) 657 { 658 log.debug("formObject1 : primitive - " + userObject); 659 } 660 } 661 else if (obj instanceof Class) 662 { 663 // there are cases when the tree node will contain only class 664 // and not MethodConfigUserObject - 665 // 1. its value has not been input by the user but it's a primitive 666 // 2. it's not a primitive but an object 667 Class type = (Class) obj; 668 if (type.isPrimitive()) 669 { 670 // it's a primitive but the user has not input a value for it 671 String errorStr = 672 type.getName() + " is a primitive with uninitialized values"; 673 log.error("formObject1 : " + errorStr); 674 throw new MethodConfigUserObjectException(errorStr); 675 } 676 else 677 { 678 // then node is an object which contains other primitives 679 if (log.isDebugEnabled()) 680 { 681 log.debug("formObject1 : Creating object - " + type); 682 } 683 int childCount = node.getChildCount(); 684 Object[] constituents = new Object[childCount]; 685 for (int i = 0; i < childCount; i++) 686 { 687 constituents[i] = 688 formObject( 689 (DefaultMutableTreeNode) treeModelHome.getChild(node, i)); 690 } 691 // get the fields of the class 692 // gather all constituents to form object 693 Field[] fields = type.getFields(); 694 try 695 { 696 for (int i = 0; i < constituents.length; i++) 697 { 698 log.debug("formObject1 : setting - " + fields[i].getName()); 699 log.debug( 700 "formObject1 : to value - " 701 + constituents[i] 702 + " of - " 703 + constituents[i].getClass()); 704 returnVal = type.newInstance(); 705 fields[i].set(returnVal, constituents[i]); 706 } 707 } 708 catch (IllegalAccessException e) 709 { 710 log.error(e); 711 throw new MethodConfigUserObjectException(e.getMessage()); 712 } 713 catch (InstantiationException e) 714 { 715 log.error(e); 716 throw new MethodConfigUserObjectException(e.getMessage()); 717 } 718 } 719 } 720 log.info("End : formObject1"); 721 return returnVal; 722 } 723 /** 724 * Sets up the pull-down menus to contain all the <code>String</code>s 725 * passed in as well as displaying the user's selection. 726 * 727 * @param methodNameBox the <code>JComboBox</code> to be manipulated 728 * @param methodName the user's selection 729 * @param strings the list of <code>String</code>s to be added 730 * into the <code>JComboBox</code> 731 */ 732 protected void setupPullDown( 733 JComboBox methodNameBox, 734 String methodName, 735 String[] strings) 736 { 737 log.info("Start : setupPullDown1"); 738 // if the list is empty then try to fill it 739 if (methodNameBox.getItemCount() == 0) 740 { 741 if (strings != null) 742 { 743 for (int i = 0; i < strings.length; i++) 744 { 745 log.debug("setupPullDown1 : adding method - " + strings[i]); 746 methodNameBox.addItem(strings[i]); 747 } 748 } 749 } 750 // change the methodBox selected item only if there's a change in the 751 // methodName to avoid triggering actionPerformed each time 752 String methodNameBoxSelected = (String) methodNameBox.getSelectedItem(); 753 if ((methodName != null) && !methodName.equals(methodNameBoxSelected)) 754 { 755 methodNameBox.setSelectedItem(methodName); 756 } 757 log.info("End : setupPullDown1"); 758 } 759 /** 760 * Resets the home method parms. This method will be called when the user 761 * makes any changes which requires the resetting the method home parms 762 * e.g. when user decides to call another home method. 763 */ 764 protected void resetHomeMethodParms() 765 { 766 log.info("Start : resetHomeMethodParms1"); 767 // remove all parms of the old method 768 int totalChild = rootHome.getChildCount(); 769 for (int i = 0; i < totalChild; i++) 770 { 771 // the child to be removed will always be 0 'cos as the child 772 // is removed the nth node will become (n-1)th 773 treeModelHome.removeNodeFromParent( 774 (DefaultMutableTreeNode) rootHome.getChildAt(0)); 775 } 776 rootHome.setUserObject("Root"); 777 log.info("End : resetHomeMethodParms1"); 778 } 779 /** 780 * Resets the remote interface list returned by the home method. This method 781 * will be called when the user makes any changes which requires the 782 * remote interface list to be modified e.g. when user decides to call 783 * another home method. 784 */ 785 protected void resetRemoteInterfaceList() 786 { 787 log.info("Start : resetRemoteInterfaceList1"); 788 model.setRemoteInterfaceList(null); 789 model.setRemoteInterfaceType(null); 790 remoteInterfaceBox.removeAllItems(); 791 log.info("End : resetRemoteInterfaceList1"); 792 } 793 /** 794 * Resets the selected remote interface. This method will be called when 795 * the user makes any changes which requires the resetting the selected 796 * remote interface e.g. when user decides to call another home method, 797 * when the user decides to change the remote interface to be executed. 798 */ 799 protected void resetRemoteMethodName() 800 { 801 log.info("Start : resetRemoteMethodName1"); 802 model.setMethodRemoteName(null); 803 methodRemoteNameBox.removeAllItems(); 804 log.info("End : resetRemoteMethodName1"); 805 } 806 /** 807 * Resets the remote method parms. This method will be called when the user 808 * makes any changes which requires the resetting the method remote parms 809 * e.g. when user decides to call another home method, when user changes the 810 * remote interface to be executed, when user changes the remote method 811 * to be run. 812 */ 813 protected void resetRemoteMethodParms() 814 { 815 log.info("Start : resetRemoteMethodParms1"); 816 // remove all parms of the old method 817 int totalChild = rootRemote.getChildCount(); 818 for (int i = 0; i < totalChild; i++) 819 { 820 // the child to be removed will always be 0 'cos as the child 821 // is removed the nth node will become (n-1)th 822 treeModelRemote.removeNodeFromParent( 823 (DefaultMutableTreeNode) rootRemote.getChildAt(0)); 824 } 825 rootRemote.setUserObject("Root"); 826 log.info("End : resetRemoteMethodParms1"); 827 } 828 //----- ActionListener interface : start ----- 829 public void actionPerformed(ActionEvent e) 830 { 831 String command = e.getActionCommand(); 832 ReflectionJMeterEngine engine = null; 833 GuiPackage guiPackage = null; 834 if (log.isDebugEnabled()) 835 { 836 log.debug("actionPerformed1 : command - " + command); 837 } 838 if (command.equals(REFLECT)) 839 { 840 guiPackage = GuiPackage.getInstance(); 841 Collection groups = TestPlan.createTestPlan(null).compileTestPlan(); 842 engine = new ReflectionJMeterEngine(); 843 for (Iterator i = groups.iterator(); i.hasNext();) 844 { 845 ThreadGroup tg = (ThreadGroup) i.next(); 846 if (log.isDebugEnabled()) 847 { 848 log.debug("actionPerformed1 : threadgroup - " + tg); 849 } 850 engine.addThreadGroup(tg); 851 } 852 guiPackage.getMainFrame().setRunning(true); 853 model.setReflectionStatus(true); 854 engine.runTest(); 855 guiPackage.getMainFrame().setRunning(false); 856 model.setReflectionStatus(false); 857 updateGui(); 858 } 859 if (command.equals(INVOKE)) 860 { 861 } 862 } 863 //----- ActionListener interface : end ----- 864 //----- TreeSelectionListener interface : start ----- 865 public void valueChanged(TreeSelectionEvent e) 866 { 867 log.debug("Start : valueChanged1"); 868 log.debug("End : valueChanged1"); 869 } 870 //----- TreeSelectionListener interface : end ----- 871 }