Split j2html in 2 projects, "code_gen" and "library" (Issue #161) (#165)

* split the project in 2, to make it easier to iterate on the code generation without breaking the build. This could also help reduce the compiled size of the library.

* update CONTRIBUTING.md

* try to fix github workflow
This commit is contained in:
pointbazaar
2020-10-17 10:23:57 +02:00
committed by GitHub
parent 07427c1433
commit acf6bff72a
310 changed files with 491 additions and 236 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
text eol=crlf

View File

@@ -23,6 +23,6 @@ jobs:
if: contains(matrix.os, 'win') == false
run: chmod +x ./mvnw
- name: Build with Maven
run: ./mvnw package --file pom.xml --batch-mode
run: ./mvnw package --file library/pom.xml --batch-mode
env:
MAVEN_OPTS: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn

90
.gitignore vendored
View File

@@ -1,99 +1,9 @@
# Created by https://www.gitignore.io
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
### Eclipse ###
.classpath
.project

View File

@@ -24,6 +24,8 @@ This means that if you're on Linux ```'\n'```, you have to configure git to hand
correctly so that you have the correct EOL in your working directory,
and the EOL is also correct in the repository itself.
For this purpose, j2html has a ```.gitattributes``` file.
[Guide to configuring EOL with git](https://docs.github.com/en/github/using-git/configuring-git-to-handle-line-endings)
If you are on Windows, there should be no Problems.
@@ -31,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 are 3 ```public static void main(...)``` Methods that generate Code.
there is the ```code_gen/``` directory which contains everything needed to generate the code.
For simplicity (and also to avoid extra dependencies), they do not format the code correctly.
@@ -47,10 +49,9 @@ The workflow (most of the time) consists of:
- Open a PR
- Adjust the PR until it is merged or discarded
## Project Architecture
### src/main/java/j2html/TagCreator.java
### library/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.
@@ -79,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 ```src/main/java/j2html/tags/specialized/``` and follow the naming convention ```tag_name + 'Tag.java'```, e.g. ```BodyTag.java```.
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```.
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 +129,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 ```j2html/src/main/java/j2html/tags/generators/```:
There are 3 classes which contain code-generating methods in ```code_gen/src/main/java/j2html_codegen/generators/```:
- AttributeInterfaceCodeGenerator.java (generating the interfaces for the attributes)
- SpecializedTagClassCodeGenerator.java (generating the classes for the tags)
@@ -150,7 +151,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**.
```j2html/src/main/java/j2html/tags/generators/AttributesList.java``` contains the different Attributes, their properties,
```library/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.

101
code_gen/.gitignore vendored Normal file
View File

@@ -0,0 +1,101 @@
# Created by https://www.gitignore.io
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
### Eclipse ###
.classpath
.project
.settings/
buildNumber.properties

74
code_gen/pom.xml Normal file
View File

@@ -0,0 +1,74 @@
<?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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</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.1.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.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.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>

View File

@@ -0,0 +1,33 @@
package j2html_codegen;
import j2html_codegen.generators.AttributeInterfaceCodeGenerator;
import j2html_codegen.generators.SpecializedTagClassCodeGenerator;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
public final class App
{
public static void main( String[] args )
{
final Path relPath = Paths.get("../library/src/main/java/j2html/");
final Path absPath = relPath.toAbsolutePath();
System.out.println("writing in "+absPath);
//decide if the files should be
//deleted or generated
final boolean delete = false;
try {
AttributeInterfaceCodeGenerator.generate(absPath, delete);
SpecializedTagClassCodeGenerator.generate(absPath, delete);
//TagCreatorCodeGenerator.print();
} catch (IOException e) {
e.printStackTrace();
}
//don't forget to auto-reformat the generated code.
}
}

View File

@@ -1,5 +1,9 @@
package j2html.tags.generators;
package j2html_codegen.generators;
import j2html_codegen.model.AttrD;
import j2html_codegen.model.AttributesList;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -9,14 +13,11 @@ import java.util.Optional;
public final class AttributeInterfaceCodeGenerator {
public static void main(String[] args){
try {
final boolean delete = false;
public static void generate(final Path absPath, final boolean delete) throws IOException {
for (final AttrD attr : AttributesList.attributesDescriptive()) {
final Path path = makePath(attr.attr);
final Path path = makePath(attr.attr, absPath);
final String interfaceName = interfaceNameFromAttribute(attr.attr)+"<T extends Tag>";
/*
IFormAction<T extends Tag> extends IInstance<T>
@@ -25,7 +26,6 @@ public final class AttributeInterfaceCodeGenerator {
return get();
}
*/
final String interfaceStr = getInterfaceTemplate(
interfaceName,
Optional.of("IInstance<T>"),
@@ -35,12 +35,16 @@ public final class AttributeInterfaceCodeGenerator {
);
if (delete) {
if(Files.exists(path)) {
System.out.println("deleting " + path);
Files.delete(path);
}
}else{
System.out.println("writing to "+path);
Files.write(path, interfaceStr.getBytes());
}
}
}catch (Exception ignored){}
}
private static String getPackage(){
@@ -178,9 +182,9 @@ public final class AttributeInterfaceCodeGenerator {
return "I" + res;
}
private static Path makePath(String tagLowerCase){
private static Path makePath(String tagLowerCase, final Path absPath){
final String filename = interfaceNameFromAttribute(tagLowerCase)+".java";
return Paths.get("src/main/java/j2html/tags/attributes/"+filename);
return Paths.get(absPath.toString(),"tags/attributes/",filename);
}
}

View File

@@ -1,6 +1,8 @@
package j2html.tags.generators;
package j2html_codegen.generators;
import j2html_codegen.model.AttributesList;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -10,26 +12,91 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static j2html.tags.generators.TagCreatorCodeGenerator.containerTags;
import static j2html.tags.generators.TagCreatorCodeGenerator.emptyTags;
import static j2html_codegen.generators.TagCreatorCodeGenerator.containerTags;
import static j2html_codegen.generators.TagCreatorCodeGenerator.emptyTags;
class SpecializedTagClassCodeGenerator {
public final class SpecializedTagClassCodeGenerator {
public static void generate(final Path absPath, final boolean delete) throws IOException {
public static void main(String[] args) {
try{
//the delete argument serves to give the possibility
//to delete the classes that were written before
mainInner(false);
}catch (Exception ignored){}
System.out.println("// EmptyTags, generated in " + SpecializedTagClassCodeGenerator.class);
for (final String tag : emptyTags()) {
final String className = classNameFromTag(tag);
final Path path = makePath(absPath,tag);
final List<String> interfaceNames = getInterfaceNamesForTag(tag);
final String classString =
getClassTemplate(
className,
Optional.of("EmptyTag<"+className+">"),
Arrays.asList(
"j2html.tags.EmptyTag",
"j2html.tags.attributes.*"
),
tag,
interfaceNames
);
/*
public InputTag() {
super("input");
}
*/
if(delete){
if(Files.exists(path)) {
System.out.println("deleting " + path);
Files.delete(path);
}
}else {
System.out.println("writing to "+path);
Files.write(path, classString.getBytes());
}
}
System.out.println("// ContainerTags, generated in " + SpecializedTagClassCodeGenerator.class);
for (final String tag : containerTags()) {
final Path path = makePath(absPath, tag);
final String className = classNameFromTag(tag);
final List<String> interfaceNames = getInterfaceNamesForTag(tag);
final String classString =
getClassTemplate(
className,
Optional.of("ContainerTag<"+className+">"),
Arrays.asList(
"j2html.tags.ContainerTag",
"j2html.tags.attributes.*"
),
tag,
interfaceNames
);
if(delete){
if(Files.exists(path)) {
System.out.println("deleting " + path);
Files.delete(path);
}
}else {
System.out.println("writing to "+path);
Files.write(path, classString.getBytes());
}
}
}
public static String classNameFromTag(String tageNameLowerCase){
String res = tageNameLowerCase.substring(0,1).toUpperCase()+tageNameLowerCase.substring(1);
return res + "Tag";
}
private static Path makePath(String tagLowerCase){
private static Path makePath(final Path absPath, String tagLowerCase){
final String filename = classNameFromTag(tagLowerCase)+".java";
return Paths.get("src/main/java/j2html/tags/specialized/"+filename);
return Paths.get(absPath.toString(),"tags/specialized/",filename);
}
private static String getPackage(){
@@ -97,65 +164,4 @@ class SpecializedTagClassCodeGenerator {
).collect(Collectors.toList());
}
public static void mainInner(final boolean delete) throws IOException {
System.out.println("// EmptyTags, generated in " + SpecializedTagClassCodeGenerator.class);
for (final String tag : emptyTags()) {
final String className = classNameFromTag(tag);
final Path path = makePath(tag);
final List<String> interfaceNames = getInterfaceNamesForTag(tag);
final String classString =
getClassTemplate(
className,
Optional.of("EmptyTag<"+className+">"),
Arrays.asList(
"j2html.tags.EmptyTag",
"j2html.tags.attributes.*"
),
tag,
interfaceNames
);
/*
public InputTag() {
super("input");
}
*/
if(delete){
Files.delete(path);
}else {
Files.write(path, classString.getBytes());
}
}
System.out.println("// ContainerTags, generated in " + SpecializedTagClassCodeGenerator.class);
for (final String tag : containerTags()) {
final Path path = makePath(tag);
final String className = classNameFromTag(tag);
final List<String> interfaceNames = getInterfaceNamesForTag(tag);
final String classString =
getClassTemplate(
className,
Optional.of("ContainerTag<"+className+">"),
Arrays.asList(
"j2html.tags.ContainerTag",
"j2html.tags.attributes.*"
),
tag,
interfaceNames
);
if(delete){
Files.delete(path);
}else {
Files.write(path, classString.getBytes());
}
}
}
}

View File

@@ -1,11 +1,11 @@
package j2html.tags.generators;
package j2html_codegen.generators;
import java.util.Arrays;
import java.util.List;
class TagCreatorCodeGenerator {
public final class TagCreatorCodeGenerator {
public static void main(String[] args) {
public static void print() {
System.out.println("// EmptyTags, generated in " + TagCreatorCodeGenerator.class);
@@ -134,7 +134,7 @@ class TagCreatorCodeGenerator {
"label",
"legend",
"li",
"main",
"generate",
"map",
"mark",
"menu",

View File

@@ -1,6 +1,6 @@
package j2html.tags.generators;
package j2html_codegen.model;
final class AttrD {
public final class AttrD {
//attribute descriptor
public final String attr;

View File

@@ -1,15 +1,14 @@
package j2html.tags.generators;
package j2html_codegen.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public final class AttributesList {
//https://www.w3schools.com/tags/ref_attributes.asp
static List<String> getCustomAttributesForHtmlTag(final String tagLowercase){
public static List<String> getCustomAttributesForHtmlTag(final String tagLowercase){
final List<String> attrs = new ArrayList<>();
for(AttrD attrD : attributesDescriptive()){
@@ -22,7 +21,7 @@ public final class AttributesList {
return attrs;
}
static List<AttrD> attributesDescriptive() {
public static List<AttrD> attributesDescriptive() {
return Arrays.asList(
new AttrD("accept", true, "input"),
//new AttrD("accept-charset","form"), //contains dashes, TODO

View File

@@ -0,0 +1,16 @@
package j2html_codegen;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class AppTest
{
@Test
public void shouldAnswerWithTrue()
{
//dummy, just to conform to the default mvn
//directory layout
assertTrue( true );
}
}

101
library/.gitignore vendored Normal file
View File

@@ -0,0 +1,101 @@
# Created by https://www.gitignore.io
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
### Eclipse ###
.classpath
.project
.settings/
buildNumber.properties

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