javax.ws.rs
diff --git a/gson/src/org/immutables/gson/Gson.java b/gson/src/org/immutables/gson/Gson.java
index ddf0d2897..529ffc627 100644
--- a/gson/src/org/immutables/gson/Gson.java
+++ b/gson/src/org/immutables/gson/Gson.java
@@ -1,5 +1,23 @@
+/*
+ Copyright 2015 Immutables Authors and Contributors
+
+ 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 org.immutables.gson;
+import java.util.Map;
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.FieldNamingStrategy;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import java.lang.annotation.Documented;
@@ -7,36 +25,83 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.immutables.gson.adapter.ExpectedSubtypesAdapter;
+import org.immutables.gson.adapter.FieldNamingTranslator;
+/**
+ * The Interface Gson.
+ */
@Retention(RetentionPolicy.SOURCE)
public @interface Gson {
/**
- * Use on a top level class to generate type adapted factory.
+ * Use on a top level class to generate type adapted factory supporting directly annotated and all
+ * nested immutable types.
*
- * Type adapter factories are also registered statically as services
- * {@code META-INF/services/com.google.gson.TypeAdapterFactory}. Easy way to configure
- * {@link com.google.gson.Gson}.
+ * Type adapter factories are registered statically as services
+ * {@code META-INF/services/com.google.gson.TypeAdapterFactory}. The most easy way to register all
+ * such factories {@link com.google.gson.Gson}.
*
- * Certain are gson options are supported for immutable objects in deliberate fashion:
+ * Certain Gson options are supported for immutable objects in deliberate fashion:
*
* - {@link GsonBuilder#serializeNulls()} - When enabled, {@code null} fields and empty array
* fields will be included, otherwise omited
+ * - {@link GsonBuilder#setFieldNamingStrategy(FieldNamingStrategy)} - Naming strategy could be
+ * used if {@code @TypeAdapters(fieldNamingStrategy=true)}. See {@link #fieldNamingStrategy()} for
+ * more information.
*
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
- public @interface TypeAdapted {}
+ public @interface TypeAdapters {
+ /**
+ * When {@code namingStrategy=true}, somewhat more involved code is generated to apply naming
+ * strategies extracted from configured {@link com.google.gson.Gson} instance.
+ *
+ * This functionality uses runtime support class and requires that this Gson integration module
+ * jar will be available at runtime. Uses some Gson internals which could
+ * potentially break in later versions of Gson library. Uses oracle JVM internals.
+ * If you really want to discuss this functionality to be more portable,
+ * file a request at {@linkplain "https://github.com/immutables/immutables/issues"}.
+ *
+ * @see FieldNamingStrategy
+ * @see FieldNamingPolicy
+ * @see GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)
+ * @see FieldNamingTranslator
+ * @return {@code true} if enabled, by default is {@code false}
+ */
+ boolean fieldNamingStrategy() default false;
+
+ /**
+ * When {@code emptyAsNulls=true}, empty arrays and objects will be omitted from output as
+ * if they where {@code null}, both field name and value will be omited.
+ *
+ * Note that {@code null} skipping behaviour is controlled by
+ * {@link GsonBuilder#serializeNulls()}, which forces all nulls and empty arrays/objects to be
+ * serialized.
+ * @return {@code true} if enabled, by default is {@code false}
+ */
+ boolean emptyAsNulls() default false;
+ }
/**
- * Expected subclasses for marshaling could be specified on attribute level or an abstract
- * supertype directly, however the former declaration site has precedence.
+ * Expected subtypes for serialization could be specified on attribute level or an abstract
+ * supertype directly, however the former declaration site has precedence. It enables polymorphic
+ * marshaling by structure. Subtype that matches JSON value will be returned, for the details
+ * please see {@link ExpectedSubtypesAdapter}.
+ *
+ * Note: when this annotation is used with {@link Map} attribute, it refers to types of values,
+ * not keys.
+ *
+ * This functionality uses runtime support class and requires that this Gson integration module
+ * jar will be available at runtime.
+ * @see ExpectedSubtypesAdapter
* @see #value()
* @see Named
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.TYPE})
- public @interface Subtypes {
+ public @interface ExpectedSubtypes {
/**
* Specifies expected subclasses of an abstract type that is matched during parsing by
diff --git a/gson/src/org/immutables/gson/stream/GsonMessageBodyProvider.java b/gson/src/org/immutables/gson/stream/GsonMessageBodyProvider.java
index 5e835eacb..32799b0f6 100644
--- a/gson/src/org/immutables/gson/stream/GsonMessageBodyProvider.java
+++ b/gson/src/org/immutables/gson/stream/GsonMessageBodyProvider.java
@@ -15,14 +15,6 @@
*/
package org.immutables.gson.stream;
-import org.immutables.value.Value.Style.ImplementationVisibility;
-import java.lang.reflect.Field;
-import org.immutables.value.Value;
-import java.util.List;
-import javax.ws.rs.core.Response;
-import com.google.common.base.Throwables;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.Produces;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
@@ -39,20 +31,26 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
import java.lang.reflect.Type;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import javax.annotation.Nullable;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import org.immutables.metainf.Metainf;
+import org.immutables.value.Value;
+import org.immutables.value.Value.Style.ImplementationVisibility;
/**
* Gson serialization provider for JAX-RS 1.0 and JAX-RS 2.0.
diff --git a/gson/src/org/immutables/gson/stream/JsonGeneratorWriter.java b/gson/src/org/immutables/gson/stream/JsonGeneratorWriter.java
index 90bcbe51e..c737521e0 100644
--- a/gson/src/org/immutables/gson/stream/JsonGeneratorWriter.java
+++ b/gson/src/org/immutables/gson/stream/JsonGeneratorWriter.java
@@ -15,11 +15,12 @@
*/
package org.immutables.gson.stream;
-import javax.annotation.concurrent.NotThreadSafe;
import com.fasterxml.jackson.core.JsonGenerator;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.Writer;
+import java.util.concurrent.Callable;
+import javax.annotation.concurrent.NotThreadSafe;
/**
* {@link JsonWriter} impementation backed by Jackson's {@link JsonGenerator}.
@@ -27,8 +28,7 @@
* Error reporting is might differ, however.
*/
@NotThreadSafe
-public class JsonGeneratorWriter extends JsonWriter {
-
+public class JsonGeneratorWriter extends JsonWriter implements Callable {
private static final Writer UNSUPPORTED_WRITER = new Writer() {
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
@@ -53,6 +53,10 @@ public JsonGeneratorWriter(JsonGenerator generator) {
this.generator = generator;
}
+ public JsonGenerator getGenerator() {
+ return generator;
+ }
+
@Override
public JsonWriter beginArray() throws IOException {
generator.writeStartArray();
@@ -145,4 +149,14 @@ public void close() throws IOException {
public String toString() {
return getClass().getSimpleName();
}
+
+ /**
+ * Implements {@link Callable} mostly as a marker interface.
+ * Better use {@link #getGenerator()} to get generator.
+ * @return unwrapped {@link JsonGenerator}
+ */
+ @Override
+ public JsonGenerator call() throws Exception {
+ return generator;
+ }
}
diff --git a/gson/src/org/immutables/gson/stream/JsonParserReader.java b/gson/src/org/immutables/gson/stream/JsonParserReader.java
index cfdc4945d..b52e9e399 100644
--- a/gson/src/org/immutables/gson/stream/JsonParserReader.java
+++ b/gson/src/org/immutables/gson/stream/JsonParserReader.java
@@ -15,6 +15,7 @@
*/
package org.immutables.gson.stream;
+import java.util.concurrent.Callable;
import com.fasterxml.jackson.core.JsonParser;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
@@ -27,10 +28,10 @@
/**
* {@link JsonReader} impementation backed by Jackson's {@link JsonParser}.
* Provides measurable JSON parsing improvements over Gson's native implementation.
- * Error reporting is might differ, however.
+ * Error reporting might differ, however.
*/
@NotThreadSafe
-public class JsonParserReader extends JsonReader {
+public class JsonParserReader extends JsonReader implements Callable {
private static final Reader UNSUPPORTED_READER = new Reader() {
@Override
@@ -51,6 +52,10 @@ public JsonParserReader(JsonParser parser) {
this.parser = parser;
}
+ public JsonParser getParser() {
+ return parser;
+ }
+
@Nullable
private com.fasterxml.jackson.core.JsonToken peek;
@@ -130,6 +135,7 @@ public String nextString() throws IOException {
clearPeek();
return value;
}
+
@Override
public boolean nextBoolean() throws IOException {
requirePeek();
@@ -216,7 +222,17 @@ private static JsonToken toGsonToken(com.fasterxml.jackson.core.JsonToken token)
case VALUE_STRING:
return JsonToken.STRING;
default: // Not semantically equivalent
- return JsonToken.END_DOCUMENT;
+ return JsonToken.NULL;
}
}
+
+ /**
+ * Implements {@link Callable} mostly as a marker interface.
+ * Better use {@link #getParser()} to get parser.
+ * @return unwrapped {@link JsonParser}
+ */
+ @Override
+ public JsonParser call() throws Exception {
+ return parser;
+ }
}
diff --git a/gson/test/org/immutables/gson/adapters/Adapt.java b/gson/test/org/immutables/gson/adapter/Adapt.java
similarity index 92%
rename from gson/test/org/immutables/gson/adapters/Adapt.java
rename to gson/test/org/immutables/gson/adapter/Adapt.java
index 601f8fc91..b7abaeb39 100644
--- a/gson/test/org/immutables/gson/adapters/Adapt.java
+++ b/gson/test/org/immutables/gson/adapter/Adapt.java
@@ -1,4 +1,4 @@
-package org.immutables.gson.adapters;
+package org.immutables.gson.adapter;
import com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;
@@ -11,7 +11,7 @@
@Value.Immutable(builder = false)
@Value.Nested
-@Gson.TypeAdapted
+@Gson.TypeAdapters
public interface Adapt {
@Value.Parameter
diff --git a/gson/test/org/immutables/gson/adapters/AdaptReadWriteTest.java b/gson/test/org/immutables/gson/adapter/AdaptReadWriteTest.java
similarity index 98%
rename from gson/test/org/immutables/gson/adapters/AdaptReadWriteTest.java
rename to gson/test/org/immutables/gson/adapter/AdaptReadWriteTest.java
index 3e1132e9d..eb44efef3 100644
--- a/gson/test/org/immutables/gson/adapters/AdaptReadWriteTest.java
+++ b/gson/test/org/immutables/gson/adapter/AdaptReadWriteTest.java
@@ -1,4 +1,4 @@
-package org.immutables.gson.adapters;
+package org.immutables.gson.adapter;
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
diff --git a/gson/test/org/immutables/gson/adapters/OtherType.java b/gson/test/org/immutables/gson/adapter/OtherType.java
similarity index 93%
rename from gson/test/org/immutables/gson/adapters/OtherType.java
rename to gson/test/org/immutables/gson/adapter/OtherType.java
index a239f5412..29b4a979f 100644
--- a/gson/test/org/immutables/gson/adapters/OtherType.java
+++ b/gson/test/org/immutables/gson/adapter/OtherType.java
@@ -1,4 +1,4 @@
-package org.immutables.gson.adapters;
+package org.immutables.gson.adapter;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multiset;
@@ -11,7 +11,7 @@
@Value.Immutable(builder = false)
@Value.Nested
-@Gson.TypeAdapted
+@Gson.TypeAdapters
public interface OtherType {
@Value.Parameter