Create new builder from Moshi instance

This commit is contained in:
Serj Lotutovici
2015-10-21 12:01:43 +02:00
parent e6a1e59dd4
commit ee01275c76
2 changed files with 38 additions and 8 deletions

View File

@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -30,6 +31,16 @@ import java.util.Set;
* Coordinates binding between JSON values and Java objects. * Coordinates binding between JSON values and Java objects.
*/ */
public final class Moshi { public final class Moshi {
static final List<JsonAdapter.Factory> BUILT_IN_FACTORIES = new ArrayList<>();
static {
BUILT_IN_FACTORIES.add(StandardJsonAdapters.FACTORY);
BUILT_IN_FACTORIES.add(CollectionJsonAdapter.FACTORY);
BUILT_IN_FACTORIES.add(MapJsonAdapter.FACTORY);
BUILT_IN_FACTORIES.add(ArrayJsonAdapter.FACTORY);
BUILT_IN_FACTORIES.add(ClassJsonAdapter.FACTORY);
}
private final List<JsonAdapter.Factory> factories; private final List<JsonAdapter.Factory> factories;
private final ThreadLocal<List<DeferredAdapter<?>>> reentrantCalls = new ThreadLocal<>(); private final ThreadLocal<List<DeferredAdapter<?>>> reentrantCalls = new ThreadLocal<>();
private final Map<Object, JsonAdapter<?>> adapterCache = new LinkedHashMap<>(); private final Map<Object, JsonAdapter<?>> adapterCache = new LinkedHashMap<>();
@@ -37,11 +48,7 @@ public final class Moshi {
private Moshi(Builder builder) { private Moshi(Builder builder) {
List<JsonAdapter.Factory> factories = new ArrayList<>(); List<JsonAdapter.Factory> factories = new ArrayList<>();
factories.addAll(builder.factories); factories.addAll(builder.factories);
factories.add(StandardJsonAdapters.FACTORY); factories.addAll(BUILT_IN_FACTORIES);
factories.add(CollectionJsonAdapter.FACTORY);
factories.add(MapJsonAdapter.FACTORY);
factories.add(ArrayJsonAdapter.FACTORY);
factories.add(ClassJsonAdapter.FACTORY);
this.factories = Collections.unmodifiableList(factories); this.factories = Collections.unmodifiableList(factories);
} }
@@ -116,6 +123,14 @@ public final class Moshi {
+ type + " annotated " + annotations); + type + " annotated " + annotations);
} }
/** Returns a new builder containing all custom factories used by the current instance. */
public Moshi.Builder newBuilder() {
int fullSize = factories.size();
int tailSize = BUILT_IN_FACTORIES.size();
List<JsonAdapter.Factory> customFactories = factories.subList(0, fullSize - tailSize);
return new Builder().addAll(customFactories);
}
/** Returns an opaque object that's equal if the type and annotations are equal. */ /** Returns an opaque object that's equal if the type and annotations are equal. */
private Object cacheKey(Type type, Set<? extends Annotation> annotations) { private Object cacheKey(Type type, Set<? extends Annotation> annotations) {
if (annotations.isEmpty()) return type; if (annotations.isEmpty()) return type;
@@ -123,7 +138,7 @@ public final class Moshi {
} }
public static final class Builder { public static final class Builder {
private final List<JsonAdapter.Factory> factories = new ArrayList<>(); final List<JsonAdapter.Factory> factories = new ArrayList<>();
public <T> Builder add(final Type type, final JsonAdapter<T> jsonAdapter) { public <T> Builder add(final Type type, final JsonAdapter<T> jsonAdapter) {
if (type == null) throw new IllegalArgumentException("type == null"); if (type == null) throw new IllegalArgumentException("type == null");
@@ -162,8 +177,8 @@ public final class Moshi {
}); });
} }
public Builder add(JsonAdapter.Factory jsonAdapter) { public Builder add(JsonAdapter.Factory factory) {
factories.add(jsonAdapter); factories.add(factory);
return this; return this;
} }
@@ -171,6 +186,11 @@ public final class Moshi {
return add(AdapterMethodsFactory.get(adapter)); return add(AdapterMethodsFactory.get(adapter));
} }
private Builder addAll(List<JsonAdapter.Factory> factories) {
this.factories.addAll(factories);
return this;
}
public Moshi build() { public Moshi build() {
return new Moshi(this); return new Moshi(this);
} }

View File

@@ -799,6 +799,16 @@ public final class MoshiTest {
assertThat(adapter1).isSameAs(adapter2); assertThat(adapter1).isSameAs(adapter2);
} }
@Test public void newBuilder() throws Exception {
Moshi moshi = new Moshi.Builder()
.add(Pizza.class, new PizzaAdapter())
.build();
Moshi.Builder newBuilder = moshi.newBuilder();
for (JsonAdapter.Factory factory : Moshi.BUILT_IN_FACTORIES) {
assertThat(factory).isNotIn(newBuilder.factories);
}
}
static class Pizza { static class Pizza {
final int diameter; final int diameter;
final boolean extraCheese; final boolean extraCheese;