136 lines
4.5 KiB
Java
136 lines
4.5 KiB
Java
/*
|
|
* Copyright (C) 2008 Google 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 org.mcteam.factions.gson;
|
|
|
|
import java.lang.reflect.Type;
|
|
|
|
/**
|
|
* A visitor that populates fields of an object with data from its equivalent
|
|
* JSON representation
|
|
*
|
|
* @author Inderjeet Singh
|
|
* @author Joel Leitch
|
|
*/
|
|
final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
|
|
|
|
JsonObjectDeserializationVisitor(JsonElement json, Type type,
|
|
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
|
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
|
JsonDeserializationContext context) {
|
|
super(json, type, factory, objectConstructor, deserializers, context);
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("unchecked")
|
|
protected T constructTarget() {
|
|
return (T) objectConstructor.construct(targetType);
|
|
}
|
|
|
|
public void startVisitingObject(Object node) {
|
|
// do nothing
|
|
}
|
|
|
|
public void visitArray(Object array, Type componentType) {
|
|
// should not be called since this case should invoke JsonArrayDeserializationVisitor
|
|
throw new JsonParseException("Expecting object but found array: " + array);
|
|
}
|
|
|
|
public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
|
|
try {
|
|
if (!json.isJsonObject()) {
|
|
throw new JsonParseException("Expecting object found: " + json);
|
|
}
|
|
JsonObject jsonObject = json.getAsJsonObject();
|
|
String fName = getFieldName(f);
|
|
JsonElement jsonChild = jsonObject.get(fName);
|
|
if (jsonChild != null) {
|
|
Object child = visitChildAsObject(typeOfF, jsonChild);
|
|
f.set(obj, child);
|
|
} else {
|
|
f.set(obj, null);
|
|
}
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
|
|
try {
|
|
if (!json.isJsonObject()) {
|
|
throw new JsonParseException("Expecting object found: " + json);
|
|
}
|
|
JsonObject jsonObject = json.getAsJsonObject();
|
|
String fName = getFieldName(f);
|
|
JsonArray jsonChild = (JsonArray) jsonObject.get(fName);
|
|
if (jsonChild != null) {
|
|
Object array = visitChildAsArray(typeOfF, jsonChild);
|
|
f.set(obj, array);
|
|
} else {
|
|
f.set(obj, null);
|
|
}
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
private String getFieldName(FieldAttributes f) {
|
|
FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
|
|
return namingPolicy.translateName(f);
|
|
}
|
|
|
|
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
|
|
try {
|
|
String fName = getFieldName(f);
|
|
if (!json.isJsonObject()) {
|
|
throw new JsonParseException("Expecting object found: " + json);
|
|
}
|
|
JsonElement child = json.getAsJsonObject().get(fName);
|
|
TypeInfo typeInfo = new TypeInfo(declaredTypeOfField);
|
|
if (child == null) { // Child will be null if the field wasn't present in Json
|
|
return true;
|
|
} else if (child.isJsonNull()) {
|
|
if (!typeInfo.isPrimitive()) {
|
|
f.set(parent, null);
|
|
}
|
|
return true;
|
|
}
|
|
ObjectTypePair objTypePair = new ObjectTypePair(null, declaredTypeOfField, false);
|
|
Pair<JsonDeserializer<?>, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers);
|
|
if (pair == null) {
|
|
return false;
|
|
}
|
|
Object value = invokeCustomDeserializer(child, pair);
|
|
if (value != null || !typeInfo.isPrimitive()) {
|
|
f.set(parent, value);
|
|
}
|
|
return true;
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public void visitPrimitive(Object primitive) {
|
|
if (!json.isJsonPrimitive()) {
|
|
throw new JsonParseException(
|
|
"Type information is unavailable, and the target object is not a primitive: " + json);
|
|
}
|
|
JsonPrimitive prim = json.getAsJsonPrimitive();
|
|
target = (T) prim.getAsObject();
|
|
}
|
|
}
|