github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgRpc/kmgRpcJava/java/src/com/google/gson/internal/bind/JsonTreeWriter.java (about)

     1  /*
     2   * Copyright (C) 2011 Google Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package com.google.gson.internal.bind;
    18  
    19  import com.google.gson.JsonArray;
    20  import com.google.gson.JsonElement;
    21  import com.google.gson.JsonNull;
    22  import com.google.gson.JsonObject;
    23  import com.google.gson.JsonPrimitive;
    24  import com.google.gson.stream.JsonWriter;
    25  import java.io.IOException;
    26  import java.io.Writer;
    27  import java.util.ArrayList;
    28  import java.util.List;
    29  
    30  /**
    31   * This writer creates a JsonElement.
    32   */
    33  public final class JsonTreeWriter extends JsonWriter {
    34    private static final Writer UNWRITABLE_WRITER = new Writer() {
    35      @Override public void write(char[] buffer, int offset, int counter) {
    36        throw new AssertionError();
    37      }
    38      @Override public void flush() throws IOException {
    39        throw new AssertionError();
    40      }
    41      @Override public void close() throws IOException {
    42        throw new AssertionError();
    43      }
    44    };
    45    /** Added to the top of the stack when this writer is closed to cause following ops to fail. */
    46    private static final JsonPrimitive SENTINEL_CLOSED = new JsonPrimitive("closed");
    47  
    48    /** The JsonElements and JsonArrays under modification, outermost to innermost. */
    49    private final List<JsonElement> stack = new ArrayList<JsonElement>();
    50  
    51    /** The name for the next JSON object value. If non-null, the top of the stack is a JsonObject. */
    52    private String pendingName;
    53  
    54    /** the JSON element constructed by this writer. */
    55    private JsonElement product = JsonNull.INSTANCE; // TODO: is this really what we want?;
    56  
    57    public JsonTreeWriter() {
    58      super(UNWRITABLE_WRITER);
    59    }
    60  
    61    /**
    62     * Returns the top level object produced by this writer.
    63     */
    64    public JsonElement get() {
    65      if (!stack.isEmpty()) {
    66        throw new IllegalStateException("Expected one JSON element but was " + stack);
    67      }
    68      return product;
    69    }
    70  
    71    private JsonElement peek() {
    72      return stack.get(stack.size() - 1);
    73    }
    74  
    75    private void put(JsonElement value) {
    76      if (pendingName != null) {
    77        if (!value.isJsonNull() || getSerializeNulls()) {
    78          JsonObject object = (JsonObject) peek();
    79          object.add(pendingName, value);
    80        }
    81        pendingName = null;
    82      } else if (stack.isEmpty()) {
    83        product = value;
    84      } else {
    85        JsonElement element = peek();
    86        if (element instanceof JsonArray) {
    87          ((JsonArray) element).add(value);
    88        } else {
    89          throw new IllegalStateException();
    90        }
    91      }
    92    }
    93  
    94    @Override public JsonWriter beginArray() throws IOException {
    95      JsonArray array = new JsonArray();
    96      put(array);
    97      stack.add(array);
    98      return this;
    99    }
   100  
   101    @Override public JsonWriter endArray() throws IOException {
   102      if (stack.isEmpty() || pendingName != null) {
   103        throw new IllegalStateException();
   104      }
   105      JsonElement element = peek();
   106      if (element instanceof JsonArray) {
   107        stack.remove(stack.size() - 1);
   108        return this;
   109      }
   110      throw new IllegalStateException();
   111    }
   112  
   113    @Override public JsonWriter beginObject() throws IOException {
   114      JsonObject object = new JsonObject();
   115      put(object);
   116      stack.add(object);
   117      return this;
   118    }
   119  
   120    @Override public JsonWriter endObject() throws IOException {
   121      if (stack.isEmpty() || pendingName != null) {
   122        throw new IllegalStateException();
   123      }
   124      JsonElement element = peek();
   125      if (element instanceof JsonObject) {
   126        stack.remove(stack.size() - 1);
   127        return this;
   128      }
   129      throw new IllegalStateException();
   130    }
   131  
   132    @Override public JsonWriter name(String name) throws IOException {
   133      if (stack.isEmpty() || pendingName != null) {
   134        throw new IllegalStateException();
   135      }
   136      JsonElement element = peek();
   137      if (element instanceof JsonObject) {
   138        pendingName = name;
   139        return this;
   140      }
   141      throw new IllegalStateException();
   142    }
   143  
   144    @Override public JsonWriter value(String value) throws IOException {
   145      if (value == null) {
   146        return nullValue();
   147      }
   148      put(new JsonPrimitive(value));
   149      return this;
   150    }
   151  
   152    @Override public JsonWriter nullValue() throws IOException {
   153      put(JsonNull.INSTANCE);
   154      return this;
   155    }
   156  
   157    @Override public JsonWriter value(boolean value) throws IOException {
   158      put(new JsonPrimitive(value));
   159      return this;
   160    }
   161  
   162    @Override public JsonWriter value(double value) throws IOException {
   163      if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value))) {
   164        throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
   165      }
   166      put(new JsonPrimitive(value));
   167      return this;
   168    }
   169  
   170    @Override public JsonWriter value(long value) throws IOException {
   171      put(new JsonPrimitive(value));
   172      return this;
   173    }
   174  
   175    @Override public JsonWriter value(Number value) throws IOException {
   176      if (value == null) {
   177        return nullValue();
   178      }
   179  
   180      if (!isLenient()) {
   181        double d = value.doubleValue();
   182        if (Double.isNaN(d) || Double.isInfinite(d)) {
   183          throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
   184        }
   185      }
   186  
   187      put(new JsonPrimitive(value));
   188      return this;
   189    }
   190  
   191    @Override public void flush() throws IOException {
   192    }
   193  
   194    @Override public void close() throws IOException {
   195      if (!stack.isEmpty()) {
   196        throw new IOException("Incomplete document");
   197      }
   198      stack.add(SENTINEL_CLOSED);
   199    }
   200  }