com.apollographql.apollo.internal.response.RealResponseReader Maven / Gradle / Ivy
/**
* Copyright 2018-2019 Amazon.com,
* Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
package com.apollographql.apollo.internal.response;
import com.apollographql.apollo.CustomTypeAdapter;
import com.apollographql.apollo.api.Operation;
import com.apollographql.apollo.api.ResponseField;
import com.apollographql.apollo.api.ResponseReader;
import com.apollographql.apollo.api.ScalarType;
import com.apollographql.apollo.api.internal.Optional;
import com.apollographql.apollo.internal.field.FieldValueResolver;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@SuppressWarnings("WeakerAccess") public final class RealResponseReader implements ResponseReader {
private final Operation.Variables operationVariables;
private final R recordSet;
private final ScalarTypeAdapters scalarTypeAdapters;
private final FieldValueResolver fieldValueResolver;
private final ResponseReaderShadow readerShadow;
private final Map variableValues;
public RealResponseReader(Operation.Variables operationVariables, R recordSet,
FieldValueResolver fieldValueResolver, ScalarTypeAdapters scalarTypeAdapters,
ResponseReaderShadow readerShadow) {
this.operationVariables = operationVariables;
this.recordSet = recordSet;
this.fieldValueResolver = fieldValueResolver;
this.scalarTypeAdapters = scalarTypeAdapters;
this.readerShadow = readerShadow;
this.variableValues = operationVariables.valueMap();
}
@Override public String readString(ResponseField field) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
String value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
if (value == null) {
readerShadow.didResolveNull();
} else {
readerShadow.didResolveScalar(value);
}
didResolve(field);
return value;
}
@Override public Integer readInt(ResponseField field) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
BigDecimal value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
if (value == null) {
readerShadow.didResolveNull();
} else {
readerShadow.didResolveScalar(value);
}
didResolve(field);
return value != null ? value.intValue() : null;
}
@Override public Long readLong(ResponseField field) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
BigDecimal value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
if (value == null) {
readerShadow.didResolveNull();
} else {
readerShadow.didResolveScalar(value);
}
didResolve(field);
return value != null ? value.longValue() : null;
}
@Override public Double readDouble(ResponseField field) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
BigDecimal value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
if (value == null) {
readerShadow.didResolveNull();
} else {
readerShadow.didResolveScalar(value);
}
didResolve(field);
return value != null ? value.doubleValue() : null;
}
@Override public Boolean readBoolean(ResponseField field) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
Boolean value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
if (value == null) {
readerShadow.didResolveNull();
} else {
readerShadow.didResolveScalar(value);
}
didResolve(field);
return value;
}
@SuppressWarnings("unchecked") @Override
public T readObject(ResponseField field, ObjectReader objectReader) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
R value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
readerShadow.willResolveObject(field, Optional.fromNullable(value));
final T parsedValue;
if (value == null) {
readerShadow.didResolveNull();
parsedValue = null;
} else {
parsedValue = (T) objectReader.read(new RealResponseReader(operationVariables, value, fieldValueResolver,
scalarTypeAdapters, readerShadow));
}
readerShadow.didResolveObject(field, Optional.fromNullable(value));
didResolve(field);
return parsedValue;
}
@SuppressWarnings("unchecked")
@Override public List readList(ResponseField field, ListReader listReader) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
List values = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, values);
final List result;
if (values == null) {
readerShadow.didResolveNull();
result = null;
} else {
result = new ArrayList<>();
for (int i = 0; i < values.size(); i++) {
readerShadow.willResolveElement(i);
Object value = values.get(i);
if (value == null) {
result.add(null);
readerShadow.didResolveNull();
}
else {
T item = (T) listReader.read(new ListItemReader(field, value));
result.add(item);
}
readerShadow.didResolveElement(i);
}
readerShadow.didResolveList(values);
}
didResolve(field);
return result != null ? Collections.unmodifiableList(result) : null;
}
@SuppressWarnings("unchecked") @Override public T readCustomType(ResponseField.CustomTypeField field) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
Object value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
final T result;
if (value == null) {
readerShadow.didResolveNull();
result = null;
} else {
CustomTypeAdapter typeAdapter = scalarTypeAdapters.adapterFor(field.scalarType());
readerShadow.didResolveScalar(value);
result = typeAdapter.decode(value.toString());
}
didResolve(field);
return result;
}
@Override
public T readConditional(ResponseField field, ConditionalTypeReader conditionalTypeReader) {
if (shouldSkip(field)) {
return null;
}
willResolve(field);
String value = fieldValueResolver.valueFor(recordSet, field);
checkValue(field, value);
if (value == null) {
readerShadow.didResolveNull();
didResolve(field);
return null;
} else {
readerShadow.didResolveScalar(value);
didResolve(field);
if (field.type() == ResponseField.Type.INLINE_FRAGMENT) {
for (ResponseField.Condition condition : field.conditions()) {
if (condition instanceof ResponseField.TypeNameCondition) {
if (((ResponseField.TypeNameCondition) condition).typeName().equals(value)) {
return (T) conditionalTypeReader.read(value, this);
}
}
}
return null;
} else {
return (T) conditionalTypeReader.read(value, this);
}
}
}
private boolean shouldSkip(ResponseField field) {
for (ResponseField.Condition condition : field.conditions()) {
if (condition instanceof ResponseField.BooleanCondition) {
ResponseField.BooleanCondition booleanCondition = (ResponseField.BooleanCondition) condition;
Boolean conditionValue = (Boolean) variableValues.get(booleanCondition.variableName());
if (booleanCondition.inverted()) {
// means it's a skip directive
if (conditionValue == Boolean.TRUE) {
return true;
}
} else {
// means it's an include directive
if (conditionValue == Boolean.FALSE) {
return true;
}
}
}
}
return false;
}
private void willResolve(ResponseField field) {
readerShadow.willResolve(field, operationVariables);
}
private void didResolve(ResponseField field) {
readerShadow.didResolve(field, operationVariables);
}
private void checkValue(ResponseField field, Object value) {
if (!field.optional() && value == null) {
throw new NullPointerException("corrupted response reader, expected non null value for " + field.fieldName());
}
}
private class ListItemReader implements ResponseReader.ListItemReader {
private final ResponseField field;
private final Object value;
ListItemReader(ResponseField field, Object value) {
this.field = field;
this.value = value;
}
@Override public String readString() {
readerShadow.didResolveScalar(value);
return (String) value;
}
@Override public Integer readInt() {
readerShadow.didResolveScalar(value);
return ((BigDecimal) value).intValue();
}
@Override public Long readLong() {
readerShadow.didResolveScalar(value);
return ((BigDecimal) value).longValue();
}
@Override public Double readDouble() {
readerShadow.didResolveScalar(value);
return ((BigDecimal) value).doubleValue();
}
@Override public Boolean readBoolean() {
readerShadow.didResolveScalar(value);
return (Boolean) value;
}
@SuppressWarnings("unchecked")
@Override public T readCustomType(ScalarType scalarType) {
CustomTypeAdapter typeAdapter = scalarTypeAdapters.adapterFor(scalarType);
readerShadow.didResolveScalar(value);
return typeAdapter.decode(value.toString());
}
@SuppressWarnings("unchecked")
@Override public T readObject(ObjectReader objectReader) {
R value = (R) this.value;
readerShadow.willResolveObject(field, Optional.fromNullable(value));
T item = (T) objectReader.read(new RealResponseReader(operationVariables, value, fieldValueResolver,
scalarTypeAdapters, readerShadow));
readerShadow.didResolveObject(field, Optional.fromNullable(value));
return item;
}
@Override public List readList(ListReader listReader) {
List values = (List) value;
if (values == null) {
return null;
}
List result = new ArrayList<>();
for (int i = 0; i < values.size(); i++) {
readerShadow.willResolveElement(i);
Object value = values.get(i);
if (value == null) {
result.add(null);
readerShadow.didResolveNull();
}
else {
T item = (T) listReader.read(new ListItemReader(field, value));
result.add(item);
}
readerShadow.didResolveElement(i);
}
readerShadow.didResolveList(values);
return Collections.unmodifiableList(result);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy