首页

关于grizzly-webserver源码包中JSONParser进行JSON对象类集间转换解析

标签:grizzly,webserver,JSONParser,json解析     发布时间:2018-05-26   

一、前言

关于grizzly-webserver源码包中com.sun.grizzly.cometd.util.JSONParser解析类,进行对象及Map转为字符串toString、从各种类型追加(append/appendNull/appendJSON/appendMap/appendArray/appendBoolean/appendNumber/appendString)为JSON字符串、对于源对象进行解析parse对象、parseObject解析Map、解析对象为parseArray数组、解析字符串parseString、解析源为parseNumber数字。

二、源码说明

package com.sun.grizzly.cometd.util;@b@@b@import java.lang.reflect.Array;@b@import java.util.ArrayList;@b@import java.util.HashMap;@b@import java.util.Iterator;@b@import java.util.List;@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import java.util.Set;@b@@b@public class JSONParser@b@{@b@  public static String toString(Object object)@b@  {@b@    StringBuilder buffer = new StringBuilder();@b@    append(buffer, object);@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(Map object) {@b@    StringBuilder buffer = new StringBuilder();@b@    appendMap(buffer, object);@b@    return buffer.toString();@b@  }@b@@b@  public static String toString(Object[] array) {@b@    StringBuilder buffer = new StringBuilder();@b@    appendArray(buffer, array);@b@    return buffer.toString();@b@  }@b@@b@  public static Object parse(String s)@b@  {@b@    return parse(new Source(s));@b@  }@b@@b@  public static void append(StringBuilder buffer, Object object)@b@  {@b@    if (object == null)@b@      buffer.append("null");@b@    else if (object instanceof Generator)@b@      appendJSON(buffer, (Generator)object);@b@    else if (object instanceof Map)@b@      appendMap(buffer, (Map)object);@b@    else if (object instanceof List)@b@      appendArray(buffer, ((List)object).toArray());@b@    else if (object.getClass().isArray())@b@      appendArray(buffer, object);@b@    else if (object instanceof Number)@b@      appendNumber(buffer, (Number)object);@b@    else if (object instanceof Boolean)@b@      appendBoolean(buffer, (Boolean)object);@b@    else if (object instanceof String) {@b@      appendString(buffer, (String)object);@b@    }@b@    else@b@      appendString(buffer, object.toString());@b@  }@b@@b@  private static void appendNull(StringBuilder buffer) {@b@    buffer.append("null");@b@  }@b@@b@  private static void appendJSON(StringBuilder buffer, Generator generator) {@b@    generator.addJSON(buffer);@b@  }@b@@b@  private static void appendMap(StringBuilder buffer, Map object) {@b@    if (object == null) {@b@      appendNull(buffer);@b@      return;@b@    }@b@@b@    buffer.append('{');@b@    Iterator iter = object.entrySet().iterator();@b@    while (iter.hasNext()) {@b@      Map.Entry entry = (Map.Entry)iter.next();@b@      quote(buffer, entry.getKey().toString());@b@      buffer.append(':');@b@      append(buffer, entry.getValue());@b@      if (iter.hasNext())@b@        buffer.append(',');@b@    }@b@@b@    buffer.append('}');@b@  }@b@@b@  private static void appendArray(StringBuilder buffer, Object array) {@b@    if (array == null) {@b@      appendNull(buffer);@b@      return;@b@    }@b@@b@    buffer.append('[');@b@    int length = Array.getLength(array);@b@@b@    for (int i = 0; i < length; ++i) {@b@      if (i != 0)@b@        buffer.append(',');@b@      append(buffer, Array.get(array, i));@b@    }@b@@b@    buffer.append(']');@b@  }@b@@b@  private static void appendBoolean(StringBuilder buffer, Boolean b) {@b@    if (b == null) {@b@      appendNull(buffer);@b@      return;@b@    }@b@    buffer.append((b.booleanValue()) ? "true" : "false");@b@  }@b@@b@  private static void appendNumber(StringBuilder buffer, Number number) {@b@    if (number == null) {@b@      appendNull(buffer);@b@      return;@b@    }@b@    buffer.append(number);@b@  }@b@@b@  private static void appendString(StringBuilder buffer, String string) {@b@    if (string == null) {@b@      appendNull(buffer);@b@      return;@b@    }@b@@b@    quote(buffer, string);@b@  }@b@@b@  private static Object parse(Source source) {@b@    int comment_state = 0;@b@@b@    while (source.hasNext()) {@b@      char c = source.peek();@b@@b@      if (comment_state == 1) {@b@        switch (c)@b@        {@b@        case '/':@b@          comment_state = -1;@b@          break;@b@        case '*':@b@          comment_state = 2;@b@        }@b@      }@b@      else {@b@        if (comment_state > 1);@b@        switch (c)@b@        {@b@        case '*':@b@          comment_state = 3;@b@          break;@b@        case '/':@b@          if (comment_state == 3)@b@            comment_state = 0;@b@          else@b@            comment_state = 2;@b@          break;@b@        default:@b@          comment_state = 2; break label334:@b@@b@          if (comment_state < 0);@b@          switch (c)@b@          {@b@          case '\n':@b@          case '\r':@b@            comment_state = 0;@b@            break;@b@          default:@b@            break label334:@b@@b@            switch (c)@b@            {@b@            case '{':@b@              return parseObject(source);@b@            case '[':@b@              return parseArray(source);@b@            case '"':@b@              return parseString(source);@b@            case '-':@b@              return parseNumber(source);@b@            case 'n':@b@              complete("null", source);@b@              return null;@b@            case 't':@b@              complete("true", source);@b@              return Boolean.TRUE;@b@            case 'f':@b@              complete("false", source);@b@              return Boolean.FALSE;@b@            case '/':@b@              comment_state = 1;@b@              break;@b@            default:@b@              if (Character.isDigit(c))@b@                return parseNumber(source);@b@              if (Character.isWhitespace(c))@b@                break label334:@b@@b@              throw new IllegalStateException("unknown char " + c); } }@b@        }@b@      }@b@      label334: source.next();@b@    }@b@@b@    return null;@b@  }@b@@b@  private static Map parseObject(Source source) {@b@    if (source.next() != '{')@b@      throw new IllegalStateException();@b@    Map map = new HashMap();@b@@b@    char next = seekTo("\"}", source);@b@@b@    while (source.hasNext()) {@b@      if (next == '}') {@b@        source.next();@b@        break;@b@      }@b@@b@      String name = parseString(source);@b@      seekTo(':', source);@b@      source.next();@b@@b@      Object value = parse(source);@b@      map.put(name, value);@b@@b@      seekTo(",}", source);@b@      next = source.next();@b@      if (next == '}')@b@        break;@b@@b@      next = seekTo("\"}", source);@b@    }@b@@b@    return map;@b@  }@b@@b@  private static Object parseArray(Source source) {@b@    if (source.next() != '[')@b@      throw new IllegalStateException();@b@@b@    ArrayList list = new ArrayList();@b@    boolean coma = true;@b@@b@    while (source.hasNext()) {@b@      char c = source.peek();@b@      switch (c)@b@      {@b@      case ']':@b@        source.next();@b@        return list.toArray(new Object[list.size()]);@b@      case ',':@b@        if (coma)@b@          throw new IllegalStateException();@b@        coma = true;@b@        source.next();@b@      }@b@@b@      if (Character.isWhitespace(c)) {@b@        source.next();@b@      } else {@b@        coma = false;@b@        list.add(parse(source));@b@      }@b@@b@    }@b@@b@    throw new IllegalStateException("unexpected end of array");@b@  }@b@@b@  private static String parseString(Source source) {@b@    if (source.next() != '"')@b@      throw new IllegalStateException();@b@@b@    boolean escape = false;@b@    StringBuilder b = new StringBuilder();@b@    while (true) { char c;@b@      while (true) { if (!(source.hasNext())) break label281;@b@        c = source.next();@b@@b@        if (escape)@b@          escape = false;@b@        switch (c)@b@        {@b@        case 'n':@b@          b.append('\n');@b@          break;@b@        case 'r':@b@          b.append('\r');@b@          break;@b@        case 't':@b@          b.append('\t');@b@          break;@b@        case 'f':@b@          b.append('\f');@b@          break;@b@        case 'b':@b@          b.append('\b');@b@          break;@b@        case 'u':@b@          b.append((char)((convertHexDigit((byte)source.next()) << 24) + (convertHexDigit((byte)source.next()) << 16) + (convertHexDigit((byte)source.next()) << 8) + convertHexDigit((byte)source.next())));@b@@b@          break;@b@        case 'c':@b@        case 'd':@b@        case 'e':@b@        case 'g':@b@        case 'h':@b@        case 'i':@b@        case 'j':@b@        case 'k':@b@        case 'l':@b@        case 'm':@b@        case 'o':@b@        case 'p':@b@        case 'q':@b@        case 's':@b@        default:@b@          b.append(c); break label278:@b@@b@          if (c != '\\') break;@b@          escape = true; }@b@      }@b@      if (c == '"')@b@        break;@b@@b@      label278: b.append(c);@b@    }@b@@b@    label281: return b.toString();@b@  }@b@@b@  private static Number parseNumber(Source source) {@b@    int start = source.index();@b@    int end = -1;@b@    boolean is_double = false;@b@    while ((source.hasNext()) && (end < 0)) {@b@      char c = source.peek();@b@      switch (c)@b@      {@b@      case '-':@b@      case '0':@b@      case '1':@b@      case '2':@b@      case '3':@b@      case '4':@b@      case '5':@b@      case '6':@b@      case '7':@b@      case '8':@b@      case '9':@b@        source.next();@b@        break;@b@      case '.':@b@      case 'E':@b@      case 'e':@b@        is_double = true;@b@        source.next();@b@        break;@b@      case '/':@b@      case ':':@b@      case ';':@b@      case '<':@b@      case '=':@b@      case '>':@b@      case '?':@b@      case '@':@b@      case 'A':@b@      case 'B':@b@      case 'C':@b@      case 'D':@b@      case 'F':@b@      case 'G':@b@      case 'H':@b@      case 'I':@b@      case 'J':@b@      case 'K':@b@      case 'L':@b@      case 'M':@b@      case 'N':@b@      case 'O':@b@      case 'P':@b@      case 'Q':@b@      case 'R':@b@      case 'S':@b@      case 'T':@b@      case 'U':@b@      case 'V':@b@      case 'W':@b@      case 'X':@b@      case 'Y':@b@      case 'Z':@b@      case '[':@b@      case '\\':@b@      case ']':@b@      case '^':@b@      case '_':@b@      case ''':@b@      case 'a':@b@      case 'b':@b@      case 'c':@b@      case 'd':@b@      default:@b@        end = source.index();@b@      }@b@    }@b@    String s = (end >= 0) ? source.from(start, end) : source.from(start);@b@    if (is_double)@b@      return new Double(s);@b@@b@    return new Long(s);@b@  }@b@@b@  private static void seekTo(char seek, Source source) {@b@    while (source.hasNext()) {@b@      char c = source.peek();@b@      if (c == seek)@b@        return;@b@@b@      if (!(Character.isWhitespace(c)))@b@        throw new IllegalStateException("Unexpected '" + c + " while seeking '" + seek + "'");@b@      source.next();@b@    }@b@@b@    throw new IllegalStateException("Expected '" + seek + "'");@b@  }@b@@b@  private static char seekTo(String seek, Source source) {@b@    while (source.hasNext()) {@b@      char c = source.peek();@b@      if (seek.indexOf(c) >= 0) {@b@        return c;@b@      }@b@@b@      if (!(Character.isWhitespace(c)))@b@        throw new IllegalStateException("Unexpected '" + c + "' while seeking one of '" + seek + "'");@b@      source.next();@b@    }@b@@b@    throw new IllegalStateException("Expected one of '" + seek + "'");@b@  }@b@@b@  private static void complete(String seek, Source source) {@b@    int i = 0;@b@    while ((source.hasNext()) && (i < seek.length())) {@b@      char c = source.next();@b@      if (c != seek.charAt(i++))@b@        throw new IllegalStateException("Unexpected '" + c + " while seeking  \"" + seek + "\"");@b@    }@b@@b@    if (i < seek.length())@b@      throw new IllegalStateException("Expected \"" + seek + "\"");@b@  }@b@@b@  public static String quote(String s)@b@  {@b@    if (s == null)@b@      return null;@b@    if (s.length() == 0)@b@      return "\"\"";@b@@b@    StringBuilder b = new StringBuilder(s.length() + 8);@b@    quote(b, s);@b@    return b.toString();@b@  }@b@@b@  public static void quote(StringBuilder buf, String s)@b@  {@b@    buf.append('"');@b@    for (int i = 0; i < s.length(); ++i)@b@    {@b@      char c = s.charAt(i);@b@      switch (c)@b@      {@b@      case '"':@b@        buf.append("\\\"");@b@        break;@b@      case '\\':@b@        buf.append("\\\\");@b@        break;@b@      case '\n':@b@        buf.append("\\n");@b@        break;@b@      case '\r':@b@        buf.append("\\r");@b@        break;@b@      case '\t':@b@        buf.append("\\t");@b@        break;@b@      case '\f':@b@        buf.append("\\f");@b@        break;@b@      case '\b':@b@        buf.append("\\b");@b@        break;@b@      default:@b@        buf.append(c);@b@      }@b@    }@b@@b@    buf.append('"');@b@  }@b@@b@  public static byte convertHexDigit(byte b)@b@  {@b@    if ((b >= 48) && (b <= 57)) return (byte)(b - 48);@b@    if ((b >= 97) && (b <= 102)) return (byte)(b - 97 + 10);@b@    if ((b >= 65) && (b <= 70)) return (byte)(b - 65 + 10);@b@    return 0;@b@  }@b@@b@  public static class Literal@b@    implements JSONParser.Generator@b@  {@b@    private String _json;@b@@b@    public Literal(String json)@b@    {@b@      JSONParser.parse(json);@b@      this._json = json;@b@    }@b@@b@    public String toString() {@b@      return this._json;@b@    }@b@@b@    public void addJSON(StringBuilder buffer) {@b@      buffer.append(this._json);@b@    }@b@  }@b@@b@  public static abstract interface Generator@b@  {@b@    public abstract void addJSON(StringBuilder paramStringBuilder);@b@  }@b@@b@  private static class Source@b@  {@b@    private final String string;@b@    private int index;@b@@b@    Source(String s)@b@    {@b@      int firstInd = s.indexOf("/*");@b@      int lastInd = s.lastIndexOf("*/");@b@      if ((firstInd != -1) && (lastInd != -1))@b@        s = s.substring(firstInd + 2, lastInd);@b@@b@      this.string = s;@b@    }@b@@b@    boolean hasNext() {@b@      return (this.index < this.string.length());@b@    }@b@@b@    char next() {@b@      return this.string.charAt(this.index++);@b@    }@b@@b@    char peek() {@b@      return this.string.charAt(this.index);@b@    }@b@@b@    int index() {@b@      return this.index;@b@    }@b@@b@    String from(int mark) {@b@      return this.string.substring(mark, this.index);@b@    }@b@@b@    String from(int mark, int end) {@b@      return this.string.substring(mark, end);@b@    }@b@  }@b@}