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

(-)a/src/components/org/apache/jmeter/visualizers/RenderAsJSON.java (-68 / +89 lines)
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
}
(-)a/test/src/org/apache/jmeter/visualizers/TestRenderAsJson.java (-6 / +11 lines)
Lines 44-50 public class TestRenderAsJson { Link Here
44
    @Test
44
    @Test
45
    public void testRenderResultWithLongStringBug54826() throws Exception {
45
    public void testRenderResultWithLongStringBug54826() throws Exception {
46
        StringBuilder json = new StringBuilder();
46
        StringBuilder json = new StringBuilder();
47
        json.append("\"customData\":\"");
47
        json.append("\"customData\": \"");
48
        for (int i = 0; i < 100; i++) {
48
        for (int i = 0; i < 100; i++) {
49
            json.append("somenotsorandomtext");
49
            json.append("somenotsorandomtext");
50
        }
50
        }
Lines 61-67 public class TestRenderAsJson { Link Here
61
61
62
    @Test
62
    @Test
63
    public void testRenderResultSimpleArray() throws Exception {
63
    public void testRenderResultSimpleArray() throws Exception {
64
        assertEquals("[\n]", prettyJSON("[]"));
64
        assertEquals("[]", prettyJSON("[]"));
65
    }
66
67
    @Test
68
    public void testRenderArrayInObject() throws Exception {
69
        assertEquals("{\n" + TAB + "\"foo\": [\n" + TAB + "]\n}",
70
                prettyJSON("{\"foo\":[]}"));
65
    }
71
    }
66
72
67
    @Test
73
    @Test
Lines 77-85 public class TestRenderAsJson { Link Here
77
    @Test
83
    @Test
78
    public void testRenderResultSimpleStructure() throws Exception {
84
    public void testRenderResultSimpleStructure() throws Exception {
79
        assertEquals(
85
        assertEquals(
80
                "{\n" + TAB + "\"Hello\": \"World\", \n" + TAB + "\"more\": \n"
86
                "{\n" + TAB + "\"Hello\": \"World\",\n" + TAB + "\"more\": [\n"
81
                        + TAB + "[\n" + TAB + TAB + "\"Something\", \n" + TAB
87
                        + TAB + TAB + "\"Something\",\n" + TAB
82
                        + TAB + "\"else\", \n" + TAB + "]\n}",
88
                        + TAB + "\"else\"\n" + TAB + "]\n}",
83
                prettyJSON("{\"Hello\": \"World\", \"more\": [\"Something\", \"else\", ]}"));
89
                prettyJSON("{\"Hello\": \"World\", \"more\": [\"Something\", \"else\", ]}"));
84
    }
90
    }
85
91
86
- 

Return to bug 62397