Maven multi module support (#222)

* Restructuring to a Maven multi-module project.

- Renamed directories to match artifact ids.
- Added parent POM.
- Added developers to parent POM.
- Added dependency management and plugin management.  No expectation that the build or release process is fully functional.
- Extracted versions into properties like other projects.

* Fixed file paths for workflow and documentation.

- Added junit to j2html-codegen module.

* Temporarily setting packaging for j2html-codegen to pom, to allow workflow to complete.

* Removed copied configuration of maven-jar-plugin from parent POM.

* Integrating code generation into the main build process.

- j2html-codegen is now supplying a Maven plugin that can read a model file and generate corresponding attribute and tag classes as part of the project build.
- j2html classes that would conflict with the generated classes have been removed.

* Targeting LTS versions only.

- JDK 9 & 10 support ended  in 2018
This commit is contained in:
Scott Embler
2022-12-26 09:51:00 -05:00
committed by GitHub
parent 38c08d4724
commit 94c82398ad
389 changed files with 2348 additions and 3423 deletions

View File

@@ -9,7 +9,7 @@ jobs:
strategy:
fail-fast: false
matrix:
java_version: [1.8, 9, 10, 11, 12, 13]
java_version: [1.8, 11, 17]
os: [windows-latest, macOS-latest, ubuntu-latest]
steps:
@@ -23,6 +23,6 @@ jobs:
if: contains(matrix.os, 'win') == false
run: chmod +x ./mvnw
- name: Build with Maven
run: ./mvnw verify --file library/pom.xml --batch-mode
run: ./mvnw verify --file pom.xml --batch-mode
env:
MAVEN_OPTS: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn

1
.gitignore vendored
View File

@@ -11,4 +11,5 @@ hs_err_pid*
buildNumber.properties
### IntelliJ ###
*.iml
.idea/

View File

@@ -33,7 +33,7 @@ If you are on Windows, there should be no Problems.
### Reformatting of generated Java Code
As this Projects makes use of Code-Generation techniques in order to generate a more typesafe API without too much manual Work,
there is the `code_gen/` directory which contains everything needed to generate the code.
there is the `j2html-codegen/` directory which contains everything needed to generate the code.
For simplicity (and also to avoid extra dependencies), they do not format the code correctly.
@@ -51,7 +51,7 @@ The workflow (most of the time) consists of:
## Project Architecture
### library/src/main/java/j2html/TagCreator.java
### j2html/src/main/java/j2html/TagCreator.java
This is **the** central class in J2HTML. It provides the methods
for users of J2HTML to generate all HTML Tags.
@@ -80,7 +80,7 @@ html(
Each HTML Tag has it's own class, which makes it possible for each Tag to have
the correct Attributes and Methods to set those Attributes.
The classes are located in `library/src/main/java/j2html/tags/specialized` and follow the naming convention `tag_name + 'Tag.java'`, e.g. `BodyTag.java`.
The classes are located in `j2html/src/main/java/j2html/tags/specialized` and follow the naming convention `tag_name + 'Tag.java'`, e.g. `BodyTag.java`.
Notice that the first letter of the Tag is in uppercase.
Each Tag-specific class `implements` interfaces which correspond to the Attributes that can be set on these Tags.
@@ -128,7 +128,7 @@ If you find a way, that would be a great PR.
### Special classes/interfaces besides TagCreator.java
There are 3 classes which contain code-generating methods in `code_gen/src/main/java/j2html_codegen/generators/`:
There are 3 classes which contain code-generating methods in `j2html-codegen/src/main/java/j2html_codegen/generators/`:
- `AttributeInterfaceCodeGenerator.java` (generating the interfaces for the attributes)
- `SpecializedTagClassCodeGenerator.java` (generating the classes for the tags)
@@ -147,7 +147,7 @@ Attributes differ in their 'type' . Some of them can be set with numbers (which
Others can only be set or not set, others still have 3 states: set, unset, and not present.
To model these propertise, a single Attribute can be described by an instance of **AttrD.java**.
`library/src/main/java/j2html/tags/generators/AttributesList.java` contains the different Attributes, their properties,
`j2html/src/main/java/j2html/tags/generators/AttributesList.java` contains the different Attributes, their properties,
and the Tags they can be set on. It is the starting point for adding new Attributes and customizing their properties.

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.j2html</groupId>
<artifactId>j2htmlcodegen</artifactId>
<version>1.0-SNAPSHOT</version>
<name>j2htmlcodegen</name>
<url>https://j2html.com/</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup</groupId>
<artifactId>javapoet</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

86
j2html-codegen/pom.xml Normal file
View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.j2html</groupId>
<artifactId>j2html-parent</artifactId>
<version>1.6.1-SNAPSHOT</version>
</parent>
<name>j2html-codegen</name>
<artifactId>j2html-codegen-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.8.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
<!--
Note: The use of version properties below is to avoid
redefining these versions when using this maven plugin
in other projects. Using the more concise dependency-
management strategy for versioning doesn't work when
another project tries to detect this plugin's dependency
versions.
-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup</groupId>
<artifactId>javapoet</artifactId>
<version>${javapoet.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.4</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -1,7 +1,7 @@
package j2html_codegen;
package com.j2html.codegen;
import j2html_codegen.generators.AttributeInterfaceCodeGenerator;
import j2html_codegen.generators.SpecializedTagClassCodeGenerator;
import com.j2html.codegen.generators.SpecializedTagClassCodeGenerator;
import com.j2html.codegen.generators.AttributeInterfaceCodeGenerator;
import java.io.IOException;
import java.nio.file.Path;

View File

@@ -0,0 +1,50 @@
package com.j2html.codegen;
import com.j2html.codegen.model.AttrD;
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.containerTags;
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.emptyTags;
import static com.j2html.codegen.model.AttributesList.attributesDescriptive;
import static com.j2html.codegen.model.AttributesList.getCustomAttributesForHtmlTag;
import static java.lang.System.*;
public class Export {
public static void main(String[] args){
for (final String tag : emptyTags()) {
out.print("EMPTY-ELEMENT[");
out.print(tag);
out.print("]");
out.println();
}
for (final String tag : containerTags()) {
out.print("ELEMENT[");
out.print(tag);
out.print("]");
out.println();
}
out.println();
for(AttrD attr : attributesDescriptive()){
if(attr.hasArgument){
out.print("STRING");
}else{
out.print("BOOLEAN");
}
out.print("[");
out.print(attr.attr);
out.print("]");
out.println();
for(String tag : attr.tags){
out.print("ATTRIBUTE[");
out.print(tag);
out.print(":");
out.print(attr.attr);
out.print("]");
out.println();
}
out.println();
}
}
}

View File

@@ -0,0 +1,199 @@
package com.j2html.codegen;
import com.j2html.codegen.Model.Node;
import com.squareup.javapoet.*;
import javax.lang.model.element.Modifier;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import static com.j2html.codegen.Model.Metadata.ON_OFF;
import static com.j2html.codegen.Model.Metadata.SELF_CLOSING;
public class Generator {
public static final ClassName INSTANCE = ClassName.get("j2html.tags", "IInstance");
public static final ClassName TAG = ClassName.get("j2html.tags", "Tag");
public static final ClassName EMPTY_TAG = ClassName.get("j2html.tags", "EmptyTag");
public static final ClassName CONTAINER_TAG = ClassName.get("j2html.tags", "ContainerTag");
public static void main(String... args) throws IOException {
Path path = Paths.get("j2html-codegen", "src", "test", "resources", "html.model");
String definitions = new String(Files.readAllBytes(path));
Model model = new Model();
Parser.parse(definitions, model);
Path dir = Paths.get("/j2html/generated-source");
Files.createDirectories(dir);
generate(dir, "j2html.tags.attributes", "j2html.tags.specialized", model);
}
public static void generate(Path root, String attributePkg, String elementPkg, Model model) throws IOException {
Map<String, JavaFile> attributes = generateAttributePackage(attributePkg, model);
for (JavaFile file : attributes.values()) {
file.writeTo(root);
}
Map<String, JavaFile> elements = generateElementPackage(elementPkg, model, attributes);
for (JavaFile file : elements.values()) {
file.writeTo(root);
}
}
private static Map<String, JavaFile> generateElementPackage(String pkg, Model model, Map<String, JavaFile> attributes) {
Map<String, JavaFile> files = new HashMap<>();
// Convert all elements into classes.
for (Node element : model.elements()) {
ClassName className = ClassName.get(pkg, capitalize(element.name) + "Tag");
TypeSpec.Builder type = defineElementClass(element, className);
// Assign attributes to this element.
for (Node attribute : element.children) {
JavaFile file = attributes.get(attribute.name);
type.addSuperinterface(
ParameterizedTypeName.get(
ClassName.get(file.packageName, file.typeSpec.name),
className
)
);
}
files.put(
element.name,
JavaFile.builder(pkg, type.build())
.skipJavaLangImports(true)
.build()
);
}
return files;
}
private static Map<String, JavaFile> generateAttributePackage(String pkg, Model model) {
Map<String, JavaFile> files = new HashMap<>();
// Convert all attributes into classes.
for (Node attribute : model.attributes()) {
TypeSpec.Builder type = defineAttributeClass(pkg, attribute);
if (attribute.type.equals(Node.Type.STRING)) {
defineStringAttributeMethods(attribute, type);
} else if (attribute.type.equals(Node.Type.BOOLEAN) && !attribute.is(ON_OFF)) {
defineBooleanAttributeMethods(attribute, type);
} else if (attribute.type.equals(Node.Type.BOOLEAN) && attribute.is(ON_OFF)) {
defineOnOffAttributeMethods(attribute, type);
}
files.put(
attribute.name,
JavaFile.builder(pkg, type.build())
.skipJavaLangImports(true)
.build()
);
}
return files;
}
private static TypeSpec.Builder defineElementClass(Node element, ClassName className) {
MethodSpec constructor = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC)
.addStatement("super(\"" + element.name + "\")")
.build();
TypeSpec.Builder type = TypeSpec.classBuilder(className)
.addModifiers(Modifier.PUBLIC)
.superclass(
ParameterizedTypeName.get(element.is(SELF_CLOSING) ? EMPTY_TAG : CONTAINER_TAG, className)
)
.addMethod(constructor);
return type;
}
private static TypeSpec.Builder defineAttributeClass(String pkg, Node attribute) {
ClassName name = ClassName.get(pkg, "I" + capitalize(attribute.name));
return TypeSpec.interfaceBuilder(name)
.addSuperinterface(ParameterizedTypeName.get(INSTANCE, TypeVariableName.get("T")))
.addTypeVariable(TypeVariableName.get("T", ParameterizedTypeName.get(TAG, TypeVariableName.get("T"))))
.addModifiers(Modifier.PUBLIC);
}
private static void defineBooleanAttributeMethods(Node attribute, TypeSpec.Builder type) {
MethodSpec with = MethodSpec.methodBuilder(methodName("is", attribute.name))
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addStatement("return self().attr(\"" + attribute.name + "\")")
.returns(TypeVariableName.get("T"))
.build();
MethodSpec withCond = MethodSpec.methodBuilder(methodName("withCond", attribute.name))
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addParameter(TypeName.BOOLEAN, "enable", Modifier.FINAL)
.addStatement("return enable ? self().attr(\"" + attribute.name + "\") : self()")
.returns(TypeVariableName.get("T"))
.build();
type.addMethod(with);
type.addMethod(withCond);
}
private static void defineOnOffAttributeMethods(Node attribute, TypeSpec.Builder type) {
MethodSpec with = MethodSpec.methodBuilder(methodName("is", attribute.name))
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addStatement("return self().attr(\"" + attribute.name + "\", \"on\")")
.returns(TypeVariableName.get("T"))
.build();
MethodSpec withCond = MethodSpec.methodBuilder(methodName("withCond", attribute.name))
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addParameter(TypeName.BOOLEAN, "enable", Modifier.FINAL)
.addStatement("return enable ? self().attr(\"" + attribute.name + "\", \"on\") : self()")
.returns(TypeVariableName.get("T"))
.build();
type.addMethod(with);
type.addMethod(withCond);
}
private static void defineStringAttributeMethods(Node attribute, TypeSpec.Builder type) {
MethodSpec with = MethodSpec.methodBuilder(methodName("with", attribute.name))
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addParameter(String.class, parameter(attribute), Modifier.FINAL)
.addStatement("return self().attr(\"" + attribute.name + "\", " + parameter(attribute) + ")")
.returns(TypeVariableName.get("T"))
.build();
MethodSpec withCond = MethodSpec.methodBuilder(methodName("withCond", attribute.name))
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
.addParameter(TypeName.BOOLEAN, "enable", Modifier.FINAL)
.addParameter(String.class, parameter(attribute), Modifier.FINAL)
.addStatement("return enable ? self().attr(\"" + attribute.name + "\", " + parameter(attribute) + ") : self()")
.returns(TypeVariableName.get("T"))
.build();
type.addMethod(with);
type.addMethod(withCond);
}
private static String parameter(Node attribute) {
return attribute.name + "_";
}
private static String methodName(String... words) {
String[] camelCase = new String[words.length];
camelCase[0] = words[0];
for (int i = 1; i < words.length; i++) {
camelCase[i] = capitalize(words[i]);
}
return String.join("", camelCase);
}
private static String capitalize(String word) {
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
}
}

View File

@@ -1,4 +1,4 @@
package j2html_codegen;
package com.j2html.codegen;
import java.io.File;
import java.io.IOException;

View File

@@ -0,0 +1,65 @@
package com.j2html.codegen;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@Mojo(name = "generate-source-files", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class J2htmlCodeGeneratorMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", required = true, readonly = true)
MavenProject project;
@Parameter(property = "modelFile", required = true)
String modelFile;
@Parameter(property = "attributePackage", required = true)
String attributePackage;
@Parameter(property = "tagPackage", required = true)
String tagPackage;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().debug("Model File: " + modelFile);
getLog().debug("Attribute Package: " + attributePackage);
getLog().debug("Tag Package: " + tagPackage);
String outputDirectory = project.getBuild().getDirectory() + "/generated-sources/j2html-codegen";
project.addCompileSourceRoot(outputDirectory);
getLog().debug("Generating J2Html sources in: " + outputDirectory);
String definitions;
try {
definitions = new String(Files.readAllBytes(Paths.get(modelFile)));
} catch (IOException e) {
throw new MojoFailureException("Unable to locate model file: " + modelFile, e);
}
Model model = new Model();
try {
Parser.parse(definitions, model);
}catch (RuntimeException e){
throw new MojoFailureException("Unable to parse model file.", e);
}
try {
Generator.generate(
Paths.get(outputDirectory).toAbsolutePath(),
attributePackage,
tagPackage,
model
);
} catch (IOException e) {
throw new MojoFailureException("Failed to generate source files.", e);
}
}
}

View File

@@ -0,0 +1,171 @@
package com.j2html.codegen;
import java.util.*;
import static com.j2html.codegen.Model.Metadata.ON_OFF;
import static com.j2html.codegen.Model.Metadata.SELF_CLOSING;
import static com.j2html.codegen.Model.Node.Type.*;
public class Model implements Parser.Listener {
private Map<String, Node> elements;
private Map<String, Node> attributes;
public Model() {
elements = new LinkedHashMap<>();
attributes = new LinkedHashMap<>();
}
public Collection<Node> elements(){
return elements.values();
}
public Collection<Node> attributes(){
return attributes.values();
}
public Node addElement(String name) {
return add(ELEMENT, name, elements);
}
public Node addBooleanAttribute(String name) {
return add(BOOLEAN, name, attributes);
}
public Node addStringAttribute(String name) {
return add(STRING, name, attributes);
}
public Node element(String name) {
if (!elements.containsKey(name)) {
throw new NodeDoesNotExist(name);
}
return elements.get(name);
}
public Node attribute(String name) {
if (!attributes.containsKey(name)) {
throw new NodeDoesNotExist(name);
}
return attributes.get(name);
}
private Node add(Node.Type type, String name, Map<String, Node> nodes) {
if (nodes.containsKey(name)) {
throw new NodeAlreadyExists(name);
}
Node node = new Node(type, name);
nodes.put(name, node);
return node;
}
@Override
public void lineCommented(int line, String txt) {
// Ignore.
}
@Override
public void elementDefined(int line, String name) {
attempt(() -> addElement(name), line);
}
@Override
public void emptyElementDefined(int line, String name) {
attempt(() -> addElement(name).annotate(SELF_CLOSING), line);
}
@Override
public void booleanDefined(int line, String name) {
attempt(() -> addBooleanAttribute(name), line);
}
@Override
public void onOffDefined(int line, String name) {
attempt(() -> addBooleanAttribute(name).annotate(ON_OFF), line);
}
@Override
public void stringDefined(int line, String name) {
attempt(() -> addStringAttribute(name), line);
}
@Override
public void attributeDefined(int line, String element, String name) {
attempt(() -> element(element).addChild(attribute(name)), line);
}
@Override
public void invalidLine(int line, String txt) {
throw new RuntimeException("Invalid line [" + line + "]: " + txt);
}
@FunctionalInterface
private interface Unsafe {
void call() throws RuntimeException;
}
private void attempt(Unsafe operation, int line) {
try {
operation.call();
} catch (RuntimeException e) {
throw new InvalidModel(e, line);
}
}
public static class Node {
enum Type {
ELEMENT,
BOOLEAN,
STRING
}
public final Type type;
public final String name;
public final List<Metadata> metadata;
public final List<Node> children;
private Node(Type type, String name) {
this.type = type;
this.name = name;
this.metadata = new ArrayList<>();
this.children = new ArrayList<>();
}
public void annotate(Metadata meta) {
metadata.add(meta);
}
public void addChild(Node node) {
children.add(node);
}
public boolean is(Metadata annotation){
return metadata.contains(annotation);
}
}
public enum Metadata {
SELF_CLOSING,
ON_OFF,
OBSOLETE
}
public static class InvalidModel extends RuntimeException {
public InvalidModel(Exception cause, int line) {
super(cause.getMessage() + ". At line " + line, cause);
}
}
public static class NodeAlreadyExists extends RuntimeException {
public NodeAlreadyExists(String name) {
super("Node already exists: " + name);
}
}
public static class NodeDoesNotExist extends RuntimeException {
public NodeDoesNotExist(String name) {
super("Node does not exist: " + name);
}
}
}

View File

@@ -0,0 +1,91 @@
package com.j2html.codegen;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Parser {
private static final Pattern EMPTY_LINE_PATTERN = Pattern.compile("\\s*");
private static final Pattern COMMENT_PATTERN = Pattern.compile("#.*");
private static final Pattern NODE_PATTERN = Pattern.compile("(?<type>ELEMENT|EMPTY-ELEMENT|BOOLEAN|ONOFF|STRING)\\[(?<name>\\S+)\\]");
private static final Pattern ATTRIBUTE_PATTERN = Pattern.compile("ATTRIBUTE\\[(?<element>\\S+):(?<name>\\S+)\\]");
public interface Listener {
void lineCommented(int line, String txt);
void elementDefined(int line, String name);
void emptyElementDefined(int line, String name);
void booleanDefined(int line, String name);
void onOffDefined(int line, String name);
void stringDefined(int line, String name);
void attributeDefined(int line, String element, String name);
void invalidLine(int line, String txt);
}
public static void parse(String txt, Listener listener) {
String[] lines = txt.split("[\r\n]+");
for (int i = 0; i < lines.length; i++) {
int number = i + 1;
String line = lines[i];
if (match(EMPTY_LINE_PATTERN, line)) continue;
if (match(COMMENT_PATTERN, line, matcher -> {
listener.lineCommented(number, line);
})) continue;
if (match(NODE_PATTERN, line, matcher -> {
String type = matcher.group("type");
String name = matcher.group("name");
switch (type) {
case "ELEMENT":
listener.elementDefined(number, name);
break;
case "EMPTY-ELEMENT":
listener.emptyElementDefined(number, name);
break;
case "BOOLEAN":
listener.booleanDefined(number, name);
break;
case "ONOFF":
listener.onOffDefined(number, name);
break;
case "STRING":
listener.stringDefined(number, name);
break;
}
})) continue;
if (match(ATTRIBUTE_PATTERN, line, matcher -> {
listener.attributeDefined(
number,
matcher.group("element"),
matcher.group("name")
);
})) continue;
listener.invalidLine(number, line);
}
}
private static boolean match(Pattern pattern, String txt) {
return pattern.matcher(txt).matches();
}
private static boolean match(Pattern pattern, String txt, Consumer<Matcher> onMatch) {
Matcher matcher = pattern.matcher(txt);
if (matcher.matches()) {
onMatch.accept(matcher);
return true;
}
return false;
}
}

View File

@@ -1,8 +1,9 @@
package j2html_codegen.generators;
package com.j2html.codegen.generators;
import com.j2html.codegen.GeneratorUtil;
import com.j2html.codegen.model.AttrD;
import com.j2html.codegen.model.AttributesList;
import j2html_codegen.GeneratorUtil;
import j2html_codegen.model.AttrD;
import j2html_codegen.model.AttributesList;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

View File

@@ -1,8 +1,8 @@
package j2html_codegen.generators;
package com.j2html.codegen.generators;
import j2html_codegen.GeneratorUtil;
import j2html_codegen.model.AttributesList;
import com.j2html.codegen.GeneratorUtil;
import com.j2html.codegen.model.AttributesList;
import java.io.IOException;
import java.nio.file.Files;
@@ -13,8 +13,8 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static j2html_codegen.generators.TagCreatorCodeGenerator.containerTags;
import static j2html_codegen.generators.TagCreatorCodeGenerator.emptyTags;
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.containerTags;
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.emptyTags;
public final class SpecializedTagClassCodeGenerator {

View File

@@ -1,4 +1,4 @@
package j2html_codegen.generators;
package com.j2html.codegen.generators;
import java.util.Arrays;
import java.util.List;

View File

@@ -1,11 +1,11 @@
package j2html_codegen.generators;
package com.j2html.codegen.generators;
import com.j2html.codegen.wattsi.AttributeDefinition;
import com.j2html.codegen.wattsi.ElementDefinition;
import com.j2html.codegen.wattsi.WattsiSource;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import j2html_codegen.wattsi.AttributeDefinition;
import j2html_codegen.wattsi.ElementDefinition;
import j2html_codegen.wattsi.WattsiSource;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@@ -64,10 +64,10 @@ public class WattsiGenerator {
}
}
// System.out.println(type.build().toString());
System.out.println(type.build().toString());
}
System.out.println(doc.select("dfn"));
// System.out.println(doc.select("dfn"));
}
private static String methodName(String prefix, String... words){

View File

@@ -1,4 +1,4 @@
package j2html_codegen.model;
package com.j2html.codegen.model;
public final class AttrD {
//attribute descriptor

View File

@@ -1,4 +1,4 @@
package j2html_codegen.model;
package com.j2html.codegen.model;
import java.util.ArrayList;
import java.util.Arrays;

View File

@@ -1,4 +1,4 @@
package j2html_codegen.wattsi;
package com.j2html.codegen.wattsi;
public interface AttributeDefinition {

View File

@@ -1,9 +1,11 @@
package j2html_codegen.wattsi;
package com.j2html.codegen.wattsi;
public interface ElementDefinition {
String name();
boolean isSelfClosing();
boolean isObsolete();
}

View File

@@ -1,4 +1,4 @@
package j2html_codegen.wattsi;
package com.j2html.codegen.wattsi;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -99,6 +99,11 @@ public class WattsiSource {
return Reference.from(dfn.childNodes()).key;
}
@Override
public boolean isSelfClosing() {
return false;
}
@Override
public boolean isObsolete() {
return obsolete.contains(reference());

View File

@@ -1,4 +1,4 @@
package j2html_codegen;
package com.j2html.codegen;
import static org.junit.Assert.assertTrue;

View File

@@ -1,8 +1,8 @@
package j2html_codegen;
package com.j2html.codegen;
import j2html_codegen.generators.TagCreatorCodeGenerator;
import j2html_codegen.wattsi.ElementDefinition;
import j2html_codegen.wattsi.WattsiSource;
import com.j2html.codegen.generators.TagCreatorCodeGenerator;
import com.j2html.codegen.wattsi.ElementDefinition;
import com.j2html.codegen.wattsi.WattsiSource;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.junit.Before;

View File

@@ -0,0 +1,69 @@
package com.j2html.codegen;
import org.junit.Test;
import org.mockito.InOrder;
import java.util.function.Consumer;
import static org.mockito.Mockito.*;
public class ParserTest {
private void verifyParsing(String txt, Consumer<Parser.Listener> checks) {
Parser.Listener listener = mock(Parser.Listener.class);
Parser.parse(txt, listener);
checks.accept(listener);
}
@Test
public void an_empty_input_has_no_events() {
verifyParsing("", listener -> {
verifyNoInteractions(listener);
});
}
@Test
public void whitespace_has_no_events() {
verifyParsing(" \t\t\t\t", listener -> {
verifyNoInteractions(listener);
});
}
@Test
public void commented_lines_are_signaled() {
verifyParsing("#Comment 1.\n# Comment B?", listener -> {
InOrder order = inOrder(listener);
order.verify(listener).lineCommented(1, "#Comment 1.");
order.verify(listener).lineCommented(2, "# Comment B?");
});
}
@Test
public void node_definitions_are_signaled() {
verifyParsing("ELEMENT[a]\nEMPTY-ELEMENT[b]\nBOOLEAN[c]\nONOFF[d]\nSTRING[e]", listener -> {
InOrder order = inOrder(listener);
order.verify(listener).elementDefined(1, "a");
order.verify(listener).emptyElementDefined(2, "b");
order.verify(listener).booleanDefined(3, "c");
order.verify(listener).onOffDefined(4, "d");
order.verify(listener).stringDefined(5, "e");
});
}
@Test
public void attribute_definitions_are_signaled() {
verifyParsing("ATTRIBUTE[a:b]", listener -> {
InOrder order = inOrder(listener);
order.verify(listener).attributeDefined(1, "a", "b");
});
}
@Test
public void invalid_lines_are_signaled() {
verifyParsing("lol, I dunno!\nIt Broke...", listener -> {
InOrder order = inOrder(listener);
order.verify(listener).invalidLine(1, "lol, I dunno!");
order.verify(listener).invalidLine(2, "It Broke...");
});
}
}

View File

@@ -0,0 +1,622 @@
EMPTY-ELEMENT[area]
EMPTY-ELEMENT[base]
EMPTY-ELEMENT[br]
EMPTY-ELEMENT[col]
EMPTY-ELEMENT[embed]
EMPTY-ELEMENT[hr]
EMPTY-ELEMENT[img]
EMPTY-ELEMENT[input]
EMPTY-ELEMENT[keygen]
EMPTY-ELEMENT[link]
EMPTY-ELEMENT[meta]
EMPTY-ELEMENT[param]
EMPTY-ELEMENT[source]
EMPTY-ELEMENT[track]
EMPTY-ELEMENT[wbr]
ELEMENT[a]
ELEMENT[abbr]
ELEMENT[address]
ELEMENT[article]
ELEMENT[aside]
ELEMENT[audio]
ELEMENT[b]
ELEMENT[bdi]
ELEMENT[bdo]
ELEMENT[blockquote]
ELEMENT[body]
ELEMENT[button]
ELEMENT[canvas]
ELEMENT[caption]
ELEMENT[cite]
ELEMENT[code]
ELEMENT[colgroup]
ELEMENT[data]
ELEMENT[datalist]
ELEMENT[dd]
ELEMENT[del]
ELEMENT[details]
ELEMENT[dfn]
ELEMENT[dialog]
ELEMENT[div]
ELEMENT[dl]
ELEMENT[dt]
ELEMENT[em]
ELEMENT[fieldset]
ELEMENT[figcaption]
ELEMENT[figure]
ELEMENT[footer]
ELEMENT[form]
ELEMENT[h1]
ELEMENT[h2]
ELEMENT[h3]
ELEMENT[h4]
ELEMENT[h5]
ELEMENT[h6]
ELEMENT[head]
ELEMENT[header]
ELEMENT[html]
ELEMENT[i]
ELEMENT[iframe]
ELEMENT[ins]
ELEMENT[kbd]
ELEMENT[label]
ELEMENT[legend]
ELEMENT[li]
ELEMENT[main]
ELEMENT[map]
ELEMENT[mark]
ELEMENT[menu]
ELEMENT[menuitem]
ELEMENT[meter]
ELEMENT[nav]
ELEMENT[noscript]
ELEMENT[object]
ELEMENT[ol]
ELEMENT[optgroup]
ELEMENT[option]
ELEMENT[output]
ELEMENT[p]
ELEMENT[picture]
ELEMENT[pre]
ELEMENT[progress]
ELEMENT[q]
ELEMENT[rp]
ELEMENT[rt]
ELEMENT[ruby]
ELEMENT[s]
ELEMENT[samp]
ELEMENT[script]
ELEMENT[section]
ELEMENT[select]
ELEMENT[slot]
ELEMENT[small]
ELEMENT[span]
ELEMENT[strong]
ELEMENT[style]
ELEMENT[sub]
ELEMENT[summary]
ELEMENT[sup]
ELEMENT[table]
ELEMENT[tbody]
ELEMENT[td]
ELEMENT[template]
ELEMENT[textarea]
ELEMENT[tfoot]
ELEMENT[th]
ELEMENT[thead]
ELEMENT[time]
ELEMENT[title]
ELEMENT[tr]
ELEMENT[u]
ELEMENT[ul]
ELEMENT[var]
ELEMENT[video]
STRING[accept]
ATTRIBUTE[input:accept]
STRING[action]
ATTRIBUTE[form:action]
STRING[alt]
ATTRIBUTE[area:alt]
ATTRIBUTE[img:alt]
ATTRIBUTE[input:alt]
BOOLEAN[async]
ATTRIBUTE[script:async]
ONOFF[autocomplete]
ATTRIBUTE[form:autocomplete]
ATTRIBUTE[input:autocomplete]
BOOLEAN[autofocus]
ATTRIBUTE[button:autofocus]
ATTRIBUTE[input:autofocus]
ATTRIBUTE[select:autofocus]
ATTRIBUTE[textarea:autofocus]
BOOLEAN[autoplay]
ATTRIBUTE[audio:autoplay]
ATTRIBUTE[video:autoplay]
STRING[charset]
ATTRIBUTE[meta:charset]
ATTRIBUTE[script:charset]
BOOLEAN[checked]
ATTRIBUTE[input:checked]
STRING[cite]
ATTRIBUTE[blockquote:cite]
ATTRIBUTE[del:cite]
ATTRIBUTE[ins:cite]
ATTRIBUTE[q:cite]
STRING[cols]
ATTRIBUTE[textarea:cols]
STRING[colspan]
ATTRIBUTE[td:colspan]
ATTRIBUTE[th:colspan]
STRING[content]
ATTRIBUTE[meta:content]
BOOLEAN[controls]
ATTRIBUTE[audio:controls]
ATTRIBUTE[video:controls]
STRING[coords]
ATTRIBUTE[area:coords]
STRING[data]
ATTRIBUTE[object:data]
STRING[datetime]
ATTRIBUTE[del:datetime]
ATTRIBUTE[ins:datetime]
ATTRIBUTE[time:datetime]
BOOLEAN[default]
ATTRIBUTE[track:default]
BOOLEAN[defer]
ATTRIBUTE[script:defer]
STRING[dirname]
ATTRIBUTE[input:dirname]
ATTRIBUTE[textarea:dirname]
BOOLEAN[disabled]
ATTRIBUTE[button:disabled]
ATTRIBUTE[fieldset:disabled]
ATTRIBUTE[input:disabled]
ATTRIBUTE[optgroup:disabled]
ATTRIBUTE[option:disabled]
ATTRIBUTE[select:disabled]
ATTRIBUTE[textarea:disabled]
BOOLEAN[download]
ATTRIBUTE[a:download]
ATTRIBUTE[area:download]
STRING[enctype]
ATTRIBUTE[form:enctype]
STRING[for]
ATTRIBUTE[label:for]
ATTRIBUTE[output:for]
STRING[form]
ATTRIBUTE[button:form]
ATTRIBUTE[fieldset:form]
ATTRIBUTE[input:form]
ATTRIBUTE[label:form]
ATTRIBUTE[meter:form]
ATTRIBUTE[object:form]
ATTRIBUTE[output:form]
ATTRIBUTE[select:form]
ATTRIBUTE[textarea:form]
STRING[formaction]
ATTRIBUTE[button:formaction]
ATTRIBUTE[input:formaction]
STRING[headers]
ATTRIBUTE[td:headers]
ATTRIBUTE[th:headers]
STRING[height]
ATTRIBUTE[canvas:height]
ATTRIBUTE[embed:height]
ATTRIBUTE[iframe:height]
ATTRIBUTE[img:height]
ATTRIBUTE[input:height]
ATTRIBUTE[object:height]
ATTRIBUTE[video:height]
STRING[high]
ATTRIBUTE[meter:high]
STRING[href]
ATTRIBUTE[a:href]
ATTRIBUTE[area:href]
ATTRIBUTE[base:href]
ATTRIBUTE[link:href]
STRING[hreflang]
ATTRIBUTE[a:hreflang]
ATTRIBUTE[area:hreflang]
ATTRIBUTE[link:hreflang]
BOOLEAN[ismap]
ATTRIBUTE[img:ismap]
STRING[kind]
ATTRIBUTE[track:kind]
STRING[label]
ATTRIBUTE[track:label]
ATTRIBUTE[option:label]
ATTRIBUTE[optgroup:label]
STRING[list]
ATTRIBUTE[input:list]
BOOLEAN[loop]
ATTRIBUTE[audio:loop]
ATTRIBUTE[video:loop]
STRING[low]
ATTRIBUTE[meter:low]
STRING[max]
ATTRIBUTE[input:max]
ATTRIBUTE[meter:max]
ATTRIBUTE[progress:max]
STRING[maxlength]
ATTRIBUTE[input:maxlength]
ATTRIBUTE[textarea:maxlength]
STRING[media]
ATTRIBUTE[a:media]
ATTRIBUTE[area:media]
ATTRIBUTE[link:media]
ATTRIBUTE[source:media]
ATTRIBUTE[style:media]
STRING[method]
ATTRIBUTE[form:method]
STRING[min]
ATTRIBUTE[input:min]
ATTRIBUTE[meter:min]
BOOLEAN[multiple]
ATTRIBUTE[input:multiple]
ATTRIBUTE[select:multiple]
BOOLEAN[muted]
ATTRIBUTE[video:muted]
ATTRIBUTE[audio:muted]
STRING[name]
ATTRIBUTE[button:name]
ATTRIBUTE[fieldset:name]
ATTRIBUTE[form:name]
ATTRIBUTE[iframe:name]
ATTRIBUTE[input:name]
ATTRIBUTE[map:name]
ATTRIBUTE[meta:name]
ATTRIBUTE[object:name]
ATTRIBUTE[output:name]
ATTRIBUTE[param:name]
ATTRIBUTE[select:name]
ATTRIBUTE[slot:name]
ATTRIBUTE[textarea:name]
BOOLEAN[novalidate]
ATTRIBUTE[form:novalidate]
STRING[onabort]
ATTRIBUTE[audio:onabort]
ATTRIBUTE[embed:onabort]
ATTRIBUTE[img:onabort]
ATTRIBUTE[object:onabort]
ATTRIBUTE[video:onabort]
STRING[onafterprint]
ATTRIBUTE[body:onafterprint]
STRING[onbeforeprint]
ATTRIBUTE[body:onbeforeprint]
STRING[onbeforeunload]
ATTRIBUTE[body:onbeforeunload]
STRING[oncanplay]
ATTRIBUTE[audio:oncanplay]
ATTRIBUTE[embed:oncanplay]
ATTRIBUTE[object:oncanplay]
ATTRIBUTE[video:oncanplay]
STRING[oncanplaythrough]
ATTRIBUTE[audio:oncanplaythrough]
ATTRIBUTE[video:oncanplaythrough]
STRING[oncuechange]
ATTRIBUTE[track:oncuechange]
STRING[ondurationchange]
ATTRIBUTE[audio:ondurationchange]
ATTRIBUTE[video:ondurationchange]
STRING[onemptied]
ATTRIBUTE[audio:onemptied]
ATTRIBUTE[video:onemptied]
STRING[onended]
ATTRIBUTE[audio:onended]
ATTRIBUTE[video:onended]
STRING[onerror]
ATTRIBUTE[audio:onerror]
ATTRIBUTE[body:onerror]
ATTRIBUTE[embed:onerror]
ATTRIBUTE[img:onerror]
ATTRIBUTE[object:onerror]
ATTRIBUTE[script:onerror]
ATTRIBUTE[style:onerror]
ATTRIBUTE[video:onerror]
STRING[onhashchange]
ATTRIBUTE[body:onhashchange]
STRING[onload]
ATTRIBUTE[body:onload]
ATTRIBUTE[iframe:onload]
ATTRIBUTE[img:onload]
ATTRIBUTE[input:onload]
ATTRIBUTE[link:onload]
ATTRIBUTE[script:onload]
ATTRIBUTE[style:onload]
STRING[onloadeddata]
ATTRIBUTE[audio:onloadeddata]
ATTRIBUTE[video:onloadeddata]
STRING[onloadedmetadata]
ATTRIBUTE[audio:onloadedmetadata]
ATTRIBUTE[video:onloadedmetadata]
STRING[onloadstart]
ATTRIBUTE[audio:onloadstart]
ATTRIBUTE[video:onloadstart]
STRING[onoffline]
ATTRIBUTE[body:onoffline]
STRING[ononline]
ATTRIBUTE[body:ononline]
STRING[onpagehide]
ATTRIBUTE[body:onpagehide]
STRING[onpageshow]
ATTRIBUTE[body:onpageshow]
STRING[onpause]
ATTRIBUTE[audio:onpause]
ATTRIBUTE[video:onpause]
STRING[onplay]
ATTRIBUTE[audio:onplay]
ATTRIBUTE[video:onplay]
STRING[onplaying]
ATTRIBUTE[audio:onplaying]
ATTRIBUTE[video:onplaying]
STRING[onpopstate]
ATTRIBUTE[body:onpopstate]
STRING[onprogress]
ATTRIBUTE[audio:onprogress]
ATTRIBUTE[video:onprogress]
STRING[onratechange]
ATTRIBUTE[audio:onratechange]
ATTRIBUTE[video:onratechange]
STRING[onreset]
ATTRIBUTE[form:onreset]
STRING[onresize]
ATTRIBUTE[body:onresize]
STRING[onsearch]
ATTRIBUTE[input:onsearch]
STRING[onseeked]
ATTRIBUTE[audio:onseeked]
ATTRIBUTE[video:onseeked]
STRING[onseeking]
ATTRIBUTE[audio:onseeking]
ATTRIBUTE[video:onseeking]
STRING[onstalled]
ATTRIBUTE[audio:onstalled]
ATTRIBUTE[video:onstalled]
STRING[onstorage]
ATTRIBUTE[body:onstorage]
STRING[onsubmit]
ATTRIBUTE[form:onsubmit]
STRING[onsuspend]
ATTRIBUTE[audio:onsuspend]
ATTRIBUTE[video:onsuspend]
STRING[ontimeupdate]
ATTRIBUTE[audio:ontimeupdate]
ATTRIBUTE[video:ontimeupdate]
STRING[ontoggle]
ATTRIBUTE[details:ontoggle]
STRING[onunload]
ATTRIBUTE[body:onunload]
STRING[onvolumechanged]
ATTRIBUTE[audio:onvolumechanged]
ATTRIBUTE[video:onvolumechanged]
STRING[onwaiting]
ATTRIBUTE[audio:onwaiting]
ATTRIBUTE[video:onwaiting]
BOOLEAN[open]
ATTRIBUTE[details:open]
STRING[optimum]
ATTRIBUTE[meter:optimum]
STRING[pattern]
ATTRIBUTE[input:pattern]
STRING[placeholder]
ATTRIBUTE[input:placeholder]
ATTRIBUTE[textarea:placeholder]
STRING[poster]
ATTRIBUTE[video:poster]
STRING[preload]
ATTRIBUTE[audio:preload]
ATTRIBUTE[video:preload]
BOOLEAN[readonly]
ATTRIBUTE[input:readonly]
ATTRIBUTE[textarea:readonly]
STRING[rel]
ATTRIBUTE[a:rel]
ATTRIBUTE[area:rel]
ATTRIBUTE[form:rel]
ATTRIBUTE[link:rel]
BOOLEAN[required]
ATTRIBUTE[input:required]
ATTRIBUTE[select:required]
ATTRIBUTE[textarea:required]
BOOLEAN[reversed]
ATTRIBUTE[ol:reversed]
STRING[rows]
ATTRIBUTE[textarea:rows]
STRING[rowspan]
ATTRIBUTE[td:rowspan]
ATTRIBUTE[th:rowspan]
BOOLEAN[sandbox]
ATTRIBUTE[iframe:sandbox]
STRING[scope]
ATTRIBUTE[th:scope]
BOOLEAN[selected]
ATTRIBUTE[option:selected]
STRING[shape]
ATTRIBUTE[area:shape]
STRING[size]
ATTRIBUTE[input:size]
ATTRIBUTE[select:size]
STRING[sizes]
ATTRIBUTE[img:sizes]
ATTRIBUTE[link:sizes]
ATTRIBUTE[source:sizes]
STRING[span]
ATTRIBUTE[col:span]
ATTRIBUTE[colgroup:span]
STRING[src]
ATTRIBUTE[audio:src]
ATTRIBUTE[embed:src]
ATTRIBUTE[iframe:src]
ATTRIBUTE[img:src]
ATTRIBUTE[input:src]
ATTRIBUTE[script:src]
ATTRIBUTE[source:src]
ATTRIBUTE[track:src]
ATTRIBUTE[video:src]
STRING[srcdoc]
ATTRIBUTE[iframe:srcdoc]
STRING[srclang]
ATTRIBUTE[track:srclang]
STRING[srcset]
ATTRIBUTE[img:srcset]
ATTRIBUTE[source:srcset]
STRING[start]
ATTRIBUTE[ol:start]
STRING[step]
ATTRIBUTE[input:step]
STRING[target]
ATTRIBUTE[a:target]
ATTRIBUTE[area:target]
ATTRIBUTE[base:target]
ATTRIBUTE[form:target]
STRING[type]
ATTRIBUTE[a:type]
ATTRIBUTE[button:type]
ATTRIBUTE[embed:type]
ATTRIBUTE[input:type]
ATTRIBUTE[link:type]
ATTRIBUTE[menu:type]
ATTRIBUTE[object:type]
ATTRIBUTE[script:type]
ATTRIBUTE[source:type]
ATTRIBUTE[style:type]
STRING[usemap]
ATTRIBUTE[img:usemap]
ATTRIBUTE[object:usemap]
STRING[value]
ATTRIBUTE[button:value]
ATTRIBUTE[data:value]
ATTRIBUTE[input:value]
ATTRIBUTE[li:value]
ATTRIBUTE[option:value]
ATTRIBUTE[meter:value]
ATTRIBUTE[progress:value]
ATTRIBUTE[param:value]
STRING[width]
ATTRIBUTE[canvas:width]
ATTRIBUTE[embed:width]
ATTRIBUTE[iframe:width]
ATTRIBUTE[img:width]
ATTRIBUTE[input:width]
ATTRIBUTE[object:width]
ATTRIBUTE[video:width]
STRING[wrap]
ATTRIBUTE[textarea:wrap]

View File

@@ -3,9 +3,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>j2html-webpage</groupId>
<artifactId>j2html-webpage</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>com.j2html</groupId>
<artifactId>j2html-parent</artifactId>
<version>1.6.1-SNAPSHOT</version>
</parent>
<artifactId>j2html-website</artifactId>
<dependencies>
<dependency>
@@ -13,11 +17,13 @@
<artifactId>javalin</artifactId>
<version>4.0.0.ALPHA2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
@@ -27,12 +33,17 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>j2html-webpage</finalName>
<finalName>j2html-website</finalName>
<archive>
<manifest>
<addClasspath>true</addClasspath>
@@ -42,15 +53,7 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
@@ -73,6 +76,7 @@
</archive>
</configuration>
</plugin>
</plugins>
</build>

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 240 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,88 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
<groupId>com.j2html</groupId>
<artifactId>j2html-parent</artifactId>
<version>1.6.1-SNAPSHOT</version>
</parent>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>1.6.1-SNAPSHOT</version>
<name>j2html</name>
<description>Java to HTML builder with a fluent API</description>
<url>http://j2html.com</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:git@github.com:tipsy/j2html.git</connection>
<developerConnection>scm:git:git@github.com:tipsy/j2html.git</developerConnection>
<url>https://github.com/tipsy/j2html.git</url>
<tag>HEAD</tag>
</scm>
<developers>
<developer>
<name>David Åse</name>
</developer>
</developers>
<issueManagement>
<system>GitHub Issue Tracker</system>
<url>https://github.com/tipsy/j2html/issues</url>
</issueManagement>
<artifactId>j2html</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.carrotsearch</groupId>
<artifactId>junit-benchmarks</artifactId>
<version>0.7.2</version>
<scope>test</scope>
</dependency>
<!-- performance test dependencies -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>com.j2html</groupId>
<artifactId>j2html-codegen-maven-plugin</artifactId>
<version>1.6.1-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>generate-source-files</goal>
</goals>
</execution>
</executions>
<configuration>
<modelFile>${project.basedir}/src/main/models/html.model</modelFile>
<attributePackage>j2html.tags.attributes</attributePackage>
<tagPackage>j2html.tags.specialized</tagPackage>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<executions>
<execution>
<id>default</id>
@@ -90,55 +81,25 @@
<goal>perform</goal>
</goals>
<configuration>
<pomFileName>library/pom.xml</pomFileName>
<pomFileName>pom.xml</pomFileName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<optimize>true</optimize>
<compilerArgs>
<arg>-Xlint:all</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.8,)</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.0</version>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
@@ -151,10 +112,10 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.6</version>
<executions>
<execution>
<id>bundle-manifest</id>
@@ -165,17 +126,10 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.revapi</groupId>
<artifactId>revapi-maven-plugin</artifactId>
<version>0.14.6</version>
<dependencies>
<dependency>
<groupId>org.revapi</groupId>
<artifactId>revapi-java</artifactId>
<version>0.26.1</version>
</dependency>
</dependencies>
<configuration>
<oldArtifacts>
<artifact>com.j2html:j2html:1.6.0</artifact>
@@ -188,7 +142,7 @@
<code>java.class.removed</code>
<old>class j2html.tags.specialized.GenerateTag</old>
<justification>
This class should never have been used. It was introduced
This class should never have been used. It was introduced
accidentally by find+replace in the code generator class.
</justification>
</item>
@@ -196,44 +150,7 @@
</revapi.differences>
</analysisConfiguration>
</configuration>
<executions>
<execution>
<id>check</id>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<activation>
<property>
<name>sign</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

Some files were not shown because too many files have changed in this diff Show More