Added formatCreditCard
This commit is contained in:
parent
9e9d2d6885
commit
625c211b62
10 changed files with 168 additions and 34 deletions
1
.github/workflows/publish.yml
vendored
1
.github/workflows/publish.yml
vendored
|
@ -1,6 +1,7 @@
|
|||
name: Publish to the Maven Central
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
|
|
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
|
@ -44,6 +44,9 @@
|
|||
<pattern value="rife.render.TestDateTime" method="testTimeIso" />
|
||||
<pattern value="rife.render.TestDateTime" method="testYear" />
|
||||
<pattern value="rife.render.ValueBean" />
|
||||
<pattern value="rife.render.RenderUtils" method="formatCreditCard" />
|
||||
<pattern value="rife.render.RenderUtils" />
|
||||
<pattern value="rife.render.RenderUtils" method="RenderUtils" />
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="PDMPlugin">
|
||||
|
|
30
README.md
30
README.md
|
@ -21,18 +21,24 @@ This project provides a collection of template renderers.
|
|||
|
||||
## Encoding Renderers
|
||||
|
||||
| Renderer | Description |
|
||||
|:---------------------------------|:--------------------------------------------------------|
|
||||
| `rife.render.EncodeBase64` | Encodes a template value to Base64 |
|
||||
| `rife.render.EncodeHtml` | Encodes a template value to HTML |
|
||||
| `rife.render.EncodeHtmlEntities` | Encodes a template value to HTML decimal entities |
|
||||
| `rife.render.EncodeJs` | Encodes a template value to JavaScript/ECMAScript |
|
||||
| `rife.render.EncodeJson` | Encodes a template value to JSON |
|
||||
| `rife.render.EncodeQp` | Converts a template value to a quoted-printable string |
|
||||
| `rife.render.EncodeUnicode` | Encodes a template value to Unicode escape codes |
|
||||
| `rife.render.EncodeUrl` | URL-encodes a template value |
|
||||
| `rife.render.EncodeXml` | Encodes a template value to XML |
|
||||
| `rife.render.ShorteUrl` | Shortens a template value using [is.gd](https://is.gd/) |
|
||||
| Renderer | Description |
|
||||
|:---------------------------------|:-------------------------------------------------------|
|
||||
| `rife.render.EncodeBase64` | Encodes a template value to Base64 |
|
||||
| `rife.render.EncodeHtml` | Encodes a template value to HTML |
|
||||
| `rife.render.EncodeHtmlEntities` | Encodes a template value to HTML decimal entities |
|
||||
| `rife.render.EncodeJs` | Encodes a template value to JavaScript/ECMAScript |
|
||||
| `rife.render.EncodeJson` | Encodes a template value to JSON |
|
||||
| `rife.render.EncodeQp` | Converts a template value to a quoted-printable string |
|
||||
| `rife.render.EncodeUnicode` | Encodes a template value to Unicode escape codes |
|
||||
| `rife.render.EncodeUrl` | URL-encodes a template value |
|
||||
| `rife.render.EncodeXml` | Encodes a template value to XML |
|
||||
|
||||
## Format Renderers
|
||||
|
||||
| Renderer | Description |
|
||||
|:---------------------------------|:-----------------------------------------------------------------|
|
||||
| `rife.render.formatCreditcard` | Formats a template credit card number value to the last 4 digits |
|
||||
| `rife.render.ShorteUrl` | Shortens a template value using [is./gd](https://is.gd/) |
|
||||
|
||||
|
||||
## Text Renderers
|
||||
|
|
|
@ -67,13 +67,13 @@ tasks {
|
|||
}
|
||||
}
|
||||
|
||||
javadoc {
|
||||
javadoc {
|
||||
title = "<a href=\"https://rife2.com\">RIFE2</a> Template Renderers"
|
||||
options {
|
||||
this as StandardJavadocDocletOptions
|
||||
keyWords(true)
|
||||
splitIndex(true)
|
||||
links()
|
||||
links("https://rife2.github.io/rife2/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
lib/src/main/java/rife/render/FormatCreditCard.java
Normal file
44
lib/src/main/java/rife/render/FormatCreditCard.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2023 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;
|
||||
|
||||
/**
|
||||
* Formats a template credit card number value to the last 4 digits.
|
||||
*
|
||||
* <p>Usage:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <!--v render:rife.render.FormatCreditCard:valueId/-->
|
||||
* {{v render:rife.render.FormatCreditCard:valueId/}}
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
public class FormatCreditCard implements ValueRenderer {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String render(Template template, String valueId, String differentiator) {
|
||||
return RenderUtils.formatCreditCard(RenderUtils.fetchValue(template, differentiator));
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ public final class RenderUtils {
|
|||
/**
|
||||
* Encodes a string to JavaScript/ECMAScript.
|
||||
*
|
||||
* @param src the source string.
|
||||
* @param src the source string
|
||||
* @return the enocded string
|
||||
*/
|
||||
public static String encodeJS(String src) {
|
||||
|
@ -96,11 +96,53 @@ public final class RenderUtils {
|
|||
return Convert.toString(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last 4 digits a credit card number. The number must satisfy the Luhn algorithm.
|
||||
* Non-digits are stripped from the number.
|
||||
*
|
||||
* @param src the credit card number
|
||||
* @return the last 4 digits of the credit card number or empty
|
||||
*/
|
||||
public static String formatCreditCard(String src) {
|
||||
if (src == null || src.isBlank()) {
|
||||
return src;
|
||||
}
|
||||
|
||||
try {
|
||||
var cc = src.replaceAll("[^0-9]", "");
|
||||
|
||||
var len = cc.length();
|
||||
if (len >= 4) {
|
||||
// Luhn algorithm
|
||||
var sum = 0;
|
||||
boolean isSecond = false;
|
||||
int digit;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
digit = cc.charAt(i) - '0';
|
||||
if (isSecond) {
|
||||
digit = digit * 2;
|
||||
}
|
||||
sum += digit / 10;
|
||||
sum += digit % 10;
|
||||
|
||||
isSecond = !isSecond;
|
||||
}
|
||||
if (sum % 10 == 0) {
|
||||
return cc.substring(len - 4);
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ignore) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a String to/from ROT13.
|
||||
*
|
||||
* @param src the source String.
|
||||
* @return the translated String.
|
||||
* @param src the source String
|
||||
* @return the translated String
|
||||
*/
|
||||
public static String rot13(String src) {
|
||||
if (src == null || src.isBlank()) {
|
||||
|
@ -144,7 +186,7 @@ public final class RenderUtils {
|
|||
* @return the short URL
|
||||
*/
|
||||
public static String shortenUrl(String url) {
|
||||
if (url == null || url.isBlank() || !url.matches("^[Hh][Tt][Tt][Pp][Ss]?:\\/\\/\\w.*")) {
|
||||
if (url == null || url.isBlank() || !url.matches("^[Hh][Tt][Tt][Pp][Ss]?://\\w.*")) {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
@ -203,8 +245,8 @@ public final class RenderUtils {
|
|||
/**
|
||||
* Converts a text string to HTML decimal entities.
|
||||
*
|
||||
* @param src the String to convert.
|
||||
* @return the converted string.
|
||||
* @param src the String to convert
|
||||
* @return the converted String
|
||||
*/
|
||||
@SuppressWarnings("PMD.AvoidReassigningLoopVariables")
|
||||
public static String toHtmlEntities(String src) {
|
||||
|
|
|
@ -19,7 +19,6 @@ package rife.render;
|
|||
|
||||
import rife.template.Template;
|
||||
import rife.template.ValueRenderer;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>Shortens a template value using <a href="https://is.gd/">is.gid</a>. The value must a valid http or https URL.</p>
|
||||
|
@ -34,7 +33,7 @@ import rife.tools.StringUtils;
|
|||
* </pre>
|
||||
*
|
||||
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||
= * @since 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
public class ShortenUrl implements ValueRenderer {
|
||||
/**
|
||||
|
|
|
@ -100,16 +100,4 @@ class TestEncode {
|
|||
t.setAttribute(TestCase.FOO, "a test &");
|
||||
assertThat(t.getContent()).isEqualTo("<test>\n <foo>a test &</foo>\n</test>");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShortenUrl() {
|
||||
var t = TemplateFactory.HTML.get("shortenUrl");
|
||||
var url = "https://example.com/";
|
||||
var shortUrl = "https://is.gd/AG3Hwv";
|
||||
t.setValue(TestCase.FOO, url);
|
||||
assertThat(t.getContent()).isEqualTo(String.format("<a href=\"%s\">%s</a>", shortUrl, url));
|
||||
t.setValue(TestCase.FOO, TestCase.FOO);
|
||||
assertThat(t.getContent()).isEqualTo("<a href=\"foo\">foo</a>");
|
||||
|
||||
}
|
||||
}
|
50
lib/src/test/java/rife/render/TestFormat.java
Normal file
50
lib/src/test/java/rife/render/TestFormat.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2023 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 org.junit.jupiter.api.Test;
|
||||
import rife.template.TemplateFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class TestFormat {
|
||||
@Test
|
||||
void testFormatCreditCard() {
|
||||
var t = TemplateFactory.TXT.get("formatCreditCard");
|
||||
t.setAttribute(TestCase.FOO, "4342 2565 6244 0179");
|
||||
assertThat(t.getContent()).as("US VISA").isEqualTo("0179");
|
||||
t.setAttribute(TestCase.FOO, "5130-3899-9169-8324");
|
||||
assertThat(t.getContent()).as("FR MASTERCARD").isEqualTo("8324");
|
||||
t.setAttribute(TestCase.FOO, "374380141731053");
|
||||
assertThat(t.getContent()).as("UK AMEX").isEqualTo("1053");
|
||||
t.setAttribute(TestCase.FOO, "000000000000001");
|
||||
assertThat(t.getContent()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShortenUrl() {
|
||||
var t = TemplateFactory.HTML.get("shortenUrl");
|
||||
var url = "https://example.com/";
|
||||
var shortUrl = "https://is.gd/AG3Hwv";
|
||||
t.setValue(TestCase.FOO, url);
|
||||
assertThat(t.getContent()).isEqualTo(String.format("<a href=\"%s\">%s</a>", shortUrl, url));
|
||||
t.setValue(TestCase.FOO, TestCase.FOO);
|
||||
assertThat(t.getContent()).isEqualTo("<a href=\"foo\">foo</a>");
|
||||
|
||||
}
|
||||
}
|
1
lib/src/test/resources/templates/formatCreditCard.txt
Normal file
1
lib/src/test/resources/templates/formatCreditCard.txt
Normal file
|
@ -0,0 +1 @@
|
|||
{{v render:rife.render.FormatCreditCard:foo/}}
|
Loading…
Add table
Add a link
Reference in a new issue