package com.apollographql.apollo.internal.field;
import com.apollographql.apollo.api.Field;
import com.apollographql.apollo.api.Operation;
import com.apollographql.apollo.cache.CacheHeaders;
import com.apollographql.apollo.cache.normalized.CacheKey;
import com.apollographql.apollo.cache.normalized.CacheKeyResolver;
import com.apollographql.apollo.cache.normalized.CacheReference;
import com.apollographql.apollo.cache.normalized.Record;
import com.apollographql.apollo.internal.cache.normalized.ReadableStore;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public final class CacheFieldValueResolver implements FieldValueResolver<Record> {
private final ReadableStore readableCache;
private final Operation.Variables variables;
private final CacheKeyResolver cacheKeyResolver;
private final CacheHeaders cacheHeaders;
public CacheFieldValueResolver(ReadableStore readableCache, Operation.Variables variables,
CacheKeyResolver cacheKeyResolver, CacheHeaders cacheHeaders) {
this.readableCache = readableCache;
this.variables = variables;
this.cacheKeyResolver = cacheKeyResolver;
this.cacheHeaders = cacheHeaders;
}
@SuppressWarnings("unchecked") @Override public <T> T valueFor(Record record, Field field)
throws IOException {
if (field instanceof Field.ObjectField) {
return (T) valueFor(record, (Field.ObjectField) field);
} else if (field instanceof Field.ScalarListField) {
return fieldValue(record, field);
} else if (field instanceof Field.ObjectListField) {
return (T) valueFor(record, (Field.ObjectListField) field);
} else {
return fieldValue(record, field);
}
}
private Record valueFor(Record record, Field.ObjectField field) throws IOException {
CacheReference cacheReference;
CacheKey fieldCacheKey = cacheKeyResolver.fromFieldArguments(field, variables);
if (fieldCacheKey != CacheKey.NO_KEY) {
cacheReference = new CacheReference(fieldCacheKey.key());
} else {
cacheReference = fieldValue(record, field);
}
return cacheReference != null ? readableCache.read(cacheReference.key(), cacheHeaders) : null;
}
private List<Record> valueFor(Record record, Field.ObjectListField field) throws IOException {
List<CacheReference> values = fieldValue(record, field);
List<Record> result = new ArrayList<>();
for (CacheReference reference : values) {
result.add(readableCache.read(reference.key(), cacheHeaders));
}
return result;
}
@SuppressWarnings("unchecked") private <T> T fieldValue(Record record, Field field) throws IOException {
String fieldKey = field.cacheKey(variables);
if (!record.hasField(fieldKey)) {
throw new IOException("Missing value: " + field.fieldName());
}
return (T) record.field(fieldKey);
}
}