View | Details | Raw Unified | Return to bug 61591
Collapse All | Expand All

(-)xdocs/changes.xml (+1 lines)
Lines 155-160 Link Here
155
    <li><bug>61697</bug>Introduce Darcula Look And Feel to make JMeter UI more attractive</li>
155
    <li><bug>61697</bug>Introduce Darcula Look And Feel to make JMeter UI more attractive</li>
156
    <li><bug>61704</bug>Toolbar : Improve a bit the right part</li>
156
    <li><bug>61704</bug>Toolbar : Improve a bit the right part</li>
157
    <li><bug>61731</bug>Enhance Test plan Backup with option to save before run. Based on a contribution by orimarko at gmail.com</li>
157
    <li><bug>61731</bug>Enhance Test plan Backup with option to save before run. Based on a contribution by orimarko at gmail.com</li>
158
    <li>Drop Workbench from test tree. Implemented by Artem Fedorov (artem at blazemeter.com) and contributed by BlazeMeter Ltd.</li>
158
</ul>
159
</ul>
159
160
160
<ch_section>Non-functional changes</ch_section>
161
<ch_section>Non-functional changes</ch_section>
(-)docs/usermanual/build-test-plan.html (-4 lines)
Lines 229-238 Link Here
229
you can save test tree fragments and individual elements for later use.</p>
229
you can save test tree fragments and individual elements for later use.</p>
230
230
231
231
232
<div class="clear"></div>
233
<div class="note">By default, the workbench is not automatically saved with the test plan, but it can be saved by checking "<span class="code">Save Workbench</span>" option on Workbench element.</div>
234
<div class="clear"></div>
235
236
</div>
232
</div>
237
233
238
234
(-)xdocs/usermanual/build-test-plan.xml (-1 lines)
Lines 53-59 Link Here
53
JMeter will save the element selected, plus all child elements beneath it.  In this way,
53
JMeter will save the element selected, plus all child elements beneath it.  In this way,
54
you can save test tree fragments and individual elements for later use.</p>
54
you can save test tree fragments and individual elements for later use.</p>
55
55
56
<note>By default, the workbench is not automatically saved with the test plan, but it can be saved by checking "<code>Save Workbench</code>" option on Workbench element.</note>
57
</subsection>
56
</subsection>
58
57
59
<subsection name="&sect-num;.3 Configuring Tree Elements" anchor="config_element">
58
<subsection name="&sect-num;.3 Configuring Tree Elements" anchor="config_element">
(-)docs/usermanual/component_reference.html (-66 lines)
Lines 591-599 Link Here
591
<a href="#Thread_Group">Thread Group</a>
591
<a href="#Thread_Group">Thread Group</a>
592
</li>
592
</li>
593
<li>
593
<li>
594
<a href="#WorkBench">WorkBench</a>
595
</li>
596
<li>
597
<a href="#SSL_Manager">SSL Manager</a>
594
<a href="#SSL_Manager">SSL Manager</a>
598
</li>
595
</li>
599
<li>
596
<li>
Lines 6556-6564 Link Here
6556
<figcaption>Screenshot of Control-Panel of Module Controller</figcaption>
6553
<figcaption>Screenshot of Control-Panel of Module Controller</figcaption>
6557
</figure>
6554
</figure>
6558
</div>
6555
</div>
6559
<div class="clear"></div>
6560
<div class="note">The Module Controller should not be used with remote testing or non-gui testing in conjunction with Workbench components since the Workbench test elements are not part of test plan <span class="code">.jmx</span> files.  Any such test will fail.</div>
6561
<div class="clear"></div>
6562
<div class="properties">
6556
<div class="properties">
6563
<h3 id="Module_Controller_parms1">
6557
<h3 id="Module_Controller_parms1">
6564
        Parameters
6558
        Parameters
Lines 16026-16091 Link Here
16026
<div class="required req-false">No</div>
16020
<div class="required req-false">No</div>
16027
</div>
16021
</div>
16028
16022
16029
</div>
16030
<div class="go-top">
16031
<a href="#">^</a>
16032
</div>
16033
</div>
16034
16035
16036
<div class="component">
16037
<h2 id="WorkBench">WorkBench<a class="sectionlink" href="#WorkBench" title="Link to here">&para;</a>
16038
</h2>
16039
<div class="description">
16040
16041
<p>The WorkBench simply provides a place to temporarily store test elements while not in use, for copy/paste purposes, or any other purpose you desire. 
16042
When you save your test plan, WorkBench items are not saved with it by default unless you check "<span class="code">Save Workbench</span>" option.
16043
Your WorkBench can be saved independently, if you like (right-click on <span class="code">WorkBench</span> and choose <span class="code">Save</span>).</p>
16044
16045
<p>Certain test elements are only available on the WorkBench:</p>
16046
16047
<ul>
16048
16049
<li>
16050
<a href="../usermanual/component_reference.html#HTTP(S)_Test_Script_Recorder">HTTP(S) Test Script Recorder</a>
16051
</li>
16052
16053
<li>
16054
<a href="../usermanual/component_reference.html#HTTP_Mirror_Server">HTTP Mirror Server</a>
16055
</li>
16056
16057
<li>
16058
<a href="../usermanual/component_reference.html#Property_Display">Property Display</a>
16059
</li>
16060
16061
</ul>
16062
16063
<div class="properties">
16064
<h3>
16065
        Parameters
16066
        </h3>
16067
<div class="property title">
16068
<div class="name title">Attribute</div>
16069
<div class="description title">Description</div>
16070
<div class="required title">Required</div>
16071
</div>
16072
         
16073
<div class="property">
16074
<div class="name req-false">Save WorkBench</div>
16075
<div class="description req-false">
16076
                Allow to save the WorkBench's elements into the JMX file.
16077
        </div>
16078
<div class="required req-false">No</div>
16079
</div>
16080
16081
</div>
16082
16083
</div>
16084
<div class="screenshot">
16085
<figure>
16086
<a href="../images/screenshots/workbench.png"><img src="../images/screenshots/workbench.png" width="384" height="103" alt="Screenshot for Control-Panel of WorkBench"></a>
16087
<figcaption>Screenshot of Control-Panel of WorkBench</figcaption>
16088
</figure>
16089
</div>
16023
</div>
16090
<div class="go-top">
16024
<div class="go-top">
16091
<a href="#">^</a>
16025
<a href="#">^</a>
(-)xdocs/usermanual/component_reference.xml (-19 lines)
Lines 2482-2488 Link Here
2482
otherwise a duplicate may be accidentally created when new elements are added to the test plan. 
2482
otherwise a duplicate may be accidentally created when new elements are added to the test plan. 
2483
</p>
2483
</p>
2484
</description>
2484
</description>
2485
<note>The Module Controller should not be used with remote testing or non-gui testing in conjunction with Workbench components since the Workbench test elements are not part of test plan <code>.jmx</code> files.  Any such test will fail.</note>
2486
<properties>
2485
<properties>
2487
        <property name="Name" required="No">Descriptive name for this controller that is shown in the tree.</property>
2486
        <property name="Name" required="No">Descriptive name for this controller that is shown in the tree.</property>
2488
        <property name="Module to Run" required="Yes">The module controller provides a list of all controllers loaded into the gui.  Select
2487
        <property name="Module to Run" required="Yes">The module controller provides a list of all controllers loaded into the gui.  Select
Lines 6374-6397 Link Here
6374
</properties>
6373
</properties>
6375
</component>
6374
</component>
6376
6375
6377
<component name="WorkBench" index="&sect-num;.9.3"  width="384" height="103" screenshot="workbench.png">
6378
<description>
6379
<p>The WorkBench simply provides a place to temporarily store test elements while not in use, for copy/paste purposes, or any other purpose you desire. 
6380
When you save your test plan, WorkBench items are not saved with it by default unless you check "<code>Save Workbench</code>" option.
6381
Your WorkBench can be saved independently, if you like (right-click on <code>WorkBench</code> and choose <code>Save</code>).</p>
6382
<p>Certain test elements are only available on the WorkBench:</p>
6383
<ul>
6384
<li><complink name="HTTP(S) Test Script Recorder"/></li>
6385
<li><complink name="HTTP Mirror Server"/></li>
6386
<li><complink name="Property Display"/></li>
6387
</ul>
6388
<properties>
6389
         <property name="Save WorkBench" required="No">
6390
                Allow to save the WorkBench's elements into the JMX file.
6391
        </property>
6392
</properties>
6393
</description>
6394
</component>
6395
6376
6396
<component name="SSL Manager" index="&sect-num;.9.4" screenshot="">
6377
<component name="SSL Manager" index="&sect-num;.9.4" screenshot="">
6397
<p>
6378
<p>
(-)src/core/org/apache/jmeter/gui/action/Load.java (-2 / +1 lines)
Lines 38-44 Link Here
38
import org.apache.jmeter.services.FileServer;
38
import org.apache.jmeter.services.FileServer;
39
import org.apache.jmeter.testelement.TestElement;
39
import org.apache.jmeter.testelement.TestElement;
40
import org.apache.jmeter.testelement.TestPlan;
40
import org.apache.jmeter.testelement.TestPlan;
41
import org.apache.jmeter.testelement.WorkBench;
42
import org.apache.jmeter.util.JMeterUtils;
41
import org.apache.jmeter.util.JMeterUtils;
43
import org.apache.jorphan.collections.HashTree;
42
import org.apache.jorphan.collections.HashTree;
44
import org.slf4j.Logger;
43
import org.slf4j.Logger;
Lines 181-187 Link Here
181
180
182
        if (merging){ // Check if target of merge is reasonable
181
        if (merging){ // Check if target of merge is reasonable
183
            final TestElement te = (TestElement)tree.getArray()[0];
182
            final TestElement te = (TestElement)tree.getArray()[0];
184
            if (!(te instanceof WorkBench || te instanceof TestPlan)){// These are handled specially by addToTree
183
            if (!(te instanceof TestPlan)){// These are handled specially by addToTree
185
                final boolean ok = MenuFactory.canAddTo(guiInstance.getCurrentNode(), te);
184
                final boolean ok = MenuFactory.canAddTo(guiInstance.getCurrentNode(), te);
186
                if (!ok){
185
                if (!ok){
187
                    String name = te.getName();
186
                    String name = te.getName();
(-)src/core/org/apache/jmeter/gui/action/Move.java (-2 / +1 lines)
Lines 33-39 Link Here
33
import org.apache.jmeter.gui.util.MenuFactory;
33
import org.apache.jmeter.gui.util.MenuFactory;
34
import org.apache.jmeter.testelement.TestElement;
34
import org.apache.jmeter.testelement.TestElement;
35
import org.apache.jmeter.testelement.TestPlan;
35
import org.apache.jmeter.testelement.TestPlan;
36
import org.apache.jmeter.testelement.WorkBench;
37
36
38
/**
37
/**
39
 * Move a node up/down/left/right 
38
 * Move a node up/down/left/right 
Lines 120-126 Link Here
120
    private JMeterTreeNode getParentNode(JMeterTreeNode currentNode) {
119
    private JMeterTreeNode getParentNode(JMeterTreeNode currentNode) {
121
        JMeterTreeNode parentNode = (JMeterTreeNode) currentNode.getParent();
120
        JMeterTreeNode parentNode = (JMeterTreeNode) currentNode.getParent();
122
        TestElement te = currentNode.getTestElement();
121
        TestElement te = currentNode.getTestElement();
123
        if (te instanceof TestPlan || te instanceof WorkBench) {
122
        if (te instanceof TestPlan) {
124
            parentNode = null; // So elements can only be added as children
123
            parentNode = null; // So elements can only be added as children
125
        }
124
        }
126
        return parentNode;
125
        return parentNode;
(-)src/core/org/apache/jmeter/gui/action/Save.java (-19 / +1 lines)
Lines 50-56 Link Here
50
import org.apache.jmeter.services.FileServer;
50
import org.apache.jmeter.services.FileServer;
51
import org.apache.jmeter.testelement.TestElement;
51
import org.apache.jmeter.testelement.TestElement;
52
import org.apache.jmeter.testelement.TestPlan;
52
import org.apache.jmeter.testelement.TestPlan;
53
import org.apache.jmeter.testelement.WorkBench;
54
import org.apache.jmeter.threads.ThreadGroup;
53
import org.apache.jmeter.threads.ThreadGroup;
55
import org.apache.jmeter.util.JMeterUtils;
54
import org.apache.jmeter.util.JMeterUtils;
56
import org.apache.jorphan.collections.HashTree;
55
import org.apache.jorphan.collections.HashTree;
Lines 163-175 Link Here
163
            }
162
            }
164
        } else {
163
        } else {
165
            fullSave = true;
164
            fullSave = true;
166
            HashTree testPlan = GuiPackage.getInstance().getTreeModel().getTestPlan();
165
            subTree = GuiPackage.getInstance().getTreeModel().getTestPlan();
167
            // If saveWorkBench 
168
            if (isWorkbenchSaveable()) {
169
                HashTree workbench = GuiPackage.getInstance().getTreeModel().getWorkBench();
170
                testPlan.add(workbench);
171
            }
172
            subTree = testPlan;
173
        }
166
        }
174
167
175
        String updateFile = GuiPackage.getInstance().getTestPlanFile();
168
        String updateFile = GuiPackage.getInstance().getTestPlanFile();
Lines 225-234 Link Here
225
            if (fullSave) { // Only update the stored copy of the tree for a full save
218
            if (fullSave) { // Only update the stored copy of the tree for a full save
226
                FileServer.getFileServer().setScriptName(new File(updateFile).getName());
219
                FileServer.getFileServer().setScriptName(new File(updateFile).getName());
227
                subTree = GuiPackage.getInstance().getTreeModel().getTestPlan(); // refetch, because convertSubTree affects it
220
                subTree = GuiPackage.getInstance().getTreeModel().getTestPlan(); // refetch, because convertSubTree affects it
228
                if (isWorkbenchSaveable()) {
229
                    HashTree workbench = GuiPackage.getInstance().getTreeModel().getWorkBench();
230
                    subTree.add(workbench);
231
                }
232
                ActionRouter.getInstance().doActionNow(new ActionEvent(subTree, e.getID(), ActionNames.SUB_TREE_SAVED));
221
                ActionRouter.getInstance().doActionNow(new ActionEvent(subTree, e.getID(), ActionNames.SUB_TREE_SAVED));
233
            }
222
            }
234
            
223
            
Lines 396-408 Link Here
396
                .orElse(0);
385
                .orElse(0);
397
    }
386
    }
398
    
387
    
399
    /**
400
     * check if the workbench should be saved
401
     */
402
    private boolean isWorkbenchSaveable() {
403
        JMeterTreeNode workbenchNode = (JMeterTreeNode) ((JMeterTreeNode) GuiPackage.getInstance().getTreeModel().getRoot()).getChildAt(1);
404
        return ((WorkBench) workbenchNode.getUserObject()).getSaveWorkBench();
405
    }
406
388
407
    /**
389
    /**
408
     * Check nodes does not contain a node of type TestPlan or ThreadGroup
390
     * Check nodes does not contain a node of type TestPlan or ThreadGroup
(-)src/core/org/apache/jmeter/gui/util/MenuFactory.java (-6 / +17 lines)
Lines 53-59 Link Here
53
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
53
import org.apache.jmeter.testbeans.gui.TestBeanGUI;
54
import org.apache.jmeter.testelement.TestElement;
54
import org.apache.jmeter.testelement.TestElement;
55
import org.apache.jmeter.testelement.TestPlan;
55
import org.apache.jmeter.testelement.TestPlan;
56
import org.apache.jmeter.testelement.WorkBench;
57
import org.apache.jmeter.util.JMeterUtils;
56
import org.apache.jmeter.util.JMeterUtils;
58
import org.apache.jmeter.visualizers.Printable;
57
import org.apache.jmeter.visualizers.Printable;
59
import org.apache.jorphan.gui.GuiUtils;
58
import org.apache.jorphan.gui.GuiUtils;
Lines 616-624 Link Here
616
        if (null == parentNode) {
615
        if (null == parentNode) {
617
            return false;
616
            return false;
618
        }
617
        }
619
        if (foundClass(nodes, new Class[]{WorkBench.class})){// Can't add a Workbench anywhere
620
            return false;
621
        }
622
        if (foundClass(nodes, new Class[]{TestPlan.class})){// Can't add a TestPlan anywhere
618
        if (foundClass(nodes, new Class[]{TestPlan.class})){// Can't add a TestPlan anywhere
623
            return false;
619
            return false;
624
        }
620
        }
Lines 632-640 Link Here
632
            return false;
628
            return false;
633
        }
629
        }
634
630
635
        if (parent instanceof WorkBench) {// allow everything else
631
        // Cannot move Non-Test Elements from root of Test Plan
636
            return true;
632
        if (!(parent instanceof TestPlan) && foundMenuCategories(nodes, NON_TEST_ELEMENTS)) {
633
            return false;
637
        }
634
        }
635
638
        if (parent instanceof TestPlan) {
636
        if (parent instanceof TestPlan) {
639
            if (foundClass(nodes,
637
            if (foundClass(nodes,
640
                     new Class[]{Sampler.class, Controller.class}, // Samplers and Controllers need not apply ...
638
                     new Class[]{Sampler.class, Controller.class}, // Samplers and Controllers need not apply ...
Lines 657-662 Link Here
657
            }
655
            }
658
            return true;
656
            return true;
659
        }
657
        }
658
660
        // All other
659
        // All other
661
        return false;
660
        return false;
662
    }
661
    }
Lines 672-677 Link Here
672
        }
671
        }
673
        return false;
672
        return false;
674
    }
673
    }
674
675
    // Is any node an instance of one of the menu category?
676
    private static boolean foundMenuCategories(JMeterTreeNode[] nodes, String category) {
677
        for (JMeterTreeNode node : nodes) {
678
            for (String c : node.getMenuCategories()) {
679
                if (category.equals(c)) {
680
                    return true;
681
                }
682
            }
683
        }
684
        return false;
685
    }
675
686
676
    // Is any node an instance of one of the classes, but not an exception?
687
    // Is any node an instance of one of the classes, but not an exception?
677
    private static boolean foundClass(JMeterTreeNode[] nodes, Class<?>[] classes, Class<?> except) {
688
    private static boolean foundClass(JMeterTreeNode[] nodes, Class<?>[] classes, Class<?> except) {
(-)src/core/org/apache/jmeter/gui/action/CheckDirty.java (-21 lines)
Lines 28-34 Link Here
28
import org.apache.jmeter.gui.GuiPackage;
28
import org.apache.jmeter.gui.GuiPackage;
29
import org.apache.jmeter.gui.tree.JMeterTreeNode;
29
import org.apache.jmeter.gui.tree.JMeterTreeNode;
30
import org.apache.jmeter.testelement.TestElement;
30
import org.apache.jmeter.testelement.TestElement;
31
import org.apache.jmeter.testelement.WorkBench;
32
import org.apache.jorphan.collections.HashTree;
31
import org.apache.jorphan.collections.HashTree;
33
import org.apache.jorphan.collections.HashTreeTraverser;
32
import org.apache.jorphan.collections.HashTreeTraverser;
34
import org.apache.jorphan.collections.ListedHashTree;
33
import org.apache.jorphan.collections.ListedHashTree;
Lines 91-99 Link Here
91
        } else if (action.equals(ActionNames.ADD_ALL)) {
90
        } else if (action.equals(ActionNames.ADD_ALL)) {
92
            previousGuiItems.clear();
91
            previousGuiItems.clear();
93
            GuiPackage.getInstance().getTreeModel().getTestPlan().traverse(this);
92
            GuiPackage.getInstance().getTreeModel().getTestPlan().traverse(this);
94
            if (isWorkbenchSaveable()) {
95
                GuiPackage.getInstance().getTreeModel().getWorkBench().traverse(this);
96
            }
97
        } else if (action.equals(ActionNames.CHECK_REMOVE) ||
93
        } else if (action.equals(ActionNames.CHECK_REMOVE) ||
98
                action.equals(ActionNames.CHECK_CUT)) {
94
                action.equals(ActionNames.CHECK_CUT)) {
99
            GuiPackage guiPackage = GuiPackage.getInstance();
95
            GuiPackage guiPackage = GuiPackage.getInstance();
Lines 118-126 Link Here
118
            //remember
114
            //remember
119
            previousGuiItems.clear();
115
            previousGuiItems.clear();
120
            GuiPackage.getInstance().getTreeModel().getTestPlan().traverse(this);
116
            GuiPackage.getInstance().getTreeModel().getTestPlan().traverse(this);
121
            if (isWorkbenchSaveable()) {
122
                GuiPackage.getInstance().getTreeModel().getWorkBench().traverse(this);
123
            }
124
        }
117
        }
125
        else {
118
        else {
126
            dirty = false;
119
            dirty = false;
Lines 129-141 Link Here
129
                HashTree wholeTree = GuiPackage.getInstance().getTreeModel().getTestPlan();
122
                HashTree wholeTree = GuiPackage.getInstance().getTreeModel().getTestPlan();
130
                wholeTree.traverse(this);
123
                wholeTree.traverse(this);
131
                
124
                
132
                // check the workbench for modification
133
                if(!dirty) { // NOSONAR
134
                    if (isWorkbenchSaveable()) {
135
                        HashTree workbench = GuiPackage.getInstance().getTreeModel().getWorkBench();
136
                        workbench.traverse(this);
137
                    }
138
                }
139
            } finally {
125
            } finally {
140
                checkMode = false;
126
                checkMode = false;
141
            }
127
            }
Lines 143-155 Link Here
143
        GuiPackage.getInstance().setDirty(dirty);
129
        GuiPackage.getInstance().setDirty(dirty);
144
    }
130
    }
145
131
146
    /**
147
     * check if the workbench should be saved
148
     */
149
    private boolean isWorkbenchSaveable() {
150
        JMeterTreeNode workbenchNode = (JMeterTreeNode) ((JMeterTreeNode) GuiPackage.getInstance().getTreeModel().getRoot()).getChildAt(1);
151
        return ((WorkBench) workbenchNode.getUserObject()).getSaveWorkBench();
152
    }
153
132
154
    /**
133
    /**
155
     * The tree traverses itself depth-first, calling addNode for each
134
     * The tree traverses itself depth-first, calling addNode for each
(-)src/core/org/apache/jmeter/control/gui/TestPlanGui.java (+1 lines)
Lines 92-97 Link Here
92
        JMenu addMenu = new JMenu(JMeterUtils.getResString("add")); // $NON-NLS-1$
92
        JMenu addMenu = new JMenu(JMeterUtils.getResString("add")); // $NON-NLS-1$
93
        addMenu.add(MenuFactory.makeMenu(MenuFactory.THREADS, ActionNames.ADD));
93
        addMenu.add(MenuFactory.makeMenu(MenuFactory.THREADS, ActionNames.ADD));
94
        addMenu.add(MenuFactory.makeMenu(MenuFactory.FRAGMENTS, ActionNames.ADD));
94
        addMenu.add(MenuFactory.makeMenu(MenuFactory.FRAGMENTS, ActionNames.ADD));
95
        addMenu.add(MenuFactory.makeMenu(MenuFactory.NON_TEST_ELEMENTS, ActionNames.ADD));
95
        addMenu.add(MenuFactory.makeMenu(MenuFactory.CONFIG_ELEMENTS, ActionNames.ADD));
96
        addMenu.add(MenuFactory.makeMenu(MenuFactory.CONFIG_ELEMENTS, ActionNames.ADD));
96
        addMenu.add(MenuFactory.makeMenu(MenuFactory.TIMERS, ActionNames.ADD));
97
        addMenu.add(MenuFactory.makeMenu(MenuFactory.TIMERS, ActionNames.ADD));
97
        addMenu.add(MenuFactory.makeMenu(MenuFactory.PRE_PROCESSORS, ActionNames.ADD));
98
        addMenu.add(MenuFactory.makeMenu(MenuFactory.PRE_PROCESSORS, ActionNames.ADD));
(-)src/core/org/apache/jmeter/control/gui/WorkBenchGui.java (+1 lines)
Lines 38-43 Link Here
38
 * preparations for the test plan.
38
 * preparations for the test plan.
39
 *
39
 *
40
 */
40
 */
41
@Deprecated
41
public class WorkBenchGui extends AbstractJMeterGuiComponent {
42
public class WorkBenchGui extends AbstractJMeterGuiComponent {
42
    private static final long serialVersionUID = 240L;
43
    private static final long serialVersionUID = 240L;
43
    // This check-box defines whether to save  WorkBench content or not
44
    // This check-box defines whether to save  WorkBench content or not
(-)src/core/org/apache/jmeter/gui/tree/JMeterTreeModel.java (-27 / +64 lines)
Lines 18-23 Link Here
18
18
19
package org.apache.jmeter.gui.tree;
19
package org.apache.jmeter.gui.tree;
20
20
21
import java.util.Collection;
21
import java.util.Enumeration;
22
import java.util.Enumeration;
22
import java.util.LinkedList;
23
import java.util.LinkedList;
23
import java.util.List;
24
import java.util.List;
Lines 25-35 Link Here
25
import javax.swing.tree.DefaultTreeModel;
26
import javax.swing.tree.DefaultTreeModel;
26
27
27
import org.apache.jmeter.config.gui.AbstractConfigGui;
28
import org.apache.jmeter.config.gui.AbstractConfigGui;
29
import org.apache.jmeter.control.TestFragmentController;
30
import org.apache.jmeter.control.gui.TestFragmentControllerGui;
28
import org.apache.jmeter.control.gui.TestPlanGui;
31
import org.apache.jmeter.control.gui.TestPlanGui;
29
import org.apache.jmeter.control.gui.WorkBenchGui;
30
import org.apache.jmeter.exceptions.IllegalUserActionException;
32
import org.apache.jmeter.exceptions.IllegalUserActionException;
31
import org.apache.jmeter.gui.GuiPackage;
33
import org.apache.jmeter.gui.GuiPackage;
32
import org.apache.jmeter.gui.JMeterGUIComponent;
34
import org.apache.jmeter.gui.JMeterGUIComponent;
35
import org.apache.jmeter.gui.util.MenuFactory;
33
import org.apache.jmeter.testelement.TestElement;
36
import org.apache.jmeter.testelement.TestElement;
34
import org.apache.jmeter.testelement.TestPlan;
37
import org.apache.jmeter.testelement.TestPlan;
35
import org.apache.jmeter.testelement.WorkBench;
38
import org.apache.jmeter.testelement.WorkBench;
Lines 40-52 Link Here
40
43
41
    private static final long serialVersionUID = 240L;
44
    private static final long serialVersionUID = 240L;
42
45
43
    public JMeterTreeModel(TestElement tp, TestElement wb) {
46
    public JMeterTreeModel(TestElement tp) {
44
        super(new JMeterTreeNode(wb, null));
47
        super(new JMeterTreeNode(tp, null));
45
        initTree(tp,wb);
48
        initTree(tp);
46
    }
49
    }
47
50
48
    public JMeterTreeModel() {
51
    public JMeterTreeModel() {
49
        this(new TestPlanGui().createTestElement(),new WorkBenchGui().createTestElement());
52
        this(new TestPlanGui().createTestElement());
50
    }
53
    }
51
54
52
    /**
55
    /**
Lines 57-63 Link Here
57
     */
60
     */
58
    @Deprecated
61
    @Deprecated
59
    public JMeterTreeModel(Object o) {
62
    public JMeterTreeModel(Object o) {
60
        this(new TestPlan(),new WorkBench());
63
        this(new TestPlan());
61
    }
64
    }
62
65
63
    /**
66
    /**
Lines 90-102 Link Here
90
     *            <code>current</code>
93
     *            <code>current</code>
91
     * @param current
94
     * @param current
92
     *            The node in which the <code>subTree</code> is to be inserted.
95
     *            The node in which the <code>subTree</code> is to be inserted.
93
     *            Will be overridden, when an instance of {@link TestPlan} or
96
     *            Will be overridden, when an instance of {@link TestPlan}
94
     *            {@link WorkBench} is found in the subtree.
95
     * @return newly created sub tree now found at <code>current</code>
97
     * @return newly created sub tree now found at <code>current</code>
96
     * @throws IllegalUserActionException
98
     * @throws IllegalUserActionException
97
     *             when <code>current</code> is not an instance of
99
     *             when <code>current</code> is not an instance of
98
     *             {@link AbstractConfigGui} and no instance of {@link TestPlan}
100
     *             {@link AbstractConfigGui} and no instance of {@link TestPlan}
99
     *             or {@link WorkBench} could be found in the
100
     *             <code>subTree</code>
101
     *             <code>subTree</code>
101
     */
102
     */
102
    public HashTree addSubTree(HashTree subTree, JMeterTreeNode current) throws IllegalUserActionException {
103
    public HashTree addSubTree(HashTree subTree, JMeterTreeNode current) throws IllegalUserActionException {
Lines 112-122 Link Here
112
                userObject.setSerialized(tp.isSerialized());
113
                userObject.setSerialized(tp.isSerialized());
113
                addSubTree(subTree.getTree(item), current);
114
                addSubTree(subTree.getTree(item), current);
114
            } else if (item instanceof WorkBench) {
115
            } else if (item instanceof WorkBench) {
115
                current = (JMeterTreeNode) ((JMeterTreeNode) getRoot()).getChildAt(1);
116
                //Move item from WorkBench to TestPlan
116
                final TestElement testElement = (TestElement) current.getUserObject();
117
                HashTree workbenchTree = subTree.getTree(item);
117
                testElement.addTestElement(item);
118
                if (workbenchTree.size() > 0) {
118
                testElement.setName(item.getName());
119
                    moveWorkBenchToTestPlan(current, workbenchTree);
119
                addSubTree(subTree.getTree(item), current);
120
                }
120
            } else {
121
            } else {
121
                addSubTree(subTree.getTree(item), addComponent(item, current));
122
                addSubTree(subTree.getTree(item), addComponent(item, current));
122
            }
123
            }
Lines 164-170 Link Here
164
    }
165
    }
165
166
166
    public void removeNodeFromParent(JMeterTreeNode node) {
167
    public void removeNodeFromParent(JMeterTreeNode node) {
167
        if (!(node.getUserObject() instanceof TestPlan) && !(node.getUserObject() instanceof WorkBench)) {
168
        if (!(node.getUserObject() instanceof TestPlan)) {
168
            super.removeNodeFromParent(node);
169
            super.removeNodeFromParent(node);
169
        }
170
        }
170
    }
171
    }
Lines 218-230 Link Here
218
        return getCurrentSubTree((JMeterTreeNode) ((JMeterTreeNode) this.getRoot()).getChildAt(0));
219
        return getCurrentSubTree((JMeterTreeNode) ((JMeterTreeNode) this.getRoot()).getChildAt(0));
219
    }
220
    }
220
221
221
    /**
222
     * Get the {@link WorkBench} from the root of this tree
223
     * @return The {@link WorkBench} found at the root of this tree
224
     */
225
    public HashTree getWorkBench() {
226
        return getCurrentSubTree((JMeterTreeNode) ((JMeterTreeNode) this.getRoot()).getChildAt(1));
227
    }
228
222
229
    /**
223
    /**
230
     * Clear the test plan, and use default node for test plan and workbench.
224
     * Clear the test plan, and use default node for test plan and workbench.
Lines 252-274 Link Here
252
            children = getChildCount(getRoot());
246
            children = getChildCount(getRoot());
253
        }
247
        }
254
        // Init the tree
248
        // Init the tree
255
        initTree(testPlan,new WorkBenchGui().createTestElement()); // Assumes this is only called from GUI mode
249
        initTree(testPlan); // Assumes this is only called from GUI mode
256
    }
250
    }
257
251
258
    /**
252
    /**
259
     * Initialize the model with nodes for testplan and workbench.
253
     * Initialize the model with nodes for testplan and workbench.
260
     *
254
     *
261
     * @param tp the element to use as testplan
255
     * @param tp the element to use as testplan
262
     * @param wb the element to use as workbench
263
     */
256
     */
264
    private void initTree(TestElement tp, TestElement wb) {
257
    private void initTree(TestElement tp) {
265
        // Insert the test plan node
258
        // Insert the test plan node
266
        insertNodeInto(new JMeterTreeNode(tp, this), (JMeterTreeNode) getRoot(), 0);
259
        insertNodeInto(new JMeterTreeNode(tp, this), (JMeterTreeNode) getRoot(), 0);
267
        // Insert the workbench node
268
        insertNodeInto(new JMeterTreeNode(wb, this), (JMeterTreeNode) getRoot(), 1);
269
        // Let others know that the tree content has changed.
260
        // Let others know that the tree content has changed.
270
        // This should not be necessary, but without it, nodes are not shown when the user
261
        // This should not be necessary, but without it, nodes are not shown when the user
271
        // uses the Close menu item
262
        // uses the Close menu item
272
        nodeStructureChanged((JMeterTreeNode)getRoot());
263
        nodeStructureChanged((JMeterTreeNode)getRoot());
273
    }
264
    }
265
266
267
    /**
268
     * Move all Non-Test Elements from WorkBench to TestPlan root.
269
     * Other Test Elements will be move to WorkBench Test Fragment in TestPlan
270
     * @param current - TestPlan root
271
     * @param workbenchTree - WorkBench hash tree
272
     */
273
    private void moveWorkBenchToTestPlan(JMeterTreeNode current, HashTree workbenchTree) throws IllegalUserActionException {
274
        Object[] workbenchTreeArray = workbenchTree.getArray();
275
        for (Object node : workbenchTreeArray) {
276
            if (isNonTestElement(node)) {
277
                HashTree subtree = workbenchTree.getTree(node);
278
                workbenchTree.remove(node);
279
                HashTree tree = new HashTree();
280
                tree.add(node);
281
                tree.add(node, subtree);
282
                ((TestElement) node).setProperty(TestElement.ENABLED, false);
283
                addSubTree(tree, current);
284
            }
285
        }
286
287
        if (workbenchTree.size() > 0) {
288
            HashTree testFragmentTree = new HashTree();
289
            TestFragmentController testFragmentController = new TestFragmentController();
290
            testFragmentController.setProperty(TestElement.NAME, "WorkBench Test Fragment");
291
            testFragmentController.setProperty(TestElement.GUI_CLASS, TestFragmentControllerGui.class.getName());
292
            testFragmentController.setProperty(TestElement.ENABLED, false);
293
            testFragmentTree.add(testFragmentController);
294
            testFragmentTree.add(testFragmentController, workbenchTree);
295
            addSubTree(testFragmentTree, current);
296
        }
297
    }
298
299
    private boolean isNonTestElement(Object node) {
300
        JMeterTreeNode treeNode = new JMeterTreeNode((TestElement) node, null);
301
        Collection<String> categories = treeNode.getMenuCategories();
302
        if (categories != null) {
303
            for (String category : categories) {
304
                if (MenuFactory.NON_TEST_ELEMENTS.equals(category)) {
305
                    return true;
306
                }
307
            }
308
        }
309
        return false;
310
    }
274
}
311
}
(-)src/protocol/http/org/apache/jmeter/protocol/http/proxy/ProxyControl.java (-6 lines)
Lines 83-89 Link Here
83
import org.apache.jmeter.testelement.TestElement;
83
import org.apache.jmeter.testelement.TestElement;
84
import org.apache.jmeter.testelement.TestPlan;
84
import org.apache.jmeter.testelement.TestPlan;
85
import org.apache.jmeter.testelement.TestStateListener;
85
import org.apache.jmeter.testelement.TestStateListener;
86
import org.apache.jmeter.testelement.WorkBench;
87
import org.apache.jmeter.testelement.property.BooleanProperty;
86
import org.apache.jmeter.testelement.property.BooleanProperty;
88
import org.apache.jmeter.testelement.property.CollectionProperty;
87
import org.apache.jmeter.testelement.property.CollectionProperty;
89
import org.apache.jmeter.testelement.property.IntegerProperty;
88
import org.apache.jmeter.testelement.property.IntegerProperty;
Lines 1055-1061 Link Here
1055
     * <li>The controller specified by the <code>target</code> property.
1054
     * <li>The controller specified by the <code>target</code> property.
1056
     * <li>If none was specified, the first RecordingController in the tree.
1055
     * <li>If none was specified, the first RecordingController in the tree.
1057
     * <li>If none is found, the first AbstractThreadGroup in the tree.
1056
     * <li>If none is found, the first AbstractThreadGroup in the tree.
1058
     * <li>If none is found, the Workspace.
1059
     * </ul>
1057
     * </ul>
1060
     *
1058
     *
1061
     * @return the tree node for the controller where the proxy must store the
1059
     * @return the tree node for the controller where the proxy must store the
Lines 1073-1082 Link Here
1073
        myTarget = findFirstNodeOfType(AbstractThreadGroup.class);
1071
        myTarget = findFirstNodeOfType(AbstractThreadGroup.class);
1074
        if (myTarget != null) {
1072
        if (myTarget != null) {
1075
            return myTarget;
1073
            return myTarget;
1076
        }
1077
        myTarget = findFirstNodeOfType(WorkBench.class);
1078
        if (myTarget != null) {
1079
            return myTarget;
1080
        }
1074
        }
1081
        log.error("Program error: test script recording target not found.");
1075
        log.error("Program error: test script recording target not found.");
1082
        return null;
1076
        return null;
(-)src/protocol/http/org/apache/jmeter/protocol/http/proxy/gui/ProxyControlGui.java (-2 / +1 lines)
Lines 77-83 Link Here
77
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
77
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerFactory;
78
import org.apache.jmeter.testelement.TestElement;
78
import org.apache.jmeter.testelement.TestElement;
79
import org.apache.jmeter.testelement.TestPlan;
79
import org.apache.jmeter.testelement.TestPlan;
80
import org.apache.jmeter.testelement.WorkBench;
81
import org.apache.jmeter.testelement.property.PropertyIterator;
80
import org.apache.jmeter.testelement.property.PropertyIterator;
82
import org.apache.jmeter.util.JMeterUtils;
81
import org.apache.jmeter.util.JMeterUtils;
83
import org.apache.jorphan.exec.KeyToolUtils;
82
import org.apache.jorphan.exec.KeyToolUtils;
Lines 1131-1137 Link Here
1131
                    targetNodesModel.addElement(tnw);
1130
                    targetNodesModel.addElement(tnw);
1132
                    name.append(separator);
1131
                    name.append(separator);
1133
                    buildNodesModel(cur, name.toString(), level + 1);
1132
                    buildNodesModel(cur, name.toString(), level + 1);
1134
                } else if (te instanceof TestPlan || te instanceof WorkBench) {
1133
                } else if (te instanceof TestPlan) {
1135
                    name.append(cur.getName());
1134
                    name.append(cur.getName());
1136
                    name.append(separator);
1135
                    name.append(separator);
1137
                    buildNodesModel(cur, name.toString(), 0);
1136
                    buildNodesModel(cur, name.toString(), 0);

Return to bug 61591