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

(-)a/src/components/org/apache/jmeter/visualizers/PropertyControlGui.java (-44 / +14 lines)
Lines 54-60 import org.apache.jorphan.gui.ObjectTableModel; Link Here
54
import org.apache.jorphan.reflect.Functor;
54
import org.apache.jorphan.reflect.Functor;
55
55
56
public class PropertyControlGui extends AbstractConfigGui
56
public class PropertyControlGui extends AbstractConfigGui
57
    implements ActionListener, UnsharedComponent {
57
                                implements ActionListener, UnsharedComponent {
58
58
59
    private static final long serialVersionUID = 1L;
59
    private static final long serialVersionUID = 1L;
60
60
Lines 72-78 public class PropertyControlGui extends AbstractConfigGui Link Here
72
    private static final String JMETER = "jmeter"; // $NON-NLS-1$
72
    private static final String JMETER = "jmeter"; // $NON-NLS-1$
73
73
74
    private final JCheckBox systemButton = new JCheckBox("System");
74
    private final JCheckBox systemButton = new JCheckBox("System");
75
    
75
76
    private final JCheckBox jmeterButton = new JCheckBox("JMeter");
76
    private final JCheckBox jmeterButton = new JCheckBox("JMeter");
77
77
78
    private final JLabel tableLabel = new JLabel("Properties");
78
    private final JLabel tableLabel = new JLabel("Properties");
Lines 83-94 public class PropertyControlGui extends AbstractConfigGui Link Here
83
    /** The model for the arguments table. */
83
    /** The model for the arguments table. */
84
    protected transient ObjectTableModel tableModel;
84
    protected transient ObjectTableModel tableModel;
85
85
86
//    /** A button for adding new arguments to the table. */
87
//    private JButton add;
88
//
89
//    /** A button for removing arguments from the table. */
90
//    private JButton delete;
91
92
    public PropertyControlGui() {
86
    public PropertyControlGui() {
93
        super();
87
        super();
94
        init();
88
        init();
Lines 121-127 public class PropertyControlGui extends AbstractConfigGui Link Here
121
            setUpData();
115
            setUpData();
122
            return;
116
            return;
123
        }
117
        }
124
125
    }
118
    }
126
119
127
    @Override
120
    @Override
Lines 138-144 public class PropertyControlGui extends AbstractConfigGui Link Here
138
131
139
    private void setUpData(){
132
    private void setUpData(){
140
        tableModel.clearData();
133
        tableModel.clearData();
141
        Properties p=null;
134
        Properties p = null;
142
        if (systemButton.isSelected()){
135
        if (systemButton.isSelected()){
143
            p = System.getProperties();
136
            p = System.getProperties();
144
        }
137
        }
Lines 154-175 public class PropertyControlGui extends AbstractConfigGui Link Here
154
            @Override
147
            @Override
155
            public int compare(Map.Entry<Object, Object> o1, Map.Entry<Object, Object> o2) {
148
            public int compare(Map.Entry<Object, Object> o1, Map.Entry<Object, Object> o2) {
156
                String m1,m2;
149
                String m1,m2;
157
                m1=(String)o1.getKey();
150
                m1 = (String)o1.getKey();
158
                m2=(String)o2.getKey();
151
                m2 = (String)o2.getKey();
159
                return m1.compareTo(m2);
152
                return m1.compareTo(m2);
160
            }
153
            }
161
        });
154
        });
162
        Iterator<Map.Entry<Object, Object>> i = al.iterator();
155
        Iterator<Map.Entry<Object, Object>> i = al.iterator();
163
        while(i.hasNext()){
156
        while (i.hasNext()) {
164
            tableModel.addRow(i.next());
157
            tableModel.addRow(i.next());
165
        }
158
        }
166
167
    }
159
    }
168
160
169
    @Override
161
    @Override
170
    public void modifyTestElement(TestElement element) {
162
    public void modifyTestElement(TestElement element) {
171
        configureTestElement(element);
163
        configureTestElement(element);
172
    }
164
    }
165
173
    private Component makeMainPanel() {
166
    private Component makeMainPanel() {
174
        initializeTableModel();
167
        initializeTableModel();
175
        table = new JTable(tableModel);
168
        table = new JTable(tableModel);
Lines 200-237 public class PropertyControlGui extends AbstractConfigGui Link Here
200
        return labelPanel;
193
        return labelPanel;
201
    }
194
    }
202
195
203
//    /**
204
//     * Create a panel containing the add and delete buttons.
205
//     *
206
//     * @return a GUI panel containing the buttons
207
//     */
208
//    private JPanel makeButtonPanel() {// Not currently used
209
//        add = new JButton(JMeterUtils.getResString("add")); // $NON-NLS-1$
210
//        add.setActionCommand(ADD);
211
//        add.setEnabled(true);
212
//
213
//        delete = new JButton(JMeterUtils.getResString("delete")); // $NON-NLS-1$
214
//        delete.setActionCommand(DELETE);
215
//
216
//        JPanel buttonPanel = new JPanel();
217
//        buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
218
//         add.addActionListener(this);
219
//        delete.addActionListener(this);
220
//        buttonPanel.add(add);
221
//        buttonPanel.add(delete);
222
//        return buttonPanel;
223
//    }
224
225
    /**
196
    /**
226
     * Initialize the components and layout of this component.
197
     * Initialize the components and layout of this component.
227
     */
198
     */
228
    private void init() {
199
    private void init() {
229
        JPanel p = this;
200
        JPanel p = this;
230
201
231
            setLayout(new BorderLayout(0, 5));
202
        setLayout(new BorderLayout(0, 5));
232
            setBorder(makeBorder());
203
        setBorder(makeBorder());
233
            add(makeTitlePanel(), BorderLayout.NORTH);
204
        add(makeTitlePanel(), BorderLayout.NORTH);
234
            p = new JPanel();
205
        p = new JPanel();
235
206
236
        p.setLayout(new BorderLayout());
207
        p.setLayout(new BorderLayout());
237
208
Lines 239-245 public class PropertyControlGui extends AbstractConfigGui Link Here
239
        p.add(makeMainPanel(), BorderLayout.CENTER);
210
        p.add(makeMainPanel(), BorderLayout.CENTER);
240
        // Force a minimum table height of 70 pixels
211
        // Force a minimum table height of 70 pixels
241
        p.add(Box.createVerticalStrut(70), BorderLayout.WEST);
212
        p.add(Box.createVerticalStrut(70), BorderLayout.WEST);
242
        //p.add(makeButtonPanel(), BorderLayout.SOUTH);
243
213
244
        add(p, BorderLayout.CENTER);
214
        add(p, BorderLayout.CENTER);
245
        table.revalidate();
215
        table.revalidate();
Lines 250-258 public class PropertyControlGui extends AbstractConfigGui Link Here
250
                new Functor(Map.Entry.class, "getKey"), // $NON-NLS-1$
220
                new Functor(Map.Entry.class, "getKey"), // $NON-NLS-1$
251
                new Functor(Map.Entry.class, "getValue") },  // $NON-NLS-1$
221
                new Functor(Map.Entry.class, "getValue") },  // $NON-NLS-1$
252
                new Functor[] {
222
                new Functor[] {
253
                null, //new Functor("setName"), // $NON-NLS-1$
223
                null,
254
                new Functor(Map.Entry.class,"setValue", new Class[] { Object.class }) // $NON-NLS-1$
224
                new Functor(Map.Entry.class,"setValue", new Class[] { Object.class }) // $NON-NLS-1$
255
            },
225
        },
256
                new Class[] { String.class, String.class });
226
        new Class[] { String.class, String.class });
257
    }
227
    }
258
}
228
}
(-)a/src/components/org/apache/jmeter/visualizers/StatVisualizer.java (-99 / +5 lines)
Lines 89-101 public class StatVisualizer extends AbstractVisualizer implements Clearable, Act Link Here
89
    private JScrollPane myScrollPane;
89
    private JScrollPane myScrollPane;
90
90
91
    private final JButton saveTable =
91
    private final JButton saveTable =
92
        new JButton(JMeterUtils.getResString("aggregate_graph_save_table"));            //$NON-NLS-1$
92
        new JButton(JMeterUtils.getResString("aggregate_graph_save_table")); //$NON-NLS-1$
93
93
94
    private final JCheckBox saveHeaders = // should header be saved with the data?
94
    private final JCheckBox saveHeaders = // should header be saved with the data?
95
        new JCheckBox(JMeterUtils.getResString("aggregate_graph_save_table_header"),true);    //$NON-NLS-1$
95
        new JCheckBox(JMeterUtils.getResString("aggregate_graph_save_table_header"), true); //$NON-NLS-1$
96
96
97
    private final JCheckBox useGroupName =
97
    private final JCheckBox useGroupName =
98
        new JCheckBox(JMeterUtils.getResString("aggregate_graph_use_group_name"));            //$NON-NLS-1$
98
        new JCheckBox(JMeterUtils.getResString("aggregate_graph_use_group_name")); //$NON-NLS-1$
99
99
100
    private transient ObjectTableModel model;
100
    private transient ObjectTableModel model;
101
101
Lines 173-181 public class StatVisualizer extends AbstractVisualizer implements Clearable, Act Link Here
173
                        model.insertRow(row, model.getRowCount() - 1);
173
                        model.insertRow(row, model.getRowCount() - 1);
174
                    }
174
                    }
175
                }
175
                }
176
                /*
176
                // Synch is needed because multiple threads can update the counts.
177
                 * Synch is needed because multiple threads can update the counts.
178
                 */
179
                synchronized(row) {
177
                synchronized(row) {
180
                    row.addSample(res);
178
                    row.addSample(res);
181
                }
179
                }
Lines 183-189 public class StatVisualizer extends AbstractVisualizer implements Clearable, Act Link Here
183
                synchronized(tot) {
181
                synchronized(tot) {
184
                    tot.addSample(res);
182
                    tot.addSample(res);
185
                }
183
                }
186
                model.fireTableDataChanged();                
184
                model.fireTableDataChanged();
187
            }
185
            }
188
        });
186
        });
189
    }
187
    }
Lines 216-223 public class StatVisualizer extends AbstractVisualizer implements Clearable, Act Link Here
216
214
217
        mainPanel.add(makeTitlePanel());
215
        mainPanel.add(makeTitlePanel());
218
216
219
        // SortFilterModel mySortedModel =
220
        // new SortFilterModel(myStatTableModel);
221
        myJTable = new JTable(model);
217
        myJTable = new JTable(model);
222
        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer());
218
        myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer());
223
        myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
219
        myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
Lines 269-361 public class StatVisualizer extends AbstractVisualizer implements Clearable, Act Link Here
269
    }
265
    }
270
}
266
}
271
267
272
/**
273
 * Pulled this mainly out of a Core Java book to implement a sorted table -
274
 * haven't implemented this yet, it needs some non-trivial work done to it to
275
 * support our dynamically-sizing TableModel for this visualizer.
276
 *
277
 */
278
279
//class SortFilterModel extends AbstractTableModel {
280
//  private TableModel model;
281
//
282
//  private int sortColumn;
283
//
284
//  private Row[] rows;
285
//
286
//  public SortFilterModel(TableModel m) {
287
//      model = m;
288
//      rows = new Row[model.getRowCount()];
289
//      for (int i = 0; i < rows.length; i++) {
290
//          rows[i] = new Row();
291
//          rows[i].index = i;
292
//      }
293
//  }
294
//
295
//  public SortFilterModel() {
296
//  }
297
//
298
//  public void setValueAt(Object aValue, int r, int c) {
299
//        model.setValueAt(aValue, rows[r].index, c);
300
//    }
301
//
302
//    public Object getValueAt(int r, int c) {
303
//        return model.getValueAt(rows[r].index, c);
304
//    }
305
//
306
//    public boolean isCellEditable(int r, int c) {
307
//        return model.isCellEditable(rows[r].index, c);
308
//    }
309
//
310
//    public int getRowCount() {
311
//        return model.getRowCount();
312
//    }
313
//
314
//    public int getColumnCount() {
315
//        return model.getColumnCount();
316
//    }
317
//
318
//    public String getColumnName(int c) {
319
//        return model.getColumnName(c);
320
//    }
321
//
322
//    public Class getColumnClass(int c) {
323
//        return model.getColumnClass(c);
324
//    }
325
//
326
//    public void sort(int c) {
327
//        sortColumn = c;
328
//        Arrays.sort(rows);
329
//        fireTableDataChanged();
330
//    }
331
//
332
//    public void addMouseListener(final JTable table) {
333
//        table.getTableHeader().addMouseListener(new MouseAdapter() {
334
//            public void mouseClicked(MouseEvent event) {
335
//                if (event.getClickCount() < 2) {
336
//                    return;
337
//                }
338
//                int tableColumn = table.columnAtPoint(event.getPoint());
339
//                int modelColumn = table.convertColumnIndexToModel(tableColumn);
340
//
341
//                sort(modelColumn);
342
//            }
343
//        });
344
//    }
345
//
346
//    private class Row implements Comparable {
347
//        public int index;
348
//
349
//        public int compareTo(Object other) {
350
//            Row otherRow = (Row) other;
351
//            Object a = model.getValueAt(index, sortColumn);
352
//            Object b = model.getValueAt(otherRow.index, sortColumn);
353
//
354
//            if (a instanceof Comparable) {
355
//                return ((Comparable) a).compareTo(b);
356
//            } else {
357
//                return index - otherRow.index;
358
//            }
359
//        }
360
//    }
361
//} // class SortFilterModel
(-)a/src/core/org/apache/jmeter/config/gui/RowDetailDialog.java (-13 / +7 lines)
Lines 76-88 public class RowDetailDialog extends JDialog implements ActionListener, Document Link Here
76
    private JButton nextButton;
76
    private JButton nextButton;
77
77
78
    private JButton previousButton;
78
    private JButton previousButton;
79
    
79
80
    private JButton closeButton;
80
    private JButton closeButton;
81
81
82
    private ObjectTableModel tableModel;
82
    private ObjectTableModel tableModel;
83
83
84
    private int selectedRow;
84
    private int selectedRow;
85
    
85
86
    private boolean textChanged = true; // change to false after the first insert
86
    private boolean textChanged = true; // change to false after the first insert
87
87
88
88
Lines 102-110 public class RowDetailDialog extends JDialog implements ActionListener, Document Link Here
102
        JRootPane rootPane = new JRootPane();
102
        JRootPane rootPane = new JRootPane();
103
        // Hide Window on ESC
103
        // Hide Window on ESC
104
        Action escapeAction = new AbstractAction("ESCAPE") {
104
        Action escapeAction = new AbstractAction("ESCAPE") {
105
            /**
106
             *
107
             */
108
            private static final long serialVersionUID = -8699034338969407625L;
105
            private static final long serialVersionUID = -8699034338969407625L;
109
106
110
            @Override
107
            @Override
Lines 114-122 public class RowDetailDialog extends JDialog implements ActionListener, Document Link Here
114
        };
111
        };
115
        // Do update on Enter
112
        // Do update on Enter
116
        Action enterAction = new AbstractAction("ENTER") {
113
        Action enterAction = new AbstractAction("ENTER") {
117
            /**
118
             *
119
             */
120
            private static final long serialVersionUID = -1529005452976176873L;
114
            private static final long serialVersionUID = -1529005452976176873L;
121
115
122
            @Override
116
            @Override
Lines 198-219 public class RowDetailDialog extends JDialog implements ActionListener, Document Link Here
198
    @Override
192
    @Override
199
    public void actionPerformed(ActionEvent e) {
193
    public void actionPerformed(ActionEvent e) {
200
        String action = e.getActionCommand();
194
        String action = e.getActionCommand();
201
        if(action.equals(CLOSE)) {
195
        if (action.equals(CLOSE)) {
202
            this.setVisible(false);
196
            this.setVisible(false);
203
        }
197
        }
204
        else if(action.equals(NEXT)) {
198
        else if (action.equals(NEXT)) {
205
            selectedRow++;
199
            selectedRow++;
206
            previousButton.setEnabled(true);
200
            previousButton.setEnabled(true);
207
            nextButton.setEnabled(selectedRow < tableModel.getRowCount()-1);
201
            nextButton.setEnabled(selectedRow < tableModel.getRowCount()-1);
208
            setValues(selectedRow);
202
            setValues(selectedRow);
209
        }
203
        }
210
        else if(action.equals(PREVIOUS)) {
204
        else if (action.equals(PREVIOUS)) {
211
            selectedRow--;
205
            selectedRow--;
212
            nextButton.setEnabled(true);
206
            nextButton.setEnabled(true);
213
            previousButton.setEnabled(selectedRow > 0);
207
            previousButton.setEnabled(selectedRow > 0);
214
            setValues(selectedRow);
208
            setValues(selectedRow);
215
        }
209
        }
216
        else if(action.equals(UPDATE)) {
210
        else if (action.equals(UPDATE)) {
217
            doUpdate(e);
211
            doUpdate(e);
218
        }
212
        }
219
    }
213
    }
Lines 265-269 public class RowDetailDialog extends JDialog implements ActionListener, Document Link Here
265
    public void changedUpdate(DocumentEvent e) {
259
    public void changedUpdate(DocumentEvent e) {
266
        changeLabelButton();
260
        changeLabelButton();
267
    }
261
    }
268
    
262
269
}
263
}
(-)a/src/core/org/apache/jmeter/control/gui/TestPlanGui.java (-10 / +8 lines)
Lines 104-110 public class TestPlanGui extends AbstractJMeterGuiComponent { Link Here
104
        return pop;
104
        return pop;
105
    }
105
    }
106
106
107
    /* Implements JMeterGUIComponent.createTestElement() */
108
    @Override
107
    @Override
109
    public TestElement createTestElement() {
108
    public TestElement createTestElement() {
110
        TestPlan tp = new TestPlan();
109
        TestPlan tp = new TestPlan();
Lines 112-118 public class TestPlanGui extends AbstractJMeterGuiComponent { Link Here
112
        return tp;
111
        return tp;
113
    }
112
    }
114
113
115
    /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
116
    @Override
114
    @Override
117
    public void modifyTestElement(TestElement plan) {
115
    public void modifyTestElement(TestElement plan) {
118
        super.configureTestElement(plan);
116
        super.configureTestElement(plan);
Lines 158-171 public class TestPlanGui extends AbstractJMeterGuiComponent { Link Here
158
        super.configure(el);
156
        super.configure(el);
159
        if (el instanceof TestPlan) {
157
        if (el instanceof TestPlan) {
160
            TestPlan tp = (TestPlan) el;
158
            TestPlan tp = (TestPlan) el;
161
        functionalMode.setSelected(tp.isFunctionalMode());
159
            functionalMode.setSelected(tp.isFunctionalMode());
162
        serializedMode.setSelected(tp.isSerialized());
160
            serializedMode.setSelected(tp.isSerialized());
163
        tearDownOnShutdown.setSelected(tp.isTearDownOnShutdown());
161
            tearDownOnShutdown.setSelected(tp.isTearDownOnShutdown());
164
        final JMeterProperty udv = tp.getUserDefinedVariablesAsProperty();
162
            JMeterProperty udv = tp.getUserDefinedVariablesAsProperty();
165
        if (udv != null) {
163
            if (udv != null) {
166
            argsPanel.configure((Arguments) udv.getObjectValue());
164
                argsPanel.configure((Arguments) udv.getObjectValue());
167
        }
165
            }
168
        browseJar.setFiles(tp.getTestPlanClasspathArray());
166
            browseJar.setFiles(tp.getTestPlanClasspathArray());
169
        }
167
        }
170
    }
168
    }
171
169
(-)a/src/core/org/apache/jmeter/functions/gui/FunctionHelper.java (-12 / +7 lines)
Lines 35-41 import javax.swing.JDialog; Link Here
35
import javax.swing.JFrame;
35
import javax.swing.JFrame;
36
import javax.swing.JPanel;
36
import javax.swing.JPanel;
37
import javax.swing.JRootPane;
37
import javax.swing.JRootPane;
38
import javax.swing.KeyStroke;
39
import javax.swing.event.ChangeEvent;
38
import javax.swing.event.ChangeEvent;
40
import javax.swing.event.ChangeListener;
39
import javax.swing.event.ChangeListener;
41
40
Lines 69-99 public class FunctionHelper extends JDialog implements ActionListener, ChangeLis Link Here
69
        init();
68
        init();
70
        JMeterUtils.addLocaleChangeListener(this);
69
        JMeterUtils.addLocaleChangeListener(this);
71
    }
70
    }
72
    
71
73
    /**
72
    /**
74
     * Allow Dialog to be closed by ESC key
73
     * Allow Dialog to be closed by ESC key
75
     */
74
     */
76
    @Override
75
    @Override
77
    protected JRootPane createRootPane() {
76
    protected JRootPane createRootPane() {
78
        JRootPane rootPane = new JRootPane();
77
        JRootPane rootPane = new JRootPane();
79
        KeyStroke stroke = KeyStrokes.ESC;
78
        Action escapeAction = new AbstractAction("ESCAPE") {
80
        javax.swing.Action escapeAction = new AbstractAction("ESCAPE") { 
81
            /**
82
             * 
83
             */
84
            private static final long serialVersionUID = -4036804004190858925L;
79
            private static final long serialVersionUID = -4036804004190858925L;
85
80
86
            @Override
81
            @Override
87
            public void actionPerformed(ActionEvent actionEvent) { 
82
            public void actionPerformed(ActionEvent actionEvent) {
88
                setVisible(false);
83
                setVisible(false);
89
            } 
84
            }
90
        };
85
        };
91
        rootPane.getActionMap().put(escapeAction.getValue(Action.NAME), escapeAction);
86
        rootPane.getActionMap().put(escapeAction.getValue(Action.NAME), escapeAction);
92
        InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
87
        InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
93
        inputMap.put(stroke, escapeAction.getValue(Action.NAME));
88
        inputMap.put(KeyStrokes.ESC, escapeAction.getValue(Action.NAME));
94
        return rootPane;
89
        return rootPane;
95
    }
90
    }
96
    
91
97
    private void init() {
92
    private void init() {
98
        parameterPanel = new ArgumentsPanel(JMeterUtils.getResString("function_params"), false); //$NON-NLS-1$
93
        parameterPanel = new ArgumentsPanel(JMeterUtils.getResString("function_params"), false); //$NON-NLS-1$
99
        initializeFunctionList();
94
        initializeFunctionList();
Lines 112-118 public class FunctionHelper extends JDialog implements ActionListener, ChangeLis Link Here
112
        generateButton.addActionListener(this);
107
        generateButton.addActionListener(this);
113
        resultsPanel.add(generateButton);
108
        resultsPanel.add(generateButton);
114
        this.getContentPane().add(resultsPanel, BorderLayout.SOUTH);
109
        this.getContentPane().add(resultsPanel, BorderLayout.SOUTH);
115
        
110
116
        this.pack();
111
        this.pack();
117
        ComponentUtil.centerComponentInWindow(this);
112
        ComponentUtil.centerComponentInWindow(this);
118
    }
113
    }
(-)a/src/core/org/apache/jmeter/gui/MainFrame.java (-33 / +26 lines)
Lines 103-128 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
103
103
104
    private static final long serialVersionUID = 240L;
104
    private static final long serialVersionUID = 240L;
105
105
106
    // This is used to keep track of local (non-remote) tests
106
    /** Keeps track of local (non-remote) tests - set to an unlikely hostname. */
107
    // The name is chosen to be an unlikely host-name
108
    public static final String LOCAL = "*local*"; // $NON-NLS-1$
107
    public static final String LOCAL = "*local*"; // $NON-NLS-1$
109
108
110
    // The application name
109
    /** The application name. */
111
    private static final String DEFAULT_APP_NAME = "Apache JMeter"; // $NON-NLS-1$
110
    private static final String DEFAULT_APP_NAME = "Apache JMeter"; // $NON-NLS-1$
112
111
113
    // The default title for the Menu bar
112
    /** The default title for the Menu bar. */
114
    private static final String DEFAULT_TITLE = DEFAULT_APP_NAME +
113
    private static final String DEFAULT_TITLE = DEFAULT_APP_NAME +
115
            " (" + JMeterUtils.getJMeterVersion() + ")"; // $NON-NLS-1$ $NON-NLS-2$
114
            " (" + JMeterUtils.getJMeterVersion() + ")"; // $NON-NLS-1$ $NON-NLS-2$
116
115
117
    // Allow display/hide toolbar
116
    /** Allow display/hide toolbar. */
118
    private static final boolean DISPLAY_TOOLBAR =
117
    private static final boolean DISPLAY_TOOLBAR =
119
            JMeterUtils.getPropDefault("jmeter.toolbar.display", true); // $NON-NLS-1$
118
            JMeterUtils.getPropDefault("jmeter.toolbar.display", true); // $NON-NLS-1$
120
119
121
    // Allow display/hide LoggerPanel
120
    /** Allow display/hide LoggerPanel. */
122
    private static final boolean DISPLAY_LOGGER_PANEL =
121
    private static final boolean DISPLAY_LOGGER_PANEL =
123
            JMeterUtils.getPropDefault("jmeter.loggerpanel.display", false); // $NON-NLS-1$
122
            JMeterUtils.getPropDefault("jmeter.loggerpanel.display", false); // $NON-NLS-1$
124
123
125
    // Allow display/hide Log Error/Fatal counter
124
    /** Allow display/hide Log Error/Fatal counter. */
126
    private static final boolean DISPLAY_ERROR_FATAL_COUNTER =
125
    private static final boolean DISPLAY_ERROR_FATAL_COUNTER =
127
            JMeterUtils.getPropDefault("jmeter.errorscounter.display", true); // $NON-NLS-1$
126
            JMeterUtils.getPropDefault("jmeter.errorscounter.display", true); // $NON-NLS-1$
128
127
Lines 206-212 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
206
        warnIndicator.setContentAreaFilled(false);
205
        warnIndicator.setContentAreaFilled(false);
207
        warnIndicator.setBorderPainted(false);
206
        warnIndicator.setBorderPainted(false);
208
        warnIndicator.setCursor(new Cursor(Cursor.HAND_CURSOR));
207
        warnIndicator.setCursor(new Cursor(Cursor.HAND_CURSOR));
209
        
208
210
        warnIndicator.setToolTipText(JMeterUtils.getResString("error_indicator_tooltip")); // $NON-NLS-1$
209
        warnIndicator.setToolTipText(JMeterUtils.getResString("error_indicator_tooltip")); // $NON-NLS-1$
211
        warnIndicator.addActionListener(this);
210
        warnIndicator.addActionListener(this);
212
        errorsOrFatalsLabel = new JLabel("0"); // $NON-NLS-1$
211
        errorsOrFatalsLabel = new JLabel("0"); // $NON-NLS-1$
Lines 318-327 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
318
     */
317
     */
319
    public void closeMenu() {
318
    public void closeMenu() {
320
        if (menuBar.isSelected()) {
319
        if (menuBar.isSelected()) {
321
            MenuElement[] menuElement = menuBar.getSubElements();
320
            MenuElement[] menuElements = menuBar.getSubElements();
322
            if (menuElement != null) {
321
            if (menuElements != null) {
323
                for (int i = 0; i < menuElement.length; i++) {
322
                for (MenuElement menuElement : menuElements) {
324
                    JMenu menu = (JMenu) menuElement[i];
323
                    JMenu menu = (JMenu) menuElement;
325
                    if (menu.isSelected()) {
324
                    if (menu.isSelected()) {
326
                        menu.setPopupMenuVisible(false);
325
                        menu.setPopupMenuVisible(false);
327
                        menu.setSelected(false);
326
                        menu.setSelected(false);
Lines 345-354 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
345
        }
344
        }
346
        stoppingMessage = new EscapeDialog(this, JMeterUtils.getResString("stopping_test_title"), true); //$NON-NLS-1$
345
        stoppingMessage = new EscapeDialog(this, JMeterUtils.getResString("stopping_test_title"), true); //$NON-NLS-1$
347
        String label = JMeterUtils.getResString("stopping_test"); //$NON-NLS-1
346
        String label = JMeterUtils.getResString("stopping_test"); //$NON-NLS-1
348
        if(!StringUtils.isEmpty(host)) {
347
        if (!StringUtils.isEmpty(host)) {
349
            label = label + JMeterUtils.getResString("stopping_test_host")+ ": " + host;
348
            label = label + JMeterUtils.getResString("stopping_test_host")+ ": " + host;
350
        }
349
        }
351
        JLabel stopLabel = new JLabel(label); //$NON-NLS-1$$NON-NLS-2$
350
        JLabel stopLabel = new JLabel(label);
352
        stopLabel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
351
        stopLabel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
353
        stoppingMessage.getContentPane().add(stopLabel);
352
        stoppingMessage.getContentPane().add(stopLabel);
354
        stoppingMessage.pack();
353
        stoppingMessage.pack();
Lines 356-362 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
356
        SwingUtilities.invokeLater(new Runnable() {
355
        SwingUtilities.invokeLater(new Runnable() {
357
            @Override
356
            @Override
358
            public void run() {
357
            public void run() {
359
                if (stoppingMessage != null) {// TODO - how can this be null?
358
                if (stoppingMessage != null) { // TODO - how can this be null?
360
                    stoppingMessage.setVisible(true);
359
                    stoppingMessage.setVisible(true);
361
                }
360
                }
362
            }
361
            }
Lines 409-415 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
409
        activeThreads.setText("0"); // $NON-NLS-1$
408
        activeThreads.setText("0"); // $NON-NLS-1$
410
        totalThreads.setText("0"); // $NON-NLS-1$
409
        totalThreads.setText("0"); // $NON-NLS-1$
411
        menuBar.setRunning(true, host);
410
        menuBar.setRunning(true, host);
412
        if(LOCAL.equals(host)) {
411
        if (LOCAL.equals(host)) {
413
            toolbar.setLocalTestStarted(true);
412
            toolbar.setLocalTestStarted(true);
414
        } else {
413
        } else {
415
            toolbar.setRemoteTestStarted(true);
414
            toolbar.setRemoteTestStarted(true);
Lines 442-448 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
442
            JMeterContextService.endTest();
441
            JMeterContextService.endTest();
443
        }
442
        }
444
        menuBar.setRunning(false, host);
443
        menuBar.setRunning(false, host);
445
        if(LOCAL.equals(host)) {
444
        if (LOCAL.equals(host)) {
446
            toolbar.setLocalTestStarted(false);
445
            toolbar.setLocalTestStarted(false);
447
        } else {
446
        } else {
448
            toolbar.setRemoteTestStarted(false);
447
            toolbar.setRemoteTestStarted(false);
Lines 486-494 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
486
                errorsAndFatalsCounterLogTarget
485
                errorsAndFatalsCounterLogTarget
487
                 });
486
                 });
488
        } else {
487
        } else {
489
            LoggingManager.addLogTargetToRootLogger(new LogTarget[]{
488
            LoggingManager.addLogTargetToRootLogger(new LogTarget[]{ logPanel });
490
                    logPanel
491
                     });
492
        }
489
        }
493
490
494
        topAndDown.setTopComponent(mainPanel);
491
        topAndDown.setTopComponent(mainPanel);
Lines 640-646 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
640
        treevar.addTreeSelectionListener(treeListener);
637
        treevar.addTreeSelectionListener(treeListener);
641
        treevar.addMouseListener(treeListener);
638
        treevar.addMouseListener(treeListener);
642
        treevar.addKeyListener(treeListener);
639
        treevar.addKeyListener(treeListener);
643
        
640
644
        // enable drag&drop, install a custom transfer handler
641
        // enable drag&drop, install a custom transfer handler
645
        treevar.setDragEnabled(true);
642
        treevar.setDragEnabled(true);
646
        treevar.setDropMode(DropMode.ON_OR_INSERT);
643
        treevar.setDropMode(DropMode.ON_OR_INSERT);
Lines 701-709 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
701
        try {
698
        try {
702
            Transferable tr = dtde.getTransferable();
699
            Transferable tr = dtde.getTransferable();
703
            DataFlavor[] flavors = tr.getTransferDataFlavors();
700
            DataFlavor[] flavors = tr.getTransferDataFlavors();
704
            for (int i = 0; i < flavors.length; i++) {
701
            for (DataFlavor flavor: flavors) {
705
                // Check for file lists specifically
702
                // Check for file lists specifically
706
                if (flavors[i].isFlavorJavaFileListType()) {
703
                if (flavor.isFlavorJavaFileListType()) {
707
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
704
                    dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
708
                    try {
705
                    try {
709
                        openJmxFilesFromDragAndDrop(tr);
706
                        openJmxFilesFromDragAndDrop(tr);
Lines 718-742 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
718
        } catch (IOException e) {
715
        } catch (IOException e) {
719
            log.warn("Dnd failed" , e);
716
            log.warn("Dnd failed" , e);
720
        }
717
        }
721
722
    }
718
    }
723
719
724
    public boolean openJmxFilesFromDragAndDrop(Transferable tr) throws UnsupportedFlavorException, IOException {
720
    public boolean openJmxFilesFromDragAndDrop(Transferable tr) throws UnsupportedFlavorException, IOException {
725
        @SuppressWarnings("unchecked")
721
        @SuppressWarnings("unchecked")
726
        List<File> files = (List<File>)
722
        List<File> files = (List<File>)
727
                tr.getTransferData(DataFlavor.javaFileListFlavor);
723
                tr.getTransferData(DataFlavor.javaFileListFlavor);
728
        if(files.isEmpty()) {
724
        if (files.isEmpty()) {
729
            return false;
725
            return false;
730
        }
726
        }
731
        File file = files.get(0);
727
        File file = files.get(0);
732
        if(!file.getName().endsWith(".jmx")) {
728
        if (!file.getName().endsWith(".jmx")) {
733
            log.warn("Importing file:" + file.getName()+ "from DnD failed because file extension does not end with .jmx");
729
            log.warn("Importing file:" + file.getName()+ "from DnD failed because file extension does not end with .jmx");
734
            return false;
730
            return false;
735
        }
731
        }
736
732
737
        ActionEvent fakeEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ActionNames.OPEN);
733
        ActionEvent fakeEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ActionNames.OPEN);
738
        LoadDraggedFile.loadProject(fakeEvent, file);
734
        LoadDraggedFile.loadProject(fakeEvent, file);
739
        
735
740
        return true;
736
        return true;
741
    }
737
    }
742
738
Lines 745-759 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
745
        // NOOP
741
        // NOOP
746
    }
742
    }
747
743
748
    /**
749
     *
750
     */
751
    public final class ErrorsAndFatalsCounterLogTarget implements LogTarget, Clearable {
744
    public final class ErrorsAndFatalsCounterLogTarget implements LogTarget, Clearable {
752
        public AtomicInteger errorOrFatal = new AtomicInteger(0);
745
        public AtomicInteger errorOrFatal = new AtomicInteger(0);
753
746
754
        @Override
747
        @Override
755
        public void processEvent(LogEvent event) {
748
        public void processEvent(LogEvent event) {
756
            if(event.getPriority().equals(Priority.ERROR) ||
749
            if (event.getPriority().equals(Priority.ERROR) ||
757
                    event.getPriority().equals(Priority.FATAL_ERROR)) {
750
                    event.getPriority().equals(Priority.FATAL_ERROR)) {
758
                final int newValue = errorOrFatal.incrementAndGet();
751
                final int newValue = errorOrFatal.incrementAndGet();
759
                SwingUtilities.invokeLater(new Runnable() {
752
                SwingUtilities.invokeLater(new Runnable() {
Lines 781-787 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
781
    @Override
774
    @Override
782
    public void clearData() {
775
    public void clearData() {
783
        logPanel.clear();
776
        logPanel.clear();
784
        if(DISPLAY_ERROR_FATAL_COUNTER) {
777
        if (DISPLAY_ERROR_FATAL_COUNTER) {
785
            errorsAndFatalsCounterLogTarget.clearData();
778
            errorsAndFatalsCounterLogTarget.clearData();
786
        }
779
        }
787
    }
780
    }
Lines 791-797 public class MainFrame extends JFrame implements TestStateListener, Remoteable, Link Here
791
     */
784
     */
792
    @Override
785
    @Override
793
    public void actionPerformed(ActionEvent event) {
786
    public void actionPerformed(ActionEvent event) {
794
        if(event.getSource()==warnIndicator) {
787
        if (event.getSource() == warnIndicator) {
795
            ActionRouter.getInstance().doActionNow(new ActionEvent(event.getSource(), event.getID(), ActionNames.LOGGER_PANEL_ENABLE_DISABLE));
788
            ActionRouter.getInstance().doActionNow(new ActionEvent(event.getSource(), event.getID(), ActionNames.LOGGER_PANEL_ENABLE_DISABLE));
796
        }
789
        }
797
    }
790
    }
(-)a/src/core/org/apache/jmeter/gui/action/AboutCommand.java (-5 / +4 lines)
Lines 80-86 public class AboutCommand implements Command { Link Here
80
80
81
    /**
81
    /**
82
     * Called by about button. Raises about dialog. Currently the about box has
82
     * Called by about button. Raises about dialog. Currently the about box has
83
     * the product image and the copyright notice. The dialog box is centered
83
     * the product image and the copyright notice. The dialog box is centred
84
     * over the MainFrame.
84
     * over the MainFrame.
85
     */
85
     */
86
    void about() {
86
    void about() {
Lines 112-121 public class AboutCommand implements Command { Link Here
112
            panel.add(infos, BorderLayout.SOUTH);
112
            panel.add(infos, BorderLayout.SOUTH);
113
        }
113
        }
114
114
115
        // NOTE: these lines center the about dialog in the
115
        // NOTE: these lines centre the about dialog in the current window.
116
        // current window. Some older Swing versions have
116
        // Some older Swing versions have a bug in getLocationOnScreen() and
117
        // a bug in getLocationOnScreen() and they may not
117
        // they may not make this behave properly.
118
        // make this behave properly.
119
        Point p = mainFrame.getLocationOnScreen();
118
        Point p = mainFrame.getLocationOnScreen();
120
        Dimension d1 = mainFrame.getSize();
119
        Dimension d1 = mainFrame.getSize();
121
        Dimension d2 = about.getSize();
120
        Dimension d2 = about.getSize();
(-)a/src/core/org/apache/jmeter/gui/action/ActionNames.java (-3 / +2 lines)
Lines 18-27 Link Here
18
18
19
package org.apache.jmeter.gui.action;
19
package org.apache.jmeter.gui.action;
20
20
21
/*
21
/**
22
 * Collect all the action names together in one place.
22
 * Collect all the action names together in one place.
23
 * This helps to ensure that there are no duplicates
23
 * This helps to ensure that there are no duplicates.
24
 *
25
 *
24
 *
26
 */
25
 */
27
public final class ActionNames {
26
public final class ActionNames {
(-)a/src/core/org/apache/jmeter/gui/action/AddToTree.java (-3 / +2 lines)
Lines 45-51 public class AddToTree implements Command { Link Here
45
        commandSet = Collections.unmodifiableSet(commands);
45
        commandSet = Collections.unmodifiableSet(commands);
46
    }
46
    }
47
47
48
49
    public AddToTree() {
48
    public AddToTree() {
50
    }
49
    }
51
50
Lines 76-82 public class AddToTree implements Command { Link Here
76
            log.error("", err); // $NON-NLS-1$
75
            log.error("", err); // $NON-NLS-1$
77
            String msg = err.getMessage();
76
            String msg = err.getMessage();
78
            if (msg == null) {
77
            if (msg == null) {
79
                msg=err.toString();
78
                msg = err.toString();
80
            }
79
            }
81
            JMeterUtils.reportErrorToUser(msg);
80
            JMeterUtils.reportErrorToUser(msg);
82
        }
81
        }
Lines 84-90 public class AddToTree implements Command { Link Here
84
            log.error("", err); // $NON-NLS-1$
83
            log.error("", err); // $NON-NLS-1$
85
            String msg = err.getMessage();
84
            String msg = err.getMessage();
86
            if (msg == null) {
85
            if (msg == null) {
87
                msg=err.toString();
86
                msg = err.toString();
88
            }
87
            }
89
            JMeterUtils.reportErrorToUser(msg);
88
            JMeterUtils.reportErrorToUser(msg);
90
        }
89
        }
(-)a/src/core/org/apache/jmeter/gui/action/Load.java (-22 / +22 lines)
Lines 81-90 public class Load implements Command { Link Here
81
            return;
81
            return;
82
        }
82
        }
83
        final File selectedFile = chooser.getSelectedFile();
83
        final File selectedFile = chooser.getSelectedFile();
84
        if(selectedFile != null) {
84
        if (selectedFile != null) {
85
            final boolean merging = e.getActionCommand().equals(ActionNames.MERGE);
85
            final boolean merging = e.getActionCommand().equals(ActionNames.MERGE);
86
            // We must ask the user if it is ok to close current project
86
            // We must ask the user if it is ok to close current project
87
            if(!merging) { // i.e. it is OPEN
87
            if (!merging) { // i.e. it is OPEN
88
                if (!Close.performAction(e)) {
88
                if (!Close.performAction(e)) {
89
                    return;
89
                    return;
90
                }
90
                }
Lines 121-145 public class Load implements Command { Link Here
121
        if (f != null) {
121
        if (f != null) {
122
            InputStream reader = null;
122
            InputStream reader = null;
123
            try {
123
            try {
124
                    if (merging) {
124
                if (merging) {
125
                        log.info("Merging file: " + f);
125
                    log.info("Merging file: " + f);
126
                    } else {
126
                } else {
127
                        log.info("Loading file: " + f);
127
                    log.info("Loading file: " + f);
128
                        // TODO should this be done even if not a full test plan?
128
                    // TODO should this be done even if not a full test plan?
129
                        // and what if load fails?
129
                    // and what if load fails?
130
                        if(setDetails) {
130
                    if(setDetails) {
131
                            FileServer.getFileServer().setBaseForScript(f);
131
                        FileServer.getFileServer().setBaseForScript(f);
132
                        }
133
                    }
134
                    reader = new FileInputStream(f);
135
                    final HashTree tree = SaveService.loadTree(reader);
136
                    final boolean isTestPlan = insertLoadedTree(e.getID(), tree, merging);
137
    
138
                    // don't change name if merging
139
                    if (!merging && isTestPlan && setDetails) {
140
                        // TODO should setBaseForScript be called here rather than above?
141
                        guiPackage.setTestPlanFile(f.getAbsolutePath());
142
                    }
132
                    }
133
                }
134
                reader = new FileInputStream(f);
135
                final HashTree tree = SaveService.loadTree(reader);
136
                final boolean isTestPlan = insertLoadedTree(e.getID(), tree, merging);
137
138
                // don't change name if merging
139
                if (!merging && isTestPlan && setDetails) {
140
                    // TODO should setBaseForScript be called here rather than above?
141
                    guiPackage.setTestPlanFile(f.getAbsolutePath());
142
                }
143
            } catch (NoClassDefFoundError ex) {// Allow for missing optional jars
143
            } catch (NoClassDefFoundError ex) {// Allow for missing optional jars
144
                reportError("Missing jar file", ex, true);
144
                reportError("Missing jar file", ex, true);
145
            } catch (ConversionException ex) {
145
            } catch (ConversionException ex) {
Lines 203-210 public class Load implements Command { Link Here
203
        // Send different event wether we are merging a test plan into another test plan,
203
        // Send different event wether we are merging a test plan into another test plan,
204
        // or loading a testplan from scratch
204
        // or loading a testplan from scratch
205
        ActionEvent actionEvent =
205
        ActionEvent actionEvent =
206
            new ActionEvent(subTree.get(subTree.getArray()[subTree.size() - 1]), id, 
206
                new ActionEvent(subTree.get(subTree.getArray()[subTree.size() - 1]), id,
207
                    merging ? ActionNames.SUB_TREE_MERGED : ActionNames.SUB_TREE_LOADED);
207
                        merging ? ActionNames.SUB_TREE_MERGED : ActionNames.SUB_TREE_LOADED);
208
208
209
        ActionRouter.getInstance().actionPerformed(actionEvent);
209
        ActionRouter.getInstance().actionPerformed(actionEvent);
210
        final JTree jTree = guiInstance.getMainFrame().getTree();
210
        final JTree jTree = guiInstance.getMainFrame().getTree();
(-)a/src/core/org/apache/jmeter/gui/action/SearchTreeDialog.java (-14 / +5 lines)
Lines 59-67 import org.apache.log.Logger; Link Here
59
 * FIXME Why is searchTF not getting focus correctly after having been setVisible(false) once
59
 * FIXME Why is searchTF not getting focus correctly after having been setVisible(false) once
60
 */
60
 */
61
public class SearchTreeDialog extends JDialog implements ActionListener {
61
public class SearchTreeDialog extends JDialog implements ActionListener {
62
    /**
63
     *
64
     */
65
    private static final long serialVersionUID = -4436834972710248247L;
62
    private static final long serialVersionUID = -4436834972710248247L;
66
63
67
    private static final Logger logger = LoggingManager.getLoggerForClass();
64
    private static final Logger logger = LoggingManager.getLoggerForClass();
Lines 93-101 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
93
        JRootPane rootPane = new JRootPane();
90
        JRootPane rootPane = new JRootPane();
94
        // Hide Window on ESC
91
        // Hide Window on ESC
95
        Action escapeAction = new AbstractAction("ESCAPE") {
92
        Action escapeAction = new AbstractAction("ESCAPE") {
96
            /**
97
             *
98
             */
99
            private static final long serialVersionUID = -6543764044868772971L;
93
            private static final long serialVersionUID = -6543764044868772971L;
100
94
101
            @Override
95
            @Override
Lines 105-113 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
105
        };
99
        };
106
        // Do search on Enter
100
        // Do search on Enter
107
        Action enterAction = new AbstractAction("ENTER") {
101
        Action enterAction = new AbstractAction("ENTER") {
108
            /**
109
             *
110
             */
111
            private static final long serialVersionUID = -3661361497864527363L;
102
            private static final long serialVersionUID = -3661361497864527363L;
112
103
113
            @Override
104
            @Override
Lines 129-135 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
129
        this.getContentPane().setLayout(new BorderLayout(10,10));
120
        this.getContentPane().setLayout(new BorderLayout(10,10));
130
121
131
        searchTF = new JLabeledTextField(JMeterUtils.getResString("search_text_field"), 20); //$NON-NLS-1$
122
        searchTF = new JLabeledTextField(JMeterUtils.getResString("search_text_field"), 20); //$NON-NLS-1$
132
        if(!StringUtils.isEmpty(lastSearch)) {
123
        if (!StringUtils.isEmpty(lastSearch)) {
133
            searchTF.setText(lastSearch);
124
            searchTF.setText(lastSearch);
134
        }
125
        }
135
        isRegexpCB = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_regexp"), false); //$NON-NLS-1$
126
        isRegexpCB = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_regexp"), false); //$NON-NLS-1$
Lines 172-178 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
172
     */
163
     */
173
    @Override
164
    @Override
174
    public void actionPerformed(ActionEvent e) {
165
    public void actionPerformed(ActionEvent e) {
175
        if(e.getSource()==cancelButton) {
166
        if (e.getSource() == cancelButton) {
176
            searchTF.requestFocusInWindow();
167
            searchTF.requestFocusInWindow();
177
            this.setVisible(false);
168
            this.setVisible(false);
178
            return;
169
            return;
Lines 186-192 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
186
    private void doSearch(ActionEvent e) {
177
    private void doSearch(ActionEvent e) {
187
        boolean expand = e.getSource()==searchAndExpandButton;
178
        boolean expand = e.getSource()==searchAndExpandButton;
188
        String wordToSearch = searchTF.getText();
179
        String wordToSearch = searchTF.getText();
189
        if(StringUtils.isEmpty(wordToSearch)) {
180
        if (StringUtils.isEmpty(wordToSearch)) {
190
            return;
181
            return;
191
        } else {
182
        } else {
192
            this.lastSearch = wordToSearch;
183
            this.lastSearch = wordToSearch;
Lines 196-202 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
196
        ActionRouter.getInstance().doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.SEARCH_RESET));
187
        ActionRouter.getInstance().doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.SEARCH_RESET));
197
        // do search
188
        // do search
198
        Searcher searcher = null;
189
        Searcher searcher = null;
199
        if(isRegexpCB.isSelected()) {
190
        if (isRegexpCB.isSelected()) {
200
            searcher = new RegexpSearcher(isCaseSensitiveCB.isSelected(), searchTF.getText());
191
            searcher = new RegexpSearcher(isCaseSensitiveCB.isSelected(), searchTF.getText());
201
        } else {
192
        } else {
202
            searcher = new RawTextSearcher(isCaseSensitiveCB.isSelected(), searchTF.getText());
193
            searcher = new RawTextSearcher(isCaseSensitiveCB.isSelected(), searchTF.getText());
Lines 211-217 public class SearchTreeDialog extends JDialog implements ActionListener { Link Here
211
                    List<JMeterTreeNode> matchingNodes = jMeterTreeNode.getPathToThreadGroup();
202
                    List<JMeterTreeNode> matchingNodes = jMeterTreeNode.getPathToThreadGroup();
212
                    List<String> searchableTokens = searchable.getSearchableTokens();
203
                    List<String> searchableTokens = searchable.getSearchableTokens();
213
                    boolean result = searcher.search(searchableTokens);
204
                    boolean result = searcher.search(searchableTokens);
214
                    if(result) {
205
                    if (result) {
215
                        nodes.addAll(matchingNodes);
206
                        nodes.addAll(matchingNodes);
216
                    }
207
                    }
217
                }
208
                }
(-)a/src/core/org/apache/jmeter/gui/tree/JMeterTreeModel.java (-7 / +1 lines)
Lines 48-56 public class JMeterTreeModel extends DefaultTreeModel { Link Here
48
48
49
    public JMeterTreeModel() {
49
    public JMeterTreeModel() {
50
        this(new TestPlanGui().createTestElement(),new WorkBenchGui().createTestElement());
50
        this(new TestPlanGui().createTestElement(),new WorkBenchGui().createTestElement());
51
//        super(new JMeterTreeNode(new WorkBenchGui().createTestElement(), null));
52
//        TestElement tp = new TestPlanGui().createTestElement();
53
//        initTree(tp);
54
    }
51
    }
55
52
56
    /**
53
    /**
Lines 62-70 public class JMeterTreeModel extends DefaultTreeModel { Link Here
62
    @Deprecated
59
    @Deprecated
63
    public JMeterTreeModel(Object o) {
60
    public JMeterTreeModel(Object o) {
64
        this(new TestPlan(),new WorkBench());
61
        this(new TestPlan(),new WorkBench());
65
//      super(new JMeterTreeNode(new WorkBench(), null));
66
//      TestElement tp = new TestPlan();
67
//      initTree(tp, new WorkBench());
68
    }
62
    }
69
63
70
    /**
64
    /**
Lines 135-141 public class JMeterTreeModel extends DefaultTreeModel { Link Here
135
        // disable the loaded node
129
        // disable the loaded node
136
        try {
130
        try {
137
            newNode.setEnabled(component.isEnabled());
131
            newNode.setEnabled(component.isEnabled());
138
        } catch (Exception e) { // TODO - can this eever happen?
132
        } catch (Exception e) { // TODO - can this ever happen?
139
            newNode.setEnabled(true);
133
            newNode.setEnabled(true);
140
        }
134
        }
141
135
(-)a/src/core/org/apache/jmeter/gui/tree/JMeterTreeNode.java (-3 / +3 lines)
Lines 70-76 public class JMeterTreeNode extends DefaultMutableTreeNode implements NamedTreeN Link Here
70
        getTestElement().setEnabled(enabled);
70
        getTestElement().setEnabled(enabled);
71
        treeModel.nodeChanged(this);
71
        treeModel.nodeChanged(this);
72
    }
72
    }
73
    
73
74
    /**
74
    /**
75
     * Return nodes to level 2
75
     * Return nodes to level 2
76
     * @return {@link List}<JMeterTreeNode>
76
     * @return {@link List}<JMeterTreeNode>
Lines 91-97 public class JMeterTreeNode extends DefaultMutableTreeNode implements NamedTreeN Link Here
91
        }
91
        }
92
        return nodes;
92
        return nodes;
93
    }
93
    }
94
    
94
95
    /**
95
    /**
96
     * Tag Node as result of a search
96
     * Tag Node as result of a search
97
     */
97
     */
Lines 99-105 public class JMeterTreeNode extends DefaultMutableTreeNode implements NamedTreeN Link Here
99
        this.markedBySearch = tagged;
99
        this.markedBySearch = tagged;
100
        treeModel.nodeChanged(this);
100
        treeModel.nodeChanged(this);
101
    }
101
    }
102
    
102
103
    /**
103
    /**
104
     * Node is markedBySearch by a search
104
     * Node is markedBySearch by a search
105
     * @return true if marked by search
105
     * @return true if marked by search
(-)a/src/protocol/http/org/apache/jmeter/protocol/http/sampler/AccessLogSampler.java (-54 / +41 lines)
Lines 35-41 import org.apache.log.Logger; Link Here
35
 * Description: <br>
35
 * Description: <br>
36
 * <br>
36
 * <br>
37
 * AccessLogSampler is responsible for a couple of things:
37
 * AccessLogSampler is responsible for a couple of things:
38
 * <p>
39
 * <ul>
38
 * <ul>
40
 * <li>creating instances of Generator
39
 * <li>creating instances of Generator
41
 * <li>creating instances of Parser
40
 * <li>creating instances of Parser
Lines 49-59 import org.apache.log.Logger; Link Here
49
 * the logs. It also doesn't care how Generator is implemented, as long as it
48
 * the logs. It also doesn't care how Generator is implemented, as long as it
50
 * implements the interface. This means a person could simply implement a dummy
49
 * implements the interface. This means a person could simply implement a dummy
51
 * parser to generate random parameters and the generator consumes the results.
50
 * parser to generate random parameters and the generator consumes the results.
52
 * This wasn't the original intent of the sampler. I originaly wanted to write
51
 * This wasn't the original intent of the sampler. I originally wanted to write
53
 * this sampler, so that I can take production logs to simulate production
52
 * this sampler, so that I can take production logs to simulate production
54
 * traffic in a test environment. Doing so is desirable to study odd or unusual
53
 * traffic in a test environment. Doing so is desirable to study odd or unusual
55
 * behavior. It's also good to compare a new system against an existing system
54
 * behavior. It's also good to compare a new system against an existing system
56
 * to get near apples- to-apples comparison. I've been asked if benchmarks are
55
 * to get near apples-to-apples comparison. I've been asked if benchmarks are
57
 * really fair comparisons just about every single time, so this helps me
56
 * really fair comparisons just about every single time, so this helps me
58
 * accomplish that task.
57
 * accomplish that task.
59
 * <p>
58
 * <p>
Lines 71-80 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
71
70
72
    public static final String DEFAULT_CLASS = "org.apache.jmeter.protocol.http.util.accesslog.TCLogParser"; // $NON-NLS-1$
71
    public static final String DEFAULT_CLASS = "org.apache.jmeter.protocol.http.util.accesslog.TCLogParser"; // $NON-NLS-1$
73
72
74
    /** private members used by class * */
73
    /** private members used by class */
75
    private transient LogParser PARSER = null;
74
    private transient LogParser parser = null;
76
75
77
    // NOTUSED private Class PARSERCLASS = null;
78
    private String logFile, parserClassName, filterClassName;
76
    private String logFile, parserClassName, filterClassName;
79
77
80
    private transient Filter filter;
78
    private transient Filter filter;
Lines 83-91 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
83
81
84
    private boolean started = false;
82
    private boolean started = false;
85
83
86
    /**
84
    /** Set the path where XML messages are stored for random selection. */
87
     * Set the path where XML messages are stored for random selection.
88
     */
89
    public void setLogFile(String path) {
85
    public void setLogFile(String path) {
90
        logFile = path;
86
        logFile = path;
91
    }
87
    }
Lines 99-106 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
99
    }
95
    }
100
96
101
    /**
97
    /**
102
     * it's kinda obvious, but we state it anyways. Set the xml file with a
98
     * Set the xml file with a String classpath.
103
     * string path.
104
     *
99
     *
105
     * @param classname -
100
     * @param classname -
106
     *            parser class name
101
     *            parser class name
Lines 119-126 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
119
    }
114
    }
120
115
121
    /**
116
    /**
122
     * sample gets a new HTTPSampler from the generator and calls it's sample()
117
     * This gets a new HTTPSampler from the generator and calls .sample()
123
     * method.
124
     */
118
     */
125
    public SampleResult sampleWithParser() {
119
    public SampleResult sampleWithParser() {
126
        initFilter();
120
        initFilter();
Lines 128-149 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
128
        SampleResult res = null;
122
        SampleResult res = null;
129
        try {
123
        try {
130
124
131
            if (PARSER == null) {
125
            if (parser == null) {
132
                throw new JMeterException("No Parser available");
126
                throw new JMeterException("No Parser available");
133
            }
127
            }
134
            /*
128
           /* we call parse with 1 to get only one. If we  change the
135
             * samp.setDomain(this.getDomain()); samp.setPort(this.getPort());
129
            * implementation to use 2, it would use every other entry and so on.
136
             */
130
            * It could use it that way if they have a huge (gigabyte)
137
            // we call parse with 1 to get only one.
131
            * log file and they only want to use a proportion of the entries.
138
            // this also means if we change the implementation
132
            */
139
            // to use 2, it would use every other entry and
133
            final int thisCount = parser.parseAndConfigure(1, this);
140
            // so on. Not that it is really useful, but a
134
            if (thisCount < 0) {
141
            // person could use it that way if they have a
142
            // huge gigabyte log file and they only want to
143
            // use a quarter of the entries.
144
            int thisCount = PARSER.parseAndConfigure(1, this);
145
            if (thisCount < 0) // Was there an error?
146
            {
147
                return errorResult(new Error("Problem parsing the log file"), new HTTPSampleResult());
135
                return errorResult(new Error("Problem parsing the log file"), new HTTPSampleResult());
148
            }
136
            }
149
            if (thisCount == 0) {
137
            if (thisCount == 0) {
Lines 154-160 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
154
                if (filter != null) {
142
                if (filter != null) {
155
                    filter.reset();
143
                    filter.reset();
156
                }
144
                }
157
                CookieManager cm = getCookieManager();
145
                final CookieManager cm = getCookieManager();
158
                if (cm != null) {
146
                if (cm != null) {
159
                    cm.clear();
147
                    cm.clear();
160
                }
148
                }
Lines 164-170 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
164
            count = thisCount;
152
            count = thisCount;
165
            res = sample();
153
            res = sample();
166
            res.setSampleLabel(toString());
154
            res.setSampleLabel(toString());
167
        } catch (Exception e) {
155
        } catch (final Exception e) {
168
            log.warn("Sampling failure", e);
156
            log.warn("Sampling failure", e);
169
            return errorResult(e, new HTTPSampleResult());
157
            return errorResult(e, new HTTPSampleResult());
170
        }
158
        }
Lines 184-210 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
184
    }
172
    }
185
173
186
    /**
174
    /**
187
     * Method will instantiate the log parser based on the class in the text
175
     * Instantiates the log parser based on the class in the text field.
188
     * field. This was done to make it easier for people to plugin their own log
176
     * This was done to make it easier for people to use their own parser.
189
     * parser and use different log parser.
190
     */
177
     */
191
    public void instantiateParser() {
178
    public void instantiateParser() {
192
        if (PARSER == null) {
179
        if (parser == null) {
193
            try {
180
            try {
194
                if (this.getParserClassName() != null && this.getParserClassName().length() > 0) {
181
                if (this.getParserClassName() != null && this.getParserClassName().length() > 0) {
195
                    if (this.getLogFile() != null && this.getLogFile().length() > 0) {
182
                    if (this.getLogFile() != null && this.getLogFile().length() > 0) {
196
                        PARSER = (LogParser) Class.forName(getParserClassName()).newInstance();
183
                        parser = (LogParser) Class.forName(getParserClassName()).newInstance();
197
                        PARSER.setSourceFile(this.getLogFile());
184
                        parser.setSourceFile(this.getLogFile());
198
                        PARSER.setFilter(filter);
185
                        parser.setFilter(filter);
199
                    } else {
186
                    } else {
200
                        log.error("No log file specified");
187
                        log.error("No log file specified");
201
                    }
188
                    }
202
                }
189
                }
203
            } catch (InstantiationException e) {
190
            } catch (final InstantiationException e) {
204
                log.error("", e);
191
                log.error("", e);
205
            } catch (IllegalAccessException e) {
192
            } catch (final IllegalAccessException e) {
206
                log.error("", e);
193
                log.error("", e);
207
            } catch (ClassNotFoundException e) {
194
            } catch (final ClassNotFoundException e) {
208
                log.error("", e);
195
                log.error("", e);
209
            }
196
            }
210
        }
197
        }
Lines 229-235 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
229
     * @return Returns the domain.
216
     * @return Returns the domain.
230
     */
217
     */
231
    @Override
218
    @Override
232
    public String getDomain() { // N.B. Must be in this class for the TestBean code to work
219
    public String getDomain() { // N.B. Required for the TestBean code
233
        return super.getDomain();
220
        return super.getDomain();
234
    }
221
    }
235
222
Lines 238-244 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
238
     *            The domain to set.
225
     *            The domain to set.
239
     */
226
     */
240
    @Override
227
    @Override
241
    public void setDomain(String domain) { // N.B. Must be in this class for the TestBean code to work
228
    public void setDomain(String domain) { // N.B. Required for the TestBean code
242
        super.setDomain(domain);
229
        super.setDomain(domain);
243
    }
230
    }
244
231
Lines 273-279 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
273
    }
260
    }
274
261
275
    /**
262
    /**
276
     *
263
     * Default constructor.
277
     */
264
     */
278
    public AccessLogSampler() {
265
    public AccessLogSampler() {
279
        super();
266
        super();
Lines 283-289 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
283
        if (filter == null && filterClassName != null && filterClassName.length() > 0) {
270
        if (filter == null && filterClassName != null && filterClassName.length() > 0) {
284
            try {
271
            try {
285
                filter = (Filter) Class.forName(filterClassName).newInstance();
272
                filter = (Filter) Class.forName(filterClassName).newInstance();
286
            } catch (Exception e) {
273
            } catch (final Exception e) {
287
                log.warn("Couldn't instantiate filter '" + filterClassName + "'", e);
274
                log.warn("Couldn't instantiate filter '" + filterClassName + "'", e);
288
            }
275
            }
289
        }
276
        }
Lines 294-300 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
294
     */
281
     */
295
    @Override
282
    @Override
296
    public Object clone() {
283
    public Object clone() {
297
        AccessLogSampler s = (AccessLogSampler) super.clone();
284
        final AccessLogSampler s = (AccessLogSampler) super.clone();
298
        if (started) {
285
        if (started) {
299
            if (filterClassName != null && filterClassName.length() > 0) {
286
            if (filterClassName != null && filterClassName.length() > 0) {
300
287
Lines 303-318 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
303
                        initFilter();
290
                        initFilter();
304
                        s.filter = (Filter) ((TestCloneable) filter).clone();
291
                        s.filter = (Filter) ((TestCloneable) filter).clone();
305
                    }
292
                    }
306
                    if(TestCloneable.class.isAssignableFrom(Class.forName(parserClassName)))
293
                    if (TestCloneable.class.isAssignableFrom(Class.forName(parserClassName)))
307
                    {
294
                    {
308
                        instantiateParser();
295
                        instantiateParser();
309
                        s.PARSER = (LogParser)((TestCloneable)PARSER).clone();
296
                        s.parser = (LogParser)((TestCloneable)parser).clone();
310
                        if(filter != null)
297
                        if (filter != null)
311
                        {
298
                        {
312
                            s.PARSER.setFilter(s.filter);
299
                            s.parser.setFilter(s.filter);
313
                        }
300
                        }
314
                    }
301
                    }
315
                } catch (Exception e) {
302
                } catch (final Exception e) {
316
                    log.warn("Could not clone cloneable filter", e);
303
                    log.warn("Could not clone cloneable filter", e);
317
                }
304
                }
318
            }
305
            }
Lines 325-332 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
325
     */
312
     */
326
    @Override
313
    @Override
327
    public void testEnded() {
314
    public void testEnded() {
328
        if (PARSER != null) {
315
        if (parser != null) {
329
            PARSER.close();
316
            parser.close();
330
        }
317
        }
331
        filter = null;
318
        filter = null;
332
        started = false;
319
        started = false;
Lines 347-356 public class AccessLogSampler extends HTTPSampler implements TestBean,ThreadList Link Here
347
     */
334
     */
348
    @Override
335
    @Override
349
    public void threadFinished() {
336
    public void threadFinished() {
350
        if(PARSER instanceof ThreadListener) {
337
        if (parser instanceof ThreadListener) {
351
            ((ThreadListener)PARSER).threadFinished();
338
            ((ThreadListener)parser).threadFinished();
352
        }
339
        }
353
        if(filter instanceof ThreadListener) {
340
        if (filter instanceof ThreadListener) {
354
            ((ThreadListener)filter).threadFinished();
341
            ((ThreadListener)filter).threadFinished();
355
        }
342
        }
356
    }
343
    }
(-)a/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC3Impl.java (-92 / +67 lines)
Lines 98-104 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
98
98
99
    private static final boolean canSetPreEmptive; // OK to set pre-emptive auth?
99
    private static final boolean canSetPreEmptive; // OK to set pre-emptive auth?
100
100
101
    private static final ThreadLocal<Map<HostConfiguration, HttpClient>> httpClients = 
101
    private static final ThreadLocal<Map<HostConfiguration, HttpClient>> httpClients =
102
        new ThreadLocal<Map<HostConfiguration, HttpClient>>(){
102
        new ThreadLocal<Map<HostConfiguration, HttpClient>>(){
103
        @Override
103
        @Override
104
        protected Map<HostConfiguration, HttpClient> initialValue() {
104
        protected Map<HostConfiguration, HttpClient> initialValue() {
Lines 112-152 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
112
    private volatile boolean resetSSLContext;
112
    private volatile boolean resetSSLContext;
113
113
114
    static {
114
    static {
115
        log.info("HTTP request retry count = "+RETRY_COUNT);
115
        log.info("HTTP request retry count = " + RETRY_COUNT);
116
        if (CPS_HTTP > 0) {
116
        if (CPS_HTTP > 0) {
117
            log.info("Setting up HTTP SlowProtocol, cps="+CPS_HTTP);
117
            log.info("Setting up HTTP SlowProtocol, cps=" + CPS_HTTP);
118
            Protocol.registerProtocol(HTTPConstants.PROTOCOL_HTTP,
118
            Protocol protocol = new Protocol(HTTPConstants.PROTOCOL_HTTP, new SlowHttpClientSocketFactory(CPS_HTTP), HTTPConstants.DEFAULT_HTTP_PORT);
119
                    new Protocol(HTTPConstants.PROTOCOL_HTTP,new SlowHttpClientSocketFactory(CPS_HTTP),HTTPConstants.DEFAULT_HTTP_PORT));
119
            Protocol.registerProtocol(HTTPConstants.PROTOCOL_HTTP, protocol);
120
        }
120
        }
121
121
122
        // Now done in JsseSSLManager (which needs to register the protocol)
123
//        cps =
124
//            JMeterUtils.getPropDefault("httpclient.socket.https.cps", 0); // $NON-NLS-1$
125
//
126
//        if (cps > 0) {
127
//            log.info("Setting up HTTPS SlowProtocol, cps="+cps);
128
//            Protocol.registerProtocol(PROTOCOL_HTTPS,
129
//                    new Protocol(PROTOCOL_HTTPS,new SlowHttpClientSocketFactory(cps),DEFAULT_HTTPS_PORT));
130
//        }
131
132
        // Set default parameters as needed
122
        // Set default parameters as needed
133
        HttpParams params = DefaultHttpParams.getDefaultParams();
123
        HttpParams params = DefaultHttpParams.getDefaultParams();
134
124
135
        // Process Commons HttpClient parameters file
125
        // Process Commons HttpClient parameters file
136
        String file=JMeterUtils.getProperty("httpclient.parameters.file"); // $NON-NLS-1$
126
        String file = JMeterUtils.getProperty("httpclient.parameters.file"); // $NON-NLS-1$
137
        if (file != null) {
127
        if (file != null) {
138
            HttpClientDefaultParameters.load(file, params);
128
            HttpClientDefaultParameters.load(file, params);
139
        }
129
        }
140
130
141
        // If the pre-emptive parameter is undefined, then we can set it as needed
131
        // If the pre-emptive parameter is undefined, then we can set it as needed
142
        // otherwise we should do what the user requested.
132
        // otherwise we should do what the user requested.
143
        canSetPreEmptive =  params.getParameter(HTTP_AUTHENTICATION_PREEMPTIVE) == null;
133
        canSetPreEmptive = params.getParameter(HTTP_AUTHENTICATION_PREEMPTIVE) == null;
144
134
145
        // Handle old-style JMeter properties
135
        // Handle old-style JMeter properties
146
        try {
136
        try {
147
            params.setParameter(HttpMethodParams.PROTOCOL_VERSION, HttpVersion.parse("HTTP/"+HTTP_VERSION));
137
            params.setParameter(HttpMethodParams.PROTOCOL_VERSION, HttpVersion.parse("HTTP/" + HTTP_VERSION));
148
        } catch (ProtocolException e) {
138
        } catch (ProtocolException e) {
149
            log.warn("Problem setting protocol version "+e.getLocalizedMessage());
139
            log.warn("Problem setting protocol version " + e.getLocalizedMessage());
150
        }
140
        }
151
141
152
        if (SO_TIMEOUT >= 0){
142
        if (SO_TIMEOUT >= 0){
Lines 193-199 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
193
183
194
        if (log.isDebugEnabled()) {
184
        if (log.isDebugEnabled()) {
195
            log.debug("Start : sample " + urlStr);
185
            log.debug("Start : sample " + urlStr);
196
            log.debug("method " + method+ " followingRedirect " + areFollowingRedirect + " depth " + frameDepth);            
186
            log.debug("method " + method + " followingRedirect " + areFollowingRedirect + " depth " + frameDepth);
197
        }
187
        }
198
188
199
        HttpMethodBase httpMethod = null;
189
        HttpMethodBase httpMethod = null;
Lines 235-241 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
235
                    }
225
                    }
236
                };
226
                };
237
            } else {
227
            } else {
238
                throw new IllegalArgumentException("Unexpected method: '"+method+"'");
228
                throw new IllegalArgumentException("Unexpected method: '" + method + "'");
239
            }
229
            }
240
230
241
            final CacheManager cacheManager = getCacheManager();
231
            final CacheManager cacheManager = getCacheManager();
Lines 256-262 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
256
            if (method.equals(HTTPConstants.POST)) {
246
            if (method.equals(HTTPConstants.POST)) {
257
                String postBody = sendPostData((PostMethod)httpMethod);
247
                String postBody = sendPostData((PostMethod)httpMethod);
258
                res.setQueryString(postBody);
248
                res.setQueryString(postBody);
259
            } else if (method.equals(HTTPConstants.PUT) || method.equals(HTTPConstants.PATCH) 
249
            } else if (method.equals(HTTPConstants.PUT) || method.equals(HTTPConstants.PATCH)
260
                    || method.equals(HTTPConstants.DELETE)) {
250
                    || method.equals(HTTPConstants.DELETE)) {
261
                String putBody = sendEntityData((EntityEnclosingMethod) httpMethod);
251
                String putBody = sendEntityData((EntityEnclosingMethod) httpMethod);
262
                res.setQueryString(putBody);
252
                res.setQueryString(putBody);
Lines 281-287 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
281
                    Header responseHeader = httpMethod.getResponseHeader(HTTPConstants.HEADER_CONTENT_ENCODING);
271
                    Header responseHeader = httpMethod.getResponseHeader(HTTPConstants.HEADER_CONTENT_ENCODING);
282
                    if (responseHeader!= null && HTTPConstants.ENCODING_GZIP.equals(responseHeader.getValue())) {
272
                    if (responseHeader!= null && HTTPConstants.ENCODING_GZIP.equals(responseHeader.getValue())) {
283
                        InputStream tmpInput = new GZIPInputStream(instream); // tmp inputstream needs to have a good counting
273
                        InputStream tmpInput = new GZIPInputStream(instream); // tmp inputstream needs to have a good counting
284
                        res.setResponseData(readResponse(res, tmpInput, (int) httpMethod.getResponseContentLength()));                        
274
                        res.setResponseData(readResponse(res, tmpInput, (int) httpMethod.getResponseContentLength()));
285
                    } else {
275
                    } else {
286
                        res.setResponseData(readResponse(res, instream, (int) httpMethod.getResponseContentLength()));
276
                        res.setResponseData(readResponse(res, instream, (int) httpMethod.getResponseContentLength()));
287
                    }
277
                    }
Lines 308-314 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
308
            if (h != null)// Can be missing, e.g. on redirect
298
            if (h != null)// Can be missing, e.g. on redirect
309
            {
299
            {
310
                ct = h.getValue();
300
                ct = h.getValue();
311
                res.setContentType(ct);// e.g. text/html; charset=ISO-8859-1
301
                res.setContentType(ct); // e.g. text/html; charset=ISO-8859-1
312
                res.setEncodingAndType(ct);
302
                res.setEncodingAndType(ct);
313
            }
303
            }
314
304
Lines 331-337 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
331
                log.debug("Response headersSize=" + res.getHeadersSize() + " bodySize=" + res.getBodySize()
321
                log.debug("Response headersSize=" + res.getHeadersSize() + " bodySize=" + res.getBodySize()
332
                        + " Total=" + (res.getHeadersSize() + res.getBodySize()));
322
                        + " Total=" + (res.getHeadersSize() + res.getBodySize()));
333
            }
323
            }
334
            
324
335
            // If we redirected automatically, the URL may have changed
325
            // If we redirected automatically, the URL may have changed
336
            if (getAutoRedirects()){
326
            if (getAutoRedirects()){
337
                res.setURL(new URL(httpMethod.getURI().toString()));
327
                res.setURL(new URL(httpMethod.getURI().toString()));
Lines 350-360 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
350
340
351
            log.debug("End : sample");
341
            log.debug("End : sample");
352
            return res;
342
            return res;
353
        } catch (IllegalArgumentException e) { // e.g. some kinds of invalid URL
343
        } catch (IllegalArgumentException e) { // e.g. some kind of invalid URL
354
            res.sampleEnd();
344
            res.sampleEnd();
355
            // pick up headers if failed to execute the request
345
            // pick up headers if failed to execute the request
356
            // httpMethod can be null if method is unexpected
346
            // httpMethod can be null if method is unexpected
357
            if(httpMethod != null) {
347
            if (httpMethod != null) {
358
                res.setRequestHeaders(getConnectionHeaders(httpMethod));
348
                res.setRequestHeaders(getConnectionHeaders(httpMethod));
359
            }
349
            }
360
            errorResult(e, res);
350
            errorResult(e, res);
Lines 372-385 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
372
            }
362
            }
373
        }
363
        }
374
    }
364
    }
375
    
365
376
    /**
366
    /**
377
     * Calculate response headers size
367
     * Calculate response headers size
378
     * 
368
     *
379
     * @return the size response headers (in bytes)
369
     * @return the size response headers (in bytes)
380
     */
370
     */
381
    private static int calculateHeadersSize(HttpMethodBase httpMethod) {
371
    private static int calculateHeadersSize(HttpMethodBase httpMethod) {
382
        int headerSize = httpMethod.getStatusLine().toString().length()+2; // add a \r\n
372
        int headerSize = httpMethod.getStatusLine().toString().length() + 2; // add a \r\n
383
        Header[] rh = httpMethod.getResponseHeaders();
373
        Header[] rh = httpMethod.getResponseHeaders();
384
        for (int i = 0; i < rh.length; i++) {
374
        for (int i = 0; i < rh.length; i++) {
385
            headerSize += rh[i].toString().length(); // already include the \r\n
375
            headerSize += rh[i].toString().length(); // already include the \r\n
Lines 428-439 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
428
        int port = uri.getPort();
418
        int port = uri.getPort();
429
419
430
        /*
420
        /*
431
         *  We use the HostConfiguration as the key to retrieve the HttpClient,
421
         * We use the HostConfiguration as the key to retrieve the HttpClient,
432
         *  so need to ensure that any items used in its equals/hashcode methods are
422
         * so need to ensure that any items used in its equals/hashcode methods are
433
         *  not changed after use, i.e.:
423
         * not changed after use, i.e.:
434
         *  host, port, protocol, localAddress, proxy
424
         * host, port, protocol, localAddress, proxy
435
         *
425
         */
436
        */
437
        HostConfiguration hc = new HostConfiguration();
426
        HostConfiguration hc = new HostConfiguration();
438
        hc.setHost(host, port, protocol); // All needed to ensure re-usablility
427
        hc.setHost(host, port, protocol); // All needed to ensure re-usablility
439
428
Lines 476-482 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
476
        if ( httpClient == null )
465
        if ( httpClient == null )
477
        {
466
        {
478
            httpClient = new HttpClient(new SimpleHttpConnectionManager());
467
            httpClient = new HttpClient(new SimpleHttpConnectionManager());
479
            httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
468
            httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
480
                    new DefaultHttpMethodRetryHandler(RETRY_COUNT, false));
469
                    new DefaultHttpMethodRetryHandler(RETRY_COUNT, false));
481
            if (log.isDebugEnabled()) {
470
            if (log.isDebugEnabled()) {
482
                log.debug("Created new HttpClient: @"+System.identityHashCode(httpClient));
471
                log.debug("Created new HttpClient: @"+System.identityHashCode(httpClient));
Lines 656-664 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
656
        // Get all the request headers
645
        // Get all the request headers
657
        StringBuilder hdrs = new StringBuilder(100);
646
        StringBuilder hdrs = new StringBuilder(100);
658
        Header[] requestHeaders = method.getRequestHeaders();
647
        Header[] requestHeaders = method.getRequestHeaders();
659
        for(int i = 0; i < requestHeaders.length; i++) {
648
        for (int i = 0; i < requestHeaders.length; i++) {
660
            // Exclude the COOKIE header, since cookie is reported separately in the sample
649
            // Exclude the COOKIE header, since cookie is reported separately in the sample
661
            if(!HTTPConstants.HEADER_COOKIE.equalsIgnoreCase(requestHeaders[i].getName())) {
650
            if (!HTTPConstants.HEADER_COOKIE.equalsIgnoreCase(requestHeaders[i].getName())) {
662
                hdrs.append(requestHeaders[i].getName());
651
                hdrs.append(requestHeaders[i].getName());
663
                hdrs.append(": "); // $NON-NLS-1$
652
                hdrs.append(": "); // $NON-NLS-1$
664
                hdrs.append(requestHeaders[i].getValue());
653
                hdrs.append(requestHeaders[i].getValue());
Lines 737-747 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
737
        HTTPFileArg files[] = getHTTPFiles();
726
        HTTPFileArg files[] = getHTTPFiles();
738
        // Check if we should do a multipart/form-data or an
727
        // Check if we should do a multipart/form-data or an
739
        // application/x-www-form-urlencoded post request
728
        // application/x-www-form-urlencoded post request
740
        if(getUseMultipartForPost()) {
729
        if (getUseMultipartForPost()) {
741
            // If a content encoding is specified, we use that as the
730
            // If a content encoding is specified, we use that as the
742
            // encoding of any parameter values
731
            // encoding of any parameter values
743
            String contentEncoding = getContentEncoding();
732
            String contentEncoding = getContentEncoding();
744
            if(isNullOrEmptyTrimmed(contentEncoding)) {
733
            if (isNullOrEmptyTrimmed(contentEncoding)) {
745
                contentEncoding = null;
734
                contentEncoding = null;
746
            }
735
            }
747
736
Lines 787-797 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
787
776
788
            // If the Multipart is repeatable, we can send it first to
777
            // If the Multipart is repeatable, we can send it first to
789
            // our own stream, without the actual file content, so we can return it
778
            // our own stream, without the actual file content, so we can return it
790
            if(multiPart.isRepeatable()) {
779
            if (multiPart.isRepeatable()) {
791
                // For all the file multiparts, we must tell it to not include
780
                // For all the file multiparts, we must tell it to not include
792
                // the actual file content
781
                // the actual file content
793
                for(int i = 0; i < partNo; i++) {
782
                for (int i = 0; i < partNo; i++) {
794
                    if(parts[i] instanceof ViewableFilePart) {
783
                    if (parts[i] instanceof ViewableFilePart) {
795
                        ((ViewableFilePart) parts[i]).setHideFileData(true); // .sendMultipartWithoutFileContent(bos);
784
                        ((ViewableFilePart) parts[i]).setHideFileData(true); // .sendMultipartWithoutFileContent(bos);
796
                    }
785
                    }
797
                }
786
                }
Lines 807-814 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
807
796
808
                // For all the file multiparts, we must revert the hiding of
797
                // For all the file multiparts, we must revert the hiding of
809
                // the actual file content
798
                // the actual file content
810
                for(int i = 0; i < partNo; i++) {
799
                for (int i = 0; i < partNo; i++) {
811
                    if(parts[i] instanceof ViewableFilePart) {
800
                    if (parts[i] instanceof ViewableFilePart) {
812
                        ((ViewableFilePart) parts[i]).setHideFileData(false);
801
                        ((ViewableFilePart) parts[i]).setHideFileData(false);
813
                    }
802
                    }
814
                }
803
                }
Lines 823-835 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
823
            Header contentTypeHeader = post.getRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE);
812
            Header contentTypeHeader = post.getRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE);
824
            boolean hasContentTypeHeader = contentTypeHeader != null && contentTypeHeader.getValue() != null && contentTypeHeader.getValue().length() > 0;
813
            boolean hasContentTypeHeader = contentTypeHeader != null && contentTypeHeader.getValue() != null && contentTypeHeader.getValue().length() > 0;
825
            // If there are no arguments, we can send a file as the body of the request
814
            // If there are no arguments, we can send a file as the body of the request
826
            // TODO: needs a multiple file upload scenerio
815
            // TODO: needs a multiple file upload scenario
827
            if(!hasArguments() && getSendFileAsPostBody()) {
816
            if (!hasArguments() && getSendFileAsPostBody()) {
828
                // If getSendFileAsPostBody returned true, it's sure that file is not null
817
                // If getSendFileAsPostBody returned true, it's sure that file is not null
829
                HTTPFileArg file = files[0];
818
                HTTPFileArg file = files[0];
830
                if(!hasContentTypeHeader) {
819
                if (!hasContentTypeHeader) {
831
                    // Allow the mimetype of the file to control the content type
820
                    // Allow the mimetype of the file to control the content type
832
                    if(file.getMimeType() != null && file.getMimeType().length() > 0) {
821
                    if (file.getMimeType() != null && file.getMimeType().length() > 0) {
833
                        post.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
822
                        post.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
834
                    }
823
                    }
835
                    else {
824
                    else {
Lines 851-873 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
851
                // the post body will be encoded in the specified content encoding
840
                // the post body will be encoded in the specified content encoding
852
                String contentEncoding = getContentEncoding();
841
                String contentEncoding = getContentEncoding();
853
                boolean haveContentEncoding = false;
842
                boolean haveContentEncoding = false;
854
                if(isNullOrEmptyTrimmed(contentEncoding)) {
843
                if (isNullOrEmptyTrimmed(contentEncoding)) {
855
                    contentEncoding=null;                    
844
                    contentEncoding = null;
856
                } else {
845
                } else {
857
                    post.getParams().setContentCharset(contentEncoding);
846
                    post.getParams().setContentCharset(contentEncoding);
858
                    haveContentEncoding = true;                    
847
                    haveContentEncoding = true;
859
                }
848
                }
860
849
861
                // If none of the arguments have a name specified, we
850
                // If none of the arguments have a name specified, we
862
                // just send all the values as the post body
851
                // just send all the values as the post body
863
                if(getSendParameterValuesAsPostBody()) {
852
                if (getSendParameterValuesAsPostBody()) {
864
                    // Allow the mimetype of the file to control the content type
853
                    // Allow the mimetype of the file to control the content type
865
                    // This is not obvious in GUI if you are not uploading any files,
854
                    // This is not obvious in GUI if you are not uploading any files,
866
                    // but just sending the content of nameless parameters
855
                    // but just sending the content of nameless parameters
867
                    // TODO: needs a multiple file upload scenerio
856
                    // TODO: needs a multiple file upload scenario
868
                    if(!hasContentTypeHeader) {
857
                    if (!hasContentTypeHeader) {
869
                        HTTPFileArg file = files.length > 0? files[0] : null;
858
                        HTTPFileArg file = files.length > 0? files[0] : null;
870
                        if(file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
859
                        if (file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
871
                            post.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
860
                            post.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
872
                        }
861
                        }
873
                        else {
862
                        else {
Lines 896-902 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
896
                    // It is a normal post request, with parameter names and values
885
                    // It is a normal post request, with parameter names and values
897
886
898
                    // Set the content type
887
                    // Set the content type
899
                    if(!hasContentTypeHeader) {
888
                    if (!hasContentTypeHeader) {
900
                        post.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
889
                        post.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, HTTPConstants.APPLICATION_X_WWW_FORM_URLENCODED);
901
                    }
890
                    }
902
                    // Add the parameters
891
                    // Add the parameters
Lines 911-923 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
911
                            continue;
900
                            continue;
912
                        }
901
                        }
913
                        String parameterValue = arg.getValue();
902
                        String parameterValue = arg.getValue();
914
                        if(!arg.isAlwaysEncoded()) {
903
                        if (!arg.isAlwaysEncoded()) {
915
                            // The value is already encoded by the user
904
                            // The value is already encoded by the user
916
                            // Must decode the value now, so that when the
905
                            // Must decode the value now, so that when the
917
                            // httpclient encodes it, we end up with the same value
906
                            // httpclient encodes it, we end up with the same value
918
                            // as the user had entered.
907
                            // as the user had entered.
919
                            String urlContentEncoding = contentEncoding;
908
                            String urlContentEncoding = contentEncoding;
920
                            if(urlContentEncoding == null || urlContentEncoding.length() == 0) {
909
                            if (urlContentEncoding == null || urlContentEncoding.length() == 0) {
921
                                // Use the default encoding for urls
910
                                // Use the default encoding for urls
922
                                urlContentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
911
                                urlContentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
923
                            }
912
                            }
Lines 927-951 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
927
                        // Add the parameter, httpclient will urlencode it
916
                        // Add the parameter, httpclient will urlencode it
928
                        post.addParameter(parameterName, parameterValue);
917
                        post.addParameter(parameterName, parameterValue);
929
                    }
918
                    }
930
931
/*
932
//                    // Alternative implementation, to make sure that HTTPSampler and HTTPSampler2
933
//                    // sends the same post body.
934
//
935
//                    // Only include the content char set in the content-type header if it is not
936
//                    // an APPLICATION_X_WWW_FORM_URLENCODED content type
937
//                    String contentCharSet = null;
938
//                    if(!post.getRequestHeader(HEADER_CONTENT_TYPE).getValue().equals(APPLICATION_X_WWW_FORM_URLENCODED)) {
939
//                        contentCharSet = post.getRequestCharSet();
940
//                    }
941
//                    StringRequestEntity requestEntity = new StringRequestEntity(getQueryString(contentEncoding), post.getRequestHeader(HEADER_CONTENT_TYPE).getValue(), contentCharSet);
942
//                    post.setRequestEntity(requestEntity);
943
*/
944
                }
919
                }
945
920
946
                // If the request entity is repeatable, we can send it first to
921
                // If the request entity is repeatable, we can send it first to
947
                // our own stream, so we can return it
922
                // our own stream, so we can return it
948
                if(post.getRequestEntity().isRepeatable()) {
923
                if (post.getRequestEntity().isRepeatable()) {
949
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
924
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
950
                    post.getRequestEntity().writeRequest(bos);
925
                    post.getRequestEntity().writeRequest(bos);
951
                    bos.flush();
926
                    bos.flush();
Lines 980-986 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
980
955
981
        // If there are no arguments, we can send a file as the body of the request
956
        // If there are no arguments, we can send a file as the body of the request
982
957
983
        if(!hasArguments() && getSendFileAsPostBody()) {
958
        if (!hasArguments() && getSendFileAsPostBody()) {
984
            hasPutBody = true;
959
            hasPutBody = true;
985
960
986
            // If getSendFileAsPostBody returned true, it's sure that file is not null
961
            // If getSendFileAsPostBody returned true, it's sure that file is not null
Lines 989-1002 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
989
        }
964
        }
990
        // If none of the arguments have a name specified, we
965
        // If none of the arguments have a name specified, we
991
        // just send all the values as the put body
966
        // just send all the values as the put body
992
        else if(getSendParameterValuesAsPostBody()) {
967
        else if (getSendParameterValuesAsPostBody()) {
993
            hasPutBody = true;
968
            hasPutBody = true;
994
969
995
            // If a content encoding is specified, we set it as http parameter, so that
970
            // If a content encoding is specified, we set it as http parameter, so that
996
            // the post body will be encoded in the specified content encoding
971
            // the post body will be encoded in the specified content encoding
997
            String contentEncoding = getContentEncoding();
972
            String contentEncoding = getContentEncoding();
998
            boolean haveContentEncoding = false;
973
            boolean haveContentEncoding = false;
999
            if(isNullOrEmptyTrimmed(contentEncoding)) {
974
            if (isNullOrEmptyTrimmed(contentEncoding)) {
1000
                contentEncoding = null;
975
                contentEncoding = null;
1001
            } else {
976
            } else {
1002
                put.getParams().setContentCharset(contentEncoding);
977
                put.getParams().setContentCharset(contentEncoding);
Lines 1017-1033 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
1017
                putBodyContent.append(value);
992
                putBodyContent.append(value);
1018
            }
993
            }
1019
            String contentTypeValue = null;
994
            String contentTypeValue = null;
1020
            if(hasContentTypeHeader) {
995
            if (hasContentTypeHeader) {
1021
                contentTypeValue = put.getRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE).getValue();
996
                contentTypeValue = put.getRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE).getValue();
1022
            }
997
            }
1023
            StringRequestEntity requestEntity = new StringRequestEntity(putBodyContent.toString(), contentTypeValue, put.getRequestCharSet());
998
            StringRequestEntity requestEntity = new StringRequestEntity(putBodyContent.toString(), contentTypeValue, put.getRequestCharSet());
1024
            put.setRequestEntity(requestEntity);
999
            put.setRequestEntity(requestEntity);
1025
        }
1000
        }
1026
        // Check if we have any content to send for body
1001
        // Check if we have any content to send for body
1027
        if(hasPutBody) {
1002
        if (hasPutBody) {
1028
            // If the request entity is repeatable, we can send it first to
1003
            // If the request entity is repeatable, we can send it first to
1029
            // our own stream, so we can return it
1004
            // our own stream, so we can return it
1030
            if(put.getRequestEntity().isRepeatable()) {
1005
            if (put.getRequestEntity().isRepeatable()) {
1031
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
1006
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
1032
                put.getRequestEntity().writeRequest(bos);
1007
                put.getRequestEntity().writeRequest(bos);
1033
                bos.flush();
1008
                bos.flush();
Lines 1038-1050 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
1038
            else {
1013
            else {
1039
                putBody.append("<RequestEntity was not repeatable, cannot view what was sent>");
1014
                putBody.append("<RequestEntity was not repeatable, cannot view what was sent>");
1040
            }
1015
            }
1041
            if(!hasContentTypeHeader) {
1016
            if (!hasContentTypeHeader) {
1042
                // Allow the mimetype of the file to control the content type
1017
                // Allow the mimetype of the file to control the content type
1043
                // This is not obvious in GUI if you are not uploading any files,
1018
                // This is not obvious in GUI if you are not uploading any files,
1044
                // but just sending the content of nameless parameters
1019
                // but just sending the content of nameless parameters
1045
                // TODO: needs a multiple file upload scenerio
1020
                // TODO: needs a multiple file upload scenario
1046
                HTTPFileArg file = files.length > 0? files[0] : null;
1021
                HTTPFileArg file = files.length > 0? files[0] : null;
1047
                if(file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
1022
                if (file != null && file.getMimeType() != null && file.getMimeType().length() > 0) {
1048
                    put.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
1023
                    put.setRequestHeader(HTTPConstants.HEADER_CONTENT_TYPE, file.getMimeType());
1049
                }
1024
                }
1050
            }
1025
            }
Lines 1074-1081 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
1074
        protected void sendData(OutputStream out) throws IOException {
1049
        protected void sendData(OutputStream out) throws IOException {
1075
            // Check if we should send only placeholder text for the
1050
            // Check if we should send only placeholder text for the
1076
            // file content, or the real file content
1051
            // file content, or the real file content
1077
            if(hideFileData) {
1052
            if (hideFileData) {
1078
                out.write("<actual file content, not shown here>".getBytes());// encoding does not really matter here
1053
                // encoding does not really matter here
1054
                out.write("<actual file content, not shown here>".getBytes());
1079
            }
1055
            }
1080
            else {
1056
            else {
1081
                super.sendData(out);
1057
                super.sendData(out);
Lines 1118-1136 public class HTTPHC3Impl extends HTTPHCAbstractImpl { Link Here
1118
    }
1094
    }
1119
1095
1120
    /**
1096
    /**
1121
     * 
1097
     *
1122
     */
1098
     */
1123
    private void closeThreadLocalConnections() {
1099
    private void closeThreadLocalConnections() {
1124
        // Does not need to be synchronised, as all access is from same thread
1100
        // Does not need to be synchronised, as all access is from same thread
1125
        Map<HostConfiguration, HttpClient> map = httpClients.get();
1101
        Map<HostConfiguration, HttpClient> map = httpClients.get();
1126
1102
1127
        if ( map != null ) {
1103
        if (map != null) {
1128
            for (HttpClient cl : map.values())
1104
            for (HttpClient cl : map.values())
1129
            {
1105
            {
1130
                // Can cause NPE in HttpClient 3.1
1106
                // Closes the connection. shutdown() can cause NPE
1131
                //((SimpleHttpConnectionManager)cl.getHttpConnectionManager()).shutdown();// Closes the connection
1107
                // in HttpClient 3.1, therefore using original method:
1132
                // Revert to original method:
1108
                cl.getHttpConnectionManager().closeIdleConnections(-1000);
1133
                cl.getHttpConnectionManager().closeIdleConnections(-1000);// Closes the connection
1134
            }
1109
            }
1135
            map.clear();
1110
            map.clear();
1136
        }
1111
        }
(-)a/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPJavaImpl.java (-5 / +4 lines)
Lines 448-454 public class HTTPJavaImpl extends HTTPAbstractImpl { Link Here
448
        String urlStr = url.toString();
448
        String urlStr = url.toString();
449
        if (log.isDebugEnabled()) {
449
        if (log.isDebugEnabled()) {
450
            log.debug("Start : sample " + urlStr);
450
            log.debug("Start : sample " + urlStr);
451
            log.debug("method " + method+ " followingRedirect " + areFollowingRedirect + " depth " + frameDepth);            
451
            log.debug("method " + method+ " followingRedirect " + areFollowingRedirect + " depth " + frameDepth);
452
        }
452
        }
453
453
454
        HTTPSampleResult res = new HTTPSampleResult();
454
        HTTPSampleResult res = new HTTPSampleResult();
Lines 520-526 public class HTTPJavaImpl extends HTTPAbstractImpl { Link Here
520
520
521
            res.setResponseData(responseData);
521
            res.setResponseData(responseData);
522
522
523
            @SuppressWarnings("null") // Cannot be null here
524
            int errorLevel = conn.getResponseCode();
523
            int errorLevel = conn.getResponseCode();
525
            String respMsg = conn.getResponseMessage();
524
            String respMsg = conn.getResponseMessage();
526
            String hdr=conn.getHeaderField(0);
525
            String hdr=conn.getHeaderField(0);
Lines 563-577 public class HTTPJavaImpl extends HTTPAbstractImpl { Link Here
563
            if (res.isRedirect()) {
562
            if (res.isRedirect()) {
564
                res.setRedirectLocation(conn.getHeaderField(HTTPConstants.HEADER_LOCATION));
563
                res.setRedirectLocation(conn.getHeaderField(HTTPConstants.HEADER_LOCATION));
565
            }
564
            }
566
            
565
567
            // record headers size to allow HTTPSampleResult.getBytes() with different options
566
            // record headers size to allow HTTPSampleResult.getBytes() with different options
568
            res.setHeadersSize(responseHeaders.replaceAll("\n", "\r\n") // $NON-NLS-1$ $NON-NLS-2$
567
            res.setHeadersSize(responseHeaders.replaceAll("\n", "\r\n") // $NON-NLS-1$ $NON-NLS-2$
569
                    .length() + 2); // add 2 for a '\r\n' at end of headers (before data) 
568
                    .length() + 2); // add 2 for a '\r\n' at end of headers (before data)
570
            if (log.isDebugEnabled()) {
569
            if (log.isDebugEnabled()) {
571
                log.debug("Response headersSize=" + res.getHeadersSize() + " bodySize=" + res.getBodySize()
570
                log.debug("Response headersSize=" + res.getHeadersSize() + " bodySize=" + res.getBodySize()
572
                        + " Total=" + (res.getHeadersSize() + res.getBodySize()));
571
                        + " Total=" + (res.getHeadersSize() + res.getBodySize()));
573
            }
572
            }
574
            
573
575
            // If we redirected automatically, the URL may have changed
574
            // If we redirected automatically, the URL may have changed
576
            if (getAutoRedirects()){
575
            if (getAutoRedirects()){
577
                res.setURL(conn.getURL());
576
                res.setURL(conn.getURL());
(-)a/src/protocol/http/org/apache/jmeter/protocol/http/util/accesslog/LogFilter.java (-24 / +13 lines)
Lines 211-217 public class LogFilter implements Filter, Serializable { Link Here
211
     * should be used. Therefore, the method will only return true if the entry
211
     * should be used. Therefore, the method will only return true if the entry
212
     * should be used. Since the interface defines both inclusion and exclusion,
212
     * should be used. Since the interface defines both inclusion and exclusion,
213
     * that means by default inclusion filtering assumes all entries are
213
     * that means by default inclusion filtering assumes all entries are
214
     * excluded unless it matches. In the case of exlusion filtering, it assumes
214
     * excluded unless it matches. In the case of exclusion filtering, it assumes
215
     * all entries are included unless it matches, which means it should be
215
     * all entries are included unless it matches, which means it should be
216
     * excluded.
216
     * excluded.
217
     *
217
     *
Lines 221-237 public class LogFilter implements Filter, Serializable { Link Here
221
     */
221
     */
222
    @Override
222
    @Override
223
    public boolean isFiltered(String path,TestElement el) {
223
    public boolean isFiltered(String path,TestElement el) {
224
        // we do a quick check to see if any
224
        if (this.FILEFILTER) {
225
        // filters are set. If not we just
225
            return filterFile(path);
226
        // return false to be efficient.
226
        } else if (this.PTRNFILTER) {
227
        if (this.FILEFILTER || this.PTRNFILTER || this.CHANGEEXT) {
227
            return filterPattern(path);
228
            if (this.FILEFILTER) {
229
                return filterFile(path);
230
            } else if (this.PTRNFILTER) {
231
                return filterPattern(path);
232
            } else {
233
                return false;
234
            }
235
        } else {
228
        } else {
236
            return false;
229
            return false;
237
        }
230
        }
Lines 270-279 public class LogFilter implements Filter, Serializable { Link Here
270
     * @return boolean include
263
     * @return boolean include
271
     */
264
     */
272
    public boolean incFile(String text) {
265
    public boolean incFile(String text) {
273
        // inclusion filter assumes most of
266
        // inclusion filter assumes most of the files are not wanted, therefore
274
        // the files are not wanted, therefore
267
        // usefile is set to false unless it matches.
275
        // usefile is set to false unless it
276
        // matches.
277
        this.USEFILE = false;
268
        this.USEFILE = false;
278
        for (int idx = 0; idx < this.INCFILE.length; idx++) {
269
        for (int idx = 0; idx < this.INCFILE.length; idx++) {
279
            if (text.indexOf(this.INCFILE[idx]) > -1) {
270
            if (text.indexOf(this.INCFILE[idx]) > -1) {
Lines 293-302 public class LogFilter implements Filter, Serializable { Link Here
293
     * @return boolean exclude
284
     * @return boolean exclude
294
     */
285
     */
295
    public boolean excFile(String text) {
286
    public boolean excFile(String text) {
296
        // exclusion filter assumes most of
287
        // exclusion filter assumes most of the files are used, therefore
297
        // the files are used, therefore
288
        // usefile is set to true, unless it matches.
298
        // usefile is set to true, unless
299
        // it matches.
300
        this.USEFILE = true;
289
        this.USEFILE = true;
301
        boolean exc = false;
290
        boolean exc = false;
302
        for (int idx = 0; idx < this.EXCFILE.length; idx++) {
291
        for (int idx = 0; idx < this.EXCFILE.length; idx++) {
Lines 310-316 public class LogFilter implements Filter, Serializable { Link Here
310
    }
299
    }
311
300
312
    /**
301
    /**
313
     * The current implemenation assumes the user has checked the regular
302
     * The current implementation assumes the user has checked the regular
314
     * expressions so that they don't cancel each other. The basic assumption is
303
     * expressions so that they don't cancel each other. The basic assumption is
315
     * the method will return true if the text should be filtered. If not, it
304
     * the method will return true if the text should be filtered. If not, it
316
     * will return false, which means it should not be filtered.
305
     * will return false, which means it should not be filtered.
Lines 377-385 public class LogFilter implements Filter, Serializable { Link Here
377
     * @return boolean
366
     * @return boolean
378
     */
367
     */
379
    public boolean replaceExtension(String text) {
368
    public boolean replaceExtension(String text) {
380
        int pt = text.indexOf(this.OLDEXT);
369
        final int pt = text.indexOf(this.OLDEXT);
381
        if (pt > -1) {
370
        if (pt > -1) {
382
            int extsize = this.OLDEXT.length();
371
            final int extsize = this.OLDEXT.length();
383
            this.NEWFILE = text.substring(0, pt) + this.NEWEXT + text.substring(pt + extsize);
372
            this.NEWFILE = text.substring(0, pt) + this.NEWEXT + text.substring(pt + extsize);
384
            return true;
373
            return true;
385
        } else {
374
        } else {
Lines 418-424 public class LogFilter implements Filter, Serializable { Link Here
418
        try {
407
        try {
419
            return JMeterUtils.getPatternCache().getPattern(pattern,
408
            return JMeterUtils.getPatternCache().getPattern(pattern,
420
                    Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.SINGLELINE_MASK);
409
                    Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.SINGLELINE_MASK);
421
        } catch (MalformedCachePatternException exception) {
410
        } catch (final MalformedCachePatternException exception) {
422
            log.error("Problem with pattern: "+pattern,exception);
411
            log.error("Problem with pattern: "+pattern,exception);
423
            return null;
412
            return null;
424
        }
413
        }
(-)a/src/protocol/http/org/apache/jmeter/protocol/http/util/accesslog/SessionFilter.java (-12 / +12 lines)
Lines 67-75 public class SessionFilter implements Filter, Serializable, TestCloneable,Thread Link Here
67
    }
67
    }
68
68
69
    protected String getIpAddress(String logLine) {
69
    protected String getIpAddress(String logLine) {
70
        Pattern incIp = JMeterUtils.getPatternCache().getPattern("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}",
70
        final Pattern incIp = JMeterUtils.getPatternCache().getPattern("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}",
71
                Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.SINGLELINE_MASK);
71
                Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.SINGLELINE_MASK);
72
        Perl5Matcher matcher = JMeterUtils.getMatcher();
72
        final Perl5Matcher matcher = JMeterUtils.getMatcher();
73
        matcher.contains(logLine, incIp);
73
        matcher.contains(logLine, incIp);
74
        return matcher.getMatch().group(0);
74
        return matcher.getMatch().group(0);
75
    }
75
    }
Lines 87-101 public class SessionFilter implements Filter, Serializable, TestCloneable,Thread Link Here
87
     */
87
     */
88
    @Override
88
    @Override
89
    public Object clone() {
89
    public Object clone() {
90
        if(cookieManagers == null)
90
        if (cookieManagers == null)
91
        {
91
        {
92
            cookieManagers = new ConcurrentHashMap<String, CookieManager>();
92
            cookieManagers = new ConcurrentHashMap<String, CookieManager>();
93
        }
93
        }
94
        if(managersInUse == null)
94
        if (managersInUse == null)
95
        {
95
        {
96
            managersInUse = Collections.synchronizedSet(new HashSet<CookieManager>());
96
            managersInUse = Collections.synchronizedSet(new HashSet<CookieManager>());
97
        }
97
        }
98
        SessionFilter f = new SessionFilter();
98
        final SessionFilter f = new SessionFilter();
99
        f.cookieManagers = cookieManagers;
99
        f.cookieManagers = cookieManagers;
100
        f.managersInUse = managersInUse;
100
        f.managersInUse = managersInUse;
101
        return f;
101
        return f;
Lines 148-155 public class SessionFilter implements Filter, Serializable, TestCloneable,Thread Link Here
148
     */
148
     */
149
    @Override
149
    @Override
150
    public boolean isFiltered(String path,TestElement sampler) {
150
    public boolean isFiltered(String path,TestElement sampler) {
151
        String ipAddr = getIpAddress(path);
151
        final String ipAddr = getIpAddress(path);
152
        CookieManager cm = getCookieManager(ipAddr);
152
        final CookieManager cm = getCookieManager(ipAddr);
153
        ((HTTPSampler)sampler).setCookieManager(cm);
153
        ((HTTPSampler)sampler).setCookieManager(cm);
154
        return false;
154
        return false;
155
    }
155
    }
Lines 161-174 public class SessionFilter implements Filter, Serializable, TestCloneable,Thread Link Here
161
        // threads stuck in wait can move on
161
        // threads stuck in wait can move on
162
        synchronized(managersInUse)
162
        synchronized(managersInUse)
163
        {
163
        {
164
            if(lastUsed != null)
164
            if (lastUsed != null)
165
            {
165
            {
166
                managersInUse.remove(lastUsed);
166
                managersInUse.remove(lastUsed);
167
                managersInUse.notify();
167
                managersInUse.notify();
168
            }
168
            }
169
        }
169
        }
170
        // let notified threads move on and get lock on managersInUse
170
        // let notified threads move on and get lock on managersInUse
171
        if(lastUsed != null)
171
        if (lastUsed != null)
172
        {
172
        {
173
            Thread.yield();
173
            Thread.yield();
174
        }
174
        }
Lines 178-194 public class SessionFilter implements Filter, Serializable, TestCloneable,Thread Link Here
178
        synchronized(managersInUse)
178
        synchronized(managersInUse)
179
        {
179
        {
180
            cm = cookieManagers.get(ipAddr);
180
            cm = cookieManagers.get(ipAddr);
181
            if(cm == null)
181
            if (cm == null)
182
            {
182
            {
183
                cm = new CookieManager();
183
                cm = new CookieManager();
184
                cm.testStarted();
184
                cm.testStarted();
185
                cookieManagers.put(ipAddr,cm);
185
                cookieManagers.put(ipAddr,cm);
186
            }
186
            }
187
            while(managersInUse.contains(cm))
187
            while (managersInUse.contains(cm))
188
            {
188
            {
189
                try {
189
                try {
190
                    managersInUse.wait();
190
                    managersInUse.wait();
191
                } catch (InterruptedException e) {
191
                } catch (final InterruptedException e) {
192
                    log.info("SessionFilter wait interrupted");
192
                    log.info("SessionFilter wait interrupted");
193
                }
193
                }
194
            }
194
            }
(-)a/src/protocol/http/org/apache/jmeter/protocol/http/util/accesslog/SharedTCLogParser.java (-6 / +2 lines)
Lines 57-63 public class SharedTCLogParser extends TCLogParser implements TestCloneable { Link Here
57
        } catch (Exception exception) {
57
        } catch (Exception exception) {
58
            log.error("Problem creating samples", exception);
58
            log.error("Problem creating samples", exception);
59
        }
59
        }
60
        return -1;// indicate that an error occured
60
        return -1;// indicate that an error occurred
61
    }
61
    }
62
62
63
    /**
63
    /**
Lines 70-77 public class SharedTCLogParser extends TCLogParser implements TestCloneable { Link Here
70
        int actualCount = 0;
70
        int actualCount = 0;
71
        String line = null;
71
        String line = null;
72
        try {
72
        try {
73
            // read one line at a time using
73
            // read one line at a time using BufferedReader
74
            // BufferedReader
75
            line = breader.readLine(FILENAME);
74
            line = breader.readLine(FILENAME);
76
            while (line != null) {
75
            while (line != null) {
77
                if (line.length() > 0) {
76
                if (line.length() > 0) {
Lines 89-97 public class SharedTCLogParser extends TCLogParser implements TestCloneable { Link Here
89
            }
88
            }
90
            if (line == null) {
89
            if (line == null) {
91
                breader.closeFile(FILENAME);
90
                breader.closeFile(FILENAME);
92
                // this.READER = new BufferedReader(new
93
                // FileReader(this.SOURCE));
94
                // parse(this.READER,el);
95
            }
91
            }
96
        } catch (IOException ioe) {
92
        } catch (IOException ioe) {
97
            log.error("Error reading log file", ioe);
93
            log.error("Error reading log file", ioe);
(-)a/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/FixedQueueExecutor.java (-6 / +6 lines)
Lines 66-74 public class FixedQueueExecutor implements QueueExecutor { Link Here
66
     * {@inheritDoc}
66
     * {@inheritDoc}
67
     */
67
     */
68
    @Override
68
    @Override
69
    public Message sendAndReceive(Message request, 
69
    public Message sendAndReceive(Message request,
70
            int deliveryMode, 
70
            int deliveryMode,
71
            int priority, 
71
            int priority,
72
            long expiration) throws JMSException {
72
            long expiration) throws JMSException {
73
        String id = request.getJMSCorrelationID();
73
        String id = request.getJMSCorrelationID();
74
        if(id == null && !useReqMsgIdAsCorrelId){
74
        if(id == null && !useReqMsgIdAsCorrelId){
Lines 80-90 public class FixedQueueExecutor implements QueueExecutor { Link Here
80
            // Note: there is only one admin object which is shared between all threads
80
            // Note: there is only one admin object which is shared between all threads
81
            synchronized (admin) {// interlock with Receiver
81
            synchronized (admin) {// interlock with Receiver
82
                producer.send(request, deliveryMode, priority, expiration);
82
                producer.send(request, deliveryMode, priority, expiration);
83
                id=request.getJMSMessageID();
83
                id = request.getJMSMessageID();
84
                admin.putRequest(id, request, countDownLatch);
84
                admin.putRequest(id, request, countDownLatch);
85
            }
85
            }
86
        } else {
86
        } else {
87
            admin.putRequest(id, request, countDownLatch);            
87
            admin.putRequest(id, request, countDownLatch);
88
            producer.send(request, deliveryMode, priority, expiration);
88
            producer.send(request, deliveryMode, priority, expiration);
89
        }
89
        }
90
90
Lines 95-101 public class FixedQueueExecutor implements QueueExecutor { Link Here
95
            // This used to be request.wait(timeout_ms), where 0 means forever
95
            // This used to be request.wait(timeout_ms), where 0 means forever
96
            // However 0 means return immediately for the latch
96
            // However 0 means return immediately for the latch
97
            if (timeout == 0){
97
            if (timeout == 0){
98
                countDownLatch.await(); //
98
                countDownLatch.await();
99
            } else {
99
            } else {
100
                countDownLatch.await(timeout, TimeUnit.MILLISECONDS);
100
                countDownLatch.await(timeout, TimeUnit.MILLISECONDS);
101
            }
101
            }
(-)a/src/reports/org/apache/jmeter/gui/ReportGuiPackage.java (-4 / +2 lines)
Lines 570-583 public final class ReportGuiPackage implements LocaleChangeListener { Link Here
570
        // will flush it away):
570
        // will flush it away):
571
        updateCurrentNode();
571
        updateCurrentNode();
572
572
573
        // Forget about all GUIs we've created so far: we'll need to re-created
573
        // Forget about all GUIs created so far: we'll need to re-created them!
574
        // them all!
575
        guis = new HashMap<Class<?>, JMeterGUIComponent>();
574
        guis = new HashMap<Class<?>, JMeterGUIComponent>();
576
        nodesToGui = new HashMap<TestElement, JMeterGUIComponent>();
575
        nodesToGui = new HashMap<TestElement, JMeterGUIComponent>();
577
        testBeanGUIs = new HashMap<Class<?>, JMeterGUIComponent>();
576
        testBeanGUIs = new HashMap<Class<?>, JMeterGUIComponent>();
578
577
579
        // BeanInfo objects also contain locale-sensitive data -- flush them
578
        // BeanInfo objects also contain locale-sensitive data - flush them away
580
        // away:
581
        Introspector.flushCaches();
579
        Introspector.flushCaches();
582
580
583
        // Now put the current GUI in place. [This code was copied from the
581
        // Now put the current GUI in place. [This code was copied from the
(-)a/src/reports/org/apache/jmeter/report/gui/action/ReportActionRouter.java (-5 / +4 lines)
Lines 49-58 public final class ReportActionRouter implements ActionListener { Link Here
49
    private static final Object LOCK = new Object();
49
    private static final Object LOCK = new Object();
50
50
51
    private Map<String, HashSet<ActionListener>> preActionListeners =
51
    private Map<String, HashSet<ActionListener>> preActionListeners =
52
        new HashMap<String, HashSet<ActionListener>>();
52
            new HashMap<String, HashSet<ActionListener>>();
53
53
54
    private Map<String, HashSet<ActionListener>> postActionListeners =
54
    private Map<String, HashSet<ActionListener>> postActionListeners =
55
        new HashMap<String, HashSet<ActionListener>>();
55
            new HashMap<String, HashSet<ActionListener>>();
56
56
57
    private ReportActionRouter() {
57
    private ReportActionRouter() {
58
    }
58
    }
Lines 263-269 public final class ReportActionRouter implements ActionListener { Link Here
263
        Class<?> commandClass;
263
        Class<?> commandClass;
264
        try {
264
        try {
265
            listClasses = ClassFinder.findClassesThatExtend(JMeterUtils.getSearchPaths(), new Class[] { Class
265
            listClasses = ClassFinder.findClassesThatExtend(JMeterUtils.getSearchPaths(), new Class[] { Class
266
                    .forName("org.apache.jmeter.gui.action.Command") });
266
                .forName("org.apache.jmeter.gui.action.Command") });
267
            commands = new HashMap<String, Set<Command>>(listClasses.size());
267
            commands = new HashMap<String, Set<Command>>(listClasses.size());
268
            if (listClasses.size() == 0) {
268
            if (listClasses.size() == 0) {
269
                log.warn("!!!!!Uh-oh, didn't find any action handlers!!!!!");
269
                log.warn("!!!!!Uh-oh, didn't find any action handlers!!!!!");
Lines 272-278 public final class ReportActionRouter implements ActionListener { Link Here
272
            while (iterClasses.hasNext()) {
272
            while (iterClasses.hasNext()) {
273
                String strClassName = iterClasses.next();
273
                String strClassName = iterClasses.next();
274
                if (strClassName.startsWith("org.apache.jmeter.report.gui.action")) {
274
                if (strClassName.startsWith("org.apache.jmeter.report.gui.action")) {
275
                    // log.info("classname:: " + strClassName);
276
                    commandClass = Class.forName(strClassName);
275
                    commandClass = Class.forName(strClassName);
277
                    if (!Modifier.isAbstract(commandClass.getModifiers())) {
276
                    if (!Modifier.isAbstract(commandClass.getModifiers())) {
278
                        command = (Command) commandClass.newInstance();
277
                        command = (Command) commandClass.newInstance();
Lines 304-310 public final class ReportActionRouter implements ActionListener { Link Here
304
    public static ReportActionRouter getInstance() {
303
    public static ReportActionRouter getInstance() {
305
        if (router == null) {
304
        if (router == null) {
306
            synchronized (LOCK) {
305
            synchronized (LOCK) {
307
                if(router == null) {
306
                if (router == null) {
308
                    router = new ReportActionRouter();
307
                    router = new ReportActionRouter();
309
                    router.populateCommandMap();
308
                    router.populateCommandMap();
310
                }
309
                }
(-)a/src/reports/org/apache/jmeter/report/gui/action/ReportDragNDrop.java (-7 / +12 lines)
Lines 24-36 import java.util.Set; Link Here
24
24
25
import org.apache.jmeter.control.Controller;
25
import org.apache.jmeter.control.Controller;
26
import org.apache.jmeter.gui.ReportGuiPackage;
26
import org.apache.jmeter.gui.ReportGuiPackage;
27
import org.apache.jmeter.report.gui.action.AbstractAction;
28
import org.apache.jmeter.report.gui.tree.ReportTreeListener;
27
import org.apache.jmeter.report.gui.tree.ReportTreeListener;
29
import org.apache.jmeter.report.gui.tree.ReportTreeNode;
28
import org.apache.jmeter.report.gui.tree.ReportTreeNode;
30
import org.apache.jmeter.samplers.Sampler;
29
import org.apache.jmeter.samplers.Sampler;
31
import org.apache.jmeter.testelement.TestElement;
30
import org.apache.jmeter.testelement.TestElement;
32
import org.apache.jmeter.testelement.TestPlan;
31
import org.apache.jmeter.testelement.TestPlan;
33
import org.apache.jmeter.testelement.WorkBench;
32
import org.apache.jmeter.testelement.WorkBench;
33
import org.apache.jorphan.logging.LoggingManager;
34
import org.apache.log.Logger;
34
35
35
public class ReportDragNDrop extends AbstractAction {
36
public class ReportDragNDrop extends AbstractAction {
36
    public static final String ADD = "drag_n_drop.add";//$NON-NLS-1$
37
    public static final String ADD = "drag_n_drop.add";//$NON-NLS-1$
Lines 39-44 public class ReportDragNDrop extends AbstractAction { Link Here
39
40
40
    public static final String INSERT_AFTER = "drag_n_drop.insert_after";//$NON-NLS-1$
41
    public static final String INSERT_AFTER = "drag_n_drop.insert_after";//$NON-NLS-1$
41
42
43
    private static final Logger log = LoggingManager.getLoggerForClass();
44
42
    private static final Set<String> commands = new HashSet<String>();
45
    private static final Set<String> commands = new HashSet<String>();
43
    static {
46
    static {
44
        commands.add(ADD);
47
        commands.add(ADD);
Lines 61-67 public class ReportDragNDrop extends AbstractAction { Link Here
61
        if (te instanceof TestPlan || te instanceof WorkBench) {
64
        if (te instanceof TestPlan || te instanceof WorkBench) {
62
            parentNode = null; // So elements can only be added as children
65
            parentNode = null; // So elements can only be added as children
63
        }
66
        }
64
        // System.out.println(action+" "+te.getClass().getName());
67
        if (log.isDebugEnabled()) {
68
            log.debug(action + " " + te.getClass().getName());
69
        }
65
70
66
        if (ADD.equals(action) && canAddTo(currentNode)) {
71
        if (ADD.equals(action) && canAddTo(currentNode)) {
67
            removeNodesFromParents(draggedNodes);
72
            removeNodesFromParents(draggedNodes);
Lines 72-85 public class ReportDragNDrop extends AbstractAction { Link Here
72
        } else if (INSERT_BEFORE.equals(action) && canAddTo(parentNode)) {
77
        } else if (INSERT_BEFORE.equals(action) && canAddTo(parentNode)) {
73
            removeNodesFromParents(draggedNodes);
78
            removeNodesFromParents(draggedNodes);
74
            for (int i = 0; i < draggedNodes.length; i++) {
79
            for (int i = 0; i < draggedNodes.length; i++) {
75
                @SuppressWarnings("null")
76
                int index = parentNode.getIndex(currentNode); // can't be null - this is checked by canAddTo
80
                int index = parentNode.getIndex(currentNode); // can't be null - this is checked by canAddTo
77
                ReportGuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], parentNode, index);
81
                ReportGuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], parentNode, index);
78
            }
82
            }
79
        } else if (INSERT_AFTER.equals(action) && canAddTo(parentNode)) {
83
        } else if (INSERT_AFTER.equals(action) && canAddTo(parentNode)) {
80
            removeNodesFromParents(draggedNodes);
84
            removeNodesFromParents(draggedNodes);
81
            for (int i = 0; i < draggedNodes.length; i++) {
85
            for (int i = 0; i < draggedNodes.length; i++) {
82
                @SuppressWarnings("null")
83
                int index = parentNode.getIndex(currentNode) + 1; // can't be null - this is checked by canAddTo
86
                int index = parentNode.getIndex(currentNode) + 1; // can't be null - this is checked by canAddTo
84
                ReportGuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], parentNode, index);
87
                ReportGuiPackage.getInstance().getTreeModel().insertNodeInto(draggedNodes[i], parentNode, index);
85
            }
88
            }
Lines 99-105 public class ReportDragNDrop extends AbstractAction { Link Here
99
            return false;
102
            return false;
100
        }
103
        }
101
        TestElement te = parentNode.getTestElement();
104
        TestElement te = parentNode.getTestElement();
102
        // System.out.println("Add to: "+te.getClass().getName());
105
        if (log.isDebugEnabled()){
106
            log.debug("Add to: " + te.getClass().getName());
107
        }
103
        if (te instanceof Controller) {
108
        if (te instanceof Controller) {
104
            return true;
109
            return true;
105
        }
110
        }
Lines 116-123 public class ReportDragNDrop extends AbstractAction { Link Here
116
    }
121
    }
117
122
118
    protected void removeNodesFromParents(ReportTreeNode[] nodes) {
123
    protected void removeNodesFromParents(ReportTreeNode[] nodes) {
119
        for (int i = 0; i < nodes.length; i++) {
124
        for (ReportTreeNode node : nodes) {
120
            ReportGuiPackage.getInstance().getTreeModel().removeNodeFromParent(nodes[i]);
125
            ReportGuiPackage.getInstance().getTreeModel().removeNodeFromParent(node);
121
        }
126
        }
122
    }
127
    }
123
128
(-)a/src/reports/org/apache/jmeter/report/gui/tree/ReportTreeNode.java (-3 / +1 lines)
Lines 44-51 public class ReportTreeNode extends DefaultMutableTreeNode implements Link Here
44
44
45
    private final ReportTreeModel treeModel;
45
    private final ReportTreeModel treeModel;
46
46
47
    // boolean enabled = true;
48
49
    public ReportTreeNode() {// Allow serializable test to work
47
    public ReportTreeNode() {// Allow serializable test to work
50
        // TODO: is the serializable test necessary now that JMeterTreeNode is
48
        // TODO: is the serializable test necessary now that JMeterTreeNode is
51
        // no longer a GUI component?
49
        // no longer a GUI component?
Lines 78-84 public class ReportTreeNode extends DefaultMutableTreeNode implements Link Here
78
                            getTestElement().getClass()).getIcon(
76
                            getTestElement().getClass()).getIcon(
79
                            BeanInfo.ICON_COLOR_16x16);
77
                            BeanInfo.ICON_COLOR_16x16);
80
                    // If icon has not been defined, then use GUI_CLASS property
78
                    // If icon has not been defined, then use GUI_CLASS property
81
                    if (img == null) {//
79
                    if (img == null) {
82
                        Object clazz = Introspector.getBeanInfo(
80
                        Object clazz = Introspector.getBeanInfo(
83
                                getTestElement().getClass())
81
                                getTestElement().getClass())
84
                                .getBeanDescriptor().getValue(
82
                                .getBeanDescriptor().getValue(
(-)a/test/src/org/apache/jmeter/visualizers/GenerateTreeGui.java (-16 / +13 lines)
Lines 52-66 import org.apache.jmeter.util.JMeterUtils; Link Here
52
/**
52
/**
53
 * Workbench test element to create a test plan containing samples of each test element
53
 * Workbench test element to create a test plan containing samples of each test element
54
 * (apart from Threads and Test Fragment).
54
 * (apart from Threads and Test Fragment).
55
 * 
55
 *
56
 * The user creates a Thread Group, and the elements are created as child elements of
56
 * The user creates a Thread Group, and the elements are created as child elements of
57
 * Simple Controllers.
57
 * Simple Controllers.
58
 * 
58
 *
59
 * Note: the code currently runs on all versions of JMeter back to 2.2.
59
 * Note: the code currently runs on all versions of JMeter back to 2.2.
60
 * Beware of making changes that rely on more recent APIs.
60
 * Beware of making changes that rely on more recent APIs.
61
 */
61
 */
62
public class GenerateTreeGui extends AbstractConfigGui
62
public class GenerateTreeGui extends AbstractConfigGui
63
    implements ActionListener, UnsharedComponent {
63
                            implements ActionListener, UnsharedComponent {
64
64
65
    private static final long serialVersionUID = 1L;
65
    private static final long serialVersionUID = 1L;
66
66
Lines 119-125 public class GenerateTreeGui extends AbstractConfigGui Link Here
119
            JMeterTreeNode myTarget) {
119
            JMeterTreeNode myTarget) {
120
        myTarget = addSimpleController(treeModel, myTarget, title);
120
        myTarget = addSimpleController(treeModel, myTarget, title);
121
        JPopupMenu jp = MenuFactory.makeMenu(menuKey, "").getPopupMenu();
121
        JPopupMenu jp = MenuFactory.makeMenu(menuKey, "").getPopupMenu();
122
        for(Component comp : jp.getComponents()) {
122
        for (Component comp : jp.getComponents()) {
123
            JMenuItem jmi = (JMenuItem) comp;
123
            JMenuItem jmi = (JMenuItem) comp;
124
            try {
124
            try {
125
                TestElement testElement = guiPackage.createTestElement(jmi.getName());
125
                TestElement testElement = guiPackage.createTestElement(jmi.getName());
Lines 156-180 public class GenerateTreeGui extends AbstractConfigGui Link Here
156
        return labelPanel;
156
        return labelPanel;
157
    }
157
    }
158
158
159
160
    /**
159
    /**
161
     * Initialize the components and layout of this component.
160
     * Initialize the components and layout of this component.
162
     */
161
     */
163
    private void init() {
162
    private void init() {
164
        JPanel p = this;
163
        JPanel p = this;
165
164
166
            setLayout(new BorderLayout(0, 5));
165
        setLayout(new BorderLayout(0, 5));
167
            setBorder(makeBorder());
166
        setBorder(makeBorder());
168
            add(makeTitlePanel(), BorderLayout.NORTH);
167
        add(makeTitlePanel(), BorderLayout.NORTH);
169
            p = new JPanel();
168
        p = new JPanel();
170
169
171
        p.setLayout(new BorderLayout());
170
        p.setLayout(new BorderLayout());
172
171
173
        p.add(makeLabelPanel(), BorderLayout.NORTH);
172
        p.add(makeLabelPanel(), BorderLayout.NORTH);
174
//        p.add(makeMainPanel(), BorderLayout.CENTER);
175
        // Force a minimum table height of 70 pixels
173
        // Force a minimum table height of 70 pixels
176
        p.add(Box.createVerticalStrut(70), BorderLayout.WEST);
174
        p.add(Box.createVerticalStrut(70), BorderLayout.WEST);
177
        //p.add(makeButtonPanel(), BorderLayout.SOUTH);
178
175
179
        add(p, BorderLayout.CENTER);
176
        add(p, BorderLayout.CENTER);
180
    }
177
    }
Lines 187-193 public class GenerateTreeGui extends AbstractConfigGui Link Here
187
     *            Node in the tree where we will add the Controller
184
     *            Node in the tree where we will add the Controller
188
     * @param name
185
     * @param name
189
     *            A name for the Controller
186
     *            A name for the Controller
190
     * @return the new node 
187
     * @return the new node
191
     */
188
     */
192
    private JMeterTreeNode addSimpleController(JMeterTreeModel model, JMeterTreeNode node, String name) {
189
    private JMeterTreeNode addSimpleController(JMeterTreeModel model, JMeterTreeNode node, String name) {
193
        final TestElement sc = new GenericController();
190
        final TestElement sc = new GenericController();
Lines 208-221 public class GenerateTreeGui extends AbstractConfigGui Link Here
208
        }
205
        }
209
206
210
        volatile JMeterTreeNode newNode;
207
        volatile JMeterTreeNode newNode;
211
        
208
212
        @Override
209
        @Override
213
        public void run() {
210
        public void run() {
214
            try {
211
            try {
215
                newNode = model.addComponent(testElement, node);
212
                newNode = model.addComponent(testElement, node);
216
            } catch (IllegalUserActionException e) {
213
            } catch (IllegalUserActionException e) {
217
                 throw new Error(e);
214
                throw new Error(e);
218
            }               
215
            }
219
        }
216
        }
220
    }
217
    }
221
218
Lines 243-249 public class GenerateTreeGui extends AbstractConfigGui Link Here
243
     *
240
     *
244
     * @param type
241
     * @param type
245
     *            class of the node to be found
242
     *            class of the node to be found
246
     * @param treeModel 
243
     * @param treeModel
247
     *
244
     *
248
     * @return the first node of the given type in the test component tree, or
245
     * @return the first node of the given type in the test component tree, or
249
     *         <code>null</code> if none was found.
246
     *         <code>null</code> if none was found.
(-)a/xdocs/changes.xml (-6 / +5 lines)
Lines 331-341 for details on configuring this component.</li> Link Here
331
<li><bugzilla>56921</bugzilla> - Templates : Improve Recording template to ignore embedded resources case and URL parameters. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
331
<li><bugzilla>56921</bugzilla> - Templates : Improve Recording template to ignore embedded resources case and URL parameters. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
332
<li><bugzilla>42248</bugzilla> - Undo-redo support on Test Plan tree modification. Developed by Andrey Pohilko (apc4 at ya.ru) and contributed by BlazeMeter Ltd. Additional contribution by Ubik Load Pack (support at ubikloadpack.com)</li>
332
<li><bugzilla>42248</bugzilla> - Undo-redo support on Test Plan tree modification. Developed by Andrey Pohilko (apc4 at ya.ru) and contributed by BlazeMeter Ltd. Additional contribution by Ubik Load Pack (support at ubikloadpack.com)</li>
333
<li><bugzilla>56920</bugzilla> - LogViewer : Make it receive all log events even when it is closed. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
333
<li><bugzilla>56920</bugzilla> - LogViewer : Make it receive all log events even when it is closed. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
334
<li><bugzilla>57083</bugzilla> - simplified the CachedResourceMode enum. Contributed by Graham Russel (graham at ham1.co.uk)</li>
334
<li><bugzilla>57083</bugzilla> - simplified the CachedResourceMode enum. Contributed by Graham Russell (graham at ham1.co.uk)</li>
335
<li><bugzilla>57082</bugzilla> - ComboStringEditor : Added hashCode to an inner class which overwrote equals. Contributed by Graham Russel (graham at ham1.co.uk)</li>
335
<li><bugzilla>57082</bugzilla> - ComboStringEditor : Added hashCode to an inner class which overwrote equals. Contributed by Graham Russell (graham at ham1.co.uk)</li>
336
<li><bugzilla>57081</bugzilla> - Updating checkstyle to only check for tabs in java files (and not images!). Contributed by Graham Russel (graham at ham1.co.uk)</li>
336
<li><bugzilla>57081</bugzilla> - Updating checkstyle to only check for tabs in java files (and not images!). Contributed by Graham Russell (graham at ham1.co.uk)</li>
337
<li><bugzilla>56178</bugzilla> - Really replace backslashes in user name before generating proxy certificate. Contributed by Graham Russel (graham at ham1.co.uk)</li>
337
<li><bugzilla>56178</bugzilla> - Really replace backslashes in user name before generating proxy certificate. Contributed by Graham Russell (graham at ham1.co.uk)</li>
338
<li><bugzilla>57084</bugzilla> - Close socket after usage in BeahShellClient. Contributed by Graham Russel (graham at ham1.co.uk)</li>
338
<li><bugzilla>57084</bugzilla> - Close socket after usage in BeahShellClient. Contributed by Graham Russell (graham at ham1.co.uk)</li>
339
</ul>
339
</ul>
340
<ch_section>Non-functional changes</ch_section>
340
<ch_section>Non-functional changes</ch_section>
341
<ul>
341
<ul>
342
- 

Return to bug 57110