This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 050d7118c3 JUNEAU-206 - Fix bug with @Beanp(format)
050d7118c3 is described below
commit 050d7118c3594e736750d628e6f44e677d35c7d4
Author: James Bognar <[email protected]>
AuthorDate: Tue Oct 14 09:49:56 2025 -0400
JUNEAU-206 - Fix bug with @Beanp(format)
---
CLAUDE.md | 5 ++
.../java/org/apache/juneau/BeanPropertyMeta.java | 4 ++
juneau-docs/docs/release-notes/9.2.0.md | 15 ++++++
.../java/org/apache/juneau/html/Common_Test.java | 54 +++++++++++++++++++++
.../org/apache/juneau/http/header/Date_Test.java | 2 +-
.../http/remote/Remote_RequestAnnotation_Test.java | 2 +-
.../java/org/apache/juneau/json/Common_Test.java | 56 +++++++++++++++++++++-
.../org/apache/juneau/xml/CommonParser_Test.java | 2 +-
.../java/org/apache/juneau/xml/Common_Test.java | 54 +++++++++++++++++++++
9 files changed, 190 insertions(+), 4 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 8e6f27c44b..73f0bef73e 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -45,6 +45,11 @@ If you encounter situations where your code changes don't
appear to be taking ef
- Test results seem to reflect old code despite edits
- Compilation succeeds but runtime behavior is wrong
+**Java Runtime Location:**
+If you can't find Java on the file system using standard commands, look for it
in the `~/jdk` folder. For example:
+- Java 17 can be found at:
`~/jdk/openjdk_17.0.14.0.101_17.57.18_aarch64/bin/java`
+- Use this path when you need to run Java commands directly
+
### 5. HTML5 Bean Enhancement Rules
#### Javadoc Enhancement for HTML5 Beans
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index d522a9a75d..e68cc2e4e6 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -194,6 +194,8 @@ public class BeanPropertyMeta implements
Comparable<BeanPropertyMeta> {
isUri |= (rawTypeMeta.isUri());
}
lp.forEach(x -> {
+ if (swap == null)
+ swap = getPropertySwap(x);
if (! x.properties().isEmpty())
properties =
splita(x.properties());
addAll(bdClasses, x.dictionary());
@@ -213,6 +215,8 @@ public class BeanPropertyMeta implements
Comparable<BeanPropertyMeta> {
rawTypeMeta =
bc.resolveClassMeta(last(lp), getter.getGenericReturnType(), typeVarImpls);
isUri |= (rawTypeMeta.isUri() ||
bc.hasAnnotation(Uri.class, getter));
lp.forEach(x -> {
+ if (swap == null)
+ swap = getPropertySwap(x);
if (properties != null && !
x.properties().isEmpty())
properties =
splita(x.properties());
addAll(bdClasses, x.dictionary());
diff --git a/juneau-docs/docs/release-notes/9.2.0.md
b/juneau-docs/docs/release-notes/9.2.0.md
index c23c13857c..702ed8cfa0 100644
--- a/juneau-docs/docs/release-notes/9.2.0.md
+++ b/juneau-docs/docs/release-notes/9.2.0.md
@@ -371,6 +371,21 @@ Major changes include:
**Note**: Disabling JSON tags can cause different data to be parsed (e.g.,
strings instead of numbers) since type information is not preserved in the XML.
+#### Bug Fixes
+
+- **@Beanp(format) Not Working**: Fixed a bug where the `@Beanp(format="...")`
annotation was not applying `String.format()` patterns during bean
serialization. The issue was caused by missing calls to `getPropertySwap()`
when processing `@Beanp` annotations on fields and getter methods. This feature
now correctly formats numeric fields using Java format strings (e.g.,
`@Beanp(format="%.2f")` for floating-point values, `@Beanp(format="%05d")` for
zero-padded integers, `@Beanp(format="$%. [...]
+
+ Example:
+ ```java
+ public class Product {
+ @Beanp(format="$%.2f")
+ public float price = 19.99f; // Serializes as "$19.99"
+
+ @Beanp(format="%05d")
+ public int id = 42; // Serializes as "00042"
+ }
+ ```
+
### juneau-bct (NEW MODULE)
#### Bean-Centric Testing Framework
diff --git a/juneau-utest/src/test/java/org/apache/juneau/html/Common_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/html/Common_Test.java
index db1f8a9925..f74f5ac321 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/html/Common_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/html/Common_Test.java
@@ -413,4 +413,58 @@ class Common_Test extends TestBase {
return ("J(f1: " + this.getF1() + ", f2: " +
this.getF2() + ")");
}
}
+
+
//====================================================================================================
+ // @Beanp(format) tests
+
//====================================================================================================
+
+ @Test
+ void a10_beanpFormat() throws Exception {
+ var s =
HtmlSerializer.create().sq().sortProperties().addKeyValueTableHeaders().build();
+
+ var bean = new K();
+ var html = s.serialize(bean);
+
+ // Verify all formatted fields are serialized correctly
+ assertTrue(html.contains("<td>doubleField</td><td>2.718</td>"));
+ assertTrue(html.contains("<td>floatField</td><td>3.14</td>"));
+
assertTrue(html.contains("<td>floatWithCurrency</td><td>$19.99</td>"));
+ assertTrue(html.contains("<td>hexField</td><td>0xFF00FF</td>"));
+ assertTrue(html.contains("<td>intField</td><td>00042</td>"));
+
assertTrue(html.contains("<td>longField</td><td>0000001234567890</td>"));
+ assertTrue(html.contains("<td>name</td><td>Test</td>"));
+ assertTrue(html.contains("<td>privateField</td><td>9.88</td>"));
+
assertTrue(html.contains("<td>scientificField</td><td>6.022e+23</td>") ||
html.contains("<td>scientificField</td><td>6.022E+23</td>"));
+ }
+
+ public static class K {
+ @Beanp(format="%.2f")
+ public float floatField = 3.14159f;
+
+ @Beanp(format="$%.2f")
+ public float floatWithCurrency = 19.987f;
+
+ @Beanp(format="%.3f")
+ public double doubleField = 2.71828;
+
+ @Beanp(format="%05d")
+ public int intField = 42;
+
+ @Beanp(format="%016d")
+ public long longField = 1234567890L;
+
+ @Beanp(format="0x%06X")
+ public int hexField = 0xFF00FF;
+
+ @Beanp(format="%.3e")
+ public double scientificField = 6.02214076e23;
+
+ public String name = "Test";
+
+ @Beanp(format="%.2f")
+ private float privateField = 9.876f;
+
+ public float getPrivateField() { return privateField; }
+ public void setPrivateField(float f) { privateField = f; }
+ }
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/http/header/Date_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/http/header/Date_Test.java
index 5af13a56bf..f7819a1484 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/header/Date_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/header/Date_Test.java
@@ -34,7 +34,7 @@ import org.apache.juneau.rest.client.*;
import org.apache.juneau.rest.mock.*;
import org.junit.jupiter.api.*;
-class Date_Test extends TestBase{
+class Date_Test extends TestBase {
private static final String HEADER = "Date";
private static final String VALUE = "Sat, 29 Oct 1994 19:43:31 GMT";
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
index 7f55d4420e..fb9db795ff 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
@@ -29,7 +29,7 @@ import org.apache.juneau.rest.mock.*;
import org.apache.juneau.utest.utils.*;
import org.junit.jupiter.api.*;
-class Remote_RequestAnnotation_Test extends TestBase{
+class Remote_RequestAnnotation_Test extends TestBase {
//-----------------------------------------------------------------------------------------------------------------
// Basic tests
diff --git a/juneau-utest/src/test/java/org/apache/juneau/json/Common_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/json/Common_Test.java
index 1aebb49608..58b6044da4 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/json/Common_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/json/Common_Test.java
@@ -27,7 +27,7 @@ import org.apache.juneau.annotation.*;
import org.apache.juneau.collections.*;
import org.junit.jupiter.api.*;
-class Common_Test extends TestBase{
+class Common_Test extends TestBase {
//====================================================================================================
// Trim nulls from beans
@@ -294,4 +294,58 @@ class Common_Test extends TestBase{
return ("J(f1: " + this.getF1() + ", f2: " +
this.getF2() + ")");
}
}
+
+
//====================================================================================================
+ // @Beanp(format) tests
+
//====================================================================================================
+
+ @Test
+ void a10_beanpFormat() throws Exception {
+ var s =
JsonSerializer.create().json5().sortProperties().build();
+
+ var bean = new K();
+ var json = s.serialize(bean);
+
+ // Verify all formatted fields are serialized correctly
+ assertTrue(json.contains("floatField:'3.14'"));
+ assertTrue(json.contains("floatWithCurrency:'$19.99'"));
+ assertTrue(json.contains("doubleField:'2.718'"));
+ assertTrue(json.contains("privateField:'9.88'"));
+ assertTrue(json.contains("intField:'00042'"));
+ assertTrue(json.contains("longField:'0000001234567890'"));
+ assertTrue(json.contains("hexField:'0xFF00FF'"));
+ assertTrue(json.contains("scientificField:'6.022e+23'") ||
json.contains("scientificField:'6.022E+23'"));
+ assertTrue(json.contains("name:'Test'"));
+ }
+
+ public static class K {
+ @Beanp(format="%.2f")
+ public float floatField = 3.14159f;
+
+ @Beanp(format="$%.2f")
+ public float floatWithCurrency = 19.987f;
+
+ @Beanp(format="%.3f")
+ public double doubleField = 2.71828;
+
+ @Beanp(format="%05d")
+ public int intField = 42;
+
+ @Beanp(format="%016d")
+ public long longField = 1234567890L;
+
+ @Beanp(format="0x%06X")
+ public int hexField = 0xFF00FF;
+
+ @Beanp(format="%.3e")
+ public double scientificField = 6.02214076e23;
+
+ public String name = "Test";
+
+ @Beanp(format="%.2f")
+ private float privateField = 9.876f;
+
+ public float getPrivateField() { return privateField; }
+ public void setPrivateField(float f) { privateField = f; }
+ }
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/xml/CommonParser_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/xml/CommonParser_Test.java
index 015b934ada..5a685ab73b 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/xml/CommonParser_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/xml/CommonParser_Test.java
@@ -27,7 +27,7 @@ import org.apache.juneau.parser.*;
import org.junit.jupiter.api.*;
@SuppressWarnings({"rawtypes","serial"})
-class CommonParser_Test extends TestBase{
+class CommonParser_Test extends TestBase {
//====================================================================================================
// testFromSerializer
diff --git a/juneau-utest/src/test/java/org/apache/juneau/xml/Common_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/xml/Common_Test.java
index 961b7a4542..489aeea94f 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/xml/Common_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/xml/Common_Test.java
@@ -247,4 +247,58 @@ class Common_Test extends TestBase {
public String name = "baz";
public R1 r1;
}
+
+
//====================================================================================================
+ // @Beanp(format) tests
+
//====================================================================================================
+
+ @Test
+ void a08_beanpFormat() throws Exception {
+ var s = XmlSerializer.create().sq().sortProperties().build();
+
+ var bean = new K();
+ var xml = s.serialize(bean);
+
+ // Verify all formatted fields are serialized correctly
+ assertTrue(xml.contains("<doubleField>2.718</doubleField>"));
+ assertTrue(xml.contains("<floatField>3.14</floatField>"));
+
assertTrue(xml.contains("<floatWithCurrency>$19.99</floatWithCurrency>"));
+ assertTrue(xml.contains("<hexField>0xFF00FF</hexField>"));
+ assertTrue(xml.contains("<intField>00042</intField>"));
+
assertTrue(xml.contains("<longField>0000001234567890</longField>"));
+ assertTrue(xml.contains("<name>Test</name>"));
+ assertTrue(xml.contains("<privateField>9.88</privateField>"));
+
assertTrue(xml.contains("<scientificField>6.022e+23</scientificField>") ||
xml.contains("<scientificField>6.022E+23</scientificField>"));
+ }
+
+ public static class K {
+ @Beanp(format="%.2f")
+ public float floatField = 3.14159f;
+
+ @Beanp(format="$%.2f")
+ public float floatWithCurrency = 19.987f;
+
+ @Beanp(format="%.3f")
+ public double doubleField = 2.71828;
+
+ @Beanp(format="%05d")
+ public int intField = 42;
+
+ @Beanp(format="%016d")
+ public long longField = 1234567890L;
+
+ @Beanp(format="0x%06X")
+ public int hexField = 0xFF00FF;
+
+ @Beanp(format="%.3e")
+ public double scientificField = 6.02214076e23;
+
+ public String name = "Test";
+
+ @Beanp(format="%.2f")
+ private float privateField = 9.876f;
+
+ public float getPrivateField() { return privateField; }
+ public void setPrivateField(float f) { privateField = f; }
+ }
}
\ No newline at end of file