use of graphql.schema.GraphQLType in project graphql-java by graphql-java.
the class NoUnbrokenInputCycles method check.
private void check(GraphQLInputObjectType type, Set<GraphQLType> seen, List<String> path, SchemaValidationErrorCollector validationErrorCollector) {
if (seen.contains(type)) {
validationErrorCollector.addError(new SchemaValidationError(SchemaValidationErrorType.UnbrokenInputCycle, getErrorMessage(path)));
return;
}
seen.add(type);
for (GraphQLInputObjectField field : type.getFieldDefinitions()) {
if (field.getType() instanceof GraphQLNonNull) {
GraphQLType unwrapped = unwrapNonNull((GraphQLNonNull) field.getType());
if (unwrapped instanceof GraphQLInputObjectType) {
path = new ArrayList<>(path);
path.add(field.getName() + "!");
check((GraphQLInputObjectType) unwrapped, new HashSet<>(seen), path, validationErrorCollector);
}
}
}
}
use of graphql.schema.GraphQLType in project graphql-java by graphql-java.
the class ValuesResolver method coerceArgumentValues.
/**
* The http://facebook.github.io/graphql/#sec-Coercing-Variable-Values says :
*
* <pre>
* 1. Let coercedValues be an empty unordered Map.
* 2. Let variableDefinitions be the variables defined by operation.
* 3. For each variableDefinition in variableDefinitions:
* a. Let variableName be the name of variableDefinition.
* b. Let variableType be the expected type of variableDefinition.
* c. Let defaultValue be the default value for variableDefinition.
* d. Let value be the value provided in variableValues for the name variableName.
* e. If value does not exist (was not provided in variableValues):
* i. If defaultValue exists (including null):
* 1. Add an entry to coercedValues named variableName with the value defaultValue.
* ii. Otherwise if variableType is a Non‐Nullable type, throw a query error.
* iii. Otherwise, continue to the next variable definition.
* f. Otherwise, if value cannot be coerced according to the input coercion rules of variableType, throw a query error.
* g. Let coercedValue be the result of coercing value according to the input coercion rules of variableType.
* h. Add an entry to coercedValues named variableName with the value coercedValue.
* 4. Return coercedValues.
* </pre>
*
* @param schema the schema
* @param variableDefinitions the variable definitions
* @param variableValues the supplied variables
*
* @return coerced variable values as a map
*/
public Map<String, Object> coerceArgumentValues(GraphQLSchema schema, List<VariableDefinition> variableDefinitions, Map<String, Object> variableValues) {
GraphqlFieldVisibility fieldVisibility = schema.getFieldVisibility();
Map<String, Object> coercedValues = new LinkedHashMap<>();
for (VariableDefinition variableDefinition : variableDefinitions) {
String variableName = variableDefinition.getName();
GraphQLType variableType = TypeFromAST.getTypeFromAST(schema, variableDefinition.getType());
// 3.e
if (!variableValues.containsKey(variableName)) {
Value defaultValue = variableDefinition.getDefaultValue();
if (defaultValue != null) {
// 3.e.i
Object coercedValue = coerceValueAst(fieldVisibility, variableType, variableDefinition.getDefaultValue(), null);
coercedValues.put(variableName, coercedValue);
} else if (isNonNullType(variableType)) {
// 3.e.ii
throw new NonNullableValueCoercedAsNullException(variableDefinition, variableType);
}
} else {
Object value = variableValues.get(variableName);
// 3.f
Object coercedValue = getVariableValue(fieldVisibility, variableDefinition, variableType, value);
// 3.g
coercedValues.put(variableName, coercedValue);
}
}
return coercedValues;
}
use of graphql.schema.GraphQLType in project graphql-java by graphql-java.
the class BatchedExecutionStrategy method completeValues.
private List<ExecutionNode> completeValues(ExecutionContext executionContext, FetchedValues fetchedValues, ExecutionTypeInfo typeInfo, String fieldName, List<Field> fields, Map<String, Object> argumentValues) {
handleNonNullType(executionContext, fetchedValues);
GraphQLType unwrappedFieldType = typeInfo.getType();
if (isPrimitive(unwrappedFieldType)) {
handlePrimitives(fetchedValues, fieldName, unwrappedFieldType);
return Collections.emptyList();
} else if (isObject(unwrappedFieldType)) {
return handleObject(executionContext, argumentValues, fetchedValues, fieldName, fields, typeInfo);
} else if (isList(unwrappedFieldType)) {
return handleList(executionContext, argumentValues, fetchedValues, fieldName, fields, typeInfo);
} else {
return Assert.assertShouldNeverHappen("can't handle type: %s", unwrappedFieldType);
}
}
use of graphql.schema.GraphQLType in project structr by structr.
the class SchemaService method reloadSchema.
public static boolean reloadSchema(final ErrorBuffer errorBuffer, final String initiatedBySessionId) {
final ConfigurationProvider config = StructrApp.getConfiguration();
final App app = StructrApp.getInstance();
boolean success = true;
// compiling must only be done once
if (compiling.compareAndSet(false, true)) {
try {
final Map<String, Map<String, PropertyKey>> removedClasses = new HashMap<>(config.getTypeAndPropertyMapping());
final Map<String, GraphQLType> graphQLTypes = new LinkedHashMap<>();
final NodeExtender nodeExtender = new NodeExtender(initiatedBySessionId);
final Set<String> dynamicViews = new LinkedHashSet<>();
try (final Tx tx = app.tx()) {
// collect auto-generated schema nodes
SchemaService.ensureBuiltinTypesExist();
// add schema nodes from database
for (final SchemaNode schemaInfo : app.nodeQuery(SchemaNode.class).getAsList()) {
schemaInfo.handleMigration();
final String sourceCode = SchemaHelper.getSource(schemaInfo, errorBuffer);
if (sourceCode != null) {
final String className = schemaInfo.getClassName();
// only load dynamic node if there were no errors while generating
// the source code (missing modules etc.)
nodeExtender.addClass(className, sourceCode);
dynamicViews.addAll(schemaInfo.getDynamicViews());
// initialize GraphQL engine as well
schemaInfo.initializeGraphQL(graphQLTypes);
}
}
// collect relationship classes
for (final SchemaRelationshipNode schemaRelationship : app.nodeQuery(SchemaRelationshipNode.class).getAsList()) {
nodeExtender.addClass(schemaRelationship.getClassName(), schemaRelationship.getSource(errorBuffer));
dynamicViews.addAll(schemaRelationship.getDynamicViews());
// initialize GraphQL engine as well
schemaRelationship.initializeGraphQL(graphQLTypes);
}
// this is a very critical section :)
synchronized (SchemaService.class) {
// clear propagating relationship cache
SchemaRelationshipNode.clearPropagatingRelationshipTypes();
// compile all classes at once and register
final Map<String, Class> newTypes = nodeExtender.compile(errorBuffer);
for (final Class newType : newTypes.values()) {
// instantiate classes to execute static initializer of helpers
try {
// do full reload
config.registerEntityType(newType);
newType.newInstance();
} catch (Throwable ignore) {
}
}
// calculate difference between previous and new classes
removedClasses.keySet().removeAll(StructrApp.getConfiguration().getTypeAndPropertyMapping().keySet());
}
// create properties and views etc.
for (final SchemaNode schemaNode : app.nodeQuery(SchemaNode.class).getAsList()) {
schemaNode.createBuiltInSchemaEntities(errorBuffer);
}
success = !errorBuffer.hasError();
if (success) {
// prevent inheritance map from leaking
SearchCommand.clearInheritanceMap();
AccessPathCache.invalidate();
// clear relationship instance cache
AbstractNode.clearRelationshipTemplateInstanceCache();
// clear permission cache
AbstractNode.clearPermissionResolutionCache();
// inject views in configuration provider
config.registerDynamicViews(dynamicViews);
if (Services.calculateHierarchy() || !Services.isTesting()) {
calculateHierarchy();
}
if (Services.updateIndexConfiguration() || !Services.isTesting()) {
updateIndexConfiguration(removedClasses);
}
tx.success();
final GraphQLObjectType.Builder queryTypeBuilder = GraphQLObjectType.newObject();
// register types in "Query" type
for (final Entry<String, GraphQLType> entry : graphQLTypes.entrySet()) {
final String className = entry.getKey();
final GraphQLType type = entry.getValue();
// register type in query type
queryTypeBuilder.field(GraphQLFieldDefinition.newFieldDefinition().name(className).type(new GraphQLList(type)).argument(GraphQLArgument.newArgument().name("id").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("type").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("name").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("_page").type(Scalars.GraphQLInt).build()).argument(GraphQLArgument.newArgument().name("_pageSize").type(Scalars.GraphQLInt).build()).argument(GraphQLArgument.newArgument().name("_sort").type(Scalars.GraphQLString).build()).argument(GraphQLArgument.newArgument().name("_desc").type(Scalars.GraphQLBoolean).build()));
}
// exchange graphQL schema after successful build
synchronized (SchemaService.class) {
graphQLSchema = GraphQLSchema.newSchema().query(queryTypeBuilder.name("Query").build()).build(new LinkedHashSet<>(graphQLTypes.values()));
}
}
} catch (FrameworkException fex) {
logger.error("Unable to compile dynamic schema: {}", fex.getMessage());
success = false;
errorBuffer.getErrorTokens().addAll(fex.getErrorBuffer().getErrorTokens());
} catch (Throwable t) {
t.printStackTrace();
logger.error("Unable to compile dynamic schema: {}", t.getMessage());
success = false;
}
if (!success) {
if (Settings.SchemAutoMigration.getValue()) {
// handle migration in separate transaction
try (final Tx tx = app.tx()) {
// try to handle certain errors automatically
handleAutomaticMigration(errorBuffer);
tx.success();
} catch (FrameworkException fex) {
}
} else {
logger.error("Unable to compile dynamic schema, and automatic migration is not enabled. Please set application.schema.automigration = true in structr.conf to enable modification of existing schema classes.");
}
}
} finally {
// compiling done
compiling.set(false);
}
}
return success;
}
use of graphql.schema.GraphQLType in project graphql-java by graphql-java.
the class ExecutionStrategy method completeValue.
/**
* Called to complete a value for a field based on the type of the field.
* <p>
* If the field is a scalar type, then it will be coerced and returned. However if the field type is an complex object type, then
* the execution strategy will be called recursively again to execute the fields of that type before returning.
* <p>
* Graphql fragments mean that for any give logical field can have one or more {@link Field} values associated with it
* in the query, hence the fieldList. However the first entry is representative of the field for most purposes.
*
* @param executionContext contains the top level execution parameters
* @param parameters contains the parameters holding the fields to be executed and source object
*
* @return an {@link ExecutionResult}
*
* @throws NonNullableFieldWasNullException if a non null field resolves to a null value
*/
protected CompletableFuture<ExecutionResult> completeValue(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException {
ExecutionTypeInfo typeInfo = parameters.getTypeInfo();
Object result = unboxPossibleOptional(parameters.getSource());
GraphQLType fieldType = typeInfo.getType();
if (result == null) {
return completeValueForNull(parameters);
} else if (fieldType instanceof GraphQLList) {
return completeValueForList(executionContext, parameters, result);
} else if (fieldType instanceof GraphQLScalarType) {
return completeValueForScalar(executionContext, parameters, (GraphQLScalarType) fieldType, result);
} else if (fieldType instanceof GraphQLEnumType) {
return completeValueForEnum(executionContext, parameters, (GraphQLEnumType) fieldType, result);
}
//
// when we are here, we have a complex type: Interface, Union or Object
// and we must go deeper
//
GraphQLObjectType resolvedObjectType = resolveType(executionContext, parameters, fieldType);
return completeValueForObject(executionContext, parameters, resolvedObjectType, result);
}
Aggregations