Skip to content

Commit 0d6a1e6

Browse files
excludePropertyAnnotations parameter (#251)
1 parent 84ed1d9 commit 0d6a1e6

File tree

8 files changed

+122
-49
lines changed

8 files changed

+122
-49
lines changed

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/Settings.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public class Settings {
7373
public List<File> javadocXmlFiles = null;
7474
public List<EmitterExtension> extensions = new ArrayList<>();
7575
public List<Class<? extends Annotation>> includePropertyAnnotations = new ArrayList<>();
76+
public List<Class<? extends Annotation>> excludePropertyAnnotations = new ArrayList<>();
7677
public List<Class<? extends Annotation>> optionalAnnotations = new ArrayList<>();
7778
public boolean generateInfoJson = false;
7879
public boolean generateNpmPackageJson = false;
@@ -158,6 +159,10 @@ public void loadIncludePropertyAnnotations(ClassLoader classLoader, List<String>
158159
this.includePropertyAnnotations = loadClasses(classLoader, includePropertyAnnotations, Annotation.class);
159160
}
160161

162+
public void loadExcludePropertyAnnotations(ClassLoader classLoader, List<String> excludePropertyAnnotations) {
163+
this.excludePropertyAnnotations = loadClasses(classLoader, excludePropertyAnnotations, Annotation.class);
164+
}
165+
161166
public void loadOptionalAnnotations(ClassLoader classLoader, List<String> optionalAnnotations) {
162167
this.optionalAnnotations = loadClasses(classLoader, optionalAnnotations, Annotation.class);
163168
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Jackson1Parser.java

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,27 +51,11 @@ private BeanModel parseBean(SourceType<Class<?>> sourceClass) {
5151
final Member propertyMember = beanPropertyWriter.getMember().getMember();
5252
checkMember(propertyMember, beanPropertyWriter.getName(), sourceClass.type);
5353
Type propertyType = beanPropertyWriter.getGenericPropertyType();
54-
boolean isInAnnotationFilter = settings.includePropertyAnnotations.isEmpty();
55-
if (!isInAnnotationFilter) {
56-
for (Class<? extends Annotation> optionalAnnotation : settings.includePropertyAnnotations) {
57-
if (beanPropertyWriter.getAnnotation(optionalAnnotation) != null) {
58-
isInAnnotationFilter = true;
59-
break;
60-
}
61-
}
62-
if (!isInAnnotationFilter) {
63-
TypeScriptGenerator.getLogger().info("Skipping " + sourceClass.type + "." + beanPropertyWriter.getName() + " because it is missing an annotation from includePropertyAnnotations!");
64-
continue;
65-
}
54+
if (!isAnnotatedPropertyIncluded(beanPropertyWriter::getAnnotation, sourceClass.type.getName() + "." + beanPropertyWriter.getName())) {
55+
continue;
6656
}
67-
final boolean optional = isAnnotatedPropertyOptional(new AnnotatedProperty() {
68-
@Override
69-
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
70-
return beanPropertyWriter.getAnnotation(annotationClass);
71-
}
72-
});
73-
final Member originalMember = beanPropertyWriter.getMember().getMember();
74-
properties.add(processTypeAndCreateProperty(beanPropertyWriter.getName(), propertyType, optional, sourceClass.type, originalMember, null));
57+
final boolean optional = isAnnotatedPropertyOptional(beanPropertyWriter::getAnnotation);
58+
properties.add(processTypeAndCreateProperty(beanPropertyWriter.getName(), propertyType, optional, sourceClass.type, propertyMember, null));
7559
}
7660
}
7761

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Jackson2Parser.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -131,27 +131,12 @@ private BeanModel parseBean(SourceType<Class<?>> sourceClass) {
131131
}
132132
}
133133

134-
boolean isInAnnotationFilter = settings.includePropertyAnnotations.isEmpty();
135-
if (!isInAnnotationFilter) {
136-
for (Class<? extends Annotation> optionalAnnotation : settings.includePropertyAnnotations) {
137-
if (beanPropertyWriter.getAnnotation(optionalAnnotation) != null) {
138-
isInAnnotationFilter = true;
139-
break;
140-
}
141-
}
142-
if (!isInAnnotationFilter) {
143-
TypeScriptGenerator.getLogger().info("Skipping " + sourceClass.type + "." + beanPropertyWriter.getName() + " because it is missing an annotation from includePropertyAnnotations!");
144-
continue;
145-
}
134+
if (!isAnnotatedPropertyIncluded(beanPropertyWriter::getAnnotation, sourceClass.type.getName() + "." + beanPropertyWriter.getName())) {
135+
continue;
146136
}
147137
final boolean optional = settings.optionalProperties == OptionalProperties.useLibraryDefinition
148138
? !beanPropertyWriter.isRequired()
149-
: isAnnotatedPropertyOptional(new AnnotatedProperty() {
150-
@Override
151-
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
152-
return beanPropertyWriter.getAnnotation(annotationClass);
153-
}
154-
});
139+
: isAnnotatedPropertyOptional(beanPropertyWriter::getAnnotation);
155140
// @JsonUnwrapped
156141
PropertyModel.PullProperties pullProperties = null;
157142
final JsonUnwrapped annotation = beanPropertyWriter.getAnnotation(JsonUnwrapped.class);

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/ModelParser.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
import cz.habarta.typescript.generator.compiler.EnumKind;
66
import cz.habarta.typescript.generator.compiler.EnumMemberModel;
77
import cz.habarta.typescript.generator.compiler.SymbolTable;
8+
import cz.habarta.typescript.generator.util.Utils;
89
import java.lang.annotation.Annotation;
910
import java.lang.reflect.Field;
1011
import java.lang.reflect.Member;
1112
import java.lang.reflect.Method;
1213
import java.lang.reflect.Type;
1314
import java.util.*;
15+
import java.util.function.Function;
1416

1517

1618
public abstract class ModelParser {
@@ -105,21 +107,27 @@ protected static void checkMember(Member propertyMember, String propertyName, Cl
105107
}
106108
}
107109

108-
// replace with lambda on Java8
109-
protected static interface AnnotatedProperty {
110-
public <T extends Annotation> T getAnnotation(Class<T> annotationClass);
110+
protected boolean isAnnotatedPropertyIncluded(Function<Class<? extends Annotation>, Annotation> getAnnotationFunction, String propertyDescription) {
111+
boolean isIncluded = settings.includePropertyAnnotations.isEmpty()
112+
|| Utils.hasAnyAnnotation(getAnnotationFunction, settings.includePropertyAnnotations);
113+
if (!isIncluded) {
114+
TypeScriptGenerator.getLogger().verbose("Skipping '" + propertyDescription + "' because it doesn't have any annotation from 'includePropertyAnnotations'");
115+
return false;
116+
}
117+
boolean isExcluded = Utils.hasAnyAnnotation(getAnnotationFunction, settings.excludePropertyAnnotations);
118+
if (isExcluded) {
119+
TypeScriptGenerator.getLogger().verbose("Skipping '" + propertyDescription + "' because it has some annotation from 'excludePropertyAnnotations'");
120+
return false;
121+
}
122+
return true;
111123
}
112124

113-
protected boolean isAnnotatedPropertyOptional(AnnotatedProperty annotatedProperty) {
125+
protected boolean isAnnotatedPropertyOptional(Function<Class<? extends Annotation>, Annotation> getAnnotationFunction) {
114126
if (settings.optionalProperties == OptionalProperties.all) {
115127
return true;
116128
}
117129
if (settings.optionalProperties == null || settings.optionalProperties == OptionalProperties.useSpecifiedAnnotations) {
118-
for (Class<? extends Annotation> optionalAnnotation : settings.optionalAnnotations) {
119-
if (annotatedProperty.getAnnotation(optionalAnnotation) != null) {
120-
return true;
121-
}
122-
}
130+
return Utils.hasAnyAnnotation(getAnnotationFunction, settings.optionalAnnotations);
123131
}
124132
return false;
125133
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/util/Utils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.lang.reflect.ParameterizedType;
1414
import java.lang.reflect.Type;
1515
import java.util.*;
16+
import java.util.function.Function;
1617
import java.util.regex.Matcher;
1718
import java.util.regex.Pattern;
1819

@@ -71,6 +72,17 @@ public static Class<?> getRawClassOrNull(Type type) {
7172
return null;
7273
}
7374

75+
public static boolean hasAnyAnnotation(
76+
Function<Class<? extends Annotation>, Annotation> getAnnotationFunction,
77+
List<Class<? extends Annotation>> annotations) {
78+
for (Class<? extends Annotation> annotation : annotations) {
79+
if (getAnnotationFunction.apply(annotation) != null) {
80+
return true;
81+
}
82+
}
83+
return false;
84+
}
85+
7486
public static <T> T getAnnotationElementValue(AnnotatedElement annotatedElement, String annotationClassName, String annotationElementName, Class<T> annotationElementType) {
7587
final Annotation annotation = getAnnotation(annotatedElement, annotationClassName);
7688
return getAnnotationElementValue(annotation, annotationElementName, annotationElementType);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
package cz.habarta.typescript.generator;
3+
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.util.Arrays;
7+
import org.junit.Assert;
8+
import org.junit.Test;
9+
10+
11+
public class IncludeExcludePropertyTest {
12+
13+
@Test
14+
public void testInclude() {
15+
final Settings settings = TestUtils.settings();
16+
settings.includePropertyAnnotations = Arrays.asList(MyInclude.class);
17+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(ClassWithAnnotatedProperties.class));
18+
Assert.assertTrue(!output.contains("property1"));
19+
Assert.assertTrue(output.contains("property2"));
20+
Assert.assertTrue(!output.contains("property3"));
21+
Assert.assertTrue(output.contains("property4"));
22+
}
23+
24+
@Test
25+
public void testExclude() {
26+
final Settings settings = TestUtils.settings();
27+
settings.excludePropertyAnnotations = Arrays.asList(MyExclude.class);
28+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(ClassWithAnnotatedProperties.class));
29+
Assert.assertTrue(output.contains("property1"));
30+
Assert.assertTrue(output.contains("property2"));
31+
Assert.assertTrue(!output.contains("property3"));
32+
Assert.assertTrue(!output.contains("property4"));
33+
}
34+
35+
@Test
36+
public void testBoth() {
37+
final Settings settings = TestUtils.settings();
38+
settings.includePropertyAnnotations = Arrays.asList(MyInclude.class);
39+
settings.excludePropertyAnnotations = Arrays.asList(MyExclude.class);
40+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(ClassWithAnnotatedProperties.class));
41+
Assert.assertTrue(!output.contains("property1"));
42+
Assert.assertTrue(output.contains("property2"));
43+
Assert.assertTrue(!output.contains("property3"));
44+
Assert.assertTrue(!output.contains("property4"));
45+
}
46+
47+
@Retention(RetentionPolicy.RUNTIME)
48+
private static @interface MyInclude {
49+
}
50+
51+
@Retention(RetentionPolicy.RUNTIME)
52+
private static @interface MyExclude {
53+
}
54+
55+
private static class ClassWithAnnotatedProperties {
56+
57+
public String property1;
58+
59+
@MyInclude
60+
public String property2;
61+
62+
@MyExclude
63+
public String property3;
64+
65+
@MyInclude
66+
@MyExclude
67+
public String property4;
68+
69+
}
70+
71+
}

typescript-generator-gradle-plugin/src/main/java/cz/habarta/typescript/generator/gradle/GenerateTask.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class GenerateTask extends DefaultTask {
2929
public List<String> excludeClasses;
3030
public List<String> excludeClassPatterns;
3131
public List<String> includePropertyAnnotations;
32+
public List<String> excludePropertyAnnotations;
3233
public JsonLibrary jsonLibrary;
3334
public Jackson2Configuration jackson2Configuration;
3435
@Deprecated public boolean declarePropertiesAsOptional;
@@ -160,6 +161,7 @@ public void generate() throws Exception {
160161
settings.javadocXmlFiles = javadocXmlFiles;
161162
settings.loadExtensions(classLoader, Utils.concat(extensionClasses, extensions), extensionsWithConfiguration);
162163
settings.loadIncludePropertyAnnotations(classLoader, includePropertyAnnotations);
164+
settings.loadExcludePropertyAnnotations(classLoader, excludePropertyAnnotations);
163165
settings.loadOptionalAnnotations(classLoader, optionalAnnotations);
164166
settings.generateInfoJson = generateInfoJson;
165167
settings.generateNpmPackageJson = generateNpmPackageJson;

typescript-generator-maven-plugin/src/main/java/cz/habarta/typescript/generator/maven/GenerateMojo.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,17 @@ public class GenerateMojo extends AbstractMojo {
145145
private List<String> excludeClassPatterns;
146146

147147
/**
148-
* If this list is not empty then TypeScript will only be generated for
149-
* methods with one of the annotations defined in this list.
148+
* If this list is not empty then only properties with any of these annotations will be included.
150149
*/
151150
@Parameter
152151
private List<String> includePropertyAnnotations;
153152

153+
/**
154+
* Properties with any of these annotations will be excluded.
155+
*/
156+
@Parameter
157+
private List<String> excludePropertyAnnotations;
158+
154159
/**
155160
* Library used in JSON classes.
156161
* Supported values are:
@@ -676,6 +681,7 @@ public void execute() {
676681
settings.javadocXmlFiles = javadocXmlFiles;
677682
settings.loadExtensions(classLoader, extensions, extensionsWithConfiguration);
678683
settings.loadIncludePropertyAnnotations(classLoader, includePropertyAnnotations);
684+
settings.loadExcludePropertyAnnotations(classLoader, excludePropertyAnnotations);
679685
settings.loadOptionalAnnotations(classLoader, optionalAnnotations);
680686
settings.generateInfoJson = generateInfoJson;
681687
settings.generateNpmPackageJson = generateNpmPackageJson;

0 commit comments

Comments
 (0)