use of com.graphql_java_generator.exception.GraphQLRequestPreparationException in project graphql-maven-plugin-project by graphql-java-generator.
the class AbstractGraphQLRequest method readRequestParameters.
/**
* Reads the parameters of the request. These parameters are actually GraphQL variables, according to the GraphQL
* spec.
*
* @param qt
* The {@link QueryTokenizer} current token is the '(' that starts the parameter list. When the method
* returns, the {@link QueryTokenizer} current token is the ')'
* @param inputParameters
* The empty list if {@link InputParameter}s.
* @throws GraphQLRequestPreparationException
*/
private void readRequestParameters(QueryTokenizer qt, List<InputParameter> inputParameters, String schema) throws GraphQLRequestPreparationException {
String token;
// We're reading the request parameters. It should be something like "($param1: Type1, $param2: Type2!)"
Step step = Step.NAME;
String name = null;
while (true) {
token = qt.nextToken();
// Are we done?
if (token.equals(")")) {
if (step.equals(Step.TYPE)) {
throw new GraphQLRequestPreparationException("Found a ')', while expecting a value for the '" + name + "' query parameter");
} else {
// Ok we're done
break;
}
} else if (token.equals(",")) {
// We should be waiting for the name of the GraphQL variable
if (!step.equals(Step.NAME)) {
throw new GraphQLRequestPreparationException("unexpected ','");
}
// Let's go to the next token, that should be the GraphQL type
token = qt.nextToken();
} else if (token.equals(":")) {
// We should be waiting for the type of the GraphQL variable
if (!step.equals(Step.TYPE)) {
throw new GraphQLRequestPreparationException("unexpected ':'");
}
// Let's go to the next token, that should be the GraphQL type
token = qt.nextToken();
}
switch(step) {
case NAME:
if (!token.startsWith("$")) {
throw new GraphQLRequestPreparationException("The GraphQL variable names should start by a '$', but this one doesn't: '" + token + "'");
}
// We store the name, without the leading '$'
name = token.substring(1);
// The next token should be the value
step = Step.TYPE;
break;
case TYPE:
// The current token is the GraphQL variable type, for instance "[[Human!]]!". Let's parse it.
int currentDepth = 0;
String graphQLTypeName = null;
boolean mandatory = false;
int listDepth = 0;
boolean itemMandatory = false;
while (true) {
switch(token) {
case "[":
listDepth += 1;
currentDepth += 1;
break;
case "]":
currentDepth -= 1;
break;
case "!":
// If we're here, it means the depth is at least one.
itemMandatory = true;
break;
case ",":
case // Too bad, the query is wrongly written
")":
throw new GraphQLRequestPreparationException("Syntax error in the query, while reading the type of the '" + name + "' parameter of the request");
default:
// We have the GraphQL type name
graphQLTypeName = token;
}
// Are we done?
if (currentDepth == 0) {
break;
}
token = qt.nextToken();
}
;
// Let's check if there is a trailing '!'
if (qt.checkNextToken("!")) {
mandatory = true;
// Then we pass this token
token = qt.nextToken();
} else {
mandatory = false;
}
inputParameters.add(InputParameter.newGraphQLVariableParameter(schema, name, graphQLTypeName, mandatory, listDepth, itemMandatory));
// The next token should be either the end of parameters (with a ')') or a name
step = Step.NAME;
break;
}
// switch
}
// while
}
use of com.graphql_java_generator.exception.GraphQLRequestPreparationException in project graphql-maven-plugin-project by graphql-java-generator.
the class Builder method withQueryResponseDef.
/**
* Builds a {@link ObjectResponse} from a part of a GraphQL query. This part define what's expected as a response
* for the field of the current {@link ObjectResponse} for this builder.
*
* @param queryResponseDef
* A part of a response, for instance (for the hero query of the Star Wars GraphQL schema): "{ id name
* friends{name}}"<BR/>
* No special character are allowed (linefeed...).<BR/>
* This parameter can be a null or an empty string. In this case, all scalar fields are added.
* @param episode
* @return
* @throws GraphQLRequestPreparationException
*/
public Builder withQueryResponseDef(String queryResponseDef) throws GraphQLRequestPreparationException {
if (queryResponseDef == null) {
queryResponseDef = "";
}
String genericErrorMessage = null;
try {
// Is it a full request ?
if (fullRequest) {
genericErrorMessage = "Could not create an instance of GraphQLRequest (for a Full request)";
objectResponse = (ObjectResponse) graphQLRequestClass.getConstructor(String.class).newInstance(queryResponseDef);
} else {
// No, it's a Partial request
genericErrorMessage = "Could not create an instance of GraphQLRequest (for a Partial request)";
Constructor<? extends AbstractGraphQLRequest> constructor = graphQLRequestClass.getConstructor(String.class, RequestType.class, String.class, InputParameter[].class);
objectResponse = (ObjectResponse) constructor.newInstance(queryResponseDef, requestType, fieldName, inputParams);
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException e) {
throw new GraphQLRequestPreparationException(genericErrorMessage + ": " + e.getMessage(), e);
} catch (InvocationTargetException e) {
if (e.getTargetException() == null) {
throw new GraphQLRequestPreparationException(genericErrorMessage, e);
} else if (e.getTargetException() instanceof GraphQLRequestPreparationException) {
throw (GraphQLRequestPreparationException) e.getTargetException();
} else if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
} else {
throw new GraphQLRequestPreparationException(genericErrorMessage, e);
}
}
return this;
}
use of com.graphql_java_generator.exception.GraphQLRequestPreparationException in project graphql-maven-plugin-project by graphql-java-generator.
the class GraphQLRepositoryInvocationHandler method registerMethod.
/**
* Register the given method with the given parameters
*
* @param registeredMethod
* The class where all the registering info should be stored
* @param method
* The method that is being registered
* @param fullRequest
* True if this method is marked with the {@link FullRequest} annotation, false otherwise, that is: the
* method is marked with the {@link PartialRequest} annotation
* @param requestName
* The name of the request, as read in the {@link PartialRequest} annotation, null for full requests
* @param requestType
* The type of request. Query is the default.
* @param request
* The string of the request. For {@link FullRequest}, it must be a valid GraphQL request. For more
* information, have a look at the <A HREF=
* "https://github.com/graphql-java-generator/graphql-maven-plugin-project/wiki/client_exec_graphql_requests">Client
* wiki</A>
* @throws GraphQLRequestPreparationException
*/
private void registerMethod(RegisteredMethod registeredMethod, Method method, boolean fullRequest, String requestName, RequestType requestType, String request) throws GraphQLRequestPreparationException {
registeredMethod.method = method;
registeredMethod.fullRequest = fullRequest;
registeredMethod.requestName = requestName;
registeredMethod.requestType = requestType;
registeredMethod.executor = getExecutor(method, requestType);
registerParameters(registeredMethod, method);
if (fullRequest) {
// It's a full request
registeredMethod.executorMethodName = "execWithBindValues";
registeredMethod.executorGetGraphQLRequestMethodName = "getGraphQLRequest";
} else if (registeredMethod.requestName == null || registeredMethod.requestName.equals("")) {
// It's a partial request, with no given requestName
registeredMethod.executorMethodName = method.getName() + "WithBindValues";
registeredMethod.executorGetGraphQLRequestMethodName = "get" + graphqlUtils.getPascalCase(method.getName()) + "GraphQLRequest";
} else {
// It's a partial request, with a given requestName
registeredMethod.executorMethodName = registeredMethod.requestName + "WithBindValues";
registeredMethod.executorGetGraphQLRequestMethodName = "get" + graphqlUtils.getPascalCase(registeredMethod.requestName) + "GraphQLRequest";
}
try {
registeredMethod.executorMethod = registeredMethod.executor.getClass().getMethod(registeredMethod.executorMethodName, registeredMethod.executorParameterTypes);
} catch (NoSuchMethodException | SecurityException e) {
StringBuffer parameters = new StringBuffer();
String separator = "";
for (Class<?> clazz : registeredMethod.executorParameterTypes) {
parameters.append(separator);
parameters.append(clazz.getName());
separator = ",";
}
throw new GraphQLRequestPreparationException("Error while preparing the GraphQL Repository, on the method '" + method.getDeclaringClass().getName() + "." + method.getName() + "(..). Couldn't find the matching executor method '" + registeredMethod.executorMethodName + "' for executor class '" + registeredMethod.executor.getClass().getName() + "' with these parameters: [" + parameters + "]. Consider marking bind parameters and GraphQL variables with the @BindParameter annotation.", e);
}
// method
if (!method.getReturnType().isAssignableFrom(registeredMethod.executorMethod.getReturnType())) {
throw new GraphQLRequestPreparationException("Error while preparing the GraphQL Repository, on the method '" + method.getDeclaringClass().getName() + "." + method.getName() + "(..). This method should return " + registeredMethod.executorMethod.getReturnType().getName() + " but returns " + method.getReturnType().getName() + " (and the later can not be assigned to the former)");
}
registeredMethod.request = request;
registeredMethod.graphQLRequest = getGraphQLRequest(registeredMethod);
}
use of com.graphql_java_generator.exception.GraphQLRequestPreparationException in project graphql-maven-plugin-project by graphql-java-generator.
the class GraphQLRepositoryInvocationHandler method registerMethod.
/**
* Register the given method of the repository interface, and returns its characteristics
*
* @throws GraphQLRequestPreparationException
*/
private RegisteredMethod registerMethod(Method method) throws GraphQLRequestPreparationException {
RegisteredMethod registeredMethod = new RegisteredMethod();
// Some checks, to begin with:
if (!Arrays.asList(method.getExceptionTypes()).contains(GraphQLRequestExecutionException.class)) {
throw new GraphQLRequestPreparationException("Error while preparing the GraphQL Repository, on the method '" + method.getDeclaringClass().getName() + "." + method.getName() + "(..). Every method of GraphQL repositories must throw the 'com.graphql_java_generator.exception.GraphQLRequestExecutionException' exception, but the '" + method.getName() + "' doesn't");
}
PartialRequest partialRequest = method.getAnnotation(PartialRequest.class);
FullRequest fullRequest = method.getAnnotation(FullRequest.class);
if (partialRequest != null) {
registerMethod(registeredMethod, method, false, partialRequest.requestName(), partialRequest.requestType(), partialRequest.request());
} else if (fullRequest != null) {
registerMethod(registeredMethod, method, true, null, fullRequest.requestType(), fullRequest.request());
} else {
throw new GraphQLRequestPreparationException("Error while preparing the GraphQL Repository, on the method '" + method.getDeclaringClass().getName() + "." + method.getName() + "(..). Every method of GraphQL repositories must be annotated by either @PartialRequest or @FullRequest. But the '" + method.getName() + "()' isn't.");
}
return registeredMethod;
}
use of com.graphql_java_generator.exception.GraphQLRequestPreparationException in project graphql-maven-plugin-project by graphql-java-generator.
the class GraphQLRepositoryInvocationHandler method createProxyInstance.
/**
* Do some checks on the instance attribute, then create the dynamic proxy
*
* @return
* @throws GraphQLRequestPreparationException
* Thrown if the given parameter for the constructor where not correct.
*/
private T createProxyInstance() throws GraphQLRequestPreparationException {
if (repositoryInterface == null) {
throw new NullPointerException("'repositoryInterface' may not be null");
}
if (!repositoryInterface.isInterface()) {
throw new RuntimeException("The 'repositoryInterface' (" + repositoryInterface.getName() + ") must be an interface, but it is not");
}
if (repositoryInterface.getAnnotation(GraphQLRepository.class) == null) {
throw new GraphQLRequestPreparationException("This InvocationHandler may only be called for GraphQL repositories. " + "GraphQL repositories must be annotated with the 'com.graphql_java_generator.annotation.GraphQLRepository' annotation. " + "But the '" + repositoryInterface.getName() + "' is not.");
}
// All basic tests are Ok. Let's go
// //////////////////////////////////////////////////////////////////////////////////////////////////////
// CREATION IF THE PROXY INSTANCE
@SuppressWarnings("unchecked") Class<T>[] classes = (Class<T>[]) new Class<?>[] { repositoryInterface };
@SuppressWarnings("unchecked") T t = (T) Proxy.newProxyInstance(repositoryInterface.getClassLoader(), classes, this);
for (Method method : repositoryInterface.getDeclaredMethods()) {
registeredMethods.put(method, registerMethod(method));
}
return t;
}
Aggregations