Skip to content

Commit 2469d29

Browse files
committed
Negated a potential NPE that was caused be HTTP methods that had a
similar structure to accessor methods.
1 parent c533cb1 commit 2469d29

File tree

5 files changed

+110
-6
lines changed

5 files changed

+110
-6
lines changed

java2typescript-jackson/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
<artifactId>jackson-annotations</artifactId>
4444
<version>${jackson.core.version}</version>
4545
</dependency>
46+
<dependency>
47+
<groupId>javax.ws.rs</groupId>
48+
<artifactId>jsr311-api</artifactId>
49+
<version>1.1.1</version>
50+
</dependency>
4651
<dependency>
4752
<groupId>com.fasterxml.jackson.core</groupId>
4853
<artifactId>jackson-core</artifactId>

java2typescript-jackson/src/main/java/java2typescript/jackson/module/Configuration.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@
1313
import java2typescript.jackson.module.grammar.ArrayType;
1414
import java2typescript.jackson.module.grammar.base.AbstractType;
1515

16+
import javax.ws.rs.DELETE;
17+
import javax.ws.rs.GET;
18+
import javax.ws.rs.POST;
19+
import javax.ws.rs.PUT;
20+
1621
public class Configuration {
1722
private Map<String, AbstractType> customTypes = Collections.emptyMap();
1823
private List<String> ignoredMethodNames = new ArrayList<String>();
1924
private TSTypeNamingStrategy namingStrategy = new SimpleJacksonTSTypeNamingStrategy();
25+
private boolean jaxrsRun = false;
2026

2127
public Map<String, AbstractType> getCustomTypes() {
2228
return customTypes;
@@ -61,4 +67,22 @@ public TSTypeNamingStrategy getNamingStrategy() {
6167
public void setNamingStrategy(TSTypeNamingStrategy namingStrategy) {
6268
this.namingStrategy = namingStrategy;
6369
}
70+
71+
public boolean getJaxrsRun() {
72+
return jaxrsRun;
73+
}
74+
75+
public void setJaxrsRun(boolean bool) {
76+
jaxrsRun = bool;
77+
}
78+
79+
public boolean methodHasHTTPAnnotation(Method method) {
80+
if (method.getAnnotation(GET.class) != null ||
81+
method.getAnnotation(POST.class) != null ||
82+
method.getAnnotation(PUT.class) != null ||
83+
method.getAnnotation(DELETE.class) != null) {
84+
return true;
85+
}
86+
return false;
87+
}
6488
}

java2typescript-jackson/src/main/java/java2typescript/jackson/module/visitors/TSJsonObjectFormatVisitor.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
import java.beans.PropertyDescriptor;
2525
import java.beans.Transient;
2626
import java.lang.reflect.Method;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
import java.util.regex.Pattern;
30+
2731
import java2typescript.jackson.module.grammar.AnyType;
2832
import java2typescript.jackson.module.grammar.FunctionType;
2933
import java2typescript.jackson.module.grammar.ClassType;
@@ -35,7 +39,6 @@
3539
import com.fasterxml.jackson.databind.JavaType;
3640
import com.fasterxml.jackson.databind.JsonMappingException;
3741
import com.fasterxml.jackson.databind.JsonSerializer;
38-
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
3942
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
4043
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
4144
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;
@@ -51,6 +54,7 @@
5154
public class TSJsonObjectFormatVisitor extends ABaseTSJsonFormatVisitor<ClassType> implements JsonObjectFormatVisitor {
5255

5356
private Class clazz;
57+
private List<String> blackListField = new ArrayList<String>();
5458

5559
public TSJsonObjectFormatVisitor(ABaseTSJsonFormatVisitor<?> parentHolder, String className, Class clazz, Configuration conf) {
5660
super(parentHolder, conf);
@@ -59,7 +63,9 @@ public TSJsonObjectFormatVisitor(ABaseTSJsonFormatVisitor<?> parentHolder, Strin
5963
}
6064

6165
private void addField(String name, AbstractType fieldType) {
62-
type.getFields().put(name, fieldType);
66+
if (!blackListField.contains(name)) {
67+
type.getFields().put(name, fieldType);
68+
}
6369
}
6470

6571
private boolean isAccessorMethod(Method method, BeanInfo beanInfo) {
@@ -74,6 +80,24 @@ private boolean isAccessorMethod(Method method, BeanInfo beanInfo) {
7480
return false;
7581
}
7682

83+
private void blackListUnnecessaryFieldMethods(Method method) {
84+
Pattern getSearcher = Pattern.compile("^get.*");
85+
Pattern setSearcher = Pattern.compile("^set.*");
86+
87+
String methodName = method.getName();
88+
String ignoredField;
89+
90+
if (getSearcher.matcher(method.getName()).matches()) {
91+
ignoredField = methodName.replaceFirst("^get","");
92+
ignoredField = Introspector.decapitalize(ignoredField);
93+
blackListField.add(ignoredField);
94+
} else if (setSearcher.matcher(method.getName()).matches()) {
95+
ignoredField = methodName.replaceFirst("^set","");
96+
ignoredField = Introspector.decapitalize(ignoredField);
97+
blackListField.add(ignoredField);
98+
}
99+
}
100+
77101
void addPublicMethods() {
78102

79103
for (Method method : this.clazz.getDeclaredMethods()) {
@@ -83,6 +107,13 @@ void addPublicMethods() {
83107
continue;
84108
}
85109

110+
//Don't exclude accessors with HTTP Annotations
111+
if (conf.getJaxrsRun() && conf.methodHasHTTPAnnotation(method)) {
112+
addMethod(method);
113+
blackListUnnecessaryFieldMethods(method);
114+
continue;
115+
}
116+
86117
// Exclude accessors
87118
try {
88119
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);

java2typescript-jaxrs/src/main/java/java2typescript/jaxrs/ServiceDescriptorGenerator.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import java.util.ArrayList;
3232
import java.util.Collection;
3333
import java.util.List;
34+
35+
import java2typescript.jackson.module.Configuration;
3436
import java2typescript.jackson.module.DefinitionGenerator;
3537
import java2typescript.jackson.module.grammar.AnyType;
3638
import java2typescript.jackson.module.grammar.ClassType;
@@ -85,14 +87,21 @@ public class ServiceDescriptorGenerator {
8587

8688
private ObjectMapper mapper;
8789

90+
private Configuration conf;
91+
8892
public ServiceDescriptorGenerator(Collection<? extends Class<?>> classes) {
8993
this(classes, new ObjectMapper());
9094
}
9195

9296
public ServiceDescriptorGenerator(Collection<? extends Class<?>> classes, ObjectMapper mapper) {
97+
this(classes,mapper, null);
98+
}
99+
100+
public ServiceDescriptorGenerator(Collection<? extends Class<?>> classes, ObjectMapper mapper, Configuration conf) {
93101
this.classes = classes;
94102
this.mapper = mapper;
95103
addDummyMappingForJAXRSClasses();
104+
this.conf = conf;
96105
}
97106

98107
private class DummySerializer extends JsonSerializer<Object> {
@@ -153,7 +162,11 @@ public Module generateTypeScript(String moduleName) throws JsonMappingException
153162

154163
// Generates Typescript module out of service classses definition
155164
DefinitionGenerator defGen = new DefinitionGenerator(mapper);
156-
Module module = defGen.generateTypeScript(moduleName, classes, null);
165+
if (conf == null) {
166+
conf = new Configuration();
167+
conf.setJaxrsRun(true);
168+
}
169+
Module module = defGen.generateTypeScript(moduleName, classes, conf);
157170

158171
// For each rest service, update methods with parameter names, got from Rest service descriptor
159172
for (RestService restService : generateRestServices(classes)) {

java2typescript-jaxrs/src/test/java/java2typescript/jaxrs/DescriptorGeneratorTest.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,39 @@ static class MyObject {
4646
}
4747

4848
@Path("/")
49-
static private interface ExampleService {
49+
class ExampleService {
5050

5151
@Path("/{id}")
5252
@POST
5353
public String aPostMethod(//
5454
@QueryParam("q1") String queryParam, //
5555
@PathParam("id") String id, //
5656
@FormParam("formParam") Integer formParam, //
57-
String postPayload);
57+
String postPayload){
58+
return "test";
59+
}
5860

5961
@Path("/{id}")
6062
@GET
6163
public void aGetMethod(//
6264
@QueryParam("q1") String queryParam, //
6365
@PathParam("id") String id, //
6466
@FormParam("formParam") Integer formParam, //
65-
MyObject postPayload);
67+
MyObject postPayload){
68+
69+
}
70+
71+
@Path("/random")
72+
@GET
73+
public int getRandom() {
74+
return 4;
75+
}
76+
77+
@Path("/multi")
78+
@GET
79+
public int getMultiWordGetter() {
80+
return 3;
81+
}
6682

6783
}
6884

@@ -92,4 +108,19 @@ public void testTypescriptGenerate() throws JsonGenerationException, JsonMapping
92108
Module tsModule = descGen.generateTypeScript("modName");
93109
tsModule.write(out);
94110
}
111+
112+
@Test
113+
public void testTypescriptGenerateWithExample() throws JsonGenerationException, JsonMappingException, IOException {
114+
115+
ServiceDescriptorGenerator descGen = new ServiceDescriptorGenerator(
116+
Collections.singletonList(ExampleService.class));
117+
118+
ObjectMapper mapper = new ObjectMapper();
119+
SimpleModule module = new SimpleModule("custom-mapping");
120+
121+
mapper.registerModule(module);
122+
123+
Module tsModule = descGen.generateTypeScript("modName");
124+
tsModule.write(out);
125+
}
95126
}

0 commit comments

Comments
 (0)