mirror of https://github.com/apache/jclouds.git
Issue 797: update to gson 2.1
This commit is contained in:
parent
7e21b0ad05
commit
ef7b91bfea
|
@ -104,7 +104,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>1.7.2</version>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
|
|
@ -20,8 +20,6 @@ package com.google.gson;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The gson project use package to control access to their objects. However, this prevents us from
|
||||
* doing valid work, like controling the json emitted on a per-object basis. This is here to afford
|
||||
|
@ -38,8 +36,8 @@ public final class JsonLiteral extends JsonElement {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void toString(Appendable sb, Escaper escaper) throws IOException {
|
||||
sb.append(literal);
|
||||
public String toString() {
|
||||
return literal.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reads and writes GSON parse trees over streams.
|
||||
*/
|
||||
final class Streams {
|
||||
|
||||
/**
|
||||
* Takes a reader in any state and returns the next value as a JsonElement.
|
||||
*/
|
||||
static JsonElement parse(JsonReader reader) throws JsonParseException {
|
||||
boolean isEmpty = true;
|
||||
try {
|
||||
reader.peek();
|
||||
isEmpty = false;
|
||||
return parseRecursive(reader);
|
||||
} catch (EOFException e) {
|
||||
/*
|
||||
* For compatibility with JSON 1.5 and earlier, we return a JsonNull for
|
||||
* empty documents instead of throwing.
|
||||
*/
|
||||
if (isEmpty) {
|
||||
return JsonNull.createJsonNull();
|
||||
}
|
||||
throw new JsonIOException(e);
|
||||
} catch (MalformedJsonException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static JsonElement parseRecursive(JsonReader reader) throws IOException {
|
||||
switch (reader.peek()) {
|
||||
case STRING:
|
||||
return new JsonPrimitive(reader.nextString());
|
||||
case NUMBER:
|
||||
String number = reader.nextString();
|
||||
return new JsonPrimitive(JsonPrimitive.stringToNumber(number));
|
||||
case BOOLEAN:
|
||||
return new JsonPrimitive(reader.nextBoolean());
|
||||
case NULL:
|
||||
reader.nextNull();
|
||||
return JsonNull.createJsonNull();
|
||||
case BEGIN_ARRAY:
|
||||
JsonArray array = new JsonArray();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
array.add(parseRecursive(reader));
|
||||
}
|
||||
reader.endArray();
|
||||
return array;
|
||||
case BEGIN_OBJECT:
|
||||
JsonObject object = new JsonObject();
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
object.add(reader.nextName(), parseRecursive(reader));
|
||||
}
|
||||
reader.endObject();
|
||||
return object;
|
||||
case END_DOCUMENT:
|
||||
case NAME:
|
||||
case END_OBJECT:
|
||||
case END_ARRAY:
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the JSON element to the writer, recursively.
|
||||
*/
|
||||
static void write(JsonElement element, boolean serializeNulls, JsonWriter writer)
|
||||
throws IOException {
|
||||
if (element == null || element.isJsonNull()) {
|
||||
if (serializeNulls) {
|
||||
writer.nullValue();
|
||||
}
|
||||
//BEGIN JCLOUDS PATCH
|
||||
// * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
} else if (element instanceof JsonLiteral ) {
|
||||
writer.value(JsonLiteral.class.cast(element));
|
||||
//END JCLOUDS PATCH
|
||||
} else if (element.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = element.getAsJsonPrimitive();
|
||||
if (primitive.isNumber()) {
|
||||
writer.value(primitive.getAsNumber());
|
||||
} else if (primitive.isBoolean()) {
|
||||
writer.value(primitive.getAsBoolean());
|
||||
} else {
|
||||
writer.value(primitive.getAsString());
|
||||
}
|
||||
|
||||
} else if (element.isJsonArray()) {
|
||||
writer.beginArray();
|
||||
for (JsonElement e : element.getAsJsonArray()) {
|
||||
/* always print null when its parent element is an array! */
|
||||
if (e.isJsonNull()) {
|
||||
writer.nullValue();
|
||||
continue;
|
||||
}
|
||||
write(e, serializeNulls, writer);
|
||||
}
|
||||
writer.endArray();
|
||||
|
||||
} else if (element.isJsonObject()) {
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, JsonElement> e : element.getAsJsonObject().entrySet()) {
|
||||
JsonElement value = e.getValue();
|
||||
if (!serializeNulls && value.isJsonNull()) {
|
||||
continue;
|
||||
}
|
||||
writer.name(e.getKey());
|
||||
write(value, serializeNulls, writer);
|
||||
}
|
||||
writer.endObject();
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Couldn't write " + element.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
static Writer writerForAppendable(Appendable appendable) {
|
||||
return appendable instanceof Writer ? (Writer) appendable : new AppendableWriter(appendable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts an {@link Appendable} so it can be passed anywhere a {@link Writer}
|
||||
* is used.
|
||||
*/
|
||||
private static class AppendableWriter extends Writer {
|
||||
private final Appendable appendable;
|
||||
private final CurrentWrite currentWrite = new CurrentWrite();
|
||||
|
||||
private AppendableWriter(Appendable appendable) {
|
||||
this.appendable = appendable;
|
||||
}
|
||||
|
||||
@Override public void write(char[] chars, int offset, int length) throws IOException {
|
||||
currentWrite.chars = chars;
|
||||
appendable.append(currentWrite, offset, offset + length);
|
||||
}
|
||||
|
||||
@Override public void write(int i) throws IOException {
|
||||
appendable.append((char) i);
|
||||
}
|
||||
|
||||
@Override public void flush() {}
|
||||
@Override public void close() {}
|
||||
|
||||
/**
|
||||
* A mutable char sequence pointing at a single char[].
|
||||
*/
|
||||
static class CurrentWrite implements CharSequence {
|
||||
char[] chars;
|
||||
public int length() {
|
||||
return chars.length;
|
||||
}
|
||||
public char charAt(int i) {
|
||||
return chars[i];
|
||||
}
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return new String(chars, start, end - start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.internal;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonLiteral;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.internal.bind.TypeAdapters;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* Reads and writes GSON parse trees over streams.
|
||||
*/
|
||||
public final class Streams {
|
||||
/**
|
||||
* Takes a reader in any state and returns the next value as a JsonElement.
|
||||
*/
|
||||
public static JsonElement parse(JsonReader reader) throws JsonParseException {
|
||||
boolean isEmpty = true;
|
||||
try {
|
||||
reader.peek();
|
||||
isEmpty = false;
|
||||
return TypeAdapters.JSON_ELEMENT.read(reader);
|
||||
} catch (EOFException e) {
|
||||
/*
|
||||
* For compatibility with JSON 1.5 and earlier, we return a JsonNull for
|
||||
* empty documents instead of throwing.
|
||||
*/
|
||||
if (isEmpty) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
throw new JsonIOException(e);
|
||||
} catch (MalformedJsonException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the JSON element to the writer, recursively.
|
||||
*/
|
||||
public static void write(JsonElement element, JsonWriter writer) throws IOException {
|
||||
//BEGIN JCLOUDS PATCH
|
||||
// * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
if (element instanceof JsonLiteral ) {
|
||||
writer.value(JsonLiteral.class.cast(element));
|
||||
//END JCLOUDS PATCH
|
||||
} else {
|
||||
TypeAdapters.JSON_ELEMENT.write(writer, element);
|
||||
}
|
||||
}
|
||||
|
||||
public static Writer writerForAppendable(Appendable appendable) {
|
||||
return appendable instanceof Writer ? (Writer) appendable : new AppendableWriter(appendable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts an {@link Appendable} so it can be passed anywhere a {@link Writer}
|
||||
* is used.
|
||||
*/
|
||||
private static class AppendableWriter extends Writer {
|
||||
private final Appendable appendable;
|
||||
private final CurrentWrite currentWrite = new CurrentWrite();
|
||||
|
||||
private AppendableWriter(Appendable appendable) {
|
||||
this.appendable = appendable;
|
||||
}
|
||||
|
||||
@Override public void write(char[] chars, int offset, int length) throws IOException {
|
||||
currentWrite.chars = chars;
|
||||
appendable.append(currentWrite, offset, offset + length);
|
||||
}
|
||||
|
||||
@Override public void write(int i) throws IOException {
|
||||
appendable.append((char) i);
|
||||
}
|
||||
|
||||
@Override public void flush() {}
|
||||
@Override public void close() {}
|
||||
|
||||
/**
|
||||
* A mutable char sequence pointing at a single char[].
|
||||
*/
|
||||
static class CurrentWrite implements CharSequence {
|
||||
char[] chars;
|
||||
public int length() {
|
||||
return chars.length;
|
||||
}
|
||||
public char charAt(int i) {
|
||||
return chars[i];
|
||||
}
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return new String(chars, start, end - start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +1,19 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
/*
|
||||
* Copyright (C) 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.gson.stream;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
@ -124,7 +122,7 @@ import com.google.gson.JsonLiteral;
|
|||
* @author Jesse Wilson
|
||||
* @since 1.6
|
||||
*/
|
||||
public final class JsonWriter implements Closeable {
|
||||
public class JsonWriter implements Closeable {
|
||||
|
||||
/** The output data, containing at most one top-level array or object. */
|
||||
private final Writer out;
|
||||
|
@ -149,6 +147,10 @@ public final class JsonWriter implements Closeable {
|
|||
|
||||
private boolean htmlSafe;
|
||||
|
||||
private String deferredName;
|
||||
|
||||
private boolean serializeNulls = true;
|
||||
|
||||
/**
|
||||
* Creates a new instance that writes a JSON-encoded stream to {@code out}.
|
||||
* For best performance, ensure {@link Writer} is buffered; wrapping in
|
||||
|
@ -169,7 +171,7 @@ public final class JsonWriter implements Closeable {
|
|||
*
|
||||
* @param indent a string containing only whitespace.
|
||||
*/
|
||||
public void setIndent(String indent) {
|
||||
public final void setIndent(String indent) {
|
||||
if (indent.length() == 0) {
|
||||
this.indent = null;
|
||||
this.separator = ":";
|
||||
|
@ -191,7 +193,7 @@ public final class JsonWriter implements Closeable {
|
|||
* Double#isInfinite() infinities}.
|
||||
* </ul>
|
||||
*/
|
||||
public void setLenient(boolean lenient) {
|
||||
public final void setLenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
|
@ -209,7 +211,7 @@ public final class JsonWriter implements Closeable {
|
|||
* setting, your XML/HTML encoder should replace these characters with the
|
||||
* corresponding escape sequences.
|
||||
*/
|
||||
public void setHtmlSafe(boolean htmlSafe) {
|
||||
public final void setHtmlSafe(boolean htmlSafe) {
|
||||
this.htmlSafe = htmlSafe;
|
||||
}
|
||||
|
||||
|
@ -217,10 +219,26 @@ public final class JsonWriter implements Closeable {
|
|||
* Returns true if this writer writes JSON that's safe for inclusion in HTML
|
||||
* and XML documents.
|
||||
*/
|
||||
public boolean isHtmlSafe() {
|
||||
public final boolean isHtmlSafe() {
|
||||
return htmlSafe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether object members are serialized when their value is null.
|
||||
* This has no impact on array elements. The default is true.
|
||||
*/
|
||||
public final void setSerializeNulls(boolean serializeNulls) {
|
||||
this.serializeNulls = serializeNulls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if object members are serialized when their value is null.
|
||||
* This has no impact on array elements. The default is true.
|
||||
*/
|
||||
public final boolean getSerializeNulls() {
|
||||
return serializeNulls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins encoding a new array. Each call to this method must be paired with
|
||||
* a call to {@link #endArray}.
|
||||
|
@ -228,6 +246,7 @@ public final class JsonWriter implements Closeable {
|
|||
* @return this writer.
|
||||
*/
|
||||
public JsonWriter beginArray() throws IOException {
|
||||
writeDeferredName();
|
||||
return open(JsonScope.EMPTY_ARRAY, "[");
|
||||
}
|
||||
|
||||
|
@ -247,6 +266,7 @@ public final class JsonWriter implements Closeable {
|
|||
* @return this writer.
|
||||
*/
|
||||
public JsonWriter beginObject() throws IOException {
|
||||
writeDeferredName();
|
||||
return open(JsonScope.EMPTY_OBJECT, "{");
|
||||
}
|
||||
|
||||
|
@ -280,6 +300,9 @@ public final class JsonWriter implements Closeable {
|
|||
if (context != nonempty && context != empty) {
|
||||
throw new IllegalStateException("Nesting problem: " + stack);
|
||||
}
|
||||
if (deferredName != null) {
|
||||
throw new IllegalStateException("Dangling name: " + deferredName);
|
||||
}
|
||||
|
||||
stack.remove(stack.size() - 1);
|
||||
if (context == nonempty) {
|
||||
|
@ -313,11 +336,21 @@ public final class JsonWriter implements Closeable {
|
|||
if (name == null) {
|
||||
throw new NullPointerException("name == null");
|
||||
}
|
||||
beforeName();
|
||||
string(name);
|
||||
if (deferredName != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
deferredName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void writeDeferredName() throws IOException {
|
||||
if (deferredName != null) {
|
||||
beforeName();
|
||||
string(deferredName);
|
||||
deferredName = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes {@code value}.
|
||||
*
|
||||
|
@ -328,6 +361,7 @@ public final class JsonWriter implements Closeable {
|
|||
if (value == null) {
|
||||
return nullValue();
|
||||
}
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
string(value);
|
||||
return this;
|
||||
|
@ -339,29 +373,42 @@ public final class JsonWriter implements Closeable {
|
|||
* @return this writer.
|
||||
*/
|
||||
public JsonWriter nullValue() throws IOException {
|
||||
if (deferredName != null) {
|
||||
if (serializeNulls) {
|
||||
writeDeferredName();
|
||||
} else {
|
||||
deferredName = null;
|
||||
return this; // skip the name and the value
|
||||
}
|
||||
}
|
||||
beforeValue(false);
|
||||
out.write("null");
|
||||
return this;
|
||||
}
|
||||
//BEGIN JCLOUDS PATCH
|
||||
// * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
//* @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
|
||||
/**
|
||||
* Writes {@code value} literally
|
||||
*
|
||||
* @return this writer.
|
||||
*/
|
||||
public JsonWriter value(JsonLiteral value) throws IOException {
|
||||
if (value == null) {
|
||||
return nullValue();
|
||||
}
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
out.write(value.toString());
|
||||
return this;
|
||||
}
|
||||
//END JCLOUDS PATCH
|
||||
//END JCLOUDS PATCH
|
||||
/**
|
||||
* Encodes {@code value}.
|
||||
*
|
||||
* @return this writer.
|
||||
*/
|
||||
public JsonWriter value(boolean value) throws IOException {
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
out.write(value ? "true" : "false");
|
||||
return this;
|
||||
|
@ -378,6 +425,7 @@ public final class JsonWriter implements Closeable {
|
|||
if (Double.isNaN(value) || Double.isInfinite(value)) {
|
||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||
}
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
out.append(Double.toString(value));
|
||||
return this;
|
||||
|
@ -389,6 +437,7 @@ public final class JsonWriter implements Closeable {
|
|||
* @return this writer.
|
||||
*/
|
||||
public JsonWriter value(long value) throws IOException {
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
out.write(Long.toString(value));
|
||||
return this;
|
||||
|
@ -406,6 +455,7 @@ public final class JsonWriter implements Closeable {
|
|||
return nullValue();
|
||||
}
|
||||
|
||||
writeDeferredName();
|
||||
String string = value.toString();
|
||||
if (!lenient
|
||||
&& (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
|
||||
|
@ -447,6 +497,10 @@ public final class JsonWriter implements Closeable {
|
|||
* quotation marks except for the characters that must be escaped:
|
||||
* quotation mark, reverse solidus, and the control characters
|
||||
* (U+0000 through U+001F)."
|
||||
*
|
||||
* We also escape '\u2028' and '\u2029', which JavaScript interprets as
|
||||
* newline characters. This prevents eval() from failing with a syntax
|
||||
* error. http://code.google.com/p/google-gson/issues/detail?id=341
|
||||
*/
|
||||
switch (c) {
|
||||
case '"':
|
||||
|
@ -487,6 +541,11 @@ public final class JsonWriter implements Closeable {
|
|||
}
|
||||
break;
|
||||
|
||||
case '\u2028':
|
||||
case '\u2029':
|
||||
out.write(String.format("\\u%04x", (int) c));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c <= 0x1F) {
|
||||
out.write(String.format("\\u%04x", (int) c));
|
||||
|
|
Loading…
Reference in New Issue