fix(weaver-pojo-serde): Align SerdePojoReaderWriterSpec with Java's identifier rules

This commit is contained in:
2026-03-01 12:30:35 +01:00
parent 3add9da6d4
commit 2e9f4c1689
3 changed files with 40 additions and 9 deletions

View File

@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Changed
- `weaver-pojo-serde-extension`: Slightly changed the `SerdePojoReaderWriterSpec`
to be more closely aligned with Java's identifier rules.
## [0.7.0] - 2025-12-19 ## [0.7.0] - 2025-12-19
### Changed ### Changed

View File

@@ -7,6 +7,18 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.PrimitiveIterator; import java.util.PrimitiveIterator;
/**
* Specification describing how to construct a reader or writer.
* <p>
* The formal syntax is:
* <code><pre>
* &lt;spec&gt; ::= &lt;identifier&gt; [ '(' &lt;spec-list&gt; ')' ]
* &lt;spec-list&gt; ::= &lt;spec&gt; [ ',' &lt;spec-list&gt; ]
* &lt;identifier&gt; ::= &lt;identifier-part&gt; [ '.' &lt;identifier&gt; ]
* &lt;identifier-part&gt; ::= ( &lt;alpha&gt; | '_' ) [ &lt;alphanumeric-identifier-part&gt; ]
* &lt;alphanumeric-identifier-part&gt; ::= ( &lt;alphanumeric&gt; | '_' ) [ &lt;alphanumeric-identifier-part&gt; ]
* </pre></code>
*/
@Value @Value
public class SerdePojoReaderWriterSpec { public class SerdePojoReaderWriterSpec {
String identifier; String identifier;
@@ -71,14 +83,14 @@ public class SerdePojoReaderWriterSpec {
int codePoint = nextCodePoint(); int codePoint = nextCodePoint();
if (codePoint == -1) { if (codePoint == -1) {
throw createException("Expected identifier, got end of input", codePoint); throw createException("Expected identifier, got end of input", codePoint);
} else if (!isIdentifierChar(codePoint)) { } else if (!isIdentifierStart(codePoint)) {
throw createException("Expected identifier (alphanumeric character)", codePoint); throw createException("Expected identifier (alphanumeric character)", codePoint);
} }
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
stringBuilder.appendCodePoint(codePoint); stringBuilder.appendCodePoint(codePoint);
boolean dot = false; boolean dot = false;
while ((codePoint = peekCodePoint()) >= 0) { while ((codePoint = peekCodePoint()) >= 0) {
if (isIdentifierChar(codePoint)) { if (isIdentifierPart(codePoint)) {
stringBuilder.appendCodePoint(nextCodePoint()); stringBuilder.appendCodePoint(nextCodePoint());
dot = false; dot = false;
} else if (codePoint == '.') { } else if (codePoint == '.') {
@@ -98,9 +110,20 @@ public class SerdePojoReaderWriterSpec {
return stringBuilder.toString(); return stringBuilder.toString();
} }
private boolean isIdentifierChar(int codePoint) { private boolean isIdentifierStart(int codePoint) {
return (codePoint >= '0' && codePoint <= '9') return isAlpha(codePoint) || codePoint == '_';
|| (codePoint >= 'a' && codePoint <= 'z') }
private boolean isIdentifierPart(int codePoint) {
return isAlphanumeric(codePoint) || codePoint == '_';
}
private boolean isAlphanumeric(int codePoint) {
return (codePoint >= '0' && codePoint <= '9') || isAlpha(codePoint);
}
private boolean isAlpha(int codePoint) {
return (codePoint >= 'a' && codePoint <= 'z')
|| (codePoint >= 'A' && codePoint <= 'Z'); || (codePoint >= 'A' && codePoint <= 'Z');
} }
@@ -167,4 +190,4 @@ public class SerdePojoReaderWriterSpec {
.toString(); .toString();
} }
} }
} }

View File

@@ -20,7 +20,8 @@ class SerdePojoReaderWriterSpecTest {
" abc() ,abc", " abc() ,abc",
" abc.123 ,abc.123", " abc.123 ,abc.123",
"abc.123 ( ) ,abc.123", "abc.123 ( ) ,abc.123",
"123.abc,123.abc", "_123._123,_123._123",
"ab_cd,ab_cd",
}) })
@SneakyThrows @SneakyThrows
void parseSimpleIdentifier(String input, String identifier) { void parseSimpleIdentifier(String input, String identifier) {
@@ -32,9 +33,9 @@ class SerdePojoReaderWriterSpecTest {
@Test @Test
@SneakyThrows @SneakyThrows
void parseNested() { void parseNested() {
SerdePojoReaderWriterSpec spec = SerdePojoReaderWriterSpec.parse("abc.def ( 12 ( def, ghi ( ) ), jkl ) "); SerdePojoReaderWriterSpec spec = SerdePojoReaderWriterSpec.parse("abc.def ( _12 ( def, ghi ( ) ), jkl ) ");
assertThat(spec).isEqualTo(new SerdePojoReaderWriterSpec("abc.def", Arrays.asList( assertThat(spec).isEqualTo(new SerdePojoReaderWriterSpec("abc.def", Arrays.asList(
new SerdePojoReaderWriterSpec("12", Arrays.asList( new SerdePojoReaderWriterSpec("_12", Arrays.asList(
new SerdePojoReaderWriterSpec("def", Collections.emptyList()), new SerdePojoReaderWriterSpec("def", Collections.emptyList()),
new SerdePojoReaderWriterSpec("ghi", Collections.emptyList()) new SerdePojoReaderWriterSpec("ghi", Collections.emptyList())
)), )),
@@ -51,6 +52,7 @@ class SerdePojoReaderWriterSpecTest {
",;1;,", ",;1;,",
"abc(,);5;,", "abc(,);5;,",
"abc..def;5;.", "abc..def;5;.",
"123.abc;1;1",
}) })
@SneakyThrows @SneakyThrows
void parseError(String input, int index, @Nullable String codePoint) { void parseError(String input, int index, @Nullable String codePoint) {