All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
br.com.caelum.vraptor.serialization.gson.GsonDeserialization Maven / Gradle / Ivy
/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource All rights reserved.
*
* 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 br.com.caelum.vraptor.serialization.gson;
import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.nio.charset.Charset;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import br.com.caelum.vraptor.Consumes;
import br.com.caelum.vraptor.controller.ControllerMethod;
import br.com.caelum.vraptor.http.Parameter;
import br.com.caelum.vraptor.http.ParameterNameProvider;
import br.com.caelum.vraptor.ioc.Container;
import br.com.caelum.vraptor.serialization.Deserializee;
import br.com.caelum.vraptor.serialization.Deserializer;
import br.com.caelum.vraptor.serialization.DeserializerConfig;
import br.com.caelum.vraptor.serialization.Deserializes;
import br.com.caelum.vraptor.view.ResultException;
import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
* A GSON deserializer.
* @author Renan Reis
* @author Guilherme Mangabeira
*/
@Deserializes({ "application/json", "json" })
public class GsonDeserialization implements Deserializer {
private static final Logger logger = LoggerFactory.getLogger(GsonDeserialization.class);
private final GsonDeserializerBuilder builder;
private final ParameterNameProvider paramNameProvider;
private final HttpServletRequest request;
private final Container container;
private final Instance deserializeeInstance;
/**
* @deprecated CDI eyes only
*/
protected GsonDeserialization() {
this(null, null, null, null, null);
}
@Inject
public GsonDeserialization(GsonDeserializerBuilder builder, ParameterNameProvider paramNameProvider, HttpServletRequest request,
Container container, Instance deserializeeInstance) {
this.builder = builder;
this.paramNameProvider = paramNameProvider;
this.request = request;
this.container = container;
this.deserializeeInstance = deserializeeInstance;
}
@Override
public Object[] deserialize(InputStream inputStream, ControllerMethod method) {
Class>[] types = getTypes(method);
if (types.length == 0) {
throw new IllegalArgumentException("Methods that consumes representations must receive just one argument");
}
Gson gson = builder.create();
final Parameter[] parameterNames = paramNameProvider.parametersFor(method.getMethod());
final Object[] values = new Object[parameterNames.length];
final Deserializee deserializee = deserializeeInstance.get();
try {
String content = getContentOfStream(inputStream);
logger.debug("json retrieved: {}", content);
if (!isNullOrEmpty(content)) {
JsonParser parser = new JsonParser();
JsonElement jsonElement = parser.parse(content);
if (jsonElement.isJsonObject()) {
JsonObject root = jsonElement.getAsJsonObject();
deserializee.setWithoutRoot(isWithoutRoot(parameterNames, root));
for(Class extends DeserializerConfig> option: method.getMethod().getAnnotation(Consumes.class).options()) {
DeserializerConfig config = container.instanceFor(option);
config.config(deserializee);
}
for (int i = 0; i < types.length; i++) {
Parameter parameter = parameterNames[i];
JsonElement node = root.get(parameter.getName());
if (deserializee.isWithoutRoot()) {
values[i] = gson.fromJson(root, fallbackTo(parameter.getParameterizedType(), types[i]));
logger.debug("json without root deserialized");
break;
} else if (node != null) {
if (node.isJsonArray()) {
JsonArray jsonArray= node.getAsJsonArray();
Type type = parameter.getParameterizedType();
if (type instanceof ParameterizedType) {
values[i] = gson.fromJson(jsonArray, type);
} else {
values[i] = gson.fromJson(jsonArray, types[i]);
}
} else {
values[i] = gson.fromJson(node, types[i]);
}
}
}
} else if (jsonElement.isJsonArray()) {
if ((parameterNames.length != 1) || (!(parameterNames[0].getParameterizedType() instanceof ParameterizedType)))
throw new IllegalArgumentException("Methods that consumes an array representation must receive only just one collection generic typed argument");
JsonArray jsonArray= jsonElement.getAsJsonArray();
values[0] = gson.fromJson(jsonArray, parameterNames[0].getParameterizedType());
} else {
throw new IllegalArgumentException("This is an invalid or not supported json content");
}
}
} catch (Exception e) {
throw new ResultException("Unable to deserialize data", e);
}
logger.debug("json deserialized: {}", (Object) values);
return values;
}
private static Type fallbackTo(Type parameterizedType, Class> type) {
if (parameterizedType instanceof TypeVariable) return type;
return parameterizedType;
}
private String getContentOfStream(InputStream input) throws IOException {
Charset charset = Charset.forName(getRequestCharset());
logger.debug("Using charset {}", charset);
return CharStreams.toString(new InputStreamReader(input, charset));
}
private String getRequestCharset() {
String charset = firstNonNull(request.getHeader("Accept-Charset"), "UTF-8");
return charset.split(",")[0];
}
private static boolean isWithoutRoot(Parameter[] parameters, JsonObject root) {
for (Parameter parameter : parameters) {
if (root.get(parameter.getName()) != null)
return false;
}
return true;
}
protected Class>[] getTypes(ControllerMethod method) {
Class>[] parameterTypes = method.getMethod().getParameterTypes();
Type genericType = getGenericSuperClass(method);
if (genericType != null) {
return parseGenericParameters(parameterTypes, genericType);
}
return parameterTypes;
}
private static Class>[] parseGenericParameters(Class>[] parameterTypes,
Type genericType) {
Class> type = (Class>) getGenericType(genericType);
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].isAssignableFrom(type)) {
parameterTypes[i] = type;
}
}
return parameterTypes;
}
private static Type getGenericSuperClass(ControllerMethod method) {
Type genericType = method.getController().getType().getGenericSuperclass();
if (genericType instanceof ParameterizedType) {
return genericType;
}
return null;
}
private static Type getGenericType(Type type) {
ParameterizedType paramType = (ParameterizedType) type;
return paramType.getActualTypeArguments()[0];
}
}