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

Allow JsonSubTypes to be interfaces/abstract classes #149

Merged
Merged
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
6 changes: 6 additions & 0 deletions typescript-generator-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
<version>2.5.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private BeanModel parseBean(SourceType<Class<?>> sourceClass) {
// this is parent
discriminantProperty = getDiscriminantPropertyName(jsonTypeInfo);
discriminantLiteral = null;
} else if (!sourceClass.type.isInterface() && !Modifier.isAbstract(sourceClass.type.getModifiers()) && isSupported(parentJsonTypeInfo = getAnnotationRecursive(sourceClass.type, JsonTypeInfo.class))) {
} else if (isSupported(parentJsonTypeInfo = getAnnotationRecursive(sourceClass.type, JsonTypeInfo.class))) {
// this is child class
discriminantProperty = getDiscriminantPropertyName(parentJsonTypeInfo);
discriminantLiteral = getTypeName(sourceClass.type);
Expand Down Expand Up @@ -186,8 +186,11 @@ public boolean test(JsonSubTypes types) {
return jsonSubType.name();
}
}
// use simplified class name
return cls.getName().substring(cls.getName().lastIndexOf(".") + 1);
// use simplified class name if it's not an interface or abstract
if(!cls.isInterface() && !Modifier.isAbstract(cls.getModifiers())) {
return cls.getName().substring(cls.getName().lastIndexOf(".") + 1);
}
return null;
}

private static JsonSubTypes.Type getJsonSubTypeForClass(JsonSubTypes types, Class<?> cls) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cz.habarta.typescript.generator;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.immutables.value.Value;

@Value.Immutable
@JsonSerialize(as = ImmutableCircle.class)
@JsonDeserialize(as = ImmutableCircle.class)
public interface Circle extends Shape {
double radius();

final class Builder extends ImmutableCircle.Builder {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

package cz.habarta.typescript.generator;

import org.junit.Assert;
import org.junit.Test;

public class ImmutablesTest {

@Test
public void testImmutables() {
final Settings settings = TestUtils.settings();
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Shape.class));
final String expected = (
"\n" +
"interface Shape {\n" +
" kind: 'square' | 'rectangle' | 'circle';\n" +
"}\n" +
"\n" +
"interface Square extends Shape {\n" +
" kind: 'square';\n" +
" size: number;\n" +
"}\n" +
"\n" +
"interface Rectangle extends Shape {\n" +
" kind: 'rectangle';\n" +
" width: number;\n" +
" height: number;\n" +
"}\n" +
"\n" +
"interface Circle extends Shape {\n" +
" kind: 'circle';\n" +
" radius: number;\n" +
"}\n" +
"\n" +
"type ShapeUnion = Square | Rectangle | Circle;\n" +
""
).replace('\'', '"');
Assert.assertEquals(expected, output);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cz.habarta.typescript.generator;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.immutables.value.Value;

@Value.Immutable
@JsonSerialize(as = ImmutableRectangle.class)
@JsonDeserialize(as = ImmutableRectangle.class)
public abstract class Rectangle implements Shape {
public abstract double width();
public abstract double height();

public static Rectangle.Builder builder() {
return new Rectangle.Builder();
}

public static final class Builder extends ImmutableRectangle.Builder {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cz.habarta.typescript.generator;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "kind")
@JsonSubTypes({
@JsonSubTypes.Type(value = Square.class, name = "square"),
@JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"),
@JsonSubTypes.Type(value = Circle.class, name = "circle"),
})
public interface Shape {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package cz.habarta.typescript.generator;

public class Square implements Shape {
public double size;
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public void testTaggedUnionsWithInterfaces() {
"}\n" +
"\n" +
"interface IQuadrilateral2 extends IShape2 {\n" +
" kind: 'square' | 'rectangle';\n" +
"}\n" +
"\n" +
"type IShape2Union = CSquare2 | CRectangle2 | CCircle2;\n" +
Expand Down