/* * 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 com.smartandroid.sa.json; import java.lang.reflect.Type; import com.smartandroid.sa.json.internal.$Gson$Preconditions; /** * Abstract data value container for the {@link ObjectNavigator.Visitor} * implementations. This class exposes the {@link #getTarget()} method which * returns the class that was visited by this object. * * @author Inderjeet Singh * @author Joel Leitch */ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor { protected final ObjectNavigator objectNavigator; protected final FieldNamingStrategy2 fieldNamingPolicy; protected final ObjectConstructor objectConstructor; protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers; protected T target; protected final JsonElement json; protected final Type targetType; protected final JsonDeserializationContext context; protected boolean constructed; JsonDeserializationVisitor(JsonElement json, Type targetType, ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy, ObjectConstructor objectConstructor, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers, JsonDeserializationContext context) { this.targetType = targetType; this.objectNavigator = objectNavigator; this.fieldNamingPolicy = fieldNamingPolicy; this.objectConstructor = objectConstructor; this.deserializers = deserializers; this.json = $Gson$Preconditions.checkNotNull(json); this.context = context; this.constructed = false; } public T getTarget() { if (!constructed) { target = constructTarget(); constructed = true; } return target; } protected abstract T constructTarget(); public void start(ObjectTypePair node) { } public void end(ObjectTypePair node) { } @SuppressWarnings("unchecked") public final boolean visitUsingCustomHandler(ObjectTypePair objTypePair) { Pair<JsonDeserializer<?>, ObjectTypePair> pair = objTypePair .getMatchingHandler(deserializers); if (pair == null) { return false; } Object value = invokeCustomDeserializer(json, pair); target = (T) value; constructed = true; return true; } protected Object invokeCustomDeserializer(JsonElement element, Pair<JsonDeserializer<?>, ObjectTypePair> pair) { if (element == null || element.isJsonNull()) { return null; } Type objType = pair.second.type; return (pair.first).deserialize(element, objType, context); } final Object visitChildAsObject(Type childType, JsonElement jsonChild) { JsonDeserializationVisitor<?> childVisitor = new JsonObjectDeserializationVisitor<Object>( jsonChild, childType, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context); return visitChild(childType, childVisitor); } final Object visitChildAsArray(Type childType, JsonArray jsonChild) { JsonDeserializationVisitor<?> childVisitor = new JsonArrayDeserializationVisitor<Object>( jsonChild.getAsJsonArray(), childType, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context); return visitChild(childType, childVisitor); } private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) { objectNavigator.accept(new ObjectTypePair(null, type, false, false), childVisitor); // the underlying object may have changed during the construction phase // This happens primarily because of custom deserializers return childVisitor.getTarget(); } }