Search in sources :

Example 1 with Path

use of core.framework.api.web.service.Path in project core-ng-project by neowu.

the class WebServiceClientBuilder method buildMethod.

private String buildMethod(Method method) {
    CodeBuilder builder = new CodeBuilder();
    Type returnType = method.getGenericReturnType();
    Map<String, Integer> pathParamIndexes = Maps.newHashMap();
    Type requestBeanType = null;
    Integer requestBeanIndex = null;
    builder.append("public {} {}(", type(returnType), method.getName());
    Annotation[][] annotations = method.getParameterAnnotations();
    Class<?>[] parameterTypes = method.getParameterTypes();
    for (int i = 0; i < parameterTypes.length; i++) {
        Class<?> paramClass = parameterTypes[i];
        if (i > 0)
            builder.append(", ");
        builder.append("{} param{}", type(paramClass), i);
        PathParam pathParam = Params.annotation(annotations[i], PathParam.class);
        if (pathParam != null) {
            pathParamIndexes.put(pathParam.value(), i);
        } else {
            requestBeanIndex = i;
            requestBeanType = method.getGenericParameterTypes()[i];
        }
    }
    builder.append(") {\n");
    builder.indent(1).append("java.lang.reflect.Type requestType = {};\n", requestBeanType == null ? "null" : variable(requestBeanType));
    builder.indent(1).append("Object requestBean = {};\n", requestBeanIndex == null ? "null" : "param" + requestBeanIndex);
    builder.indent(1).append("java.util.Map pathParams = new java.util.HashMap();\n");
    pathParamIndexes.forEach((name, index) -> builder.indent(1).append("pathParams.put({}, param{});\n", variable(name), index));
    String returnTypeLiteral = returnType == void.class ? type(Void.class) : type(returnType);
    String path = method.getDeclaredAnnotation(Path.class).value();
    // to pass path as string literal, the escaped char will not be transferred, like \\, currently not convert is because only type regex may contain special char
    builder.indent(1).append("String serviceURL = client.serviceURL({}, pathParams);\n", variable(path));
    HTTPMethod httpMethod = HTTPMethods.httpMethod(method);
    builder.indent(1).append("{} response = ({}) client.execute({}, serviceURL, requestType, requestBean, {});\n", returnTypeLiteral, returnTypeLiteral, variable(httpMethod), variable(returnType));
    if (returnType != void.class)
        builder.indent(1).append("return response;\n");
    builder.append("}");
    return builder.build();
}
Also used : Path(core.framework.api.web.service.Path) CodeBuilder(core.framework.impl.asm.CodeBuilder) Type(java.lang.reflect.Type) HTTPMethod(core.framework.http.HTTPMethod) PathParam(core.framework.api.web.service.PathParam)

Example 2 with Path

use of core.framework.api.web.service.Path in project core-ng-project by neowu.

the class APIConfig method service.

public <T> void service(Class<T> serviceInterface, T service) {
    logger.info("create api service, interface={}", serviceInterface.getCanonicalName());
    new WebServiceInterfaceValidator(serviceInterface, context.httpServer.handler.requestBeanMapper, context.httpServer.handler.responseBeanTypeValidator).validate();
    new WebServiceImplValidator<>(serviceInterface, service).validate();
    for (Method method : serviceInterface.getMethods()) {
        HTTPMethod httpMethod = HTTPMethods.httpMethod(method);
        String path = method.getDeclaredAnnotation(Path.class).value();
        Controller controller = new WebServiceControllerBuilder<>(serviceInterface, service, method).build();
        try {
            Class<?>[] parameterTypes = method.getParameterTypes();
            Class<?> serviceClass = service.getClass();
            Method targetMethod = serviceClass.getMethod(method.getName(), parameterTypes);
            String controllerInfo = serviceClass.getCanonicalName() + "." + targetMethod.getName();
            String action = "api:" + ASCII.toLowerCase(httpMethod.name()) + ":" + path;
            context.httpServer.handler.route.add(httpMethod, path, new ControllerHolder(controller, targetMethod, controllerInfo, action, false));
        } catch (NoSuchMethodException e) {
            throw new Error("failed to find impl method", e);
        }
    }
    apiController().serviceInterfaces.add(serviceInterface);
}
Also used : Path(core.framework.api.web.service.Path) HTTPMethod(core.framework.http.HTTPMethod) Method(java.lang.reflect.Method) Controller(core.framework.web.Controller) APIController(core.framework.impl.web.management.APIController) ControllerHolder(core.framework.impl.web.ControllerHolder) HTTPMethod(core.framework.http.HTTPMethod) WebServiceInterfaceValidator(core.framework.impl.web.service.WebServiceInterfaceValidator)

Example 3 with Path

use of core.framework.api.web.service.Path in project core-ng-project by neowu.

the class WebServiceInterfaceValidator method validate.

private void validate(Method method) {
    validateHTTPMethod(method);
    HTTPMethod httpMethod = HTTPMethods.httpMethod(method);
    Path path = method.getDeclaredAnnotation(Path.class);
    if (path == null)
        throw Exceptions.error("method must have @Path, method={}", method);
    new PathPatternValidator(path.value()).validate();
    validateResponseBeanType(method.getGenericReturnType());
    Set<String> pathVariables = pathVariables(path.value());
    Type requestBeanType = null;
    Annotation[][] annotations = method.getParameterAnnotations();
    Type[] paramTypes = method.getGenericParameterTypes();
    Set<String> pathParams = Sets.newHashSet();
    for (int i = 0; i < paramTypes.length; i++) {
        Type paramType = paramTypes[i];
        PathParam pathParam = Params.annotation(annotations[i], PathParam.class);
        if (pathParam != null) {
            validatePathParamType(paramType);
            pathParams.add(pathParam.value());
        } else {
            if (requestBeanType != null)
                throw Exceptions.error("service method must not have more than one bean param, previous={}, current={}", requestBeanType.getTypeName(), paramType.getTypeName());
            requestBeanType = paramType;
            if (httpMethod == HTTPMethod.GET || httpMethod == HTTPMethod.DELETE) {
                requestBeanMapper.registerQueryParamBean(requestBeanType);
            } else {
                requestBeanMapper.registerRequestBean(requestBeanType);
            }
        }
    }
    if (pathVariables.size() != pathParams.size() || !pathVariables.containsAll(pathParams))
        throw Exceptions.error("service method @PathParam params must match variable in path pattern, path={}, method={}", path.value(), method);
}
Also used : Path(core.framework.api.web.service.Path) Type(java.lang.reflect.Type) HTTPMethod(core.framework.http.HTTPMethod) PathPatternValidator(core.framework.impl.web.route.PathPatternValidator) PathParam(core.framework.api.web.service.PathParam)

Aggregations

Path (core.framework.api.web.service.Path)3 HTTPMethod (core.framework.http.HTTPMethod)3 PathParam (core.framework.api.web.service.PathParam)2 Type (java.lang.reflect.Type)2 CodeBuilder (core.framework.impl.asm.CodeBuilder)1 ControllerHolder (core.framework.impl.web.ControllerHolder)1 APIController (core.framework.impl.web.management.APIController)1 PathPatternValidator (core.framework.impl.web.route.PathPatternValidator)1 WebServiceInterfaceValidator (core.framework.impl.web.service.WebServiceInterfaceValidator)1 Controller (core.framework.web.Controller)1 Method (java.lang.reflect.Method)1