diff --git a/examples/src/main/java/com/squareup/moshi/recipes/DefaultOnDataMismatchAdapter.java b/examples/src/main/java/com/squareup/moshi/recipes/DefaultOnDataMismatchAdapter.java new file mode 100644 index 0000000..c7082e4 --- /dev/null +++ b/examples/src/main/java/com/squareup/moshi/recipes/DefaultOnDataMismatchAdapter.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017 Square, 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.squareup.moshi.recipes; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonDataException; +import com.squareup.moshi.JsonReader; +import com.squareup.moshi.JsonWriter; +import com.squareup.moshi.Moshi; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Set; + +public final class DefaultOnDataMismatchAdapter extends JsonAdapter { + private final JsonAdapter delegate; + private final T defaultValue; + private final JsonAdapter objectAdapter; + + private DefaultOnDataMismatchAdapter(JsonAdapter delegate, T defaultValue, + JsonAdapter objectAdapter) { + this.delegate = delegate; + this.defaultValue = defaultValue; + this.objectAdapter = objectAdapter; + } + + @Override public T fromJson(JsonReader reader) throws IOException { + // Read the value first so that the reader will be in a known state even if there's an + // exception. Otherwise it may be awkward to recover: it might be between calls to + // beginObject() and endObject() for example. + Object jsonValue = objectAdapter.fromJson(reader); + + // Use the delegate to convert the JSON value to the target type. + try { + return delegate.fromJsonValue(jsonValue); + } catch (JsonDataException e) { + return defaultValue; + } + } + + @Override public void toJson(JsonWriter writer, T value) throws IOException { + delegate.toJson(writer, value); + } + + public static Factory newFactory(final Class type, final T defaultValue) { + return new Factory() { + @Override public JsonAdapter create( + Type requestedType, Set annotations, Moshi moshi) { + if (type != requestedType) return null; + JsonAdapter objectAdapter = moshi.adapter(Object.class); + JsonAdapter delegate = moshi.nextAdapter(this, type, annotations); + return new DefaultOnDataMismatchAdapter<>(delegate, defaultValue, objectAdapter); + } + }; + } +} diff --git a/examples/src/main/java/com/squareup/moshi/recipes/RecoverFromTypeMismatch.java b/examples/src/main/java/com/squareup/moshi/recipes/RecoverFromTypeMismatch.java new file mode 100644 index 0000000..ad5d805 --- /dev/null +++ b/examples/src/main/java/com/squareup/moshi/recipes/RecoverFromTypeMismatch.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 Square, 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.squareup.moshi.recipes; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; +import com.squareup.moshi.recipes.models.Suit; +import java.util.List; + +public final class RecoverFromTypeMismatch { + public void run() throws Exception { + String json = "[\"DIAMONDS\", \"STARS\", \"HEARTS\"]"; + + Moshi moshi = new Moshi.Builder() + .add(DefaultOnDataMismatchAdapter.newFactory(Suit.class, Suit.CLUBS)) + .build(); + JsonAdapter> jsonAdapter = moshi.adapter( + Types.newParameterizedType(List.class, Suit.class)); + + List suits = jsonAdapter.fromJson(json); + System.out.println(suits); + } + + public static void main(String[] args) throws Exception { + new RecoverFromTypeMismatch().run(); + } +}