Skip to content

Commit

Permalink
Add possibility to use custom builder for RestMethodModel
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksandr Porunov <[email protected]>
  • Loading branch information
porunov committed Feb 3, 2022
1 parent 0188fd0 commit 4255bd4
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cz.habarta.typescript.generator;

import cz.habarta.typescript.generator.parser.MethodParameterModel;
import cz.habarta.typescript.generator.parser.RestMethodModel;
import cz.habarta.typescript.generator.parser.RestQueryParam;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;

public class DefaultRestMethodBuilder implements RestMethodBuilder{

@Override
public RestMethodModel build(Class<?> originClass, String name, Type returnType, Method originalMethod,
Class<?> rootResource, String httpMethod, String path,
List<MethodParameterModel> pathParams, List<RestQueryParam> queryParams,
MethodParameterModel entityParam, List<String> comments) {

return new RestMethodModel(originClass, name, returnType, originalMethod, rootResource, httpMethod, path,
pathParams, queryParams, entityParam, comments);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package cz.habarta.typescript.generator;

import cz.habarta.typescript.generator.parser.MethodParameterModel;
import cz.habarta.typescript.generator.parser.RestMethodModel;
import cz.habarta.typescript.generator.parser.RestQueryParam;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;

public interface RestMethodBuilder {

RestMethodModel build(Class<?> originClass, String name, Type returnType, Method originalMethod,
Class<?> rootResource, String httpMethod, String path, List<MethodParameterModel> pathParams, List<RestQueryParam> queryParams, MethodParameterModel entityParam,
List<String> comments);

}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public class Settings {
public boolean restOptionsTypeIsGeneric;
private List<RestApplicationParser.Factory> restApplicationParserFactories;
public TypeProcessor customTypeProcessor = null;
public RestMethodBuilder customRestMethodBuilder = null;
public boolean sortDeclarations = false;
public boolean sortTypeDeclarations = false;
public boolean noFileComment = false;
Expand Down Expand Up @@ -231,6 +232,12 @@ public void loadCustomTypeProcessor(ClassLoader classLoader, String customTypePr
}
}

public void loadCustomRestMethodBuilder(ClassLoader classLoader, String customRestMethodBuilder) {
if (customRestMethodBuilder != null) {
this.customRestMethodBuilder = loadInstance(classLoader, customRestMethodBuilder, RestMethodBuilder.class);
}
}

public void loadExtensions(ClassLoader classLoader, List<String> extensions, List<Settings.ConfiguredExtension> extensionsWithConfiguration) {
this.extensions = new ArrayList<>();
this.extensions.addAll(loadInstances(classLoader, extensions, EmitterExtension.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private void parseResourceMethod(Result result, ResourceContext context, Class<?
// comments
final List<String> comments = Swagger.getOperationComments(swaggerOperation);
// create method
model.getMethods().add(new RestMethodModel(resourceClass, method.getName(), resolvedModelReturnType, method,
model.getMethods().add(restMethodBuilder.build(resourceClass, method.getName(), resolvedModelReturnType, method,
context.rootResource, httpMethod.value(), context.path, pathParams, queryParams, entityParameter, comments));
}
// JAX-RS specification - 3.4.1 Sub Resources
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

package cz.habarta.typescript.generator.parser;

import cz.habarta.typescript.generator.DefaultRestMethodBuilder;
import cz.habarta.typescript.generator.RestMethodBuilder;
import cz.habarta.typescript.generator.Settings;
import cz.habarta.typescript.generator.TypeProcessor;
import cz.habarta.typescript.generator.util.Utils;
Expand All @@ -17,6 +19,7 @@ public abstract class RestApplicationParser {
protected final Predicate<String> isClassNameExcluded;
protected final TypeProcessor commonTypeProcessor;
protected final RestApplicationModel model;
protected final RestMethodBuilder restMethodBuilder;

public static abstract class Factory {

Expand All @@ -33,6 +36,9 @@ public RestApplicationParser(Settings settings, TypeProcessor commonTypeProcesso
this.isClassNameExcluded = settings.getExcludeFilter();
this.commonTypeProcessor = commonTypeProcessor;
this.model = model;
this.restMethodBuilder = settings.customRestMethodBuilder == null ?
new DefaultRestMethodBuilder() :
settings.customRestMethodBuilder;
}

public RestApplicationModel getModel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import cz.habarta.typescript.generator.compiler.ModelCompiler;
import cz.habarta.typescript.generator.parser.BeanModel;
import cz.habarta.typescript.generator.parser.JaxrsApplicationParser;
import cz.habarta.typescript.generator.parser.MethodParameterModel;
import cz.habarta.typescript.generator.parser.Model;
import cz.habarta.typescript.generator.parser.RestMethodModel;
import cz.habarta.typescript.generator.parser.RestQueryParam;
import cz.habarta.typescript.generator.parser.SourceType;
import cz.habarta.typescript.generator.type.JGenericArrayType;
import cz.habarta.typescript.generator.type.JTypeWithNullability;
Expand Down Expand Up @@ -40,6 +43,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
Expand Down Expand Up @@ -704,6 +708,18 @@ public void testGenericResources() {
Assertions.assertTrue(output.contains("interface AccountDto"));
}

@Test
public void testCustomREstMethodBuilder() {
final Settings settings = TestUtils.settings();
settings.generateJaxrsApplicationClient = true;
settings.outputFileType = TypeScriptFileType.implementationFile;
settings.customRestMethodBuilder = new CustomRestMethodBuilder();
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(AccountResource.class));
Assertions.assertTrue(!output.contains("get(testParam: ID): RestResponse<ENTITY>"));
Assertions.assertTrue(output.contains("get(testParam: string): RestResponse<AccountDto>"));
Assertions.assertTrue(output.contains("interface AccountDto"));
}

public static class AccountDto {
public Integer id;
public String name;
Expand All @@ -728,4 +744,16 @@ public static void main(String[] args) {
System.out.println("Jersey started.");
}

public class CustomRestMethodBuilder implements RestMethodBuilder{

@Override
public RestMethodModel build(Class<?> originClass, String name, Type returnType,
Method originalMethod, Class<?> rootResource, String httpMethod,
String path, List<MethodParameterModel> pathParams, List<RestQueryParam> queryParams,
MethodParameterModel entityParam, List<String> comments) {

return new RestMethodModel(originClass, name, returnType, originalMethod, rootResource, httpMethod, path,
Arrays.asList(new MethodParameterModel("testParam", String.class)), queryParams, entityParam, comments);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import cz.habarta.typescript.generator.OptionalProperties;
import cz.habarta.typescript.generator.OptionalPropertiesDeclaration;
import cz.habarta.typescript.generator.Output;
import cz.habarta.typescript.generator.RestMethodBuilder;
import cz.habarta.typescript.generator.RestNamespacing;
import cz.habarta.typescript.generator.Settings;
import cz.habarta.typescript.generator.StringQuotes;
Expand Down Expand Up @@ -625,6 +626,15 @@ public class GenerateMojo extends AbstractMojo {
@Parameter
private String customTypeProcessor;

/**
* Specifies custom class implementing {@link RestMethodBuilder}.
* This allows to customize how Rest methods are mapped to TypeScript.
* For example, it is possible to implement RestMethodBuilder to filter or add some query parameters or
* change the returned type, etc.
*/
@Parameter
private String customRestMethodBuilder;

/**
* If <code>true</code> TypeScript declarations (interfaces, properties) will be sorted alphabetically.
*/
Expand Down Expand Up @@ -949,6 +959,7 @@ private Settings createSettings(URLClassLoader classLoader) {
settings.restResponseType = restResponseType;
settings.setRestOptionsType(restOptionsType);
settings.loadCustomTypeProcessor(classLoader, customTypeProcessor);
settings.loadCustomRestMethodBuilder(classLoader, customRestMethodBuilder);
settings.sortDeclarations = sortDeclarations;
settings.sortTypeDeclarations = sortTypeDeclarations;
settings.noFileComment = noFileComment;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ private void parseControllerMethod(JaxrsApplicationParser.Result result, JaxrsAp
final Type modelReturnType = parseReturnType(controllerClass, method);
foundType(result, modelReturnType, controllerClass, method.getName());

model.getMethods().add(new RestMethodModel(controllerClass, method.getName(), modelReturnType, method,
model.getMethods().add(restMethodBuilder.build(controllerClass, method.getName(), modelReturnType, method,
controllerClass, httpMethod.name(), context.path, pathParams, queryParams, entityParameter, null));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@
package cz.habarta.typescript.generator.spring;

import cz.habarta.typescript.generator.Input;
import cz.habarta.typescript.generator.RestMethodBuilder;
import cz.habarta.typescript.generator.Settings;
import cz.habarta.typescript.generator.TestUtils;
import cz.habarta.typescript.generator.TypeScriptFileType;
import cz.habarta.typescript.generator.TypeScriptGenerator;
import cz.habarta.typescript.generator.parser.MethodParameterModel;
import cz.habarta.typescript.generator.parser.RestMethodModel;
import cz.habarta.typescript.generator.parser.RestQueryParam;
import cz.habarta.typescript.generator.util.Utils;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
Expand All @@ -35,7 +42,6 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


public class SpringTest {

@Test
Expand Down Expand Up @@ -169,6 +175,17 @@ public void testInheritance() {
Assertions.assertFalse(output.contains("uriEncoding`test/b`"));
}

@Test
public void testCustomRestMethodBuilder() {
final Settings settings = TestUtils.settings();
settings.outputFileType = TypeScriptFileType.implementationFile;
settings.generateSpringApplicationClient = true;
settings.customRestMethodBuilder = new CustomRestMethodBuilder();
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Controller3.class));
Assertions.assertTrue(output.contains("testName(data: Data1, queryParams: { testParam1: string; testParam2?: number; }): RestResponse<void>"));
Assertions.assertTrue(output.contains("interface Data1"));
}

@RestController
@RequestMapping("/owners/{ownerId}")
public static class Controller1 {
Expand Down Expand Up @@ -203,6 +220,23 @@ public String echo(
}
}

@RestController
public static class Controller8 {
@RequestMapping("/echo3")
public String echo(
@CustomRequestParam String message
) {
return message;
}
}

@RestController
public static class Controller9 {
@RequestMapping(path = "/data2", method = RequestMethod.PUT)
public void setEntity(@CustomRequestBody Data1 data) {
}
}

@Test
public void testQueryParametersWithModel() {
final Settings settings = TestUtils.settings();
Expand Down Expand Up @@ -488,4 +522,32 @@ public String shouldBeExcluded() {
}
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface CustomRequestParam {

}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface CustomRequestBody {

}

public class CustomRestMethodBuilder implements RestMethodBuilder{

@Override
public RestMethodModel build(Class<?> originClass, String name, Type returnType,
Method originalMethod, Class<?> rootResource, String httpMethod,
String path, List<MethodParameterModel> pathParams, List<RestQueryParam> queryParams,
MethodParameterModel entityParam, List<String> comments) {

RestQueryParam.Single queryParam1 = new RestQueryParam.Single(new MethodParameterModel("testParam1", String.class), true);
RestQueryParam.Single queryParam2 = new RestQueryParam.Single(new MethodParameterModel("testParam2", Integer.class), false);

return new RestMethodModel(originClass, "testName", returnType, originalMethod, rootResource, httpMethod, path,
pathParams, Arrays.asList(queryParam1, queryParam2), entityParam, comments);
}
}

}

0 comments on commit 4255bd4

Please sign in to comment.