Author: sebb
Date: Sun Jun 10 11:07:10 2007
New Revision: 545917
URL: http://svn.apache.org/viewvc?view=rev&rev=545917
Log:
Bug 42582 - JSON pretty printing in Tree View Listener
Modified:
jakarta/jmeter/branches/rel-2-2/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
jakarta/jmeter/branches/rel-2-2/xdocs/changes.xml
jakarta/jmeter/branches/rel-2-2/xdocs/usermanual/component_reference.xml
Modified:
jakarta/jmeter/branches/rel-2-2/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/branches/rel-2-2/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java?view=diff&rev=545917&r1=545916&r2=545917
==============================================================================
---
jakarta/jmeter/branches/rel-2-2/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
(original)
+++
jakarta/jmeter/branches/rel-2-2/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
Sun Jun 10 11:07:10 2007
@@ -28,9 +28,12 @@
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
+import java.lang.Character;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
@@ -116,6 +119,8 @@
private static final String HTML_BUTTON_LABEL = "Render HTML";
+ private static final String JSON_BUTTON_LABEL = "Render JSON";
+
private static final String XML_BUTTON_LABEL = "Render XML";
private static final String TEXT_BUTTON_LABEL = "Show Text";
@@ -124,6 +129,8 @@
private static final String HTML_COMMAND = "html"; // $NON-NLS-1$
+ private static final String JSON_COMMAND = "json"; // $NON-NLS-1$
+
private static final String XML_COMMAND = "xml"; // $NON-NLS-1$
private static final String TEXT_COMMAND = "text"; // $NON-NLS-1$
@@ -136,6 +143,19 @@
private boolean textMode = true;
+ private static final String ESC_CHAR_REGEX =
"\\\\[\"\\\\/bfnrt]|\\\\u[0-9A-Fa-f]{4}"; // $NON-NLS-1$
+
+ private static final String NORMAL_CHARACTER_REGEX = "[^\"\\\\]"; //
$NON-NLS-1$
+
+ private static final String STRING_REGEX = "\"(" + ESC_CHAR_REGEX + "|"
+ NORMAL_CHARACTER_REGEX + ")*\""; // $NON-NLS-1$
+
+ // This 'other value' regex is deliberately weak, even accepting an
empty string, to be useful when reporting malformed data.
+ private static final String OTHER_VALUE_REGEX = "[^\\{\\[\\]\\}\\,]*";
// $NON-NLS-1$
+
+ private static final String VALUE_OR_PAIR_REGEX = "((" + STRING_REGEX +
"\\s*:)?\\s*(" + STRING_REGEX + "|" + OTHER_VALUE_REGEX + ")\\s*,?\\s*)"; //
$NON-NLS-1$
+
+ private static final Pattern VALUE_OR_PAIR_PATTERN =
Pattern.compile(VALUE_OR_PAIR_REGEX);
+
// set default command to Text
private String command = TEXT_COMMAND;
@@ -166,6 +186,8 @@
private JRadioButton htmlButton;
+ private JRadioButton jsonButton;
+
private JRadioButton xmlButton;
private JCheckBox downloadAll;
@@ -393,6 +415,8 @@
showTextResponse(response);
} else if
(command.equals(HTML_COMMAND)) {
showRenderedResponse(response, res);
+ } else if
(command.equals(JSON_COMMAND)) {
+
showRenderJSONResponse(response);
} else if
(command.equals(XML_COMMAND)) {
showRenderXMLResponse(response);
}
@@ -436,6 +460,7 @@
resultsScrollPane.setViewportView(imageLabel);
textButton.setEnabled(false);
htmlButton.setEnabled(false);
+ jsonButton.setEnabled(false);
xmlButton.setEnabled(false);
}
@@ -447,6 +472,74 @@
textButton.setEnabled(true);
htmlButton.setEnabled(true);
+ jsonButton.setEnabled(true);
+ xmlButton.setEnabled(true);
+ }
+
+ // It might be useful also to make this available in the 'Request' tab,
for
+ // when posting JSON.
+ private static String prettyJSON(String json) {
+ StringBuffer pretty = new StringBuffer(json.length() * 2); //
Educated guess
+
+ final String tab = ": "; // $NON-NLS-1$
+ StringBuffer index = new StringBuffer();
+ String nl = ""; // $NON-NLS-1$
+
+ Matcher valueOrPair = VALUE_OR_PAIR_PATTERN.matcher(json);
+
+ boolean misparse = false;
+
+ for (int i = 0; i < json.length(); ) {
+ final char currentChar = json.charAt(i);
+ if ((currentChar == '{') || (currentChar == '[')) {
+
pretty.append(nl).append(index).append(currentChar);
+ i++;
+ index.append(tab);
+ misparse = false;
+ }
+ else if ((currentChar == '}') || (currentChar == ']')) {
+ if (index.length() > 0) {
+ index.delete(0, tab.length());
+ }
+
pretty.append(nl).append(index).append(currentChar);
+ i++;
+ int j = i;
+ while ((j < json.length()) &&
Character.isWhitespace(json.charAt(j))) {
+ j++;
+ }
+ if ((j < json.length()) && (json.charAt(j) ==
',')) {
+ pretty.append(","); // $NON-NLS-1$
+ i=j+1;
+ }
+ misparse = false;
+ }
+ else if (valueOrPair.find(i) &&
valueOrPair.group().length() > 0) {
+
pretty.append(nl).append(index).append(valueOrPair.group());
+ i=valueOrPair.end();
+ misparse = false;
+ }
+ else {
+ if (!misparse) {
+ pretty.append(nl).append("- Parse
failed from:");
+ }
+ pretty.append(currentChar);
+ i++;
+ misparse = true;
+ }
+ nl = "\n"; // $NON-NLS-1$
+ }
+ return pretty.toString();
+ }
+
+ private void showRenderJSONResponse(String response) {
+ results.setContentType("text/plain"); // $NON-NLS-1$
+ results.setText(response == null ? "" : prettyJSON(response));
+ results.setCaretPosition(0);
+ resultsScrollPane.setViewportView(results);
+
+ textButton.setEnabled(true);
+ htmlButton.setEnabled(true);
+ jsonButton.setEnabled(true);
xmlButton.setEnabled(true);
}
@@ -509,6 +602,7 @@
resultsScrollPane.setViewportView(view);
textButton.setEnabled(true);
htmlButton.setEnabled(true);
+ jsonButton.setEnabled(true);
xmlButton.setEnabled(true);
}
@@ -552,7 +646,8 @@
command = e.getActionCommand();
if (command != null
- && (command.equals(TEXT_COMMAND) ||
command.equals(HTML_COMMAND) || command.equals(XML_COMMAND))) {
+ && (command.equals(TEXT_COMMAND) ||
command.equals(HTML_COMMAND)
+ || command.equals(JSON_COMMAND) ||
command.equals(XML_COMMAND))) {
textMode = command.equals(TEXT_COMMAND);
@@ -570,6 +665,8 @@
showTextResponse(response);
} else if (command.equals(HTML_COMMAND)) {
showRenderedResponse(response, res);
+ } else if (command.equals(JSON_COMMAND)) {
+ showRenderJSONResponse(response);
} else if (command.equals(XML_COMMAND)) {
showRenderXMLResponse(response);
}
@@ -627,6 +724,7 @@
textButton.setEnabled(true);
htmlButton.setEnabled(true);
+ jsonButton.setEnabled(true);
xmlButton.setEnabled(true);
}
@@ -645,6 +743,12 @@
htmlButton.setSelected(!textMode);
group.add(htmlButton);
+ jsonButton = new JRadioButton(JSON_BUTTON_LABEL);
+ jsonButton.setActionCommand(JSON_COMMAND);
+ jsonButton.addActionListener(this);
+ jsonButton.setSelected(!textMode);
+ group.add(jsonButton);
+
xmlButton = new JRadioButton(XML_BUTTON_LABEL);
xmlButton.setActionCommand(XML_COMMAND);
xmlButton.addActionListener(this);
@@ -657,6 +761,7 @@
pane.add(textButton);
pane.add(htmlButton);
pane.add(xmlButton);
+ pane.add(jsonButton);
pane.add(downloadAll);
return pane;
}
Modified: jakarta/jmeter/branches/rel-2-2/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/branches/rel-2-2/xdocs/changes.xml?view=diff&rev=545917&r1=545916&r2=545917
==============================================================================
--- jakarta/jmeter/branches/rel-2-2/xdocs/changes.xml (original)
+++ jakarta/jmeter/branches/rel-2-2/xdocs/changes.xml Sun Jun 10 11:07:10 2007
@@ -166,6 +166,7 @@
<li>Bug 41913 - TransactionController now creates samples as sub-samples of
the transaction</li>
<li>Bug 42506 - JMeter threads all use the same SSL session</li>
<li>BeanShell elements now support ThreadListener and TestListener
interfaces</li>
+<li>Bug 42582 - JSON pretty printing in Tree View Listener</li>
</ul>
<h4>Non-functional improvements:</h4>
Modified:
jakarta/jmeter/branches/rel-2-2/xdocs/usermanual/component_reference.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/branches/rel-2-2/xdocs/usermanual/component_reference.xml?view=diff&rev=545917&r1=545916&r2=545917
==============================================================================
--- jakarta/jmeter/branches/rel-2-2/xdocs/usermanual/component_reference.xml
(original)
+++ jakarta/jmeter/branches/rel-2-2/xdocs/usermanual/component_reference.xml
Sun Jun 10 11:07:10 2007
@@ -1663,8 +1663,7 @@
Note that the Request panel only shows the headers added by JMeter.
It does not show any headers (such as Host) that may be added by the HTTP
protocol implementation.
<p>
-There are three ways to view the response, selectable by a radio
-button.</p>
+There are several ways to view the response, selectable by a radio button.</p>
<p>The default view shows all of the text contained in the
response.</p>
<p>The HTML view attempts to render the response as
@@ -1678,6 +1677,7 @@
<p>The Render XML view will show response in tree style.
Any DTD nodes or Prolog nodes will not show up in tree; however, response may
contain those nodes.
</p>
+<p>The Render JSON view will show the response in tree style (also handles
JSON embedded in JavaScript).</p>
</description>
<p>
The Control Panel (above) shows an example of an HTML display.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]