{"id":21131154,"url":"https://github.com/wnameless/spelscriptassert","last_synced_at":"2025-03-14T12:16:01.819Z","repository":{"id":239120023,"uuid":"798594072","full_name":"wnameless/spelscriptassert","owner":"wnameless","description":"Spring Expression Language(SpEL) Jakarta validator","archived":false,"fork":false,"pushed_at":"2024-05-12T12:28:54.000Z","size":96,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-21T06:11:48.997Z","etag":null,"topics":["hibernate-validator","jakarta-bean-validation","java","spring-validation"],"latest_commit_sha":null,"homepage":"https://github.com/wnameless/spelscriptassert","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wnameless.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-10T04:57:48.000Z","updated_at":"2024-10-17T12:59:32.000Z","dependencies_parsed_at":"2024-05-10T06:27:14.322Z","dependency_job_id":"756b36f8-9f69-4569-9ea5-3b5a29f35284","html_url":"https://github.com/wnameless/spelscriptassert","commit_stats":null,"previous_names":["wnameless/spelscriptassert"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wnameless%2Fspelscriptassert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wnameless%2Fspelscriptassert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wnameless%2Fspelscriptassert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wnameless%2Fspelscriptassert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wnameless","download_url":"https://codeload.github.com/wnameless/spelscriptassert/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243573495,"owners_count":20312883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hibernate-validator","jakarta-bean-validation","java","spring-validation"],"created_at":"2024-11-20T05:49:53.567Z","updated_at":"2025-03-14T12:16:01.774Z","avatar_url":"https://github.com/wnameless.png","language":"Java","readme":"[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.wnameless.spring/spelscriptassert/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.wnameless.spring/spelscriptassert)\n[![codecov](https://codecov.io/gh/wnameless/spelscriptassert/branch/master/graph/badge.svg)](https://codecov.io/gh/wnameless/spelscriptassert)\n\nSpELScriptAssert\n=============\nSpring Expression Language(SpEL) Jakarta validator.\n\n## Purpose\nApply SpEL to Hibernate @ScriptAssert by creating a new validation annotation @SpELScriptAssert.\n\n## Demo - basic usage\nUsing Spring Expression Language(SpEL) to validate a Java bean.\n\nBean\n```java\n@SpELScriptAssert( //\n    script = \"@mathComponent.multiply(#add(a, b), c) == output\", //\n    performIf = \"a != null \u0026\u0026 b != null \u0026\u0026 c != null\", //\n    helpers = {MathHelper.class}, //\n    reportOn = \"output\", //\n    message = \"{validation.MixBean.output}\")\npublic class MixBean {\n\n  public Integer output = 10;\n  public Integer a = 1;\n  public Integer b = 2;\n  public Integer c = 3;\n\n}\n```\n\nValidation message:\n```\noutput != (a + b) * c\n```\n\nMessage properties:\n```properties\nvalidation.MixBean.output={reportOn} != (a + b) * c\n```\n\nSpring Component:\n```java\n@Component\npublic class MathComponent {\n  public int multiply(int a, int b) { return a * b; }\n}\n```\n\nHelper class:\n```java\npublic class MathHelper {\n  public static int add(int a, int b) { return a + b; }\n}\n```\n\n## Demo - advanced usage\n`target` evaluated value can be reused in script and message attributes by calling **#target**\n\u003cbr\u003e\n`#{...}` blocks in message attribute are all SpEL expressions which will be evaluated eventually\n\nBean\n```java\n@SpELScriptAssert( //\n    target = \"a * b * c\", //\n    script = \"#target \u003e= 10\", //\n    message = \"#{#target} {validation.AdvancedBean.msg} #{T(java.lang.Math).abs(#target - 10)}\")\npublic class AdvancedBean {\n\n  public Integer a = 1;\n  public Integer b = 2;\n  public Integer c = 3;\n\n}\n```\n\nValidation message:\n```\n6 is NOT greater than or equal to Ten before adding 4\n```\n\nMessage properties:\n```properties\nvalidation.AdvancedBean.msg=is NOT greater than or equal to Ten before adding\n```\n\n# Maven Repo\n```xml\n\u003cdependency\u003e\n\t\u003cgroupId\u003ecom.github.wnameless.spring\u003c/groupId\u003e\n\t\u003cartifactId\u003espelscriptassert\u003c/artifactId\u003e\n\t\u003cversion\u003e${newestVersion}\u003c/version\u003e\n\t\u003c!-- Newest version shows in the maven-central badge above --\u003e\n\u003c/dependency\u003e\n```\n\n## Quick Start - configure ValidationMessages resource bundle\nSpring Environment - Inject MessageSource into the Jakarta Validator.\n```java\n@Configuration\npublic class SpELScriptAssertConfig {\n  @Bean\n  LocalValidatorFactoryBean validatorFactoryBean(MessageSource messageSource) {\n    var bean = new LocalValidatorFactoryBean();\n    bean.setValidationMessageSource(messageSource);\n    return bean;\n  }\n}\n```\n\nStandalone mode\n```java\n// Jakarta Validator looks up `ValidationMessages.properties` file under classpath by default\n```\n\n# Feature List\u003ca id='top'\u003e\u003c/a\u003e\n| Name | Description | Since |\n| --- | --- | --- |\n| [SpEL code blocks in message template](#1.1.0_1) | Them message attribute of @SpELScriptAssert now accepts #{spel_expr} code blocks. | v1.1.0 |\n| [target](#1.1.0_2) | An optional attribute can hold an evaluation result for further use. | v1.1.0 |\n| Optional Spring Environment | @SpELScriptAssert can be used standalone or with Spring Environment. The only difference is that `@springComponent` syntax of SpEL expression won't work in standalone mode. | v1.0.0 |\n| Java Module supported  | The module-info.java included. | v1.0.0 |\n| performIf | A condition expression for determining whether a validation is performed or NOT. | v1.0.0 |\n| helpers | Register static methods from given Helper Classes. Methods can be called by `#helperMethod` syntax in SpEL expression. | v1.0.0 |\n| reportOn | Same as `reportOn` in Hibernate validation @ScriptAssert annotation. | v1.0.0 |\n| [Smart Evaluation Strategies](#1.0.0_1) | Smart boolean convertion for evaluation values. | v1.0.0 |\n\n## [:top:](#top) SpEL code blocks(#{...}) in message template\u003ca id=\"1.1.0_1\"\u003e\u003c/a\u003e\n```java\n@SpELScriptAssert( //\n    script = \"str.empty\", //\n    message = \"str is NOT empty, str is '#{str}' with length of #{str.length}\")\npublic class CodeBlockBean {\n  public String str = \"SpELScriptAssert\";\n}\n```\nValidation message:\n```\nstr is NOT empty, str is 'SpELScriptAssert' with length of 16\n```\n\n## [:top:](#top) Utilize `target` attribute\u003ca id=\"1.1.0_2\"\u003e\u003c/a\u003e\nThe `target` attribute can hold an evaluation value for further uses in `script` and `message` contents. It can not only impove the readability but also save computation time if the evaluation of the expression in `target` attribute is highly time comsuming.\n```java\n@SpELScriptAssert( //\n    target = \"bi1.multiply(bi2)\", //\n    script = \"#target.toString.length \u003c 10\", //\n    reportOn = \"bi1 * bi2\", //\n    message = \"{reportOn} = #{#target} and the digits are more than 10\")\npublic class TargetBean {\n  public BigInteger bi1 = new BigInteger(\"123456789\");\n  public BigInteger bi2 = new BigInteger(\"987654321\");\n}\n```\nValidation message:\n```\nbi1 * bi2 = 121932631112635269 and the digits are more than 10\n```\n\n## [:top:](#top) Smart Evaluation Strategies\u003ca id=\"1.0.0_1\"\u003e\u003c/a\u003e\nSpELScriptAssert expects all evaluation scripts (both `script` and `performIf`) which always return Boolean values, however it also accepts other returning value types and treats them as Boolean values.\n\n### 1. Non-zero number is True, zero is False.\n```java\n@SpELScriptAssert(script = \"a\", reportOn = \"a\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"b\", reportOn = \"b\", message = \"{reportOn} is false\")\npublic class NumBean {\n  public int a = 0;\n  public long b = 1L;\n}\n```\nValidation message:\n```\na is false\n```\n\n### 2. Non-empty Array or Collection is True, otherwise False.\n```java\n@SpELScriptAssert(script = \"a\", reportOn = \"a\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"b\", reportOn = \"b\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"c\", performIf = \"d\", reportOn = \"c\", message = \"{reportOn} is false\")\npublic class ArrayCollectionBean {\n  public int[] a = {};\n  public String[] b = {\"I\"};\n  public List\u003c?\u003e c = List.of();\n  public Map\u003c?, ?\u003e d = Map.of(\"II\", \"III\");\n}\n```\nValidation message:\n```\na is false\nc is false\n```\n\n### 3. Non-blank CharSequence is True, otherwise False.\n```java\n@SpELScriptAssert(script = \"a\", reportOn = \"a\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"b\", reportOn = \"b\", message = \"{reportOn} is false\")\npublic class CharSequenceBean {\n  public String a = \"   \";\n  public CharSequence b = \"I\";\n}\n```\nValidation message:\n```\na is false\n```\n\n### 4. Non-empty Optional is True, otherwise False. However Optional\\\u003cBoolean\\\u003e can only be dertermined by its own returning value.\n```java\n@SpELScriptAssert(script = \"a\", reportOn = \"a\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"b\", reportOn = \"b\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"c\", reportOn = \"c\", message = \"{reportOn} is false\")\npublic class OptionalBean {\n  public Optional\u003cString\u003e a = Optional.empty();\n  public Optional\u003cString\u003e b = Optional.of(\"I\");\n  public Optional\u003cBoolean\u003e c = Optional.of(false);\n}\n\n```\nValidation message:\n```\na is false\nc is false\n```\n\n### 5. Default behavior: Non-null is True, otherwise False.\n```java\n@SpELScriptAssert(script = \"a\", reportOn = \"a\", message = \"{reportOn} is false\")\n@SpELScriptAssert(script = \"b\", reportOn = \"b\", message = \"{reportOn} is false\")\npublic class NullBean {\n  public BigInteger a = null;\n  public BigDecimal b = BigDecimal.valueOf(123L);\n}\n```\nValidation message:\n```\na is false\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwnameless%2Fspelscriptassert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwnameless%2Fspelscriptassert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwnameless%2Fspelscriptassert/lists"}