/**
* Get a JMeterGUIComponent for the specified test element. If the GUI has
* already been created, that instance will be returned. Otherwise, if a GUI
* component of the same type has been created, and the component is not
* marked as an {@link UnsharedComponent}, that shared component will be
* returned. Otherwise, a new instance of the component will be created. The
* TestElement's GUI_CLASS property will be used to determine the
* appropriate type of GUI component to use.
*
* @param node
* the test element which this GUI is being created for
*
* @return the GUI component corresponding to the specified test element
*/
public JMeterGUIComponent getGui(TestElement node) {
String testClassName = node.getPropertyAsString(TestElement.TEST_CLASS);
String guiClassName = node.getPropertyAsString(TestElement.GUI_CLASS);
try {
Class testClass;
if (testClassName.equals("")) { // $NON-NLS-1$
testClass = node.getClass();
}
else {
testClass = Class.forName(testClassName);
}
Class guiClass = null;
if ( !guiClassName.equals("")) { // $NON-NLS-1$
guiClass = Class.forName(guiClassName);
}
return getGui(node, guiClass, testClass);
}
catch (ClassNotFoundException
e) {
log.error("Could not get GUI for " + node, e);
return null;
}
}
/**
* Get a JMeterGUIComponent for the specified test element. If the GUI has
* already been created, that instance will be returned. Otherwise, if a GUI
* component of the same type has been created, and the component is not
* marked as an {@link UnsharedComponent}, that shared component will be
* returned. Otherwise, a new instance of the component will be created.
*
* @param node
* the test element which this GUI is being created for
* @param guiClass
* the fully qualifed class name of the GUI component which will
* be created if it doesn't already exist
* @param testClass
* the fully qualifed class name of the test elements which have
* to be edited by the returned GUI component
*
* @return the GUI component corresponding to the specified test element
*/
public JMeterGUIComponent getGui(TestElement node, Class guiClass, Class testClass) {
try {
JMeterGUIComponent comp = (JMeterGUIComponent) nodesToGui.get(node);
if (comp == null) {
comp = getGuiFromCache(guiClass, testClass);
nodesToGui.put(node, comp);
}
log.debug("Gui retrieved = " + comp);
return comp;
}
catch (Exception
e) {
log.error("Problem retrieving gui", e);
return null;
}
}
/**
* Remove a test element from the tree. This removes the reference to any
* associated GUI component.
*
* @param node
* the test element being removed
*/
public void removeNode(TestElement node) {
nodesToGui.remove(node);
}
/**
* Convenience method for grabbing the gui for the current node.
*
* @return the GUI component associated with the currently selected node
*/
public JMeterGUIComponent getCurrentGui() {
try {
updateCurrentNode();
TestElement curNode = treeListener.getCurrentNode().getTestElement();
JMeterGUIComponent comp = getGui(curNode);
comp.clearGui();
log.debug("Updating gui to new node");
comp.configure(curNode);
currentNodeUpdated = false;
return comp;
}
catch (Exception
e) {
log.error("Problem retrieving gui", e);
return null;
}
}
/**
* Find the JMeterTreeNode for a certain TestElement object.
*
* @param userObject
* the test element to search for
* @return the tree node associated with the test element
*/
public JMeterTreeNode getNodeOf(TestElement userObject) {
return treeModel.getNodeOf(userObject);
}
/**
* Create a TestElement corresponding to the specified GUI class.
*
* @param guiClass
* the fully qualified class name of the GUI component or a
* TestBean class for TestBeanGUIs.
* @param testClass
* the fully qualified class name of the test elements edited by
* this GUI component.
* @return the test element corresponding to the specified GUI class.
*/
public TestElement createTestElement(Class guiClass, Class testClass) {
try {
JMeterGUIComponent comp = getGuiFromCache(guiClass, testClass);
comp.clearGui();
TestElement node = comp.createTestElement();
nodesToGui.put(node, comp);
return node;
}
catch (Exception
e) {
log.error("Problem retrieving gui", e);
return null;
}
}
/**
* Create a TestElement for a GUI or TestBean class.
* <p>
* This is a utility method to help actions do with one single String
* parameter.
*
* @param objClass
* the fully qualified class name of the GUI component or of the
* TestBean subclass for which a TestBeanGUI is wanted.
* @return the test element corresponding to the specified GUI class.
*/
public TestElement createTestElement(String objClass) {
JMeterGUIComponent comp;
Class c;
try {
c = Class.forName(objClass);
if (TestBean.class .isAssignableFrom(c)) {
comp = getGuiFromCache(TestBeanGUI.class , c);
}
else {
comp = getGuiFromCache(c, null);
}
comp.clearGui();
TestElement node = comp.createTestElement();
nodesToGui.put(node, comp);
return node;
}
catch (NoClassDefFoundError
e) {
log.error("Problem retrieving gui for " + objClass, e);
String msg = "Cannot find class: " + e.getMessage();
JOptionPane.showMessageDialog(null, msg, "Missing jar? See log file.", JOptionPane.ERROR_MESSAGE);
throw new RuntimeException(e.toString()); // Probably a missing
// jar
}
catch (ClassNotFoundException
e) {
log.error("Problem retrieving gui for " + objClass, e);
throw new RuntimeException(e.toString()); // Programming error:
// bail out.
}
catch (InstantiationException
e) {
log.error("Problem retrieving gui for " + objClass, e);
throw new RuntimeException(e.toString()); // Programming error:
// bail out.
}
catch (IllegalAccessException
e) {
log.error("Problem retrieving gui for " + objClass, e);
throw new RuntimeException(e.toString()); // Programming error:
// bail out.
}
}
/**
* Get an instance of the specified JMeterGUIComponent class. If an instance
* of the GUI class has previously been created and it is not marked as an
* {@link UnsharedComponent}, that shared instance will be returned.
* Otherwise, a new instance of the component will be created, and shared
* components will be cached for future retrieval.
*
* @param guiClass
* the fully qualified class name of the GUI component. This
* class must implement JMeterGUIComponent.
* @param testClass
* the fully qualified class name of the test elements edited by
* this GUI component. This class must implement TestElement.
* @return an instance of the specified class
*
* @throws InstantiationException
* if an instance of the object cannot be created
* @throws IllegalAccessException
* if access rights do not allow the default constructor to be
* called
* @throws ClassNotFoundException
* if the specified GUI class cannot be found
*/
private JMeterGUIComponent getGuiFromCache(Class guiClass, Class testClass) throws InstantiationException, IllegalAccessException {
JMeterGUIComponent comp;
if (guiClass == TestBeanGUI.class ) {
comp = (TestBeanGUI) testBeanGUIs.get(testClass);
if (comp == null) {
comp = new TestBeanGUI(testClass);
testBeanGUIs.put(testClass, comp);
}
}
else {
comp = (JMeterGUIComponent) guis.get(guiClass);
if (comp == null) {
comp = (JMeterGUIComponent) guiClass.newInstance();
if ( !(comp instanceof UnsharedComponent)) {
guis.put(guiClass, comp);
}
}
}
return comp;
}
/**
* Update the GUI for the currently selected node. The GUI component is
* configured to reflect the settings in the current tree node.
*
*/
public void updateCurrentGui() {
updateCurrentNode();
currentNode = treeListener.getCurrentNode();
TestElement element = currentNode.getTestElement();
JMeterGUIComponent comp = getGui(element);
comp.configure(element);
currentNodeUpdated = false;
}
/**
* This method should be called in order for GuiPackage to change the
* current node. This will save any changes made to the earlier node before
* choosing the new node.
*/
public void updateCurrentNode() {
try {
if (currentNode != null && !currentNodeUpdated) {
log.debug("Updating current node " + currentNode.getName());
JMeterGUIComponent comp = getGui(currentNode.getTestElement());
TestElement el = currentNode.getTestElement();
comp.modifyTestElement(el);
}
// The current node is now updated
currentNodeUpdated = true;
currentNode = treeListener.getCurrentNode();
}
catch (Exception
e) {
log.error("Problem retrieving gui", e);
}
}
public JMeterTreeNode getCurrentNode() {
return treeListener.getCurrentNode();
}
public TestElement getCurrentElement() {
return getCurrentNode().getTestElement();
}
/**
* The dirty property is a flag that indicates whether there are parts of
* JMeter's test tree that the user has not saved since last modification.
* Various (@link Command actions) set this property when components are
* modified/created/saved.
*
* @param dirty
* the new value of the dirty flag
*/
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
/**
* Retrieves the state of the 'dirty' property, a flag that indicates if
* there are test tree components that have been modified since they were
* last saved.
*
* @return true if some tree components have been modified since they were
* last saved, false otherwise
*/
public boolean isDirty() {
return dirty;
}
/**
* Add a subtree to the currently selected node.
*
* @param subTree
* the subtree to add.
*
* @return the resulting subtree starting with the currently selected node
*
* @throws IllegalUserActionException
* if a subtree cannot be added to the currently selected node
*/
public HashTree addSubTree(HashTree subTree) throws IllegalUserActionException {
return treeModel.addSubTree(subTree, treeListener.getCurrentNode());
}
/**
* Get the currently selected subtree.
*
* @return the subtree of the currently selected node
*/
public HashTree getCurrentSubTree() {
return treeModel.getCurrentSubTree(treeListener.getCurrentNode());
}