You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2020/03/14 15:54:43 UTC
[juneau] branch master updated: JUNEAU-187
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 9249b14 JUNEAU-187
9249b14 is described below
commit 9249b147a9d3f189035bccb6edc7f68a6c1c84a4
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sat Mar 14 11:54:26 2020 -0400
JUNEAU-187
HtmlSerializer does not honor @Bean(bpi) on collections of beans with
null values in first row.
---
.../java/org/apache/juneau/html/CommonTest.java | 20 ++--
.../test/java/org/apache/juneau/html/HtmlTest.java | 54 +++++++--
.../juneau/transforms/CalendarSwapComboTest.java | 6 +-
.../juneau/transforms/DateSwapComboTest.java | 6 +-
.../juneau/transforms/ReaderObjectSwapTest.java | 6 +-
.../main/java/org/apache/juneau/BeanSession.java | 5 +
.../org/apache/juneau/html/HtmlParserSession.java | 5 +-
.../apache/juneau/html/HtmlSerializerSession.java | 122 ++++++---------------
.../juneau/serializer/SerializerSession.java | 6 +-
juneau-doc/docs/ReleaseNotes/8.1.4.html | 6 +
10 files changed, 116 insertions(+), 120 deletions(-)
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/CommonTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/CommonTest.java
index 5832564..60d30e3 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/CommonTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/CommonTest.java
@@ -112,19 +112,19 @@ public class CommonTest {
s.trimEmptyCollections(false);
r = s.build().serialize(t1);
- assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><ul></ul></td></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r);
+ assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><ul></ul></td></tr><tr><td>f2</td><td><table _type='array'><tr><th>s1</th><th>s2</th></tr><tr><null/></tr><tr><td><null/></td><td>s2</td></tr></table></td></tr></table>", r);
t2 = p.parse(r, C.class);
assertEqualObjects(t1, t2);
s.trimEmptyCollections(true);
r = s.build().serialize(t1);
- assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r);
+ assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table _type='array'><tr><th>s1</th><th>s2</th></tr><tr><null/></tr><tr><td><null/></td><td>s2</td></tr></table></td></tr></table>", r);
t2 = p.parse(r, C.class);
assertNull(t2.f1);
s.trimEmptyCollections();
r = s.build().serialize(t1);
- assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r);
+ assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table _type='array'><tr><th>s1</th><th>s2</th></tr><tr><null/></tr><tr><td><null/></td><td>s2</td></tr></table></td></tr></table>", r);
t2 = p.parse(r, C.class);
assertNull(t2.f1);
}
@@ -163,14 +163,15 @@ public class CommonTest {
+"<td>f2</td>"
+"<td>"
+"<table _type='array'>"
- +"<tr><th>s2</th></tr>"
+ +"<tr><th>s1</th><th>s2</th></tr>"
+"<tr><null/></tr>"
- +"<tr><td>s2</td></tr>"
+ +"<tr><td><null/></td><td>s2</td></tr>"
+"</table>"
+"</td>"
+"</tr>"
+"</table>",
r);
+
t2 = p.parse(r, D.class);
assertEqualObjects(t1, t2);
@@ -183,9 +184,9 @@ public class CommonTest {
+"<td>f2</td>"
+"<td>"
+"<table _type='array'>"
- +"<tr><th>s2</th></tr>"
+ +"<tr><th>s1</th><th>s2</th></tr>"
+"<tr><null/></tr>"
- +"<tr><td>s2</td></tr>"
+ +"<tr><td><null/></td><td>s2</td></tr>"
+"</table>"
+"</td>"
+"</tr>"
@@ -203,9 +204,9 @@ public class CommonTest {
+"<td>f2</td>"
+"<td>"
+"<table _type='array'>"
- +"<tr><th>s2</th></tr>"
+ +"<tr><th>s1</th><th>s2</th></tr>"
+"<tr><null/></tr>"
- +"<tr><td>s2</td></tr>"
+ +"<tr><td><null/></td><td>s2</td></tr>"
+"</table>"
+"</td>"
+"</tr>"
@@ -340,6 +341,7 @@ public class CommonTest {
+"<td>2</td>"
+"</tr>"
+"</table>", html);
+
}
public static class F {
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/HtmlTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/HtmlTest.java
index c549564..0332904 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/HtmlTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/HtmlTest.java
@@ -18,6 +18,7 @@ import static org.junit.Assert.*;
import java.util.*;
import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
import org.apache.juneau.html.annotation.*;
import org.apache.juneau.testutils.pojos.*;
import org.junit.*;
@@ -29,7 +30,7 @@ public class HtmlTest {
// Verifies that lists of maps/beans are converted to tables correctly.
//-----------------------------------------------------------------------------------------------------------------
@Test
- public void testTables1() throws Exception {
+ public void a01_testTables1() throws Exception {
HtmlSerializer s = HtmlSerializer.DEFAULT_SQ;
Object[] t;
String html;
@@ -48,7 +49,7 @@ public class HtmlTest {
// Test URI_ANCHOR_SET options
//-----------------------------------------------------------------------------------------------------------------
@Test
- public void testAnchorTextOptions() throws Exception {
+ public void a02_testAnchorTextOptions() throws Exception {
HtmlSerializerBuilder s = HtmlSerializer.create().sq().addKeyValueTableHeaders().uriResolution(UriResolution.NONE);
TestURI t = new TestURI();
String r;
@@ -209,7 +210,7 @@ public class HtmlTest {
// Test @Html.asPlainText annotation on classes and fields
//-----------------------------------------------------------------------------------------------------------------
@Test
- public void testHtmlAnnotationAsPlainText() throws Exception {
+ public void b01_testHtmlAnnotationAsPlainText() throws Exception {
HtmlSerializer s = HtmlSerializer.create().sq().addKeyValueTableHeaders().build();
Object o = null;
String r;
@@ -238,7 +239,7 @@ public class HtmlTest {
}
@Test
- public void testHtmlAnnotationAsPlainText_usingConfig() throws Exception {
+ public void b02_testHtmlAnnotationAsPlainText_usingConfig() throws Exception {
HtmlSerializer s = HtmlSerializer.create().sq().addKeyValueTableHeaders().applyAnnotations(B3.class).applyAnnotations(B4.class).build();
Object o = null;
@@ -271,7 +272,7 @@ public class HtmlTest {
// Test @Html.asXml annotation on classes and fields
//-----------------------------------------------------------------------------------------------------------------
@Test
- public void testHtmlAnnotationAsXml() throws Exception {
+ public void c01_testHtmlAnnotationAsXml() throws Exception {
HtmlSerializer s = HtmlSerializer.create().sq().addKeyValueTableHeaders().build();
Object o = null;
String r;
@@ -296,7 +297,7 @@ public class HtmlTest {
}
@Test
- public void testHtmlAnnotationAsXml_usingConfig() throws Exception {
+ public void c02_testHtmlAnnotationAsXml_usingConfig() throws Exception {
HtmlSerializer s = HtmlSerializer.create().sq().addKeyValueTableHeaders().applyAnnotations(C3.class).build();
Object o = null;
String r;
@@ -323,7 +324,7 @@ public class HtmlTest {
// Test @Html.noTableHeaders
//-----------------------------------------------------------------------------------------------------------------
@Test
- public void testNoTableHeaders() throws Exception {
+ public void d01_testNoTableHeaders() throws Exception {
HtmlSerializer s = HtmlSerializer.DEFAULT_SQ;
Object o = null;
String r;
@@ -339,7 +340,7 @@ public class HtmlTest {
public static class MyMap extends LinkedHashMap<String,String> {}
@Test
- public void testNoTableHeaders_usingConfig() throws Exception {
+ public void d02_testNoTableHeaders_usingConfig() throws Exception {
HtmlSerializer s = HtmlSerializer.DEFAULT_SQ.builder().applyAnnotations(MyMap2.class).build();
Object o = null;
String r;
@@ -358,7 +359,7 @@ public class HtmlTest {
// Test @Html.noTableHeaders on beans
//-----------------------------------------------------------------------------------------------------------------
@Test
- public void testNoTableHeadersOnBeans() throws Exception {
+ public void d03_testNoTableHeadersOnBeans() throws Exception {
HtmlSerializer s = HtmlSerializer.DEFAULT_SQ;
Object o = null;
String r;
@@ -375,7 +376,7 @@ public class HtmlTest {
}
@Test
- public void testNoTableHeadersOnBeans_usingConfig() throws Exception {
+ public void d04_testNoTableHeadersOnBeans_usingConfig() throws Exception {
HtmlSerializer s = HtmlSerializer.DEFAULT_SQ.builder().applyAnnotations(MyBean2.class).build();
Object o = null;
String r;
@@ -392,7 +393,7 @@ public class HtmlTest {
}
@Test
- public void testNoTableHeadersOnBeans_usingConcreteAnnotation() throws Exception {
+ public void d05_testNoTableHeadersOnBeans_usingConcreteAnnotation() throws Exception {
HtmlSerializer s = HtmlSerializer.DEFAULT_SQ.builder().annotations(new HtmlAnnotation("MyBean2").noTables(true)).build();
Object o = null;
String r;
@@ -402,4 +403,35 @@ public class HtmlTest {
r = s.serialize(o);
assertEquals("<table _type='array'><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>1</td><td>2</td><td>3</td></tr></table>", r);
}
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // @Bean(bpi) on collections of beans
+ //-----------------------------------------------------------------------------------------------------------------
+
+ @Bean(bpi="f3,f2,f1")
+ public static class E {
+ public Integer f1, f2, f3;
+
+ public E(Integer f1, Integer f2, Integer f3) {
+ this.f1 = f1;
+ this.f2 = f2;
+ this.f3 = f3;
+ }
+ }
+
+ @Test
+ public void e01_collectionOfBeansWithBpi() throws Exception {
+ E[] ee = new E[]{
+ new E(null, 2, 3),
+ new E(4, 5, 6)
+ };
+ assertEquals("<table _type='array'><tr><th>f3</th><th>f2</th><th>f1</th></tr><tr><td>3</td><td>2</td><td><null/></td></tr><tr><td>6</td><td>5</td><td>4</td></tr></table>", HtmlSerializer.DEFAULT_SQ.toString(ee));
+ assertEquals("<table _type='array'><tr><th>f3</th><th>f2</th><th>f1</th></tr><tr><td>3</td><td>2</td><td><null/></td></tr><tr><td>6</td><td>5</td><td>4</td></tr></table>", HtmlSerializer.DEFAULT_SQ.toString(Arrays.asList(ee)));
+
+ ee = new E[] {
+ new E(null, null, null),
+ new E(null, null, null)
+ };
+ assertEquals("<table _type='array'><tr><th>f3</th><th>f2</th><th>f1</th></tr><tr><td><null/></td><td><null/></td><td><null/></td></tr><tr><td><null/></td><td><null/></td><td><null/></td></tr></table>", HtmlSerializer.DEFAULT_SQ.toString(ee));
+ }
}
\ No newline at end of file
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
index f8f64e5..d99f6c4 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
@@ -514,9 +514,9 @@ public class CalendarSwapComboTest extends ComboRoundTripTest {
/* XmlT */ "<array><object><time t='number'>-2172116928000</time><timeZone>PST</timeZone></object></array>",
/* XmlR */ "<array>\n\t<object>\n\t\t<time _type='number'>-2172116928000</time>\n\t\t<timeZone>PST</timeZone>\n\t</object>\n</array>\n",
/* XmlNs */ "<array><object><time _type='number'>-2172116928000</time><timeZone>PST</timeZone></object></array>",
- /* Html */ "<ul><li><table><tr><td>time</td><td><number>-2172116928000</number></td></tr><tr><td>timeZone</td><td>PST</td></tr></table></li></ul>",
- /* HtmlT */ "<ul><li><table><tr><td>time</td><td><number>-2172116928000</number></td></tr><tr><td>timeZone</td><td>PST</td></tr></table></li></ul>",
- /* HtmlR */ "<ul>\n\t<li>\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td>time</td>\n\t\t\t\t<td><number>-2172116928000</number></td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td>timeZone</td>\n\t\t\t\t<td>PST</td>\n\t\t\t</tr>\n\t\t</table>\n\t</li>\n</ul>\n",
+ /* Html */ "<table _type='array'><tr><th>time</th><th>timeZone</th></tr><tr><td><number>-2172116928000</number></td><td>PST</td></tr></table>",
+ /* HtmlT */ "<table t='array'><tr><th>time</th><th>timeZone</th></tr><tr><td><number>-2172116928000</number></td><td>PST</td></tr></table>",
+ /* HtmlR */ "<table _type='array'>\n\t<tr>\n\t\t<th>time</th>\n\t\t<th>timeZone</th>\n\t</tr>\n\t<tr>\n\t\t<td><number>-2172116928000</number></td>\n\t\t<td>PST</td>\n\t</tr>\n</table>\n",
/* Uon */ "@((time=-2172116928000,timeZone=PST))",
/* UonT */ "@((time=-2172116928000,timeZone=PST))",
/* UonR */ "@(\n\t(\n\t\ttime=-2172116928000,\n\t\ttimeZone=PST\n\t)\n)",
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
index 1536bd4..389a890 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
@@ -510,9 +510,9 @@ public class DateSwapComboTest extends ComboRoundTripTest {
/* XmlT */ "<array><object><time t='number'>-2172116928000</time></object></array>",
/* XmlR */ "<array>\n\t<object>\n\t\t<time _type='number'>-2172116928000</time>\n\t</object>\n</array>\n",
/* XmlNs */ "<array><object><time _type='number'>-2172116928000</time></object></array>",
- /* Html */ "<ul><li><table><tr><td>time</td><td><number>-2172116928000</number></td></tr></table></li></ul>",
- /* HtmlT */ "<ul><li><table><tr><td>time</td><td><number>-2172116928000</number></td></tr></table></li></ul>",
- /* HtmlR */ "<ul>\n\t<li>\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td>time</td>\n\t\t\t\t<td><number>-2172116928000</number></td>\n\t\t\t</tr>\n\t\t</table>\n\t</li>\n</ul>\n",
+ /* Html */ "<table _type='array'><tr><th>time</th></tr><tr><td><number>-2172116928000</number></td></tr></table>",
+ /* HtmlT */ "<table t='array'><tr><th>time</th></tr><tr><td><number>-2172116928000</number></td></tr></table>",
+ /* HtmlR */ "<table _type='array'>\n\t<tr>\n\t\t<th>time</th>\n\t</tr>\n\t<tr>\n\t\t<td><number>-2172116928000</number></td>\n\t</tr>\n</table>\n",
/* Uon */ "@((time=-2172116928000))",
/* UonT */ "@((time=-2172116928000))",
/* UonR */ "@(\n\t(\n\t\ttime=-2172116928000\n\t)\n)",
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
index 4208b6e..48272b4 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/ReaderObjectSwapTest.java
@@ -299,9 +299,9 @@ public class ReaderObjectSwapTest extends ComboSerializeTest {
/* XmlT */ "<object><f><object><f1>x1a-xml</f1><f2>x2a-xmlx2b-xml<null/></f2><f4>x4a-xmlx4b-xml<null/></f4><f5><foo>x5a-xml</foo><bar t='null'/><_x0000_>x5c-xml</_x0000_></f5></object><null/></f></object>",
/* XmlR */ "<object>\n\t<f>\n\t\t<object>\n\t\t\t<f1>x1a-xml</f1>\n\t\t\t<f2>\n\t\t\t\tx2a-xml\n\t\t\t\tx2b-xml\n\t\t\t\t<null/>\n\t\t\t</f2>\n\t\t\t<f4>\n\t\t\t\tx4a-xml\n\t\t\t\tx4b-xml\n\t\t\t\t<null/>\n\t\t\t</f4>\n\t\t\t<f5>\n\t\t\t\t<foo>x5a-xml</foo>\n\t\t\t\t<bar _type='null'/>\n\t\t\t\t<_x0000_>x5c-xml</_x0000_>\n\t\t\t</f5>\n\t\t</object>\n\t\t<null/>\n\t</f>\n</object>\n",
/* XmlNs */ "<object><f><object><f1>x1a-xml</f1><f2>x2a-xmlx2b-xml<null/></f2><f4>x4a-xmlx4b-xml<null/></f4><f5><foo>x5a-xml</foo><bar _type='null'/><_x0000_>x5c-xml</_x0000_></f5></object><null/></f></object>",
- /* Html */ "<table><tr><td>f</td><td><table _type='array'><tr><th>f1</th><th>f2</th><th>f4</th><th>f5</th></tr><tr><td>x1a-html</td><td><ul><li>x2a-html</li><li>x2b-html</li><li><null/></li></ul></td><td><ul><li>x4a-html</li><li>x4b-html</li><li><null/></li></ul></td><td><table><tr><td>foo</td><td>x5a-html</td></tr><tr><td>bar</td><td><null/></td></tr><tr><td><null/></td><td>x5c-html</td></tr></table></td></tr><tr><null/></tr></table></td></tr></table>",
- /* HtmlT */ "<table><tr><td>f</td><td><table t='array'><tr><th>f1</th><th>f2</th><th>f4</th><th>f5</th></tr><tr><td>x1a-html</td><td><ul><li>x2a-html</li><li>x2b-html</li><li><null/></li></ul></td><td><ul><li>x4a-html</li><li>x4b-html</li><li><null/></li></ul></td><td><table><tr><td>foo</td><td>x5a-html</td></tr><tr><td>bar</td><td><null/></td></tr><tr><td><null/></td><td>x5c-html</td></tr></table></td></tr><tr><null/></tr></table></td></tr></table>",
- /* HtmlR */ "<table>\n\t<tr>\n\t\t<td>f</td>\n\t\t<td>\n\t\t\t<table _type='array'>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>f1</th>\n\t\t\t\t\t<th>f2</th>\n\t\t\t\t\t<th>f4</th>\n\t\t\t\t\t<th>f5</th>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>x1a-html</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t<li>x2a-html</li>\n\t\t\t\t\t\t\t<li>x2b-html</li>\n\t\t\t\t\t\t\t<li><null/></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t<li>x4a-html</li>\n\t [...]
+ /* Html */ "<table><tr><td>f</td><td><table _type='array'><tr><th>f1</th><th>f2</th><th>f3</th><th>f4</th><th>f5</th></tr><tr><td>x1a-html</td><td><ul><li>x2a-html</li><li>x2b-html</li><li><null/></li></ul></td><td><null/></td><td><ul><li>x4a-html</li><li>x4b-html</li><li><null/></li></ul></td><td><table><tr><td>foo</td><td>x5a-html</td></tr><tr><td>bar</td><td><null/></td></tr><tr><td><null/></td><td>x5c-html</td></tr></table></td></tr><tr><null/></tr></table></td></tr></table>",
+ /* HtmlT */ "<table><tr><td>f</td><td><table t='array'><tr><th>f1</th><th>f2</th><th>f3</th><th>f4</th><th>f5</th></tr><tr><td>x1a-html</td><td><ul><li>x2a-html</li><li>x2b-html</li><li><null/></li></ul></td><td><null/></td><td><ul><li>x4a-html</li><li>x4b-html</li><li><null/></li></ul></td><td><table><tr><td>foo</td><td>x5a-html</td></tr><tr><td>bar</td><td><null/></td></tr><tr><td><null/></td><td>x5c-html</td></tr></table></td></tr><tr><null/></tr></table></td></tr></table>",
+ /* HtmlR */ "<table>\n\t<tr>\n\t\t<td>f</td>\n\t\t<td>\n\t\t\t<table _type='array'>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>f1</th>\n\t\t\t\t\t<th>f2</th>\n\t\t\t\t\t<th>f3</th>\n\t\t\t\t\t<th>f4</th>\n\t\t\t\t\t<th>f5</th>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>x1a-html</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t<li>x2a-html</li>\n\t\t\t\t\t\t\t<li>x2b-html</li>\n\t\t\t\t\t\t\t<li><null/></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td><null/></td>\n\t\t\t\t\t<td>\n\t [...]
/* Uon */ "(f=@((f1=x1a-uon,f2=@(x2a-uon,x2b-uon,null),f4=@(x4a-uon,x4b-uon,null),f5=(foo=x5a-uon,bar=null,null=x5c-uon)),null))",
/* UonT */ "(f=@((f1=x1a-uon,f2=@(x2a-uon,x2b-uon,null),f4=@(x4a-uon,x4b-uon,null),f5=(foo=x5a-uon,bar=null,null=x5c-uon)),null))",
/* UonR */ "(\n\tf=@(\n\t\t(\n\t\t\tf1=x1a-uon,\n\t\t\tf2=@(\n\t\t\t\tx2a-uon,\n\t\t\t\tx2b-uon,\n\t\t\t\tnull\n\t\t\t),\n\t\t\tf4=@(\n\t\t\t\tx4a-uon,\n\t\t\t\tx4b-uon,\n\t\t\t\tnull\n\t\t\t),\n\t\t\tf5=(\n\t\t\t\tfoo=x5a-uon,\n\t\t\t\tbar=null,\n\t\t\t\tnull=x5c-uon\n\t\t\t)\n\t\t),\n\t\tnull\n\t)\n)",
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 88985a0..0d58457 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -756,6 +756,9 @@ public class BeanSession extends Session {
* If object is not a true bean, then throws a {@link BeanRuntimeException} with an explanation of why it's not a
* bean.
*
+ * <p>
+ * If object is already a {@link BeanMap}, simply returns the same object.
+ *
* <h5 class='section'>Example:</h5>
* <p class='bcode w800'>
* <jc>// Construct a bean map around a bean instance</jc>
@@ -767,6 +770,8 @@ public class BeanSession extends Session {
* @return The wrapped object.
*/
public final <T> BeanMap<T> toBeanMap(T o) {
+ if (o instanceof BeanMap)
+ return (BeanMap<T>)o;
return this.toBeanMap(o, (Class<T>)o.getClass());
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
index dc00be3..85266d4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParserSession.java
@@ -486,7 +486,10 @@ public final class HtmlParserSession extends XmlParserSession {
m2.put(getBeanTypePropertyName(type.getElementType()), c);
l.add((E)cast(m2, pMeta, elementType));
} else {
- l.add((E)m);
+ if (m instanceof ObjectMap)
+ l.add((E)convertToType(m, elementType));
+ else
+ l.add((E)m);
}
}
nextTag(r, xTR);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index 72dac32..e5c5f10 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -608,11 +608,7 @@ public class HtmlSerializerSession extends XmlSerializerSession {
out.eTag("td").nl(i+2);
}
} else {
- BeanMap m2 = null;
- if (o instanceof BeanMap)
- m2 = (BeanMap)o;
- else
- m2 = toBeanMap(o);
+ BeanMap m2 = toBeanMap(o);
if (th == null)
th = m2.keySet().toArray(new Object[m2.size()]);
@@ -712,15 +708,17 @@ public class HtmlSerializerSession extends XmlSerializerSession {
/*
* Returns the table column headers for the specified collection of objects.
* Returns null if collection should not be serialized as a 2-dimensional table.
+ * Returns an empty array if it should be treated as a table but without headers.
* 2-dimensional tables are used for collections of objects that all have the same set of property names.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Object[] getTableHeaders(Collection c, HtmlBeanPropertyMeta bpHtml) throws SerializeException {
+
if (c.size() == 0)
return null;
+
c = sort(c);
- Object[] th;
- Set<ClassMeta> prevC = new HashSet<>();
+
Object o1 = null;
for (Object o : c)
if (o != null) {
@@ -729,107 +727,55 @@ public class HtmlSerializerSession extends XmlSerializerSession {
}
if (o1 == null)
return null;
- ClassMeta<?> cm = getClassMetaForObject(o1);
- PojoSwap swap = cm.getPojoSwap(this);
- if (swap != null) {
- o1 = swap(swap, o1);
- cm = swap.getSwapClassMeta(this);
- }
+ ClassMeta<?> cm1 = getClassMetaForObject(o1);
- if (cm == null || ! cm.isMapOrBean())
- return null;
- if (cm.hasAnnotation(HtmlLink.class))
+ PojoSwap swap = cm1.getPojoSwap(this);
+ o1 = swap(swap, o1);
+ if (swap != null)
+ cm1 = swap.getSwapClassMeta(this);
+
+ if (cm1 == null || ! cm1.isMapOrBean() || cm1.hasAnnotation(HtmlLink.class))
return null;
- HtmlClassMeta cHtml = getHtmlClassMeta(cm);
+ HtmlClassMeta cHtml = getHtmlClassMeta(cm1);
- if (cHtml.isNoTables() || bpHtml.isNoTables() || cHtml.isXml() || bpHtml.isXml())
+ if (cHtml.isNoTables() || bpHtml.isNoTables() || cHtml.isXml() || bpHtml.isXml() || canIgnoreValue(cm1, null, o1))
return null;
+
if (cHtml.isNoTableHeaders() || bpHtml.isNoTableHeaders())
return new Object[0];
- if (canIgnoreValue(cm, null, o1))
- return null;
- if (cm.isMap() && ! cm.isBeanMap()) {
+
+ // If it's a non-bean map, only use table if all entries are also maps.
+ if (cm1.isMap() && ! cm1.isBeanMap()) {
+
Set<Object> set = new LinkedHashSet<>();
for (Object o : c) {
- if (! canIgnoreValue(cm, null, o)) {
- if (! cm.isInstance(o))
+ o = swap(swap, o);
+ if (! canIgnoreValue(cm1, null, o)) {
+ if (! cm1.isInstance(o))
return null;
Map m = sort((Map)o);
- for (Map.Entry e : (Set<Map.Entry>)m.entrySet()) {
- if (e.getValue() != null)
- set.add(e.getKey() == null ? null : e.getKey());
- }
- }
- }
- th = set.toArray(new Object[set.size()]);
- } else {
- Map<String,Boolean> m = new LinkedHashMap<>();
- for (Object o : c) {
- if (! canIgnoreValue(cm, null, o)) {
- if (! cm.isInstance(o))
- return null;
- BeanMap<?> bm = (o instanceof BeanMap ? (BeanMap)o : toBeanMap(o));
- for (Map.Entry<String,Object> e : bm.entrySet()) {
- String key = e.getKey();
- if (e.getValue() != null)
- m.put(key, true);
- else if (! m.containsKey(key))
- m.put(key, false);
- }
+ for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
+ if (! set.contains(e.getKey()))
+ set.add(e.getKey());
}
}
- for (Iterator<Boolean> i = m.values().iterator(); i.hasNext();)
- if (! i.next())
- i.remove();
- th = m.keySet().toArray(new Object[m.size()]);
+ return set.toArray(new Object[set.size()]);
+
}
- prevC.add(cm);
- boolean isSortable = true;
- for (Object o : th)
- isSortable &= (o instanceof Comparable);
- Set<Object> s = (isSortable ? new TreeSet<>() : new LinkedHashSet<>());
- s.addAll(Arrays.asList(th));
+ // Must be a bean or BeanMap.
for (Object o : c) {
- if (o == null)
- continue;
- cm = getClassMetaForObject(o);
-
- PojoSwap ps = cm == null ? null : cm.getPojoSwap(this);
- if (ps != null) {
- o = swap(ps, o);
- cm = ps.getSwapClassMeta(this);
- }
- if (prevC.contains(cm))
- continue;
- if (cm == null || ! (cm.isMap() || cm.isBean()))
- return null;
- if (cm.hasAnnotation(HtmlLink.class))
- return null;
- if (canIgnoreValue(cm, null, o))
- return null;
- if (cm.isMap() && ! cm.isBeanMap()) {
- Map m = (Map)o;
- if (th.length != m.keySet().size())
- return null;
- for (Object k : m.keySet())
- if (! s.contains(k.toString()))
- return null;
- } else {
- BeanMap<?> bm = (o instanceof BeanMap ? (BeanMap)o : toBeanMap(o));
- int l = 0;
- for (String k : bm.keySet()) {
- if (! s.contains(k))
- return null;
- l++;
- }
- if (s.size() != l)
+ o = swap(swap, o);
+ if (! canIgnoreValue(cm1, null, o)) {
+ if (! cm1.isInstance(o))
return null;
}
}
- return th;
+
+ BeanMap<?> bm = toBeanMap(o1);
+ return bm.keySet().toArray(new String[bm.size()]);
}
//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 2991a09..fa9a06e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -653,9 +653,9 @@ public abstract class SerializerSession extends BeanTraverseSession {
}
/**
- * Invokes the specified swap on the specified object.
+ * Invokes the specified swap on the specified object if the swap is not null.
*
- * @param swap The swap to invoke.
+ * @param swap The swap to invoke. Can be <jk>null</jk>.
* @param o The input object.
* @return The swapped object.
* @throws SerializeException If swap method threw an exception.
@@ -663,6 +663,8 @@ public abstract class SerializerSession extends BeanTraverseSession {
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object swap(PojoSwap swap, Object o) throws SerializeException {
try {
+ if (swap == null)
+ return o;
return swap.swap(this, o);
} catch (Exception e) {
throw new SerializeException(e);
diff --git a/juneau-doc/docs/ReleaseNotes/8.1.4.html b/juneau-doc/docs/ReleaseNotes/8.1.4.html
index f8b10de..4fc0812 100644
--- a/juneau-doc/docs/ReleaseNotes/8.1.4.html
+++ b/juneau-doc/docs/ReleaseNotes/8.1.4.html
@@ -142,6 +142,12 @@
<li>
New {@link oaj.html.annotation.HtmlDoc#asideFloat} setting so that you can position the contents of the aside section on the page.
<li>
+ Various minor fixes surrounding HTML serialization.
+ <ul>
+ <li>Collections of beans that were supposed to be serialized as tables were being serialized as lists.
+ <li>Collections of beans with <c><ja>@Bean</ja>(bpi)</c> were not being serialized in the correct column order.
+ </ul>
+ <li>
HTML-Schema support is being deprecated due to low-use and difficulty in maintaining. It will be removed in 9.0.
</ul>