PageRenderTime 21ms CodeModel.GetById 12ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 1ms

/hudson-core/src/main/java/hudson/util/JSONCanonicalUtils.java

http://github.com/hudson/hudson
Java | 160 lines | 109 code | 11 blank | 40 comment | 27 complexity | f30d48e3d6f59d3f13e2f5bd002966c5 MD5 | raw file
  1/*
  2* The MIT License
  3*
  4* Copyright (c) 2011, Oracle Corporation
  5*
  6* Permission is hereby granted, free of charge, to any person obtaining a copy
  7* of this software and associated documentation files (the "Software"), to deal
  8* in the Software without restriction, including without limitation the rights
  9* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10* copies of the Software, and to permit persons to whom the Software is
 11* furnished to do so, subject to the following conditions:
 12*
 13* The above copyright notice and this permission notice shall be included in
 14* all copies or substantial portions of the Software.
 15*
 16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22* THE SOFTWARE.
 23*/
 24package hudson.util;
 25
 26import java.io.IOException;
 27import java.io.Writer;
 28import java.util.Iterator;
 29import net.sf.json.JSON;
 30import net.sf.json.JSONArray;
 31import net.sf.json.JSONFunction;
 32import net.sf.json.JSONNull;
 33import net.sf.json.JSONObject;
 34import net.sf.json.JSONString;
 35import net.sf.json.util.JSONUtils;
 36
 37/**
 38 * Json utils for canonical writing.
 39 */
 40public class JSONCanonicalUtils {
 41    /**
 42     * Write JSON object to writer in canonical form.
 43     *
 44     * @param json JSONObject
 45     * @param writer Writer
 46     * @throws IOException if any
 47     */
 48    public static void write(JSONObject json, Writer writer) throws IOException {
 49
 50        if (json.isNullObject()) {
 51            writer.write(JSONNull.getInstance().toString());
 52            return;
 53        }
 54
 55        boolean b = false;
 56        Iterator keys = json.keys();
 57        writer.write('{');
 58
 59        while (keys.hasNext()) {
 60            if (b) {
 61                writer.write(',');
 62            }
 63            Object k = keys.next();
 64            writer.write(JSONUtils.quote(k.toString()));
 65            writer.write(':');
 66            Object v = json.get(k);
 67            if (v instanceof JSON) {
 68                write((JSON) v, writer);
 69            } else {
 70                writer.write(toCanonical(v));
 71            }
 72            b = true;
 73        }
 74        writer.write('}');
 75    }
 76
 77    /**
 78     * Write JSON array to writer in canonical form.
 79     *
 80     * @param json JSONArray
 81     * @param writer Writer
 82     * @throws IOException
 83     */
 84    public static void write(JSONArray json, Writer writer) throws IOException {
 85        boolean b = false;
 86        int len = json.size();
 87        writer.write('[');
 88        for (int i = 0; i < len; i += 1) {
 89            if (b) {
 90                writer.write(',');
 91            }
 92            Object v = json.get(i);
 93            if (v instanceof JSON) {
 94                write((JSON) v, writer);
 95            } else {
 96                writer.write(toCanonical(v));
 97            }
 98            b = true;
 99        }
100        writer.write(']');
101    }
102
103    private static void write(JSON o, Writer writer) throws IOException {
104        if (o instanceof JSONObject) {
105            write((JSONObject) o, writer);
106        } else if (o instanceof JSONArray) {
107            write((JSONArray) o, writer);
108        }
109    }
110
111    private static String toCanonical(Object value) throws IOException {
112        if (value == null || JSONUtils.isNull(value)) {
113            return "null";
114        }
115        if (value instanceof JSONFunction) {
116            return value.toString();
117        }
118        if (value instanceof JSONString) {
119            return ((JSONString) value).toJSONString();
120        }
121        if (value instanceof Number) {
122            return JSONUtils.numberToString((Number) value).toLowerCase();
123        }
124        if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) {
125            return value.toString();
126        }
127        return quoteCanonical(value.toString());
128    }
129
130    private static String quoteCanonical(String s) {
131        if (s == null || s.length() == 0) {
132            return "\"\"";
133        }
134
135        int len = s.length();
136        StringBuilder sb = new StringBuilder(len + 4);
137
138        sb.append('"');
139        for (int i = 0; i < len; i += 1) {
140            char c = s.charAt(i);
141            switch (c) {
142                case '\\':
143                case '"':
144                    sb.append('\\');
145                    sb.append(c);
146                    break;
147                default:
148                    if (c < ' ') {
149                        String t = "000" + Integer.toHexString(c);
150                        sb.append("\\u")
151                            .append(t.substring(t.length() - 4));
152                    } else {
153                        sb.append(c);
154                    }
155            }
156        }
157        sb.append('"');
158        return sb.toString();
159    }
160}