/* * Hibernate Search, full-text search for your domain model * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.elasticsearch.gson.impl; import java.io.IOException; import java.util.Map; import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; /** * @author Yoann Rodiere */ public abstract class AbstractExtraPropertiesJsonAdapter<T> extends TypeAdapter<T> { interface FieldAdapter<T> { void read(JsonReader in, T instance) throws IOException; void write(JsonWriter out, T instance) throws IOException; boolean serialized(); } interface ExtraPropertyAdapter<T> { void readOne(JsonReader in, String name, T instance) throws IOException; void writeAll(JsonWriter out, T instance) throws IOException; } private final Map<String, ? extends FieldAdapter<? super T>> fieldAdapters; private final ExtraPropertyAdapter<? super T> extraPropertyAdapter; public AbstractExtraPropertiesJsonAdapter(Map<String, ? extends FieldAdapter<? super T>> fieldAdapters, ExtraPropertyAdapter<? super T> extraPropertyAdapter) { super(); this.fieldAdapters = fieldAdapters; this.extraPropertyAdapter = extraPropertyAdapter; } @Override public T read(JsonReader in) throws IOException { if ( in.peek() == JsonToken.NULL ) { in.nextNull(); return null; } T instance = createInstance(); try { in.beginObject(); while ( in.hasNext() ) { String name = in.nextName(); FieldAdapter<? super T> fieldAdapter = fieldAdapters.get( name ); if ( fieldAdapter == null ) { extraPropertyAdapter.readOne( in, name, instance ); } else { fieldAdapter.read( in, instance ); } } in.endObject(); } catch (IllegalStateException e) { throw new JsonSyntaxException( e ); } return instance; } @Override public void write(JsonWriter out, T instance) throws IOException { if ( instance == null ) { out.nullValue(); } out.beginObject(); for ( Map.Entry<String, ? extends FieldAdapter<? super T>> entry : fieldAdapters.entrySet() ) { FieldAdapter<? super T> fieldAdapter = entry.getValue(); if ( fieldAdapter.serialized() ) { out.name( entry.getKey() ); entry.getValue().write( out, instance ); } } extraPropertyAdapter.writeAll( out, instance ); out.endObject(); } protected abstract T createInstance(); }