Lines 19-48
Link Here
|
19 |
|
19 |
|
20 |
package org.apache.jmeter.visualizers; |
20 |
package org.apache.jmeter.visualizers; |
21 |
|
21 |
|
22 |
import java.util.regex.Matcher; |
22 |
import java.io.IOException; |
23 |
import java.util.regex.Pattern; |
|
|
24 |
|
23 |
|
|
|
24 |
import org.apache.commons.lang3.StringUtils; |
25 |
import org.apache.jmeter.samplers.SampleResult; |
25 |
import org.apache.jmeter.samplers.SampleResult; |
26 |
import org.apache.jmeter.util.JMeterUtils; |
26 |
import org.apache.jmeter.util.JMeterUtils; |
27 |
|
27 |
|
|
|
28 |
import net.minidev.json.JSONObject; |
29 |
import net.minidev.json.JSONStyle; |
30 |
import net.minidev.json.parser.JSONParser; |
31 |
import net.minidev.json.parser.ParseException; |
32 |
|
28 |
public class RenderAsJSON extends SamplerResultTab implements ResultRenderer { |
33 |
public class RenderAsJSON extends SamplerResultTab implements ResultRenderer { |
29 |
private static final String TAB_SEPARATOR = ": "; //$NON-NLS-1$ |
34 |
private static final String TAB_SEPARATOR = ": "; //$NON-NLS-1$ |
30 |
|
35 |
|
31 |
private static final String ESC_CHAR_REGEX = "\\\\[\"\\\\/bfnrt]|\\\\u[0-9A-Fa-f]{4}"; // $NON-NLS-1$ |
|
|
32 |
|
33 |
private static final String NORMAL_CHARACTER_REGEX = "[^\"\\\\]"; // $NON-NLS-1$ |
34 |
|
35 |
private static final String STRING_REGEX = "\"(" + ESC_CHAR_REGEX + "|" + NORMAL_CHARACTER_REGEX + ")*+\""; // $NON-NLS-1$ |
36 |
|
37 |
// This 'other value' regex is deliberately weak, even accepting an empty string, to be useful when reporting malformed data. |
38 |
private static final String OTHER_VALUE_REGEX = "[^\\{\\[\\]\\}\\,]*"; // $NON-NLS-1$ |
39 |
|
40 |
private static final String VALUE_OR_PAIR_REGEX = "((" + STRING_REGEX |
41 |
+ "\\s*:)?\\s*(" + STRING_REGEX + "|" + OTHER_VALUE_REGEX |
42 |
+ ")\\s*,?\\s*)"; // $NON-NLS-1$ |
43 |
|
44 |
private static final Pattern VALUE_OR_PAIR_PATTERN = Pattern.compile(VALUE_OR_PAIR_REGEX); |
45 |
|
46 |
/** {@inheritDoc} */ |
36 |
/** {@inheritDoc} */ |
47 |
@Override |
37 |
@Override |
48 |
public void renderResult(SampleResult sampleResult) { |
38 |
public void renderResult(SampleResult sampleResult) { |
Lines 62-130
public class RenderAsJSON extends SamplerResultTab implements ResultRenderer {
Link Here
|
62 |
/** |
52 |
/** |
63 |
* Pretty-print JSON text |
53 |
* Pretty-print JSON text |
64 |
* @param json input text |
54 |
* @param json input text |
65 |
* @return prettyfied json |
55 |
* @return prettied json string |
66 |
*/ |
56 |
*/ |
67 |
public static String prettyJSON(String json) { |
57 |
public static String prettyJSON(String json) { |
68 |
return prettyJSON(json, RenderAsJSON.TAB_SEPARATOR); |
58 |
return prettyJSON(json, TAB_SEPARATOR); |
69 |
} |
59 |
} |
70 |
|
60 |
|
71 |
/** |
61 |
/** |
72 |
* Pretty-print JSON text |
62 |
* Pretty-print JSON text |
73 |
* @param json input text |
63 |
* @param json input text |
74 |
* @param tabSeparator String tab separator |
64 |
* @param tabSeparator String tab separator |
75 |
* @return prettyfied json |
65 |
* @return prettied json string |
76 |
*/ |
66 |
*/ |
77 |
public static String prettyJSON(String json, String tabSeparator) { |
67 |
public static String prettyJSON(String json, String tabSeparator) { |
78 |
StringBuilder pretty = new StringBuilder(json.length() * 2); // Educated guess |
68 |
try { |
79 |
|
69 |
Object o = new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE) |
80 |
final String tab = tabSeparator; // $NON-NLS-1$ |
70 |
.parse(json); |
81 |
StringBuilder index = new StringBuilder(); |
71 |
if (o instanceof JSONObject) { |
82 |
String nl = ""; // $NON-NLS-1$ |
72 |
return ((JSONObject) o) |
83 |
|
73 |
.toJSONString(new PrettyJSONStyle(tabSeparator)); |
84 |
Matcher valueOrPair = VALUE_OR_PAIR_PATTERN.matcher(json); |
|
|
85 |
|
86 |
boolean misparse = false; |
87 |
|
88 |
for (int i = 0; i < json.length();) { |
89 |
final char currentChar = json.charAt(i); |
90 |
if ((currentChar == '{') || (currentChar == '[')) { |
91 |
pretty.append(nl).append(index).append(currentChar); |
92 |
i++; |
93 |
index.append(tab); |
94 |
misparse = false; |
95 |
} |
96 |
else if ((currentChar == '}') || (currentChar == ']')) { |
97 |
if (index.length() > 0) { |
98 |
index.delete(0, tab.length()); |
99 |
} |
100 |
pretty.append(nl).append(index).append(currentChar); |
101 |
i++; |
102 |
int j = i; |
103 |
while ((j < json.length()) && Character.isWhitespace(json.charAt(j))) { |
104 |
j++; |
105 |
} |
106 |
if ((j < json.length()) && (json.charAt(j) == ',')) { |
107 |
pretty.append(","); // $NON-NLS-1$ |
108 |
i=j+1; |
109 |
} |
110 |
misparse = false; |
111 |
} |
112 |
else if (valueOrPair.find(i) && valueOrPair.group().length() > 0) { |
113 |
pretty.append(nl).append(index).append(valueOrPair.group()); |
114 |
i=valueOrPair.end(); |
115 |
misparse = false; |
116 |
} |
74 |
} |
117 |
else { |
75 |
} catch (ParseException e) { |
118 |
if (!misparse) { |
76 |
return json; |
119 |
pretty.append(nl).append("- Parse failed from:"); |
|
|
120 |
} |
121 |
pretty.append(currentChar); |
122 |
i++; |
123 |
misparse = true; |
124 |
} |
125 |
nl = "\n"; // $NON-NLS-1$ |
126 |
} |
77 |
} |
127 |
return pretty.toString(); |
78 |
return json; |
128 |
} |
79 |
} |
129 |
|
80 |
|
130 |
/** {@inheritDoc} */ |
81 |
/** {@inheritDoc} */ |
Lines 133-136
public class RenderAsJSON extends SamplerResultTab implements ResultRenderer {
Link Here
|
133 |
return JMeterUtils.getResString("view_results_render_json"); // $NON-NLS-1$ |
84 |
return JMeterUtils.getResString("view_results_render_json"); // $NON-NLS-1$ |
134 |
} |
85 |
} |
135 |
|
86 |
|
|
|
87 |
private static class PrettyJSONStyle extends JSONStyle { |
88 |
private int level = 0; |
89 |
private String indentString = TAB_SEPARATOR; |
90 |
|
91 |
public PrettyJSONStyle(String indentString) { |
92 |
this.indentString = indentString; |
93 |
} |
94 |
|
95 |
private void indent(Appendable out) throws IOException { |
96 |
out.append('\n'); |
97 |
out.append(StringUtils.repeat(indentString, level)); |
98 |
} |
99 |
|
100 |
@Override |
101 |
public void objectStart(Appendable out) throws IOException { |
102 |
super.objectStart(out); |
103 |
level++; |
104 |
} |
105 |
|
106 |
@Override |
107 |
public void objectStop(Appendable out) throws IOException { |
108 |
level--; |
109 |
indent(out); |
110 |
super.objectStop(out); |
111 |
} |
112 |
|
113 |
@Override |
114 |
public void objectNext(Appendable out) throws IOException { |
115 |
super.objectNext(out); |
116 |
indent(out); |
117 |
} |
118 |
|
119 |
@Override |
120 |
public void objectEndOfKey(Appendable out) throws IOException { |
121 |
super.objectEndOfKey(out); |
122 |
out.append(' '); |
123 |
} |
124 |
|
125 |
@Override |
126 |
public void objectFirstStart(Appendable out) throws IOException { |
127 |
indent(out); |
128 |
super.objectFirstStart(out); |
129 |
} |
130 |
|
131 |
@Override |
132 |
public void arrayfirstObject(Appendable out) throws IOException { |
133 |
indent(out); |
134 |
super.arrayfirstObject(out); |
135 |
} |
136 |
|
137 |
@Override |
138 |
public void arrayNextElm(Appendable out) throws IOException { |
139 |
super.arrayNextElm(out); |
140 |
indent(out); |
141 |
} |
142 |
|
143 |
@Override |
144 |
public void arrayStart(Appendable out) throws IOException { |
145 |
super.arrayStart(out); |
146 |
level++; |
147 |
} |
148 |
|
149 |
@Override |
150 |
public void arrayStop(Appendable out) throws IOException { |
151 |
level--; |
152 |
indent(out); |
153 |
super.arrayStop(out); |
154 |
} |
155 |
|
156 |
} |
136 |
} |
157 |
} |