/* * Copyright 2015 MovingBlocks * * 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.terasology.web.io; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.naming.gson.NameTypeAdapter; import org.terasology.naming.gson.VersionTypeAdapter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; /** * Adapted from * http://eclipsesource.com/blogs/2012/11/02/integrating-gson-into-a-jax-rs-based-application/ */ @Provider @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public final class GsonMessageBodyHandler implements MessageBodyWriter<Object>, MessageBodyReader<Object> { private static final Gson GSON = new GsonBuilder() .setPrettyPrinting() .registerTypeAdapter(Version.class, new VersionTypeAdapter()) .registerTypeAdapter(Name.class, new NameTypeAdapter()) .create(); @Override public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return true; } @Override public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException { try (Reader streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) { Type jsonType; if (type.equals(genericType)) { jsonType = type; } else { jsonType = genericType; } return GSON.fromJson(streamReader, jsonType); } } @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return true; } @Override public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return -1; } @Override public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException { try (Writer writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) { Type jsonType; if (type.equals(genericType)) { jsonType = type; } else { jsonType = genericType; } GSON.toJson(object, jsonType, writer); } } }