use of cz.habarta.typescript.generator.parser.MethodParameterModel in project typescript-generator by vojtechhabarta.
the class ModelCompiler method processRestMethod.
private TsMethodModel processRestMethod(TsModel tsModel, SymbolTable symbolTable, String pathPrefix, Symbol responseSymbol, RestMethodModel method, boolean createLongName, TsType optionsType, boolean implement) {
final String path = Utils.joinPath(pathPrefix, method.getPath());
final PathTemplate pathTemplate = PathTemplate.parse(path);
final List<String> comments = Utils.concat(method.getComments(), Arrays.asList("HTTP " + method.getHttpMethod() + " /" + path, "Java method: " + method.getOriginClass().getName() + "." + method.getName()));
final List<TsParameterModel> parameters = new ArrayList<>();
// path params
for (MethodParameterModel parameter : method.getPathParams()) {
parameters.add(processParameter(symbolTable, method, parameter));
}
// entity param
if (method.getEntityParam() != null) {
parameters.add(processParameter(symbolTable, method, method.getEntityParam()));
}
// query params
final List<RestQueryParam> queryParams = method.getQueryParams();
final TsParameterModel queryParameter;
if (queryParams != null && !queryParams.isEmpty()) {
final List<TsType> types = new ArrayList<>();
if (queryParams.stream().anyMatch(param -> param instanceof RestQueryParam.Map)) {
types.add(new TsType.IndexedArrayType(TsType.String, TsType.Any));
} else {
final List<TsProperty> currentSingles = new ArrayList<>();
final Runnable flushSingles = () -> {
if (!currentSingles.isEmpty()) {
types.add(new TsType.ObjectType(currentSingles));
currentSingles.clear();
}
};
for (RestQueryParam restQueryParam : queryParams) {
if (restQueryParam instanceof RestQueryParam.Single) {
final MethodParameterModel queryParam = ((RestQueryParam.Single) restQueryParam).getQueryParam();
final TsType type = typeFromJava(symbolTable, queryParam.getType(), method.getName(), method.getOriginClass());
currentSingles.add(new TsProperty(queryParam.getName(), restQueryParam.required ? type : new TsType.OptionalType(type)));
}
if (restQueryParam instanceof RestQueryParam.Bean) {
final BeanModel queryBean = ((RestQueryParam.Bean) restQueryParam).getBean();
flushSingles.run();
final Symbol queryParamsSymbol = symbolTable.getSymbol(queryBean.getOrigin(), "QueryParams");
if (tsModel.getBean(queryParamsSymbol) == null) {
tsModel.getBeans().add(new TsBeanModel(queryBean.getOrigin(), TsBeanCategory.Data, /*isClass*/
false, queryParamsSymbol, /*typeParameters*/
null, /*parent*/
null, /*extendsList*/
null, /*implementsList*/
null, processProperties(symbolTable, null, queryBean), /*constructor*/
null, /*methods*/
null, /*comments*/
null));
}
types.add(new TsType.ReferenceType(queryParamsSymbol));
}
}
flushSingles.run();
}
boolean allQueryParamsOptional = queryParams.stream().noneMatch(queryParam -> queryParam.required);
TsType.IntersectionType queryParamType = new TsType.IntersectionType(types);
queryParameter = new TsParameterModel("queryParams", allQueryParamsOptional ? new TsType.OptionalType(queryParamType) : queryParamType);
parameters.add(queryParameter);
} else {
queryParameter = null;
}
if (optionsType != null) {
final TsParameterModel optionsParameter = new TsParameterModel("options", new TsType.OptionalType(optionsType));
parameters.add(optionsParameter);
}
// return type
final TsType returnType = typeFromJava(symbolTable, method.getReturnType(), method.getName(), method.getOriginClass());
final TsType wrappedReturnType = new TsType.GenericReferenceType(responseSymbol, returnType);
// method name
final String nameSuffix;
if (createLongName) {
nameSuffix = "$" + method.getHttpMethod() + "$" + pathTemplate.format("", "", false).replaceAll("/", "_").replaceAll("\\W", "");
} else {
nameSuffix = "";
}
// implementation
final List<TsStatement> body;
if (implement) {
body = new ArrayList<>();
body.add(new TsReturnStatement(new TsCallExpression(new TsMemberExpression(new TsMemberExpression(new TsThisExpression(), "httpClient"), "request"), new TsObjectLiteral(new TsPropertyDefinition("method", new TsStringLiteral(method.getHttpMethod())), new TsPropertyDefinition("url", processPathTemplate(pathTemplate)), queryParameter != null ? new TsPropertyDefinition("queryParams", new TsIdentifierReference("queryParams")) : null, method.getEntityParam() != null ? new TsPropertyDefinition("data", new TsIdentifierReference(method.getEntityParam().getName())) : null, optionsType != null ? new TsPropertyDefinition("options", new TsIdentifierReference("options")) : null))));
} else {
body = null;
}
// method
final TsMethodModel tsMethodModel = new TsMethodModel(method.getName() + nameSuffix, TsModifierFlags.None, null, parameters, wrappedReturnType, body, comments);
return tsMethodModel;
}
use of cz.habarta.typescript.generator.parser.MethodParameterModel in project typescript-generator by vojtechhabarta.
the class SpringApplicationParser method parseControllerMethod.
// https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods
private void parseControllerMethod(JaxrsApplicationParser.Result result, JaxrsApplicationParser.ResourceContext context, Class<?> controllerClass, Method method) {
final RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
if (requestMapping != null) {
// swagger
final SwaggerOperation swaggerOperation = settings.ignoreSwaggerAnnotations ? new SwaggerOperation() : Swagger.parseSwaggerAnnotations(method);
if (swaggerOperation.possibleResponses != null) {
for (SwaggerResponse response : swaggerOperation.possibleResponses) {
if (response.responseType != null) {
foundType(result, response.responseType, controllerClass, method.getName());
}
}
}
if (swaggerOperation.hidden) {
return;
}
// subContext
context = context.subPath(requestMapping.path().length == 0 ? "" : requestMapping.path()[0]);
final Map<String, Type> pathParamTypes = new LinkedHashMap<>();
for (Parameter parameter : method.getParameters()) {
final PathVariable pathVariableAnnotation = AnnotationUtils.findAnnotation(parameter, PathVariable.class);
if (pathVariableAnnotation != null) {
String pathVariableName = pathVariableAnnotation.value();
// Can be empty if the URI template variable matches the method argument
if (pathVariableName.isEmpty()) {
pathVariableName = parameter.getName();
}
pathParamTypes.put(pathVariableName, parameter.getParameterizedType());
}
}
context = context.subPathParamTypes(pathParamTypes);
final RequestMethod httpMethod = requestMapping.method().length == 0 ? RequestMethod.GET : requestMapping.method()[0];
// path parameters
final PathTemplate pathTemplate = PathTemplate.parse(context.path);
final Map<String, Type> contextPathParamTypes = context.pathParamTypes;
final List<MethodParameterModel> pathParams = pathTemplate.getParts().stream().filter(PathTemplate.Parameter.class::isInstance).map(PathTemplate.Parameter.class::cast).map(parameter -> {
final Type type = contextPathParamTypes.get(parameter.getOriginalName());
final Type paramType = type != null ? type : String.class;
foundType(result, paramType, controllerClass, method.getName());
return new MethodParameterModel(parameter.getValidName(), paramType);
}).collect(Collectors.toList());
// query parameters
final List<RestQueryParam> queryParams = new ArrayList<>();
for (Parameter parameter : method.getParameters()) {
if (parameter.getType() == Pageable.class) {
queryParams.add(new RestQueryParam.Single(new MethodParameterModel("page", Long.class), false));
queryParams.add(new RestQueryParam.Single(new MethodParameterModel("size", Long.class), false));
queryParams.add(new RestQueryParam.Single(new MethodParameterModel("sort", String.class), false));
} else {
final RequestParam requestParamAnnotation = AnnotationUtils.findAnnotation(parameter, RequestParam.class);
if (requestParamAnnotation != null) {
if (parameter.getType() == MultiValueMap.class) {
queryParams.add(new RestQueryParam.Map(false));
} else {
final boolean isRequired = requestParamAnnotation.required() && requestParamAnnotation.defaultValue().equals(ValueConstants.DEFAULT_NONE);
queryParams.add(new RestQueryParam.Single(new MethodParameterModel(firstOf(requestParamAnnotation.value(), parameter.getName()), parameter.getParameterizedType()), isRequired));
foundType(result, parameter.getParameterizedType(), controllerClass, method.getName());
}
}
final ModelAttribute modelAttributeAnnotation = AnnotationUtils.findAnnotation(parameter, ModelAttribute.class);
if (modelAttributeAnnotation != null) {
try {
final BeanInfo beanInfo = Introspector.getBeanInfo(parameter.getType());
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
final Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null) {
queryParams.add(new RestQueryParam.Single(new MethodParameterModel(propertyDescriptor.getName(), propertyDescriptor.getPropertyType()), false));
foundType(result, propertyDescriptor.getPropertyType(), controllerClass, method.getName());
}
}
} catch (IntrospectionException e) {
TypeScriptGenerator.getLogger().warning(String.format("Cannot introspect '%s' class: " + e.getMessage(), parameter.getAnnotatedType()));
}
}
}
}
// entity parameter
final MethodParameterModel entityParameter = getEntityParameter(controllerClass, method);
if (entityParameter != null) {
foundType(result, entityParameter.getType(), controllerClass, method.getName());
}
final Type modelReturnType = parseReturnType(controllerClass, method);
foundType(result, modelReturnType, controllerClass, method.getName());
model.getMethods().add(new RestMethodModel(controllerClass, method.getName(), modelReturnType, method, controllerClass, httpMethod.name(), context.path, pathParams, queryParams, entityParameter, null));
}
}
use of cz.habarta.typescript.generator.parser.MethodParameterModel in project typescript-generator by vojtechhabarta.
the class SpringApplicationParser method getEntityParameter.
private MethodParameterModel getEntityParameter(Class<?> controller, Method method) {
final List<Type> parameterTypes = settings.getTypeParser().getMethodParameterTypes(method);
final List<Pair<Parameter, Type>> parameters = Utils.zip(Arrays.asList(method.getParameters()), parameterTypes);
for (Pair<Parameter, Type> pair : parameters) {
final RequestBody requestBodyAnnotation = AnnotationUtils.findAnnotation(pair.getValue1(), RequestBody.class);
if (requestBodyAnnotation != null) {
final Type resolvedType = GenericsResolver.resolveType(controller, pair.getValue2(), method.getDeclaringClass());
return new MethodParameterModel(pair.getValue1().getName(), resolvedType);
}
}
return null;
}
Aggregations