Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
fmcarvalho committed Dec 16, 2019
2 parents c5deb21 + 063e20f commit c991f3e
Show file tree
Hide file tree
Showing 14 changed files with 1,060 additions and 24 deletions.
29 changes: 24 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,23 @@ Check out the performance results in the most popular benchmarks at
[spring-comparing-template-engines](https://github.com/jreijn/spring-comparing-template-engines)
and our fork of
[xmlet/template-benchmark](https://github.com/xmlet/template-benchmark).
You can find more comparison details in DZone article about [Modern Type-Safe
Template Engines](https://dzone.com/articles/modern-type-safe-template-engines).

Since the release 3.4 you can also automatically translate an HTML source to the corresponding HtmlFlow definition through
the [`Flowifier`](src/main/java/htmlflow/flowifier/Flowifier.java) utility methods, such as **`Flowifier.fromHtml(html)`**,
which produces the above HtmlFlow sample given the following `html` variable:
`String html = <html><head><title>HtmlFlow</title></head><body><div class="container"><h1>My first page with HtmlFlow</h1><img src="https://avatars1.githubusercontent.com/u/35267172"><p>Typesafe is awesome! :-)</p></div></body></html>`.


## References

* 2019, [HoT: Unleash Web Views with Higher-order Templates](https://scholar.google.com/scholar?cluster=972807510162637933),
[15th WebIst](http://www.webist.org/?y=2019) conference, 2019, Viena - This paper highlights
the compositional nature of HtmlFlow to compose templates through higher-order functions.
* 2018, [Domain Specific Language generation based on a XML
Schema](https://www.slideshare.net/LuisDuarte105/domain-specific-language-generation-based-on-a-xml-schema) - Slides
of the MsC thesis presentation of Luís Duarte.
* 2018, [Modern Type-Safe Template Engines](https://dzone.com/articles/modern-type-safe-template-engines) - You can find
more details in this DZone article about performance comparison.

[Get started](#getting-started) or check out some more examples regarding [_dynamic views_](#dynamic-views)
built with the support of `htmlflow.DynamicHtml`.
Expand Down Expand Up @@ -256,6 +271,10 @@ Check out one of our use cases of partial views in the template function
## Changelog


### 3.4 (December, 2019)

First release of _Flowifier_ an HTML to HtmlFlow translator, developed by Julien Gouesse. [Issue 43](https://github.com/xmlet/HtmlFlow/issues/43)

### 3.3 (August, 2019)

* Upgrade to Java 11.
Expand Down Expand Up @@ -325,8 +344,8 @@ and add it as child of that `HtmlView`.
* All these features together with the existing `º()` make possible to build a view in a single
pass, reducing the number of auxiliary variables capturing intermediate elements.
Now all the views of the examples of this `README.md` are built in static fields assignment.
More usage examples in [HtmlTables](src/test/java/htmlflow/test/HtmlTables.java) and
[HtmlLists](src/test/java/htmlflow/test/HtmlLists.java).
More usage examples in [HtmlTables](src/test/java/htmlflow/test/views/HtmlTables.java) and
[HtmlLists](src/test/java/htmlflow/test/views/HtmlLists.java).

### 2.0 (March, 2018)

Expand Down Expand Up @@ -403,4 +422,4 @@ HtmlFlow was created by [Miguel Gamboa](http://gamboa.pt/) (aka
[Computer Science and
Engineering](https://www.isel.pt/en/courses/bsc-degree/computer-science-and-engineering)
of [ISEL](https://www.isel.pt/en/), [Polytechnic Institute of
Lisbon](https://www.ipl.pt/en).
Lisbon](https://www.ipl.pt/en).
26 changes: 21 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,31 @@
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<argLine>-Xss16m</argLine>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<property>
<name>java.util.logging.config.file</name>
<value>src/test/resources/logging.properties</value>
</property>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
<version>2.5.2</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
Expand Down Expand Up @@ -110,7 +121,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<version>3.1.1</version>
<configuration>
<additionalOptions>
<additionalOption>-Xdoclint:none</additionalOption>
</additionalOptions>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
Expand All @@ -123,7 +139,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</version>
<version>0.8.4</version>
<executions>
<execution>
<id>default-prepare-agent</id>
Expand Down Expand Up @@ -167,4 +183,4 @@
</plugin>
</plugins>
</build>
</project>
</project>
7 changes: 7 additions & 0 deletions src/main/java/htmlflow/HtmlView.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ public abstract class HtmlView<T> implements HtmlWriter<T>, Element<HtmlView, El
}

private final HtmlVisitorCache visitor;
/**
* This issue is regarding ThreadLocal variables that are supposed to be garbage collected.
* The given example deals with a static field of ThreadLocal which persists beyond an instance.
* In this case the ThreadLocal is hold in an instance field and should stay with all
* thread local instances during its entire life cycle.
*/
@java.lang.SuppressWarnings("squid:S5164")
private final ThreadLocal<HtmlVisitorCache> threadLocalVisitor;
private final Supplier<HtmlVisitorCache> visitorSupplier;
private final boolean threadSafe;
Expand Down
27 changes: 21 additions & 6 deletions src/main/java/htmlflow/HtmlVisitorCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,22 @@

package htmlflow;

import org.xmlet.htmlapifaster.*;
import org.xmlet.htmlapifaster.Area;
import org.xmlet.htmlapifaster.Base;
import org.xmlet.htmlapifaster.Br;
import org.xmlet.htmlapifaster.Col;
import org.xmlet.htmlapifaster.Element;
import org.xmlet.htmlapifaster.ElementVisitor;
import org.xmlet.htmlapifaster.Embed;
import org.xmlet.htmlapifaster.Hr;
import org.xmlet.htmlapifaster.Img;
import org.xmlet.htmlapifaster.Input;
import org.xmlet.htmlapifaster.Link;
import org.xmlet.htmlapifaster.Meta;
import org.xmlet.htmlapifaster.Param;
import org.xmlet.htmlapifaster.Root;
import org.xmlet.htmlapifaster.Source;
import org.xmlet.htmlapifaster.Text;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -65,7 +80,7 @@ public abstract class HtmlVisitorCache extends ElementVisitor {
/**
* A cache list of static html blocks.
*/
private final List<HtmlVisitorStringBuilder.HtmlBlockInfo> cacheBlocksList = new ArrayList<>();
private final List<HtmlBlockInfo> cacheBlocksList = new ArrayList<>();
/**
* The current index in cacheBlocksList corresponding to a static HTML block.
*/
Expand Down Expand Up @@ -172,14 +187,14 @@ public final void visitOpenDynamic(){

openDynamic = true;
if (isCached){
HtmlVisitorStringBuilder.HtmlBlockInfo block = cacheBlocksList.get(cacheIndex);
HtmlBlockInfo block = cacheBlocksList.get(cacheIndex);
this.write(block.html);
this.depth = block.currentDepth;
this.isClosed = block.isClosed;
++cacheIndex;
} else {
String staticBlock = substring(staticBlockIndex);
cacheBlocksList.add(new HtmlVisitorStringBuilder.HtmlBlockInfo(staticBlock, depth, isClosed));
cacheBlocksList.add(new HtmlBlockInfo(staticBlock, depth, isClosed));
}
}

Expand Down Expand Up @@ -240,15 +255,15 @@ final void closeBeginTag() {

final String finished(){
if (isCached && cacheIndex <= cacheBlocksList.size()){
HtmlVisitorStringBuilder.HtmlBlockInfo block = cacheBlocksList.get(cacheIndex);
HtmlBlockInfo block = cacheBlocksList.get(cacheIndex);
write(block.html);
isClosed = block.isClosed;
depth = block.currentDepth;
}

if (!isCached){
String staticBlock = substring(staticBlockIndex);
cacheBlocksList.add(new HtmlVisitorStringBuilder.HtmlBlockInfo(staticBlock, depth, isClosed));
cacheBlocksList.add(new HtmlBlockInfo(staticBlock, depth, isClosed));
isCached = true;
}

Expand Down
Loading

0 comments on commit c991f3e

Please sign in to comment.