spring-graphql AbstractGraphQlResponse 源码
spring-graphql AbstractGraphQlResponse 代码
文件路径:/spring-graphql/src/main/java/org/springframework/graphql/support/AbstractGraphQlResponse.java
/*
* Copyright 2002-2022 the original author or authors.
*
* 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
*
* https://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.springframework.graphql.support;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.graphql.GraphQlResponse;
import org.springframework.graphql.ResponseError;
import org.springframework.graphql.ResponseField;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Base class for {@link GraphQlResponse} that pre-implements the ability to
* access a {@link ResponseField}.
*
* @author Rossen Stoyanchev
* @since 1.0.0
*/
public abstract class AbstractGraphQlResponse implements GraphQlResponse {
@Override
public ResponseField field(String path) {
return new DefaultResponseField(this, path);
}
/**
* Default implementation of {@link ResponseField}.
*/
private static class DefaultResponseField implements ResponseField {
private final GraphQlResponse response;
private final String path;
private final List<Object> parsedPath;
@Nullable
private final Object value;
private final List<ResponseError> fieldErrors;
DefaultResponseField(GraphQlResponse response, String path) {
this.response = response;
this.path = path;
this.parsedPath = parsePath(path);
this.value = initFieldValue(this.parsedPath, response);
this.fieldErrors = initFieldErrors(path, response);
}
private static List<Object> parsePath(String path) {
if (!StringUtils.hasText(path)) {
return Collections.emptyList();
}
String invalidPathMessage = "Invalid path: '" + path + "'";
List<Object> dataPath = new ArrayList<>();
StringBuilder sb = new StringBuilder();
boolean readingIndex = false;
for (int i = 0; i < path.length(); i++) {
char c = path.charAt(i);
switch (c) {
case '.':
case '[':
Assert.isTrue(!readingIndex, invalidPathMessage);
break;
case ']':
i++;
Assert.isTrue(readingIndex, invalidPathMessage);
Assert.isTrue(i == path.length() || path.charAt(i) == '.', invalidPathMessage);
break;
default:
sb.append(c);
if (i < path.length() - 1) {
continue;
}
}
String token = sb.toString();
Assert.hasText(token, invalidPathMessage);
dataPath.add(readingIndex ? Integer.parseInt(token) : token);
sb.delete(0, sb.length());
readingIndex = (c == '[');
}
return dataPath;
}
@Nullable
private static Object initFieldValue(List<Object> path, GraphQlResponse response) {
Object value = (response.isValid() ? response.getData() : null);
for (Object segment : path) {
if (value == null) {
return null;
}
if (segment instanceof String) {
Assert.isTrue(value instanceof Map, () -> "Invalid path " + path + ", data: " + response.getData());
value = ((Map<?, ?>) value).getOrDefault(segment, null);
}
else {
Assert.isTrue(value instanceof List, () -> "Invalid path " + path + ", data: " + response.getData());
int index = (int) segment;
value = (index < ((List<?>) value).size() ? ((List<?>) value).get(index) : null);
}
}
return value;
}
/**
* Return field errors whose path starts with the given field path.
* @param path the field path to match
* @return errors whose path starts with the dataPath
*/
private static List<ResponseError> initFieldErrors(String path, GraphQlResponse response) {
if (path.isEmpty() || response.getErrors().isEmpty()) {
return Collections.emptyList();
}
return response.getErrors().stream()
.filter(error -> {
String errorPath = error.getPath();
return !errorPath.isEmpty() && (errorPath.startsWith(path) || path.startsWith(errorPath));
})
.collect(Collectors.toList());
}
@Override
public String getPath() {
return this.path;
}
@Override
public List<Object> getParsedPath() {
return this.parsedPath;
}
@Override
public boolean hasValue() {
return (this.value != null);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getValue() {
return (T) this.value;
}
@Override
public ResponseError getError() {
if (!hasValue()) {
if (!this.fieldErrors.isEmpty()) {
return this.fieldErrors.get(0);
}
if (!this.response.getErrors().isEmpty()) {
return this.response.getErrors().get(0);
}
// No errors, set to null by DataFetcher
}
return null;
}
@Override
public List<ResponseError> getErrors() {
return this.fieldErrors;
}
}
}
相关信息
相关文章
spring-graphql CachingDocumentSource 源码
spring-graphql DefaultExecutionGraphQlRequest 源码
spring-graphql DefaultExecutionGraphQlResponse 源码
spring-graphql DefaultGraphQlRequest 源码
spring-graphql DocumentSource 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦