Index: /src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java =================================================================== --- /src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java (revision 784434) +++ /src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java (working copy) @@ -118,13 +118,13 @@ private static final String TEXT_HTML = "text/html"; // $NON-NLS-1$ - private static final String HTML_COMMAND = "html"; // $NON-NLS-1$ + protected static final String HTML_COMMAND = "html"; // $NON-NLS-1$ - private static final String JSON_COMMAND = "json"; // $NON-NLS-1$ + protected static final String JSON_COMMAND = "json"; // $NON-NLS-1$ - private static final String XML_COMMAND = "xml"; // $NON-NLS-1$ + protected static final String XML_COMMAND = "xml"; // $NON-NLS-1$ - private static final String TEXT_COMMAND = "text"; // $NON-NLS-1$ + protected static final String TEXT_COMMAND = "text"; // $NON-NLS-1$ private static final String STYLE_SERVER_ERROR = "ServerError"; // $NON-NLS-1$ @@ -161,7 +161,7 @@ private JTextPane stats; - private JEditorPane results; + protected JEditorPane results; private JScrollPane resultsScrollPane; @@ -183,9 +183,9 @@ private JCheckBox downloadAll; - private JTree jTree; + protected JTree jTree; - private JTabbedPane rightSide; + protected JTabbedPane rightSide; private static final ImageIcon imageSuccess = JMeterUtils.getImage( JMeterUtils.getPropDefault("viewResultsTree.success", //$NON-NLS-1$ @@ -453,7 +453,7 @@ log.debug("End : valueChanged1"); } - private void showImage(Icon image) { + protected void showImage(Icon image) { imageLabel.setIcon(image); resultsScrollPane.setViewportView(imageLabel); textButton.setEnabled(false); @@ -462,7 +462,7 @@ xmlButton.setEnabled(false); } - private void showTextResponse(String response) { + protected void showTextResponse(String response) { results.setContentType("text/plain"); // $NON-NLS-1$ results.setText(response == null ? "" : response); // $NON-NLS-1$ results.setCaretPosition(0); @@ -529,7 +529,7 @@ return pretty.toString(); } - private void showRenderJSONResponse(String response) { + protected void showRenderJSONResponse(String response) { results.setContentType("text/plain"); // $NON-NLS-1$ results.setText(response == null ? "" : prettyJSON(response)); results.setCaretPosition(0); @@ -541,7 +541,7 @@ xmlButton.setEnabled(true); } - private void showRenderXMLResponse(SampleResult res) { + protected void showRenderXMLResponse(SampleResult res) { results.setContentType("text/xml"); // $NON-NLS-1$ results.setCaretPosition(0); byte[] source = res.getResponseData(); @@ -576,7 +576,7 @@ xmlButton.setEnabled(true); } - private static String getResponseAsString(SampleResult res) { + protected static String getResponseAsString(SampleResult res) { String response = null; if ((SampleResult.TEXT).equals(res.getDataType())) { @@ -638,7 +638,7 @@ } } - private void showRenderedResponse(String response, SampleResult res) { + protected void showRenderedResponse(String response, SampleResult res) { if (response == null) { results.setText(""); return; @@ -734,7 +734,7 @@ /** * Initialize this visualizer */ - private void init() { + protected void init() { setLayout(new BorderLayout(0, 5)); setBorder(makeBorder()); @@ -752,7 +752,7 @@ add(mainSplit, BorderLayout.CENTER); } - private void setupTabPaneForSampleResult() { + protected void setupTabPaneForSampleResult() { // Set the title for the first tab rightSide.setTitleAt(0, JMeterUtils.getResString("view_results_tab_sampler")); //$NON-NLS-1$ // Add the other tabs if not present @@ -764,7 +764,7 @@ } } - private void setupTabPaneForAssertionResult() { + protected void setupTabPaneForAssertionResult() { // Set the title for the first tab rightSide.setTitleAt(0, JMeterUtils.getResString("view_results_tab_assertion")); //$NON-NLS-1$ // Remove the other tabs if present Index: /src/components/org/apache/jmeter/visualizers/ViewResultsWithRegexpTester.java =================================================================== --- /src/components/org/apache/jmeter/visualizers/ViewResultsWithRegexpTester.java (revision 0) +++ /src/components/org/apache/jmeter/visualizers/ViewResultsWithRegexpTester.java (revision 0) @@ -0,0 +1,215 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.jmeter.visualizers; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; + +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTextArea; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.tree.DefaultMutableTreeNode; + +import org.apache.jmeter.samplers.SampleResult; +import org.apache.jmeter.util.JMeterUtils; +import org.apache.jmeter.util.RegexpExtractor; +import org.apache.jorphan.gui.JLabeledTextField; +import org.apache.jorphan.logging.LoggingManager; +import org.apache.log.Logger; + +/** + * Extend ViewResultatsFullVisualizer to test a regexp in response data + * + */ +public class ViewResultsWithRegexpTester extends ViewResultsFullVisualizer { + + private static final long serialVersionUID = -985808335882006762L; + + private static final Logger log = LoggingManager.getLoggerForClass(); + + private static final String REGEXP_TESTER_COMMAND = "regexp_tester"; // $NON-NLS-1$ + + // set command to RegExp Tester + private String command = REGEXP_TESTER_COMMAND; + + private JPanel regexpPane; + + private JTextArea regexpDataField; + + private JLabeledTextField regexpField; + + private JTextArea regexpResultField; + + public ViewResultsWithRegexpTester() { + super(); + init(); + } + + public String getLabelResource() { + return "regexp_tester_title"; // $NON-NLS-1$ + } + + /** + * Returns the description of this visualizer. + * + * @return description of this visualizer + */ + public String toString() { + String desc = "Shows the text results of sampling in tree form"; + return desc; + } + + /** + * Sets the right pane to correspond to the selected node of the left tree. + */ + public void valueChanged(TreeSelectionEvent e) { + super.valueChanged(e); + + DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree + .getLastSelectedPathComponent(); + + regexpDataField.setText(""); // $NON-NLS-1$ + // don't set empty to keep regexp + //regexpField.setText(""); // $NON-NLS-1$ + regexpResultField.setText(""); // $NON-NLS-1$ + + if (node != null) { + Object userObject = node.getUserObject(); + if (userObject instanceof SampleResult) { + SampleResult res = (SampleResult) userObject; + + // get the text response and image icon + // to determine which is NOT null + if ((SampleResult.TEXT).equals(res.getDataType())) { + String response = getResponseAsString(res); + regexpDataField.setText(response); + regexpDataField.setCaretPosition(0); + } + } + } + } + + /** + * Launch regexp engine to parse a input text + * @param textToParse + */ + private void executeAndShowRegexpTester(String textToParse) { + if (textToParse.length() > 0 && this.regexpField.getText().length() > 0) { + RegexpExtractor ree = new RegexpExtractor(); + log.debug("regexpField = " + this.regexpField.getText()); + ree.setRegex(this.regexpField.getText()); + ree.setInputString(textToParse); + this.regexpResultField.setText(ree.process()); + } + } + + /** + * Display the response as text or as rendered HTML. Change the text on the + * button appropriate to the current display. + * + * @param e the ActionEvent being processed + */ + public void actionPerformed(ActionEvent e) { + super.actionPerformed(e); + command = e.getActionCommand(); + if (command != null && (command.equals(REGEXP_TESTER_COMMAND))) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree + .getLastSelectedPathComponent(); + if (node == null) { + results.setText(""); + return; + } + SampleResult res = (SampleResult) node.getUserObject(); + String response = getResponseAsString(res); + executeAndShowRegexpTester(response); + } + } + + /** + * Initialize this visualizer + */ + protected void init() { + super.init(); + // Create the panels for the regexp tab + regexpPane = createRegexpPanel(); + } + + /* (non-Javadoc) + * @see org.apache.jmeter.visualizers.ViewResultsFullVisualizer#setupTabPaneForSampleResult() + */ + protected void setupTabPaneForSampleResult() { + super.setupTabPaneForSampleResult(); + // Add regexp tester pane + if (rightSide.indexOfTab(JMeterUtils.getResString("view_results_tab_regexp_tester")) < 0) { // $NON-NLS-1$ + rightSide.addTab(JMeterUtils.getResString("view_results_tab_regexp_tester"), regexpPane); // $NON-NLS-1$ + } + } + + /** + * @return RegExp Tester panel + */ + private JPanel createRegexpPanel() { + regexpDataField = new JTextArea(); + regexpDataField.setEditable(false); + regexpDataField.setLineWrap(true); + regexpDataField.setWrapStyleWord(true); + + JScrollPane regexpDataPane = makeScrollPane(regexpDataField); + regexpDataPane.setMinimumSize(new Dimension(0, 200)); + + JPanel pane = new JPanel(new BorderLayout(0, 5)); + + JSplitPane mainSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, + regexpDataPane, createRegexpTasksPanel()); + mainSplit.setDividerLocation(300); + pane.add(mainSplit, BorderLayout.CENTER); + return pane; + } + + /** + * Create the Regexp task pane + * + * @return Regexp task pane + */ + private JPanel createRegexpTasksPanel() { + JPanel regexpActionPanel = new JPanel(); + regexpField = new JLabeledTextField(JMeterUtils.getResString("regexp_tester_field"), 30); // $NON-NLS-1$ + regexpActionPanel.add(regexpField, BorderLayout.WEST); + + JButton regexpTester = new JButton(JMeterUtils.getResString("regexp_tester_button_test")); + regexpTester.setActionCommand(REGEXP_TESTER_COMMAND); + regexpTester.addActionListener(this); + regexpActionPanel.add(regexpTester, BorderLayout.EAST); + + regexpResultField = new JTextArea(); + regexpResultField.setEditable(false); + regexpResultField.setLineWrap(true); + regexpResultField.setWrapStyleWord(true); + + JPanel regexpTasksPanel = new JPanel(new BorderLayout(0, 5)); + regexpTasksPanel.add(regexpActionPanel, BorderLayout.NORTH); + regexpTasksPanel.add(makeScrollPane(regexpResultField), BorderLayout.CENTER); + + return regexpTasksPanel; + } +} Index: /src/core/org/apache/jmeter/resources/messages.properties =================================================================== --- /src/core/org/apache/jmeter/resources/messages.properties (revision 784434) +++ /src/core/org/apache/jmeter/resources/messages.properties (working copy) @@ -612,6 +612,9 @@ regexfunc_param_4=Between text. If ALL is selected, the between text will be used to generate the results ([""]) regexfunc_param_5=Default text. Used instead of the template if the regular expression finds no matches ([""]) regexfunc_param_7=Input variable name containing the text to be parsed ([previous sample]) +regexp_tester_button_test=Test +regexp_tester_field=Regular expression: +regexp_tester_title=RegExp Tester remote_error_init=Error initialising remote server remote_error_starting=Error starting remote server remote_exit=Remote Exit @@ -886,6 +889,7 @@ view_results_sample_start=Sample Start: view_results_size_in_bytes=Size in bytes: view_results_tab_assertion=Assertion result +view_results_tab_regexp_tester=Regexp tester view_results_tab_request=Request view_results_tab_response=Response data view_results_tab_sampler=Sampler result Index: /src/core/org/apache/jmeter/resources/messages_fr.properties =================================================================== --- /src/core/org/apache/jmeter/resources/messages_fr.properties (revision 784434) +++ /src/core/org/apache/jmeter/resources/messages_fr.properties (working copy) @@ -505,6 +505,9 @@ regexfunc_param_3=Quelle correspondance utiliser. Un entier 1 ou plus grand, RAND pour indiquer que JMeter doit choisir al\u00E9atoirement , A d\u00E9cimal, ou ALL indique que toutes les correspondances doivent \u00EAtre utilis\u00E9es regexfunc_param_4=Entre le texte. Si ALL est s\u00E9lectionn\u00E9, l'entre-texte sera utilis\u00E9 pour g\u00E9n\u00E9rer les r\u00E9sultats ([""]) regexfunc_param_5=Text par d\u00E9faut. Utilis\u00E9 \u00E0 la place du canevas si l'expression r\u00E9guli\u00E8re ne trouve pas de correspondance +regexp_tester_button_test=Tester +regexp_tester_field=Expression r\u00E9guli\u00E8re \: +regexp_tester_title=Testeur de RegExp remote_exit=Sortie distante remote_exit_all=Sortie distante de tous remote_start=D\u00E9marrage distant @@ -733,6 +736,7 @@ view_results_sample_start=Date d\u00E9but \u00E9chantillon \: view_results_size_in_bytes=Taille en octets \: view_results_tab_assertion=R\u00E9sultats d'assertion +view_results_tab_regexp_tester=Testeur de regexp view_results_tab_request=Requ\u00EAte view_results_tab_response=Donn\u00E9es de r\u00E9ponse view_results_tab_sampler=R\u00E9sultat de l'\u00E9chantillon Index: /src/core/org/apache/jmeter/util/RegexpExtractor.java =================================================================== --- /src/core/org/apache/jmeter/util/RegexpExtractor.java (revision 0) +++ /src/core/org/apache/jmeter/util/RegexpExtractor.java (revision 0) @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jmeter.util; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.oro.text.PatternCacheLRU; +import org.apache.oro.text.regex.MatchResult; +import org.apache.oro.text.regex.Pattern; +import org.apache.oro.text.regex.PatternMatcherInput; +import org.apache.oro.text.regex.Perl5Compiler; +import org.apache.oro.text.regex.Perl5Matcher; + +/** + * Util to parse a test with a regexp + * + */ +public class RegexpExtractor { + + /** + * @return Multi-line string found by regexp engine + */ + public String process() { + + Perl5Matcher matcher = new Perl5Matcher(); + PatternMatcherInput input = new PatternMatcherInput(this.getInputString()); + + PatternCacheLRU pcLRU = new PatternCacheLRU(); + Pattern pattern = pcLRU.getPattern(this.getRegex(), Perl5Compiler.READ_ONLY_MASK); + List matches = new ArrayList(); + int x = 0; + boolean done = false; + do { + if (matcher.contains(input, pattern)) { + //log.debug("RegexExtractor: Match found!"); + matches.add(matcher.getMatch()); + } else { + done = true; + } + x++; + } while (!done); + + // Construct a multi-line string with all matches + StringBuffer sb = new StringBuffer(); + for (int j = 0; j < matches.size(); j++) { + MatchResult mr = (MatchResult) matches.get(j); + final int groups = mr.groups(); + for (int i = 0; i < groups; i++) { + sb.append(" group[" + j + "][" + i + "]=" + mr.group(i) + "\n"); + + } + } + return sb.toString(); + + } + private String inputString; + private String regex; + + public String getRegex() { + return regex; + } + + public void setRegex(String regex) { + this.regex = regex; + } + + public String getInputString() { + return inputString; + } + + public void setInputString(String inputString) { + this.inputString = inputString; + } +}