diff --git a/pom.xml b/pom.xml index 5d529808..e8b16421 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,21 @@ + + org.apache.commons + commons-lang3 + 3.7 + + + com.google.code.gson + gson + 2.8.5 + + + com.squareup + javapoet + 1.11.1 + junit junit @@ -52,12 +67,6 @@ 1.3 test - - org.apache.commons - commons-lang3 - 3.0 - test - com.carrotsearch junit-benchmarks @@ -149,6 +158,19 @@ + + com.j2html + j2html-maven-plugin + 1.0-SNAPSHOT + + + generate-tags + + generate-tags + + + + diff --git a/src/main/java/j2html/tags/ContainerTag.java b/src/main/java/j2html/tags/ContainerTag.java index ceb40507..0ef5c20d 100644 --- a/src/main/java/j2html/tags/ContainerTag.java +++ b/src/main/java/j2html/tags/ContainerTag.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.stream.Stream; -public class ContainerTag extends Tag { +public class ContainerTag> extends Tag { private List children; @@ -22,15 +22,15 @@ public ContainerTag(String tagName) { * @param child DomContent-object to be appended * @return itself for easy chaining */ - public ContainerTag with(DomContent child) { + public T with(DomContent child) { if (this == child) { throw new RuntimeException("Cannot append a tag to itself."); } if (child == null) { - return this; // in some cases, like when using iff(), we ignore null children + return (T) this; // in some cases, like when using iff(), we ignore null children } children.add(child); - return this; + return (T) this; } @@ -121,7 +121,7 @@ public ContainerTag condWith(boolean condition, DomContent... children) { * @param text the text to be appended * @return itself for easy chaining */ - public ContainerTag withText(String text) { + public T withText(String text) { return with(new Text(text)); } diff --git a/src/main/java/j2html/tags/EmptyTag.java b/src/main/java/j2html/tags/EmptyTag.java index 7dd63f49..97dcff6c 100644 --- a/src/main/java/j2html/tags/EmptyTag.java +++ b/src/main/java/j2html/tags/EmptyTag.java @@ -4,7 +4,7 @@ import j2html.attributes.Attribute; import java.io.IOException; -public class EmptyTag extends Tag { +public class EmptyTag> extends Tag { public EmptyTag(String tagName) { super(tagName); diff --git a/src/main/java/j2html/tags/Tag.java b/src/main/java/j2html/tags/Tag.java index 888a8dee..1537bbba 100644 --- a/src/main/java/j2html/tags/Tag.java +++ b/src/main/java/j2html/tags/Tag.java @@ -132,7 +132,7 @@ public T attr(String attribute) { * @param value the attribute value * @return itself for easy chaining */ - public T condAttr(boolean condition, String attribute, String value) { + public T condAttr(boolean condition, String attribute, Object value) { return (condition ? attr(attribute, value) : (T) this); } diff --git a/src/main/java/j2html/tags/TagCreatorCodeGeneratorFromJson.java b/src/main/java/j2html/tags/TagCreatorCodeGeneratorFromJson.java new file mode 100644 index 00000000..60296239 --- /dev/null +++ b/src/main/java/j2html/tags/TagCreatorCodeGeneratorFromJson.java @@ -0,0 +1,78 @@ +package j2html.tags; + +import com.google.gson.*; +import com.squareup.javapoet.*; +import j2html.attributes.Attr; + +import javax.lang.model.element.Modifier; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.StringWriter; + +import static org.apache.commons.lang3.StringUtils.capitalize; + +public class TagCreatorCodeGeneratorFromJson { + + public static void main(String[] args) throws Exception { + StringWriter output = new StringWriter(); + + try (FileReader fileReader = new FileReader("src/main/resources/tagClasses.json")) { + JsonObject json = new Gson().fromJson(fileReader, JsonObject.class); + ClassName containerTagClassName = ClassName.get(ContainerTag.class); + json.getAsJsonArray("tags").forEach(element -> { + JsonObject tagJson = element.getAsJsonObject(); + + String tag = tagJson.get("tag").getAsString(); + ClassName tagClassName = ClassName.get("j2html.tags", capitalize(tag + "Tag")); + TypeSpec.Builder typeSpec = TypeSpec.classBuilder(tagClassName) + .superclass(ParameterizedTypeName.get(containerTagClassName, tagClassName)) + .addMethod( + MethodSpec.constructorBuilder() + .addModifiers(Modifier.PUBLIC) + .addStatement("super(\"" + tag + "\")") + .build()); + + JsonArray attrs = tagJson.getAsJsonArray("attrs"); + attrs.forEach(attrElement -> { + String attrName = attrElement.isJsonObject() ? attrElement.getAsJsonObject().get("name").getAsString() : attrElement.getAsString(); + String attrNameCapitalized = capitalize(attrName); + + MethodSpec.Builder methodSpec = MethodSpec.methodBuilder("with" + attrNameCapitalized) + .addModifiers(Modifier.PUBLIC) + .returns(tagClassName); + + MethodSpec.Builder condMethodSpec = MethodSpec.methodBuilder("withCond" + attrNameCapitalized) + .addModifiers(Modifier.PUBLIC) + .addParameter(boolean.class, "condition") + .returns(tagClassName); + + if (attrElement.isJsonObject() && new JsonPrimitive(true).equals(attrElement.getAsJsonObject().get("empty"))) { + methodSpec.addStatement("return attr(\"" + attrName + "\")"); + condMethodSpec.addStatement("return condAttr(condition, \"" + attrName + "\", \"" + attrName + "\")"); + } else { + methodSpec + .addParameter(String.class, attrName) + .addStatement("return attr(\"" + attrName + "\", " + attrName + ")"); + condMethodSpec + .addParameter(boolean.class, "condition") + .addParameter(String.class, attrName) + .addStatement("return condAttr(condition, \"" + attrName + "\", " + attrName + ")"); + } + typeSpec.addMethod(methodSpec.build()) + .addMethod(condMethodSpec.build()); + }); + + try { + JavaFile.builder("j2html.tags", typeSpec.build()) + .build() + .writeTo(output); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + + System.out.println(output); + } +} diff --git a/src/main/resources/globalAttributes.json b/src/main/resources/globalAttributes.json new file mode 100644 index 00000000..983ff470 --- /dev/null +++ b/src/main/resources/globalAttributes.json @@ -0,0 +1,7 @@ +[ + { + "name": "tabindex", + "type": "Integer" + }, + "title" +] diff --git a/src/main/resources/tagClasses.json b/src/main/resources/tagClasses.json new file mode 100644 index 00000000..80cfaeed --- /dev/null +++ b/src/main/resources/tagClasses.json @@ -0,0 +1,18 @@ +{ + "tags": [ + { + "tag": "a", + "attrs": [ + "href", + "charset" + ] + }, + { + "tag": "video", + "attrs": [ + { "name": "autoplay", "empty": true }, "controls", "height", "loop", "muted", "poster", "preload", "src", "width" + ] + }, + "abbr" + ] +}