Search in sources :

Example 1 with GraphQLRequestPreparationException

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
}
Also used : GraphQLRequestPreparationException(com.graphql_java_generator.exception.GraphQLRequestPreparationException)

Example 2 with GraphQLRequestPreparationException

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;
}
Also used : GraphQLRequestPreparationException(com.graphql_java_generator.exception.GraphQLRequestPreparationException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 3 with GraphQLRequestPreparationException

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);
}
Also used : GraphQLRequestPreparationException(com.graphql_java_generator.exception.GraphQLRequestPreparationException)

Example 4 with GraphQLRequestPreparationException

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;
}
Also used : GraphQLRequestPreparationException(com.graphql_java_generator.exception.GraphQLRequestPreparationException) GraphQLRequestExecutionException(com.graphql_java_generator.exception.GraphQLRequestExecutionException)

Example 5 with GraphQLRequestPreparationException

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;
}
Also used : GraphQLRequestPreparationException(com.graphql_java_generator.exception.GraphQLRequestPreparationException) Method(java.lang.reflect.Method)

Aggregations

GraphQLRequestPreparationException (com.graphql_java_generator.exception.GraphQLRequestPreparationException)41 Test (org.junit.jupiter.api.Test)28 QueryExecutorImpl_allGraphqlCases_Test (com.graphql_java_generator.client.QueryExecutorImpl_allGraphqlCases_Test)9 GraphQLRequest (com.graphql_java_generator.domain.client.starwars.GraphQLRequest)5 GraphQLRequestExecutionException (com.graphql_java_generator.exception.GraphQLRequestExecutionException)4 Field (java.lang.reflect.Field)4 Character (com.graphql_java_generator.domain.client.starwars.Character)3 ScalarTest (com.graphql_java_generator.domain.client.starwars.scalar.ScalarTest)3 Method (java.lang.reflect.Method)3 ArrayList (java.util.ArrayList)3 Execution (org.junit.jupiter.api.parallel.Execution)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 JsonSubTypes (com.fasterxml.jackson.annotation.JsonSubTypes)1 Type (com.fasterxml.jackson.annotation.JsonSubTypes.Type)1 JsonParseException (com.fasterxml.jackson.core.JsonParseException)1 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 InvalidFormatException (com.fasterxml.jackson.databind.exc.InvalidFormatException)1 UnrecognizedPropertyException (com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException)1 GraphQLInputParameters (com.graphql_java_generator.annotation.GraphQLInputParameters)1