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/),
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
### Changed

View File

@@ -7,6 +7,18 @@ import java.util.Collections;
import java.util.List;
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
public class SerdePojoReaderWriterSpec {
String identifier;
@@ -71,14 +83,14 @@ public class SerdePojoReaderWriterSpec {
int codePoint = nextCodePoint();
if (codePoint == -1) {
throw createException("Expected identifier, got end of input", codePoint);
} else if (!isIdentifierChar(codePoint)) {
} else if (!isIdentifierStart(codePoint)) {
throw createException("Expected identifier (alphanumeric character)", codePoint);
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.appendCodePoint(codePoint);
boolean dot = false;
while ((codePoint = peekCodePoint()) >= 0) {
if (isIdentifierChar(codePoint)) {
if (isIdentifierPart(codePoint)) {
stringBuilder.appendCodePoint(nextCodePoint());
dot = false;
} else if (codePoint == '.') {
@@ -98,9 +110,20 @@ public class SerdePojoReaderWriterSpec {
return stringBuilder.toString();
}
private boolean isIdentifierChar(int codePoint) {
return (codePoint >= '0' && codePoint <= '9')
|| (codePoint >= 'a' && codePoint <= 'z')
private boolean isIdentifierStart(int codePoint) {
return isAlpha(codePoint) || codePoint == '_';
}
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');
}

View File

@@ -20,7 +20,8 @@ class SerdePojoReaderWriterSpecTest {
" abc() ,abc",
" abc.123 ,abc.123",
"abc.123 ( ) ,abc.123",
"123.abc,123.abc",
"_123._123,_123._123",
"ab_cd,ab_cd",
})
@SneakyThrows
void parseSimpleIdentifier(String input, String identifier) {
@@ -32,9 +33,9 @@ class SerdePojoReaderWriterSpecTest {
@Test
@SneakyThrows
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(
new SerdePojoReaderWriterSpec("12", Arrays.asList(
new SerdePojoReaderWriterSpec("_12", Arrays.asList(
new SerdePojoReaderWriterSpec("def", Collections.emptyList()),
new SerdePojoReaderWriterSpec("ghi", Collections.emptyList())
)),
@@ -51,6 +52,7 @@ class SerdePojoReaderWriterSpecTest {
",;1;,",
"abc(,);5;,",
"abc..def;5;.",
"123.abc;1;1",
})
@SneakyThrows
void parseError(String input, int index, @Nullable String codePoint) {