Compare commits

..

18 commits

Author SHA1 Message Date
ba0b5b2e9c
1.2.1-SNAPSHOT 2025-02-25 09:39:08 -08:00
013218f399
Bump bld to version 2.2.1 2025-02-25 09:38:36 -08:00
68d88ea7d3
Bump AssertJ to version 3.27.3 2025-02-25 09:37:49 -08:00
10ea21245b
Bump JUnit to version 5.12.0 2025-02-25 09:37:02 -08:00
9c14794ee8
Version 1.2.0 2025-01-14 12:50:49 -08:00
8383f75ad9
Bumped bld to version 2.2.0 2025-01-14 12:50:32 -08:00
b0f9c5a4ed
Bumped RIFE2 to version 1.9.1 2025-01-14 12:49:24 -08:00
b10826481e
Bumped JUnit to version 5.11.4 2025-01-14 12:48:54 -08:00
2c842bdb6a
Bumped AssertJ to version 3.27.2 2025-01-14 12:47:49 -08:00
a1ab01a7fc
Bumped PMD extension to version 1.1.0 2025-01-14 12:46:09 -08:00
4731afb83b
Bumped Jacoco extension to version 0.9.9 2025-01-14 12:45:47 -08:00
6dc23012cc
1.2.0 SNAPSHOT 2024-11-15 11:48:01 -08:00
99f6afe4fb
Added capitalizeWords renderer 2024-11-15 11:47:40 -08:00
daadd0bc4a
Added missing and cleaned up JavaDocs 2024-10-29 22:59:27 -07:00
97edc07160
Updated dependencies
Bumped JDK to version 23 (GitHub CI Workflow)
Bumped PMD extensions to version 1.1.7
Bumped JUnit to version 5.11.3
2024-10-29 22:39:52 -07:00
911d54c10b
Minor cleanups 2024-09-04 23:47:12 -07:00
5090b8224c
Added soft assertions 2024-09-04 23:46:13 -07:00
5cfb6fa5f8
Bumped bld to version 2.1.0 2024-09-04 23:45:51 -07:00
48 changed files with 377 additions and 84 deletions

View file

@ -1,6 +1,6 @@
name: bld-ci name: bld-ci
on: [ push, pull_request, workflow_dispatch ] on: [push, pull_request, workflow_dispatch]
jobs: jobs:
build-bld-project: build-bld-project:
@ -8,7 +8,7 @@ jobs:
strategy: strategy:
matrix: matrix:
java-version: [ 17, 21, 22 ] java-version: [17, 21, 23]
steps: steps:
- name: Checkout source repository - name: Checkout source repository

View file

@ -47,11 +47,11 @@ jobs:
uses: actions/configure-pages@v3 uses: actions/configure-pages@v3
- name: Upload artifact - name: Upload artifact
uses: actions/upload-pages-artifact@v1 uses: actions/upload-pages-artifact@v3
with: with:
# Upload generated Javadocs repository # Upload generated Javadocs repository
path: "build/javadoc/" path: "build/javadoc/"
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@v1 uses: actions/deploy-pages@v4

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
</state>
</component>

12
.idea/icon.svg generated Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with Vectornator (http://vectornator.io/) -->
<svg height="100%" stroke-miterlimit="10" style="fill-rule:nonzero;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;" version="1.1" viewBox="0 0 50 50" width="100%" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs/>
<g id="Untitled">
<g opacity="1">
<path d="M31.9421 4.99551C26.8094 7.90585 24.7641 12.0654 24.2025 17.855C23.7876 22.1321 27.3936 27.0983 27.5933 29.9084C27.8096 32.9493 26.063 35.2557 22.623 35.8686C20.4949 36.2477 17.8742 36.0139 14.6092 33.2624C14.6678 38.0258 16.7542 42.433 21.5076 44.1302C26.4211 45.8835 31.2671 44.9143 34.6016 41.9865C39.1593 38.2111 40.2692 32.4953 36.786 26.6511C33.0398 20.3619 29.6701 15.5562 31.9421 4.99551" fill="#fa9052" fill-rule="nonzero" opacity="1" stroke="none"/>
<path d="M17.349 14.5478C17.3497 14.5395 17.349 14.5478 17.349 14.5478C17.1626 14.8365 16.9754 15.1245 16.7869 15.4119C15.8906 16.7783 14.949 18.1004 13.9706 19.4087C12.6688 21.1498 10.9828 23.3556 11.1816 25.6096C11.3531 26.7195 12.0143 27.6556 12.9129 28.3061C13.6009 28.7369 14.38 28.9871 15.1883 29.0868C16.1147 29.2013 17.0209 29.1429 17.9083 28.834C19.257 28.1671 19.8037 27.4604 20.0005 26.4317C20.0649 26.1834 20.0437 25.8312 20.0437 25.8312C20.0343 25.73 20.0272 25.6537 20.0152 25.5528C19.9908 25.3475 19.9566 25.1434 19.9147 24.9411C19.8678 24.7142 19.8113 24.4896 19.7476 24.2671C19.7361 24.2271 19.6483 23.9399 19.6927 24.0786C19.6573 23.9677 19.6198 23.8574 19.5812 23.7477C19.4341 23.3294 19.2669 22.9183 19.0904 22.5114C19.0904 22.5114 18.2023 20.4746 17.8867 19.4599C17.3927 17.8737 17.1809 16.2048 17.349 14.5478Z" fill="#2392ff" fill-rule="nonzero" opacity="1" stroke="none"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -2,12 +2,12 @@
<library name="bld"> <library name="bld">
<CLASSES> <CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" /> <root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.0.1.jar!/" /> <root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/bld" /> <root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.0.1-sources.jar!/" /> <root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES> </SOURCES>
<excluded> <excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" /> <root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />

View file

@ -7,7 +7,7 @@
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" /> <root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES> </SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library> </library>
</component> </component>

View file

@ -7,7 +7,7 @@
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" /> <root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES> </SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library> </library>
</component> </component>

View file

@ -7,7 +7,7 @@
<SOURCES> <SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" /> <root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES> </SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" /> <jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" type="SOURCES" /> <jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library> </library>
</component> </component>

1
.idea/misc.xml generated
View file

@ -3,6 +3,7 @@
<component name="EntryPointsManager"> <component name="EntryPointsManager">
<pattern value="rife.render.TemplateRenderersBuild" method="jacoco" /> <pattern value="rife.render.TemplateRenderersBuild" method="jacoco" />
<pattern value="rife.render.TemplateRenderersBuild" method="pmd" /> <pattern value="rife.render.TemplateRenderersBuild" method="pmd" />
<pattern value="rife.render.ValueBean" method="setValue" />
</component> </component>
<component name="PDMPlugin"> <component name="PDMPlugin">
<option name="customRuleSets"> <option name="customRuleSets">

View file

@ -9,7 +9,7 @@
], ],
"java.configuration.updateBuildConfiguration": "automatic", "java.configuration.updateBuildConfiguration": "automatic",
"java.project.referencedLibraries": [ "java.project.referencedLibraries": [
"${HOME}/.bld/dist/bld-2.0.1.jar", "${HOME}/.bld/dist/bld-2.2.1.jar",
"lib/**/*.jar" "lib/**/*.jar"
] ]
} }

View file

@ -1,6 +1,6 @@
[![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
[![bld](https://img.shields.io/badge/2.0.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/rife2/rife2-template-renderers)](https://github.com/rife2/rife2-template-renderers/releases/latest) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/rife2/rife2-template-renderers)](https://github.com/rife2/rife2-template-renderers/releases/latest)
[![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/rife2-renderers/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/rife2-renderers) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/rife2-renderers/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/rife2-renderers)
[![Maven Central](https://img.shields.io/maven-central/v/com.uwyn.rife2/rife2-renderers)](https://central.sonatype.com/artifact/com.uwyn.rife2/rife2-renderers/) [![Maven Central](https://img.shields.io/maven-central/v/com.uwyn.rife2/rife2-renderers)](https://central.sonatype.com/artifact/com.uwyn.rife2/rife2-renderers/)
@ -52,15 +52,16 @@ This project provides a collection of useful template renderers.
## Text Renderers ## Text Renderers
| Renderer | Description | | Renderer | Description |
|:------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------| |:------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------|
| [rife.render.Capitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Capitalize) | Capitalizes a template value | | [rife.render.Capitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Capitalize) | Capitalizes a template value |
| [rife.render.CapitalizeWords](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.CapitalizeWords) | Capitalizes words of a template value |
| [rife.render.Lowercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Lowercase) | Converts a template value to lowercase | | [rife.render.Lowercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Lowercase) | Converts a template value to lowercase |
| [rife.render.Rot13](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Rot13) | Translates a template value to/from ROT13 | | [rife.render.Rot13](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Rot13) | Translates a template value to/from ROT13 |
| [rife.render.SwapCase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.SwapCase) | Swap case of a template value | | [rife.render.SwapCase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.SwapCase) | Swaps case of a template value |
| [rife.render.Trim](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Trim) | Removes leading and trailing whitespace from a template value | | [rife.render.Trim](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Trim) | Removes leading and trailing whitespace from a template value |
| [rife.render.Uncapitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uncapitalize) | Uncapitalizes a template value | | [rife.render.Uncapitalize](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uncapitalize) | Uncapitalizes a template value |
| [rife.render.Uppercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uppercase) | Converts a template value to uppercase | | [rife.render.Uppercase](https://github.com/rife2/rife2-template-renderers/wiki/rife.render.Uppercase) | Converts a template value to uppercase |
## Documentation ## Documentation
Read more in the [documenation](https://github.com/rife2/rife2-template-renderers/wiki). Read more in the [documentation](https://github.com/rife2/rife2-template-renderers/wiki).

View file

@ -7,9 +7,9 @@
<!-- BEST PRACTICES --> <!-- BEST PRACTICES -->
<rule ref="category/java/bestpractices.xml"> <rule ref="category/java/bestpractices.xml">
<exclude name="AvoidPrintStackTrace"/> <exclude name="AvoidPrintStackTrace"/>
<exclude name="JUnit4TestShouldUseTestAnnotation"/>
<exclude name="JUnitTestContainsTooManyAsserts"/>
<exclude name="GuardLogStatement"/> <exclude name="GuardLogStatement"/>
<exclude name="UnitTestContainsTooManyAsserts"/>
<exclude name="UnitTestShouldUseTestAnnotation"/>
</rule> </rule>
<rule ref="category/java/bestpractices.xml/MissingOverride"> <rule ref="category/java/bestpractices.xml/MissingOverride">

Binary file not shown.

View file

@ -1,8 +1,8 @@
bld.downloadExtensionJavadoc=false bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true bld.downloadExtensionSources=true
bld.downloadLocation= bld.downloadLocation=
bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.7 bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.9
bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.1.4 bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.2.0
bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.4.6 bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.4.6
bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
bld.version=2.0.1 bld.version=2.2.1

View file

@ -40,7 +40,7 @@ public class TemplateRenderersBuild extends Project {
public TemplateRenderersBuild() { public TemplateRenderersBuild() {
pkg = "rife.render"; pkg = "rife.render";
name = "rife2-template-renderers"; name = "rife2-template-renderers";
version = version(1, 1, 6); version = version(1, 2, 1, "SNAPSHOT");
javaRelease = 17; javaRelease = 17;
downloadSources = true; downloadSources = true;
@ -48,11 +48,11 @@ public class TemplateRenderersBuild extends Project {
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES); repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
scope(compile) scope(compile)
.include(dependency("com.uwyn.rife2", "rife2", version(1, 8, 0))); .include(dependency("com.uwyn.rife2", "rife2", version(1, 9, 1)));
scope(test) scope(test)
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3))) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 0)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3))) .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 0)))
.include(dependency("org.assertj", "assertj-core", version(3, 26, 3))); .include(dependency("org.assertj", "assertj-core", version(3, 27, 3)));
javadocOperation().javadocOptions() javadocOperation().javadocOptions()
.docTitle("<a href=\"https://rife2.com\">RIFE2</a> Template Renderers") .docTitle("<a href=\"https://rife2.com\">RIFE2</a> Template Renderers")
@ -75,13 +75,21 @@ public class TemplateRenderersBuild extends Project {
.name("RIFE2 Template Renderers") .name("RIFE2 Template Renderers")
.description("Template Renderers for the RIFE2 web framework") .description("Template Renderers for the RIFE2 web framework")
.url("https://github.com/rife2/rife2-template-renderers") .url("https://github.com/rife2/rife2-template-renderers")
.developer(new PublishDeveloper().id("ethauvin").name("Erik C. Thauvin").email("erik@thauvin.net") .developer(new PublishDeveloper()
.id("ethauvin")
.name("Erik C. Thauvin")
.email("erik@thauvin.net")
.url("https://erik.thauvin.net/")) .url("https://erik.thauvin.net/"))
.developer(new PublishDeveloper().id("gbevin").name("Geert Bevin").email("gbevin@uwyn.com") .developer(new PublishDeveloper()
.id("gbevin")
.name("Geert Bevin")
.email("gbevin@uwyn.com")
.url("https://github.com/gbevin")) .url("https://github.com/gbevin"))
.license(new PublishLicense().name("The Apache License, Version 2.0") .license(new PublishLicense()
.name("The Apache License, Version 2.0")
.url("https://www.apache.org/licenses/LICENSE-2.0.txt")) .url("https://www.apache.org/licenses/LICENSE-2.0.txt"))
.scm(new PublishScm().connection("scm:git:https://github.com/rife2/rife2-template-renderers.git") .scm(new PublishScm()
.connection("scm:git:https://github.com/rife2/rife2-template-renderers.git")
.developerConnection("scm:git:git@github.com:rife2/rife2-template-renderers.git") .developerConnection("scm:git:git@github.com:rife2/rife2-template-renderers.git")
.url("https://github.com/rife2/rife2-template-renderers")) .url("https://github.com/rife2/rife2-template-renderers"))
.signKey(property("signKey")) .signKey(property("signKey"))

View file

@ -21,7 +21,7 @@ import rife.template.Template;
import rife.template.ValueRenderer; import rife.template.ValueRenderer;
/** /**
* <p>Abbreviate a template value with ellipses.</p> * <p>Abbreviates a template value with ellipses.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -36,7 +36,18 @@ import rife.template.ValueRenderer;
*/ */
public class Abbreviate implements ValueRenderer { public class Abbreviate implements ValueRenderer {
/** /**
* {@inheritDoc} * <p>Returns the template value abbreviated with ellipses.</p>
*
* <p>Two parameters can be specified:</p>
* <ul>
* <li><code>mark</code>: the string that will be used to abbreviate the value. Default is <code>...</code></li>
* <li><code>max</code>: the maximum number of characters to render. Default is <code>-1</code> (no abbreviation).</li>
* </ul>
*
* @param template the template that contains the value
* @param valueId the id of the value to render
* @param differentiator a generic string that can be used to differentiate the rendering
* @return the abbreviated value, or the original value if no abbreviation is necessary
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class BeatTime implements ValueRenderer { public class BeatTime implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current time in Swatch Internet (.beat) Time format.
*
* @param template the template instance
* @param valueId the value id
* @param differentiator the differentiator
* @return the rendered value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -37,7 +37,12 @@ import rife.tools.StringUtils;
*/ */
public class Capitalize implements ValueRenderer { public class Capitalize implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value by capitalizing it.
*
* @param template the template containing the value to be rendered
* @param valueId the identifier of the value to render
* @param differentiator a string used to differentiate the rendering
* @return the capitalized and encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -0,0 +1,50 @@
/*
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package rife.render;
import rife.template.Template;
import rife.template.ValueRenderer;
/**
* <p>Capitalizes words of a template value.</p>
*
* <p>Usage:</p>
*
* <pre>
* &lt;!--v render:rife.render.CapitalizeWords:valueId/--&gt;
* {{v render:rife.render.CapitalizeWords:valueId/}}
* </pre>
*
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @see <a href="https://github.com/rife2/rife2-template-renderers/wiki/rife.render.CapitalizeWords">rife.render.CapitalizeWords</a>
* @since 1.2
*/
public class CapitalizeWords implements ValueRenderer {
/**
* Returns the template value by capitalizing it.
*
* @param template the template containing the value to be rendered
* @param valueId the identifier of the value to render
* @param differentiator a string used to differentiate the rendering
* @return the capitalized and encoded value
*/
@Override
public String render(Template template, String valueId, String differentiator) {
return template.getEncoder().encode(RenderUtils.capitalizeWords(template.getValueOrAttribute(differentiator)));
}
}

View file

@ -23,7 +23,7 @@ import rife.template.ValueRenderer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current date in ISO 8601 format.</p> * <p>Renders the current date in ISO 8601 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class DateIso implements ValueRenderer { public class DateIso implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current date in ISO 8601 format, encoded according to the template's encoding rules.
*
* @param template the template that is currently being rendered
* @param valueId the value id that triggers the rendering of this value renderer
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current date in ISO 8601 format, encoded according to the template's encoding rules
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -24,7 +24,7 @@ import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current date and time in ISO 8601 format.</p> * <p>Renders the current date and time in ISO 8601 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -39,7 +39,15 @@ import java.time.ZonedDateTime;
*/ */
public class DateTimeIso implements ValueRenderer { public class DateTimeIso implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the current date and time in ISO 8601 format.
*
* <p>Additionally, it allows specifying a time zone through the template's default value properties with the key
* {@code tz}. If no time zone is specified, the system default time zone is used.</p>
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to be rendered
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current date and time in ISO 8601 format
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -23,7 +23,7 @@ import rife.template.ValueRenderer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current date and time in RFC 2822 format.</p> * <p>Renders the current date and time in RFC 2822 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class DateTimeRfc2822 implements ValueRenderer { public class DateTimeRfc2822 implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current date and time in RFC 2822 format.
*
* @param template the template instance
* @param valueId the value id
* @param differentiator the differentiator
* @return the current date and time in RFC 2822 format
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -40,7 +40,12 @@ import java.nio.charset.StandardCharsets;
*/ */
public class EncodeBase64 implements ValueRenderer { public class EncodeBase64 implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to Base64.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the Base64-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeHtml implements ValueRenderer { public class EncodeHtml implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to HTML.
*
* @param template the template containing the value to be rendered
* @param valueId the identifier of the value to render
* @param differentiator a string used to differentiate the rendering
* @return the HTML-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class EncodeHtmlEntities implements ValueRenderer { public class EncodeHtmlEntities implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to HTML decimal entities.
*
* @param template the template instance
* @param valueId the value id
* @param differentiator the differentiator
* @return the encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeJs implements ValueRenderer { public class EncodeJs implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to JavaScript/ECMAScript.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the JavaScript/ECMAScript-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeJson implements ValueRenderer { public class EncodeJson implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to JSON.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the JSON-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeUnicode implements ValueRenderer { public class EncodeUnicode implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to Unicode escape codes.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the Unicode escape codes-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeUrl implements ValueRenderer { public class EncodeUrl implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to URL.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the URL-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.tools.StringUtils;
*/ */
public class EncodeXml implements ValueRenderer { public class EncodeXml implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded to XML.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the XML-encoded value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class FormatCreditCard implements ValueRenderer { public class FormatCreditCard implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the last 4 digits of the template credit number value.
*
* @param template the {@link Template}
* @param valueId the value id
* @param differentiator the differentiator
* @return the formatted value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -37,7 +37,12 @@ import rife.tools.Localization;
*/ */
public class Lowercase implements ValueRenderer { public class Lowercase implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value converted to lowercase.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the lowercase value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -35,8 +35,30 @@ import rife.template.ValueRenderer;
* @since 1.0 * @since 1.0
*/ */
public class Mask implements ValueRenderer { public class Mask implements ValueRenderer {
/** /**
* {@inheritDoc} * <p>Renders a template value with characters of the value masked using the specified mask.</p>
*
* <p>The mask is specified as a template default value with the following syntax:</p>
*
* <pre>
* mask=&lt;mask&gt;[,unmasked=&lt;unmasked&gt;][,fromStart=&lt;fromStart&gt;]
* </pre>
*
* <p>Where:</p>
*
* <ul>
* <li><var>mask</var> is the character to use for masking, defaulting to <code>*</code></li>
* <li><var>unmasked</var> is the number of characters at the beginning of the value that should be left unmasked,
* defaulting to <code>0</code></li>
* <li><var>fromStart</var> is a boolean indicating whether the <var>unmasked</var> value should be counted from
* the start of the value, defaulting to <code>false</code></li>
* </ul>
*
* @param template the template to render the value in
* @param valueId the ID of the value to render
* @param differentiator the differentiator of the value to render
* @return the rendered value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class Normalize implements ValueRenderer { public class Normalize implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value normalized for inclusion in a URL path.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the normalized value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class QrCode implements ValueRenderer { public class QrCode implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value encoded as an SVG QR Code.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the SVG QR Code
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -83,7 +83,7 @@ public final class RenderUtils {
DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss zzz").withLocale(Localization.getLocale()); DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss zzz").withLocale(Localization.getLocale());
private static final String DEFAULT_USER_AGENT = private static final String DEFAULT_USER_AGENT =
"Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0"; "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0";
private final static Logger LOGGER = Logger.getLogger(RenderUtils.class.getName()); private static final Logger LOGGER = Logger.getLogger(RenderUtils.class.getName());
private RenderUtils() { private RenderUtils() {
// no-op // no-op
@ -124,6 +124,38 @@ public final class RenderUtils {
return String.format("@%03d", beats); return String.format("@%03d", beats);
} }
/**
* Returns a {@code String} with the first letter of each word capitalized.
*
* @param src the source {@code String}
* @return the capitalized {@code String}
*/
public static String capitalizeWords(String src) {
if (src == null || src.isBlank()) {
return src;
}
var result = new StringBuilder();
var capitalizeNext = true;
for (var i = 0; i < src.length(); i++) {
var c = src.charAt(i);
if (Character.isWhitespace(c)) {
capitalizeNext = true;
result.append(c);
} else {
if (capitalizeNext) {
result.append(Character.toUpperCase(c));
} else {
result.append(Character.toLowerCase(c));
}
capitalizeNext = false;
}
}
return result.toString();
}
/** /**
* <p>Encodes the source {@code String} to the specified encoding.</p> * <p>Encodes the source {@code String} to the specified encoding.</p>
* *
@ -216,8 +248,9 @@ public final class RenderUtils {
public static String fetchUrl(String url, String defaultContent) { public static String fetchUrl(String url, String defaultContent) {
try { try {
var fetchUrl = new URL(url); var fetchUrl = new URL(url);
HttpURLConnection connection = null;
try { try {
var connection = (HttpURLConnection) fetchUrl.openConnection(); connection = (HttpURLConnection) fetchUrl.openConnection();
connection.setRequestProperty("User-Agent", DEFAULT_USER_AGENT); connection.setRequestProperty("User-Agent", DEFAULT_USER_AGENT);
var code = connection.getResponseCode(); var code = connection.getResponseCode();
if (code >= 200 && code <= 399) { if (code >= 200 && code <= 399) {
@ -233,10 +266,15 @@ public final class RenderUtils {
if (LOGGER.isLoggable(Level.WARNING)) { if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, "An IO error occurred while connecting to " + fetchUrl.getHost(), ioe); LOGGER.log(Level.WARNING, "An IO error occurred while connecting to " + fetchUrl.getHost(), ioe);
} }
} finally {
if (connection != null) {
connection.disconnect();
}
} }
} catch (MalformedURLException ignored) { } catch (MalformedURLException ignored) {
// do nothing // do nothing
} }
return defaultContent; return defaultContent;
} }

View file

@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class Rot13 implements ValueRenderer { public class Rot13 implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value translated to/from ROT13.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the ROT13 value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import rife.template.ValueRenderer;
*/ */
public class ShortenUrl implements ValueRenderer { public class ShortenUrl implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value shortened using <a href="https://is.gd/">is.gid</a>.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the template shortened value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -21,7 +21,7 @@ import rife.template.Template;
import rife.template.ValueRenderer; import rife.template.ValueRenderer;
/** /**
* <p>Swap case of a template value.</p> * <p>Swaps case of a template value.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -35,9 +35,13 @@ import rife.template.ValueRenderer;
* @since 1.0 * @since 1.0
*/ */
public class SwapCase implements ValueRenderer { public class SwapCase implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value with swapped case.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the swapped case value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -23,7 +23,7 @@ import rife.template.ValueRenderer;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
/** /**
* <p>Return the current time in ISO 8601 format.</p> * <p>Renders the current time in ISO 8601 format.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -38,7 +38,12 @@ import java.time.ZonedDateTime;
*/ */
public class TimeIso implements ValueRenderer { public class TimeIso implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the current time in ISO 8601 format.
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to be rendered
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current time in ISO 8601 format
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -36,7 +36,12 @@ import rife.template.ValueRenderer;
*/ */
public class Trim implements ValueRenderer { public class Trim implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the template value by removing leading and trailing whitespace.
*
* @param template the template instance
* @param valueId the id of the value to render
* @param differentiator an optional differentiator to use for cache invalidation
* @return the trimmed value, or the original value if it is {@code null} or empty
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -37,7 +37,12 @@ import rife.tools.StringUtils;
*/ */
public class Uncapitalize implements ValueRenderer { public class Uncapitalize implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the un-capitalized template value.
*
* @param template the template to render
* @param valueId the id of the value to render
* @param differentiator the differentiator to use for the value lookup
* @return the un-capitalized value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -22,7 +22,7 @@ import rife.template.ValueRenderer;
import rife.tools.Localization; import rife.tools.Localization;
/** /**
* <p>Convert a template value to uppercase.</p> * <p>Converts a template value to uppercase.</p>
* *
* <p>Usage:</p> * <p>Usage:</p>
* *
@ -37,7 +37,12 @@ import rife.tools.Localization;
*/ */
public class Uppercase implements ValueRenderer { public class Uppercase implements ValueRenderer {
/** /**
* {@inheritDoc} * Returns the template value converted to uppercase.
*
* @param template the template that contains the value
* @param valueId the id of the value
* @param differentiator the differentiator to use
* @return the uppercased value
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -38,7 +38,12 @@ import java.lang.management.ManagementFactory;
*/ */
public class Uptime implements ValueRenderer { public class Uptime implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the server uptime.
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to render
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the server uptime
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -37,9 +37,13 @@ import java.time.ZonedDateTime;
* @since 1.0 * @since 1.0
*/ */
public class Year implements ValueRenderer { public class Year implements ValueRenderer {
/** /**
* {@inheritDoc} * Renders the current year.
*
* @param template the template that is currently being rendered
* @param valueId the id of the value to render
* @param differentiator a differentiator that may be used to differentiate the rendering of this value renderer
* @return the current year
*/ */
@Override @Override
public String render(Template template, String valueId, String differentiator) { public String render(Template template, String valueId, String differentiator) {

View file

@ -30,7 +30,7 @@ import java.lang.annotation.Target;
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a> * @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @since 1.0 * @since 1.0
*/ */
@Target({ ElementType.TYPE, ElementType.METHOD }) @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisableOnCiCondition.class) @ExtendWith(DisableOnCiCondition.class)
public @interface DisabledOnCi { public @interface DisabledOnCi {

View file

@ -17,6 +17,7 @@
package rife.render; package rife.render;
import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Properties; import java.util.Properties;
@ -39,6 +40,17 @@ class TestRenderUtils {
assertThat(RenderUtils.abbreviate("", 10, "")).as("").isEmpty(); assertThat(RenderUtils.abbreviate("", 10, "")).as("").isEmpty();
} }
@Test
void testCapitalizeWords() {
assertThat(RenderUtils.capitalizeWords("hello world")).isEqualTo("Hello World");
assertThat(RenderUtils.capitalizeWords("java programming")).isEqualTo("Java Programming");
assertThat(RenderUtils.capitalizeWords("TEST")).isEqualTo("Test");
assertThat(RenderUtils.capitalizeWords("multiple spaces")).isEqualTo("Multiple Spaces");
assertThat(RenderUtils.capitalizeWords("white\t\fspaces")).isEqualTo("White\t\fSpaces");
assertThat(RenderUtils.capitalizeWords("")).isEmpty();
assertThat(RenderUtils.capitalizeWords(null)).isNull();
}
@Test @Test
void testEncode() { void testEncode() {
var p = new Properties(); var p = new Properties();
@ -127,10 +139,12 @@ class TestRenderUtils {
@Test @Test
void testValidateCreditCard() { void testValidateCreditCard() {
assertThat(RenderUtils.validateCreditCard("4505 4672 3366 6430")).as("visa").isTrue(); try (var softly = new AutoCloseableSoftAssertions()) {
assertThat(RenderUtils.validateCreditCard("5189-5923-3915-0425")).as("mastercard").isTrue(); softly.assertThat(RenderUtils.validateCreditCard("4505 4672 3366 6430")).as("visa").isTrue();
assertThat(RenderUtils.validateCreditCard("3433634926643302")).as("amex").isTrue(); softly.assertThat(RenderUtils.validateCreditCard("5189-5923-3915-0425")).as("mastercard").isTrue();
assertThat(RenderUtils.validateCreditCard("6011 1076-8252 0629")).as("discover").isTrue(); softly.assertThat(RenderUtils.validateCreditCard("3433634926643302")).as("amex").isTrue();
assertThat(RenderUtils.validateCreditCard("0123456789012345")).as("invalid").isFalse(); softly.assertThat(RenderUtils.validateCreditCard("6011 1076-8252 0629")).as("discover").isTrue();
softly.assertThat(RenderUtils.validateCreditCard("0123456789012345")).as("invalid").isFalse();
}
} }
} }