Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to use custom builder for RestMethodModel #788

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -101,6 +101,7 @@ public class GenerateTask extends DefaultTask {
public String restNamespacingAnnotation;
public String restResponseType;
public String restOptionsType;
public String customRestMethodBuilder;
public String customTypeProcessor;
public boolean sortDeclarations;
public boolean sortTypeDeclarations;
Expand Down Expand Up @@ -190,6 +191,7 @@ private Settings createSettings(URLClassLoader classLoader) {
settings.setRestNamespacingAnnotation(classLoader, restNamespacingAnnotation);
settings.restResponseType = restResponseType;
settings.setRestOptionsType(restOptionsType);
settings.loadCustomRestMethodBuilder(classLoader, customRestMethodBuilder);
settings.loadCustomTypeProcessor(classLoader, customTypeProcessor);
settings.sortDeclarations = sortDeclarations;
settings.sortTypeDeclarations = sortTypeDeclarations;
Expand Down
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 @@ -488,4 +505,20 @@ public String shouldBeExcluded() {
}
}

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);
}
}

}