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 }