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

(-)src/core/org/apache/jmeter/gui/Replaceable.java (+42 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.gui;
20
21
/**
22
 * Interface for nodes that have replaceable content.
23
 * <p>
24
 * A {@link Replaceable} component will get asked for tokens, that should be used
25
 * in a search. These tokens will then be matched against a user given search
26
 * string.
27
 * @since 3.2
28
 */
29
public interface Replaceable {
30
    /**
31
     * Replace in object  by replaceBy
32
     *
33
     * @param regex Regular expression
34
     * @param replaceBy Text replacing
35
     * @param caseSensitive
36
     * @return number of replacements
37
     * @throws Exception
38
     *             when something fails while replacing
39
     */
40
    int replace(String regex, String replaceBy, boolean caseSensitive)
41
        throws Exception;
42
}
(-)src/core/org/apache/jmeter/gui/action/SearchTreeDialog.java (-17 / +112 lines)
Lines 19-31 Link Here
19
package org.apache.jmeter.gui.action;
19
package org.apache.jmeter.gui.action;
20
20
21
import java.awt.BorderLayout;
21
import java.awt.BorderLayout;
22
import java.awt.Dimension;
22
import java.awt.FlowLayout;
23
import java.awt.FlowLayout;
23
import java.awt.Font;
24
import java.awt.Font;
24
import java.awt.event.ActionEvent;
25
import java.awt.event.ActionEvent;
25
import java.awt.event.ActionListener;
26
import java.awt.event.ActionListener;
27
import java.text.MessageFormat;
26
import java.util.HashSet;
28
import java.util.HashSet;
27
import java.util.List;
29
import java.util.List;
28
import java.util.Set;
30
import java.util.Set;
31
import java.util.regex.Pattern;
29
32
30
import javax.swing.AbstractAction;
33
import javax.swing.AbstractAction;
31
import javax.swing.Action;
34
import javax.swing.Action;
Lines 38-43 Link Here
38
import javax.swing.JComponent;
41
import javax.swing.JComponent;
39
import javax.swing.JDialog;
42
import javax.swing.JDialog;
40
import javax.swing.JFrame;
43
import javax.swing.JFrame;
44
import javax.swing.JLabel;
41
import javax.swing.JPanel;
45
import javax.swing.JPanel;
42
import javax.swing.JRootPane;
46
import javax.swing.JRootPane;
43
import javax.swing.JTree;
47
import javax.swing.JTree;
Lines 46-54 Link Here
46
50
47
import org.apache.commons.lang3.StringUtils;
51
import org.apache.commons.lang3.StringUtils;
48
import org.apache.jmeter.gui.GuiPackage;
52
import org.apache.jmeter.gui.GuiPackage;
53
import org.apache.jmeter.gui.Replaceable;
49
import org.apache.jmeter.gui.Searchable;
54
import org.apache.jmeter.gui.Searchable;
50
import org.apache.jmeter.gui.tree.JMeterTreeModel;
55
import org.apache.jmeter.gui.tree.JMeterTreeModel;
51
import org.apache.jmeter.gui.tree.JMeterTreeNode;
56
import org.apache.jmeter.gui.tree.JMeterTreeNode;
57
import org.apache.jmeter.testelement.TestElement;
52
import org.apache.jmeter.util.JMeterUtils;
58
import org.apache.jmeter.util.JMeterUtils;
53
import org.apache.jorphan.gui.ComponentUtil;
59
import org.apache.jorphan.gui.ComponentUtil;
54
import org.apache.jorphan.gui.JLabeledTextField;
60
import org.apache.jorphan.gui.JLabeledTextField;
Lines 72-77 Link Here
72
78
73
    private JLabeledTextField searchTF;
79
    private JLabeledTextField searchTF;
74
80
81
    private JLabeledTextField replaceTF;
82
83
    private JLabel statusLabel;
84
75
    private JCheckBox isRegexpCB;
85
    private JCheckBox isRegexpCB;
76
86
77
    private JCheckBox isCaseSensitiveCB;
87
    private JCheckBox isCaseSensitiveCB;
Lines 84-89 Link Here
84
    private transient String lastSearch = null;
94
    private transient String lastSearch = null;
85
95
86
    private JButton searchAndExpandButton;
96
    private JButton searchAndExpandButton;
97
    
98
    private JButton replaceButton;
87
99
88
    public SearchTreeDialog() {
100
    public SearchTreeDialog() {
89
        super((JFrame) null, JMeterUtils.getResString("search_tree_title"), true); //$NON-NLS-1$
101
        super((JFrame) null, JMeterUtils.getResString("search_tree_title"), true); //$NON-NLS-1$
Lines 130-137 Link Here
130
        if(!StringUtils.isEmpty(lastSearch)) {
142
        if(!StringUtils.isEmpty(lastSearch)) {
131
            searchTF.setText(lastSearch);
143
            searchTF.setText(lastSearch);
132
        }
144
        }
145
        
146
        replaceTF = new JLabeledTextField(JMeterUtils.getResString("search_text_replace"), 20); //$NON-NLS-1$
147
        statusLabel = new JLabel();
148
        statusLabel.setMinimumSize(new Dimension(100, 30));
133
        isRegexpCB = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_regexp"), false); //$NON-NLS-1$
149
        isRegexpCB = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_regexp"), false); //$NON-NLS-1$
134
        isCaseSensitiveCB = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_case"), false); //$NON-NLS-1$
150
        isCaseSensitiveCB = new JCheckBox(JMeterUtils.getResString("search_text_chkbox_case"), true); //$NON-NLS-1$
135
        
151
        
136
        isRegexpCB.setFont(FONT_SMALL);
152
        isRegexpCB.setFont(FONT_SMALL);
137
        isCaseSensitiveCB.setFont(FONT_SMALL);
153
        isCaseSensitiveCB.setFont(FONT_SMALL);
Lines 142-163 Link Here
142
158
143
        JPanel searchPanel = new JPanel();
159
        JPanel searchPanel = new JPanel();
144
        searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.Y_AXIS));
160
        searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.Y_AXIS));
145
        searchPanel.setBorder(BorderFactory.createEmptyBorder(7, 3, 3, 3));
161
        searchPanel.setBorder(BorderFactory.createEmptyBorder(7, 3, 3, 3));        
146
        searchPanel.add(searchTF, BorderLayout.NORTH);
162
        searchPanel.add(searchTF);
147
        searchPanel.add(searchCriterionPanel, BorderLayout.CENTER);
163
        searchPanel.add(replaceTF);
148
        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
164
        searchPanel.add(statusLabel);
149
165
166
        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
150
        searchButton = new JButton(JMeterUtils.getResString("search")); //$NON-NLS-1$
167
        searchButton = new JButton(JMeterUtils.getResString("search")); //$NON-NLS-1$
151
        searchButton.addActionListener(this);
168
        searchButton.addActionListener(this);
152
        searchAndExpandButton = new JButton(JMeterUtils.getResString("search_expand")); //$NON-NLS-1$
169
        searchAndExpandButton = new JButton(JMeterUtils.getResString("search_expand")); //$NON-NLS-1$
153
        searchAndExpandButton.addActionListener(this);
170
        searchAndExpandButton.addActionListener(this);
171
        replaceButton = new JButton(JMeterUtils.getResString("search_replace_all")); //$NON-NLS-1$
172
        replaceButton.addActionListener(this);
154
        cancelButton = new JButton(JMeterUtils.getResString("cancel")); //$NON-NLS-1$
173
        cancelButton = new JButton(JMeterUtils.getResString("cancel")); //$NON-NLS-1$
155
        cancelButton.addActionListener(this);
174
        cancelButton.addActionListener(this);
156
        buttonsPanel.add(searchButton);
175
        buttonsPanel.add(searchButton);
157
        buttonsPanel.add(searchAndExpandButton);
176
        buttonsPanel.add(searchAndExpandButton);
177
        buttonsPanel.add(replaceButton);
158
        buttonsPanel.add(cancelButton);
178
        buttonsPanel.add(cancelButton);
159
        searchPanel.add(buttonsPanel, BorderLayout.SOUTH);
179
160
        this.getContentPane().add(searchPanel);
180
        JPanel searchAndReplacePanel = new JPanel();
181
        searchAndReplacePanel.setLayout(new BorderLayout());
182
        searchAndReplacePanel.add(searchPanel, BorderLayout.NORTH);
183
        searchAndReplacePanel.add(searchCriterionPanel, BorderLayout.CENTER);
184
        searchAndReplacePanel.add(buttonsPanel, BorderLayout.SOUTH);
185
        this.getContentPane().add(searchAndReplacePanel);
161
        searchTF.requestFocusInWindow();
186
        searchTF.requestFocusInWindow();
162
187
163
        this.pack();
188
        this.pack();
Lines 170-181 Link Here
170
     */
195
     */
171
    @Override
196
    @Override
172
    public void actionPerformed(ActionEvent e) {
197
    public void actionPerformed(ActionEvent e) {
198
        statusLabel.setText("");
173
        if (e.getSource()==cancelButton) {
199
        if (e.getSource()==cancelButton) {
174
            searchTF.requestFocusInWindow();
200
            searchTF.requestFocusInWindow();
175
            this.setVisible(false);
201
            this.setVisible(false);
176
            return;
202
            return;
203
        } else if(e.getSource() == searchButton ||
204
                e.getSource() == searchAndExpandButton) {
205
            doSearch(e);
206
        } else {
207
            doReplaceAll(e);
177
        }
208
        }
178
        doSearch(e);
179
    }
209
    }
180
210
181
    /**
211
    /**
Lines 202-217 Link Here
202
        GuiPackage guiPackage = GuiPackage.getInstance();
232
        GuiPackage guiPackage = GuiPackage.getInstance();
203
        JMeterTreeModel jMeterTreeModel = guiPackage.getTreeModel();
233
        JMeterTreeModel jMeterTreeModel = guiPackage.getTreeModel();
204
        Set<JMeterTreeNode> nodes = new HashSet<>();
234
        Set<JMeterTreeNode> nodes = new HashSet<>();
235
        int numberOfMatches = 0;
205
        for (JMeterTreeNode jMeterTreeNode : jMeterTreeModel.getNodesOfType(Searchable.class)) {
236
        for (JMeterTreeNode jMeterTreeNode : jMeterTreeModel.getNodesOfType(Searchable.class)) {
206
            try {
237
            try {
207
                if (jMeterTreeNode.getUserObject() instanceof Searchable){
238
                Searchable searchable = (Searchable) jMeterTreeNode.getUserObject();
208
                    Searchable searchable = (Searchable) jMeterTreeNode.getUserObject();
239
                List<JMeterTreeNode> matchingNodes = jMeterTreeNode.getPathToThreadGroup();
209
                    List<JMeterTreeNode> matchingNodes = jMeterTreeNode.getPathToThreadGroup();
240
                List<String> searchableTokens = searchable.getSearchableTokens();
210
                    List<String> searchableTokens = searchable.getSearchableTokens();
241
                boolean result = searcher.search(searchableTokens);
211
                    boolean result = searcher.search(searchableTokens);
242
                if (result) {
212
                    if (result) {
243
                    numberOfMatches++;
213
                        nodes.addAll(matchingNodes);
244
                    nodes.addAll(matchingNodes);
214
                    }
215
                }
245
                }
216
            } catch (Exception ex) {
246
            } catch (Exception ex) {
217
                logger.error("Error occured searching for word:"+ wordToSearch, ex);
247
                logger.error("Error occured searching for word:"+ wordToSearch, ex);
Lines 228-233 Link Here
228
        }
258
        }
229
        GuiPackage.getInstance().getMainFrame().repaint();
259
        GuiPackage.getInstance().getMainFrame().repaint();
230
        searchTF.requestFocusInWindow();
260
        searchTF.requestFocusInWindow();
231
        this.setVisible(false);
261
        if(numberOfMatches > 0) {
262
            statusLabel.setText(MessageFormat.format("{0} nodes match the search", new Object[]{numberOfMatches}));
263
        }
264
    }
265
    
266
    /**
267
     * @param e {@link ActionEvent}
268
     */
269
    private void doReplaceAll(ActionEvent e) {
270
        String wordToSearch = searchTF.getText();
271
        String wordToReplace = replaceTF.getText();
272
        
273
        if (StringUtils.isEmpty(wordToReplace)) {
274
            return;
275
        } 
276
        // reset previous result
277
        ActionRouter.getInstance().doActionNow(new ActionEvent(e.getSource(), e.getID(), ActionNames.SEARCH_RESET));
278
279
        Searcher searcher = null;
280
        String regex = null;
281
        if (isRegexpCB.isSelected()) {
282
            regex = wordToSearch;
283
            searcher = new RegexpSearcher(isCaseSensitiveCB.isSelected(), wordToSearch);
284
        } else {
285
            regex = Pattern.quote(wordToSearch);
286
            searcher = new RawTextSearcher(isCaseSensitiveCB.isSelected(), wordToSearch);
287
        }
288
        GuiPackage guiPackage = GuiPackage.getInstance();
289
        JMeterTreeModel jMeterTreeModel = guiPackage.getTreeModel();
290
        Set<JMeterTreeNode> nodes = new HashSet<>();
291
        boolean caseSensitiveReplacement = isCaseSensitiveCB.isSelected();
292
        int totalReplaced = 0;
293
        for (JMeterTreeNode jMeterTreeNode : jMeterTreeModel.getNodesOfType(Searchable.class)) {
294
            try {
295
                Searchable searchable = (Searchable) jMeterTreeNode.getUserObject();
296
                List<String> searchableTokens = searchable.getSearchableTokens();
297
                boolean result = searcher.search(searchableTokens);
298
                if (result) {
299
                    if(jMeterTreeNode.getUserObject() instanceof Replaceable) {
300
                        Replaceable replaceable = (Replaceable) jMeterTreeNode.getUserObject();
301
                        int numberOfReplacements = replaceable.replace(regex, wordToReplace, caseSensitiveReplacement);
302
                        if(logger.isInfoEnabled()) {
303
                            logger.info("Replaced "+numberOfReplacements+" in element:"+((TestElement)jMeterTreeNode.getUserObject()).getName());
304
                        }
305
                        totalReplaced += numberOfReplacements;
306
                        if(numberOfReplacements > 0) {
307
                            List<JMeterTreeNode> matchingNodes = jMeterTreeNode.getPathToThreadGroup();
308
                            nodes.addAll(matchingNodes);
309
                        }
310
                    }   
311
                }
312
            } catch (Exception ex) {
313
                logger.error("Error occured searching for word:"+ wordToSearch, ex);
314
            }
315
        }
316
        statusLabel.setText(MessageFormat.format("Replaced {0} occurences", new Object[]{totalReplaced}));
317
        GuiPackage guiInstance = GuiPackage.getInstance();
318
        JTree jTree = guiInstance.getMainFrame().getTree();
319
320
        for (JMeterTreeNode jMeterTreeNode : nodes) {
321
            jMeterTreeNode.setMarkedBySearch(true);
322
            jTree.expandPath(new TreePath(jMeterTreeNode.getPath()));
323
        }
324
        GuiPackage.getInstance().updateCurrentGui();
325
        GuiPackage.getInstance().getMainFrame().repaint();
326
        searchTF.requestFocusInWindow();
232
    }
327
    }
233
}
328
}
(-)src/core/org/apache/jmeter/resources/messages.properties (+2 lines)
Lines 957-962 Link Here
957
search_base=Search base
957
search_base=Search base
958
search_expand=Search & Expand
958
search_expand=Search & Expand
959
search_filter=Search Filter
959
search_filter=Search Filter
960
search_replace_all=Replace All
960
search_test=Search Test
961
search_test=Search Test
961
search_text_button_close=Close
962
search_text_button_close=Close
962
search_text_button_find=Find
963
search_text_button_find=Find
Lines 965-970 Link Here
965
search_text_chkbox_regexp=Regular exp.
966
search_text_chkbox_regexp=Regular exp.
966
search_text_field=Search: 
967
search_text_field=Search: 
967
search_text_msg_not_found=Text not found
968
search_text_msg_not_found=Text not found
969
search_text_replace=Replace by
968
search_text_title_not_found=Not found
970
search_text_title_not_found=Not found
969
search_tree_title=Search Tree
971
search_tree_title=Search Tree
970
searchbase=Search base
972
searchbase=Search base
(-)src/core/org/apache/jmeter/resources/messages_fr.properties (+2 lines)
Lines 947-952 Link Here
947
search_base=Base de recherche
947
search_base=Base de recherche
948
search_expand=Rechercher & D\u00E9plier
948
search_expand=Rechercher & D\u00E9plier
949
search_filter=Filtre de recherche
949
search_filter=Filtre de recherche
950
search_replace_all=Tout remplacer
950
search_test=Recherche
951
search_test=Recherche
951
search_text_button_close=Fermer
952
search_text_button_close=Fermer
952
search_text_button_find=Rechercher
953
search_text_button_find=Rechercher
Lines 955-960 Link Here
955
search_text_chkbox_regexp=Exp. reguli\u00E8re
956
search_text_chkbox_regexp=Exp. reguli\u00E8re
956
search_text_field=Rechercher \:
957
search_text_field=Rechercher \:
957
search_text_msg_not_found=Texte non trouv\u00E9
958
search_text_msg_not_found=Texte non trouv\u00E9
959
search_text_replace=Remplacer par
958
search_text_title_not_found=Pas trouv\u00E9
960
search_text_title_not_found=Pas trouv\u00E9
959
search_tree_title=Rechercher dans l'arbre
961
search_tree_title=Rechercher dans l'arbre
960
searchbase=Base de recherche
962
searchbase=Base de recherche
(-)src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSamplerBase.java (-1 / +34 lines)
Lines 46-51 Link Here
46
import org.apache.jmeter.config.Arguments;
46
import org.apache.jmeter.config.Arguments;
47
import org.apache.jmeter.config.ConfigTestElement;
47
import org.apache.jmeter.config.ConfigTestElement;
48
import org.apache.jmeter.engine.event.LoopIterationEvent;
48
import org.apache.jmeter.engine.event.LoopIterationEvent;
49
import org.apache.jmeter.gui.Replaceable;
49
import org.apache.jmeter.protocol.http.control.AuthManager;
50
import org.apache.jmeter.protocol.http.control.AuthManager;
50
import org.apache.jmeter.protocol.http.control.CacheManager;
51
import org.apache.jmeter.protocol.http.control.CacheManager;
51
import org.apache.jmeter.protocol.http.control.Cookie;
52
import org.apache.jmeter.protocol.http.control.Cookie;
Lines 93-99 Link Here
93
 *
94
 *
94
 */
95
 */
95
public abstract class HTTPSamplerBase extends AbstractSampler
96
public abstract class HTTPSamplerBase extends AbstractSampler
96
    implements TestStateListener, TestIterationListener, ThreadListener, HTTPConstantsInterface {
97
    implements TestStateListener, TestIterationListener, ThreadListener, HTTPConstantsInterface,
98
        Replaceable {
97
99
98
    private static final long serialVersionUID = 241L;
100
    private static final long serialVersionUID = 241L;
99
101
Lines 2036-2039 Link Here
2036
        String guiClass = configElement.getProperty(TestElement.GUI_CLASS).getStringValue();
2038
        String guiClass = configElement.getProperty(TestElement.GUI_CLASS).getStringValue();
2037
        return APPLIABLE_CONFIG_CLASSES.contains(guiClass);
2039
        return APPLIABLE_CONFIG_CLASSES.contains(guiClass);
2038
    }
2040
    }
2041
2042
    @Override
2043
    public int replace(String regex, String replaceBy, boolean caseSensitive) throws Exception {
2044
        int totalReplaced = 0;
2045
        for (JMeterProperty jMeterProperty : getArguments()) {
2046
            HTTPArgument arg = (HTTPArgument) jMeterProperty.getObjectValue();
2047
            String value = arg.getValue();
2048
            if(!StringUtils.isEmpty(value)) {
2049
                Object[] result = JOrphanUtils.replaceAllWithRegex(value, regex, replaceBy, caseSensitive);
2050
                //check if there is anything to replace
2051
                totalReplaced = ((Integer)result[1]).intValue();
2052
                if (totalReplaced>0) {
2053
                    String replacedText = (String) result[0];
2054
                    arg.setValue(replacedText);
2055
                }
2056
            }
2057
        }
2058
        
2059
        Object[] result = JOrphanUtils.replaceAllWithRegex(getPath(), regex, replaceBy, caseSensitive);
2060
        int nbReplaced = ((Integer)result[1]).intValue();
2061
        if (nbReplaced>0) {
2062
            totalReplaced += nbReplaced;
2063
            String replacedText = (String) result[0];
2064
            setPath(replacedText);
2065
        }
2066
        
2067
        if(totalReplaced == -1) {
2068
            return 0;
2069
        }
2070
        return totalReplaced;
2071
    }
2039
}
2072
}

Return to bug 54525