Better representation of null bean content properties.
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
index 4ee4b0b..918c67c 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
@@ -16,11 +16,13 @@
import static org.junit.Assert.*;
import java.util.*;
+import java.util.Map;
import javax.xml.datatype.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.dto.html5.*;
import org.apache.juneau.json.*;
import org.apache.juneau.json.annotation.*;
import org.apache.juneau.parser.*;
@@ -959,4 +961,33 @@
return m;
}
}
+
+ //====================================================================================================
+ // testBeanPropertyWithBeanWithAttrsField
+ //====================================================================================================
+
+ @Test
+ public void testBeanPropertyWithBeanWithAttrsField() throws Exception {
+ N t = N.create();
+ t = roundTrip(t, N.class);
+
+ t.f1.type("foo");
+ t = roundTrip(t, N.class);
+
+ t.f1.attr("foo", "bar").attrUri("href", "http://foo");
+ t = roundTrip(t, N.class);
+
+ Head h = new Head().child(new Style());
+ h = roundTrip(h, Head.class);
+ }
+
+ public static class N {
+ public Style f1;
+
+ static N create() {
+ N n = new N();
+ n.f1 = new Style();
+ return n;
+ }
+ }
}
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
index 9091240..2a3af7d 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
@@ -177,13 +177,13 @@
/* Json */ "{_type:'a',a:{href:'http://foo'}}",
/* JsonT */ "{t:'a',a:{href:'http://foo'}}",
/* JsonR */ "{\n\t_type: 'a',\n\ta: {\n\t\thref: 'http://foo'\n\t}\n}",
- /* Xml */ "<a href='http://foo'/>",
- /* XmlT */ "<a href='http://foo'/>",
- /* XmlR */ "<a href='http://foo'/>\n",
- /* XmlNs */ "<a href='http://foo'/>",
- /* Html */ "<a href='http://foo'></a>",
- /* HtmlT */ "<a href='http://foo'></a>",
- /* HtmlR */ "<a href='http://foo'></a>\n",
+ /* Xml */ "<a href='http://foo' nil='true'></a>",
+ /* XmlT */ "<a href='http://foo' nil='true'></a>",
+ /* XmlR */ "<a href='http://foo' nil='true'>\n</a>\n",
+ /* XmlNs */ "<a href='http://foo' nil='true'></a>",
+ /* Html */ "<a href='http://foo' nil='true'></a>",
+ /* HtmlT */ "<a href='http://foo' nil='true'></a>",
+ /* HtmlR */ "<a href='http://foo' nil='true'>\n</a>\n",
/* Uon */ "(_type=a,a=(href=http://foo))",
/* UonT */ "(t=a,a=(href=http://foo))",
/* UonR */ "(\n\t_type=a,\n\ta=(\n\t\thref=http://foo\n\t)\n)",
@@ -279,13 +279,13 @@
/* Json */ "{_type:'address'}",
/* JsonT */ "{t:'address'}",
/* JsonR */ "{\n\t_type: 'address'\n}",
- /* Xml */ "<address/>",
- /* XmlT */ "<address/>",
- /* XmlR */ "<address/>\n",
- /* XmlNs */ "<address/>",
- /* Html */ "<address></address>",
- /* HtmlT */ "<address></address>",
- /* HtmlR */ "<address></address>\n",
+ /* Xml */ "<address nil='true'></address>",
+ /* XmlT */ "<address nil='true'></address>",
+ /* XmlR */ "<address nil='true'>\n</address>\n",
+ /* XmlNs */ "<address nil='true'></address>",
+ /* Html */ "<address nil='true'></address>",
+ /* HtmlT */ "<address nil='true'></address>",
+ /* HtmlR */ "<address nil='true'>\n</address>\n",
/* Uon */ "(_type=address)",
/* UonT */ "(t=address)",
/* UonR */ "(\n\t_type=address\n)",
@@ -667,13 +667,13 @@
/* Json */ "{_type:'canvas',a:{width:100,height:200}}",
/* JsonT */ "{t:'canvas',a:{width:100,height:200}}",
/* JsonR */ "{\n\t_type: 'canvas',\n\ta: {\n\t\twidth: 100,\n\t\theight: 200\n\t}\n}",
- /* Xml */ "<canvas width='100' height='200'/>",
- /* XmlT */ "<canvas width='100' height='200'/>",
- /* XmlR */ "<canvas width='100' height='200'/>\n",
- /* XmlNs */ "<canvas width='100' height='200'/>",
- /* Html */ "<canvas width='100' height='200'></canvas>",
- /* HtmlT */ "<canvas width='100' height='200'></canvas>",
- /* HtmlR */ "<canvas width='100' height='200'></canvas>\n",
+ /* Xml */ "<canvas width='100' height='200' nil='true'></canvas>",
+ /* XmlT */ "<canvas width='100' height='200' nil='true'></canvas>",
+ /* XmlR */ "<canvas width='100' height='200' nil='true'>\n</canvas>\n",
+ /* XmlNs */ "<canvas width='100' height='200' nil='true'></canvas>",
+ /* Html */ "<canvas width='100' height='200' nil='true'></canvas>",
+ /* HtmlT */ "<canvas width='100' height='200' nil='true'></canvas>",
+ /* HtmlR */ "<canvas width='100' height='200' nil='true'>\n</canvas>\n",
/* Uon */ "(_type=canvas,a=(width=100,height=200))",
/* UonT */ "(t=canvas,a=(width=100,height=200))",
/* UonR */ "(\n\t_type=canvas,\n\ta=(\n\t\twidth=100,\n\t\theight=200\n\t)\n)",
@@ -1657,13 +1657,13 @@
/* Json */ "{_type:'form',a:{action:'testform',oninput:'x.value=parseInt(a.value)+parseInt(b.value)'},c:[0,{_type:'input',a:{type:'range',id:'a',value:50}},'+',{_type:'input',a:{type:'number',id:'b',value:50}},'=',{_type:'output',a:{name:'x','for':'a b'}}]}",
/* JsonT */ "{t:'form',a:{action:'testform',oninput:'x.value=parseInt(a.value)+parseInt(b.value)'},c:[0,{t:'input',a:{type:'range',id:'a',value:50}},'+',{t:'input',a:{type:'number',id:'b',value:50}},'=',{t:'output',a:{name:'x','for':'a b'}}]}",
/* JsonR */ "{\n\t_type: 'form',\n\ta: {\n\t\taction: 'testform',\n\t\toninput: 'x.value=parseInt(a.value)+parseInt(b.value)'\n\t},\n\tc: [\n\t\t0,\n\t\t{\n\t\t\t_type: 'input',\n\t\t\ta: {\n\t\t\t\ttype: 'range',\n\t\t\t\tid: 'a',\n\t\t\t\tvalue: 50\n\t\t\t}\n\t\t},\n\t\t'+',\n\t\t{\n\t\t\t_type: 'input',\n\t\t\ta: {\n\t\t\t\ttype: 'number',\n\t\t\t\tid: 'b',\n\t\t\t\tvalue: 50\n\t\t\t}\n\t\t},\n\t\t'=',\n\t\t{\n\t\t\t_type: 'output',\n\t\t\ta: {\n\t\t\t\tname: 'x',\n\t\t\t\t'for': 'a b'\n\t\t\t}\n\t\t}\n\t]\n}",
- /* Xml */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
- /* XmlT */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
- /* XmlR */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>\n",
- /* XmlNs */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'/></form>",
- /* Html */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'></output></form>",
- /* HtmlT */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'></output></form>",
- /* HtmlR */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b'></output></form>\n",
+ /* Xml */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>",
+ /* XmlT */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>",
+ /* XmlR */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>\n",
+ /* XmlNs */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>",
+ /* Html */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>",
+ /* HtmlT */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>",
+ /* HtmlR */ "<form action='testform' oninput='x.value=parseInt(a.value)+parseInt(b.value)'>0<input type='range' id='a' value='50'/>+<input type='number' id='b' value='50'/>=<output name='x' for='a b' nil='true'></output></form>\n",
/* Uon */ "(_type=form,a=(action=testform,oninput='x.value=parseInt(a.value)+parseInt(b.value)'),c=@(0,(_type=input,a=(type=range,id=a,value=50)),+,(_type=input,a=(type=number,id=b,value=50)),'=',(_type=output,a=(name=x,for='a b'))))",
/* UonT */ "(t=form,a=(action=testform,oninput='x.value=parseInt(a.value)+parseInt(b.value)'),c=@(0,(t=input,a=(type=range,id=a,value=50)),+,(t=input,a=(type=number,id=b,value=50)),'=',(t=output,a=(name=x,for='a b'))))",
/* UonR */ "(\n\t_type=form,\n\ta=(\n\t\taction=testform,\n\t\toninput='x.value=parseInt(a.value)+parseInt(b.value)'\n\t),\n\tc=@(\n\t\t0,\n\t\t(\n\t\t\t_type=input,\n\t\t\ta=(\n\t\t\t\ttype=range,\n\t\t\t\tid=a,\n\t\t\t\tvalue=50\n\t\t\t)\n\t\t),\n\t\t+,\n\t\t(\n\t\t\t_type=input,\n\t\t\ta=(\n\t\t\t\ttype=number,\n\t\t\t\tid=b,\n\t\t\t\tvalue=50\n\t\t\t)\n\t\t),\n\t\t'=',\n\t\t(\n\t\t\t_type=output,\n\t\t\ta=(\n\t\t\t\tname=x,\n\t\t\t\tfor='a b'\n\t\t\t)\n\t\t)\n\t)\n)",
@@ -1762,13 +1762,13 @@
/* Json */ "{_type:'progress',a:{value:1}}",
/* JsonT */ "{t:'progress',a:{value:1}}",
/* JsonR */ "{\n\t_type: 'progress',\n\ta: {\n\t\tvalue: 1\n\t}\n}",
- /* Xml */ "<progress value='1'/>",
- /* XmlT */ "<progress value='1'/>",
- /* XmlR */ "<progress value='1'/>\n",
- /* XmlNs */ "<progress value='1'/>",
- /* Html */ "<progress value='1'></progress>",
- /* HtmlT */ "<progress value='1'></progress>",
- /* HtmlR */ "<progress value='1'></progress>\n",
+ /* Xml */ "<progress value='1' nil='true'></progress>",
+ /* XmlT */ "<progress value='1' nil='true'></progress>",
+ /* XmlR */ "<progress value='1' nil='true'>\n</progress>\n",
+ /* XmlNs */ "<progress value='1' nil='true'></progress>",
+ /* Html */ "<progress value='1' nil='true'></progress>",
+ /* HtmlT */ "<progress value='1' nil='true'></progress>",
+ /* HtmlR */ "<progress value='1' nil='true'>\n</progress>\n",
/* Uon */ "(_type=progress,a=(value=1))",
/* UonT */ "(t=progress,a=(value=1))",
/* UonR */ "(\n\t_type=progress,\n\ta=(\n\t\tvalue=1\n\t)\n)",
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/BasicHtmlTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
index d39c3b6..e1fbcdc 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
@@ -2174,9 +2174,9 @@
"BeanWithWhitespaceTextFields-1",
BeanWithWhitespaceTextFields.class,
new BeanWithWhitespaceTextFields().init(null),
- "<object></object>",
- "<object></object>\n",
- "<object></object>"
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>"
)
{
@Override
@@ -2254,9 +2254,9 @@
"BeanWithWhitespaceTextPwsFields-1",
BeanWithWhitespaceTextPwsFields.class,
new BeanWithWhitespaceTextPwsFields().init(null),
- "<object></object>",
- "<object></object>\n",
- "<object></object>"
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>"
)
{
@Override
@@ -2334,9 +2334,9 @@
"BeanWithWhitespaceMixedFields-1",
BeanWithWhitespaceMixedFields.class,
new BeanWithWhitespaceMixedFields().init(null),
- "<object></object>",
- "<object></object>\n",
- "<object></object>"
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>"
)
{
@Override
@@ -2430,9 +2430,9 @@
"BeanWithWhitespaceMixedPwsFields-1",
BeanWithWhitespaceMixedPwsFields.class,
new BeanWithWhitespaceMixedPwsFields().init(null),
- "<object></object>",
- "<object></object>\n",
- "<object></object>"
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>"
)
{
@Override
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/BasicXmlTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/BasicXmlTest.java
index e1911ad..a126acc 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/BasicXmlTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/BasicXmlTest.java
@@ -940,9 +940,9 @@
{ /* 42 */
"BeanWithWhitespaceTextFields-1",
new BeanWithWhitespaceTextFields().init(null),
- "<object/>",
- "<object/>\n",
- "<object/>",
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>",
},
{ /* 43 */
"BeanWithWhitespaceTextFields-2",
@@ -975,9 +975,9 @@
{ /* 47 */
"BeanWithWhitespaceTextPwsFields-1",
new BeanWithWhitespaceTextPwsFields().init(null),
- "<object/>",
- "<object/>\n",
- "<object/>",
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>",
},
{ /* 48 */
"BeanWithWhitespaceTextPwsFields-2",
@@ -1010,16 +1010,16 @@
{ /* 52 */
"BeanWithWhitespaceMixedFields-1",
new BeanWithWhitespaceMixedFields().init(null),
- "<object/>",
- "<object/>\n",
- "<object/>",
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>",
},
{ /* 53 */
"BeanWithWhitespaceMixedFields-2",
new BeanWithWhitespaceMixedFields().init(new String[0]),
- "<object/>",
- "<object/>\n",
- "<object/>",
+ "<object></object>",
+ "<object></object>\n",
+ "<object></object>",
},
{ /* 54 */
"BeanWithWhitespaceMixedFields-3",
@@ -1052,16 +1052,16 @@
{ /* 58 */
"BeanWithWhitespaceMixedPwsFields-1",
new BeanWithWhitespaceMixedPwsFields().init(null),
- "<object/>",
- "<object/>\n",
- "<object/>",
+ "<object nil='true'></object>",
+ "<object nil='true'>\n</object>\n",
+ "<object nil='true'></object>",
},
{ /* 59 */
"BeanWithWhitespaceMixedPwsFields-2",
new BeanWithWhitespaceMixedPwsFields().init(new String[0]),
- "<object/>",
- "<object/>\n",
- "<object/>",
+ "<object></object>",
+ "<object></object>\n",
+ "<object></object>",
},
{ /* 60 */
"BeanWithWhitespaceMixedPwsFields-3",
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlContentTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlContentTest.java
index d735513..9b5dcbf 100755
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlContentTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlContentTest.java
@@ -47,7 +47,7 @@
session = s1.createSession(SerializerSessionArgs.create());
session.serialize(t, sw);
r = sw.toString();
- assertEquals("<A f1='f1'>_x0000_</A>", r);
+ assertEquals("<A f1='f1' nil='true'></A>", r);
t2 = p.parse(r, A.class);
assertEqualObjects(t, t2);
@@ -55,7 +55,7 @@
session = s2.createSession(SerializerSessionArgs.create());
session.serialize(t, sw);
r = sw.toString();
- assertEquals("<A f1='f1'>_x0000_</A>\n", r);
+ assertEquals("<A f1='f1' nil='true'></A>\n", r);
t2 = p.parse(r, A.class);
assertEqualObjects(t, t2);
@@ -155,7 +155,7 @@
session = s1.createSession(SerializerSessionArgs.create());
session.serialize(t, sw);
r = sw.toString();
- assertEquals("<A f1='f1'>_x0000_</A>", r);
+ assertEquals("<A f1='f1' nil='true'></A>", r);
t2 = p.parse(r, B.class);
assertEqualObjects(t, t2);
@@ -163,7 +163,7 @@
session = s2.createSession(SerializerSessionArgs.create());
session.serialize(t, sw);
r = sw.toString();
- assertEquals("<A f1='f1'>_x0000_</A>\n", r);
+ assertEquals("<A f1='f1' nil='true'></A>\n", r);
t2 = p.parse(r, B.class);
assertEqualObjects(t, t2);
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java
index 37b87ae..e163eee 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/xml/XmlIgnoreCommentsTest.java
@@ -604,7 +604,7 @@
"BeanWithWhitespaceMixedFields-1",
BeanWithWhitespaceMixedFields.class,
new BeanWithWhitespaceMixedFields().init(null),
- "|<object/>|",
+ "|<object nil='true'></object>|",
false
},
{ /* 53 */
@@ -639,7 +639,7 @@
"BeanWithWhitespaceMixedPwsFields-1",
BeanWithWhitespaceMixedPwsFields.class,
new BeanWithWhitespaceMixedPwsFields().init(null),
- "|<object/>|",
+ "|<object nil='true'></object>|",
false
},
{ /* 58 */
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java
index 912d939..54ab888 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java
@@ -60,10 +60,12 @@
*/
@Beanp("a")
public HtmlElement setAttrs(LinkedHashMap<String,Object> attrs) {
- for (Entry<String,Object> e : attrs.entrySet()) {
- String key = e.getKey();
- if ("url".equals(key) || "href".equals(key) || key.endsWith("action"))
- e.setValue(StringUtils.toURI(e.getValue()));
+ if (attrs != null) {
+ for (Entry<String,Object> e : attrs.entrySet()) {
+ String key = e.getKey();
+ if ("url".equals(key) || "href".equals(key) || key.endsWith("action"))
+ e.setValue(StringUtils.toURI(e.getValue()));
+ }
}
this.attrs = attrs;
return this;
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 fd31ca6..bf4678b 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
@@ -581,7 +581,9 @@
* Equivalent to calling {@link BeanMap#get(Object)}, but is faster since it avoids looking up the property meta.
*
* @param m The bean map to get the transformed value from.
- * @param pName The property name.
+ * @param pName
+ * The property name if this is a dyna property (i.e. <js>"*"</js>).
+ * <br>Otherwise can be <jk>null</jk>.
* @return
* The property value.
* <br>Returns <jk>null</jk> if this is a write-only property.
@@ -616,7 +618,9 @@
* Equivalent to calling {@link BeanMap#getRaw(Object)}, but is faster since it avoids looking up the property meta.
*
* @param m The bean map to get the transformed value from.
- * @param pName The property name.
+ * @param pName
+ * The property name if this is a dyna property (i.e. <js>"*"</js>).
+ * <br>Otherwise can be <jk>null</jk>.
* @return The raw property value.
*/
public Object getRaw(BeanMap<?> m, String pName) {
@@ -680,7 +684,9 @@
* This is a no-op on a read-only property.
*
* @param m The bean map to set the property value on.
- * @param pName The property name.
+ * @param pName
+ * The property name if this is a dyna property (i.e. <js>"*"</js>).
+ * <br>Otherwise can be <jk>null</jk>.
* @param value The value to set.
* @return The previous property value.
* @throws BeanRuntimeException If property could not be set.
@@ -966,7 +972,9 @@
* larger array on each operation.
*
* @param m The bean of the field being set.
- * @param pName The property name.
+ * @param pName
+ * The property name if this is a dyna property (i.e. <js>"*"</js>).
+ * <br>Otherwise can be <jk>null</jk>.
* @param value The value to add to the field.
* @throws BeanRuntimeException If field is not a collection or array.
*/
@@ -1042,7 +1050,9 @@
* Adds a value to a {@link Map} or bean property.
*
* @param m The bean of the field being set.
- * @param pName The property name.
+ * @param pName
+ * The property name if this is a dyna property (i.e. <js>"*"</js>).
+ * <br>Otherwise can be <jk>null</jk>.
* @param key The key to add to the field.
* @param value The value to add to the field.
* @throws BeanRuntimeException If field is not a map or array.
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 151fbeb..8e66874 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
@@ -99,7 +99,7 @@
else
sType = eType;
- if (sType.isOptional())
+ if (sType.isOptional())
return (T)Optional.ofNullable(parseAnything(eType.getElementType(), r, outer, isRoot, pMeta));
setCurrentClass(sType);
@@ -511,7 +511,9 @@
pMeta.set(m, key, value);
}
}
- nextTag(r, xTR);
+ HtmlTag t = nextTag(r, xTD, xTR);
+ if (t == xTD)
+ nextTag(r, xTR);
}
return m;
}
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 e926d69..7213563 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
@@ -164,7 +164,7 @@
* @throws IOException If a problem occurred trying to send output to the writer.
*/
private XmlWriter doSerialize(Object o, XmlWriter w) throws IOException, SerializeException {
- serializeAnything(w, o, getExpectedRootType(o), null, null, getInitialDepth()-1, true);
+ serializeAnything(w, o, getExpectedRootType(o), null, null, getInitialDepth()-1, true, false);
return w;
}
@@ -201,7 +201,7 @@
HtmlClassMeta cHtml = cHtml(type);
if (type.isMapOrBean() && ! cHtml.isXml())
- return serializeAnything(out, o, eType, elementName, pMeta, 0, false);
+ return serializeAnything(out, o, eType, elementName, pMeta, 0, false, false);
return super.serializeAnything(out, o, eType, elementName, elementNamespace, addNamespaceUris, format, isMixed, preserveWhitespace, pMeta);
}
@@ -217,13 +217,14 @@
* @param pMeta The bean property being serialized, or <jk>null</jk> if we're not serializing a bean property.
* @param xIndent The current indentation value.
* @param isRoot <jk>true</jk> if this is the root element of the document.
+ * @param nlIfElement <jk>true</jk> if we should add a newline to the output before serializing only if the object is an element and not text.
* @return The type of content encountered. Either simple (no whitespace) or normal (elements with whitespace).
* @throws IOException Thrown by underlying stream.
* @throws SerializeException Generic serialization error occurred.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected ContentResult serializeAnything(XmlWriter out, Object o,
- ClassMeta<?> eType, String name, BeanPropertyMeta pMeta, int xIndent, boolean isRoot) throws IOException, SerializeException {
+ ClassMeta<?> eType, String name, BeanPropertyMeta pMeta, int xIndent, boolean isRoot, boolean nlIfElement) throws IOException, SerializeException {
ClassMeta<?> aType = null; // The actual type
ClassMeta<?> wType = null; // The wrapped type (delegate)
@@ -239,7 +240,7 @@
o = null;
aType = object();
}
-
+
// Handle Optional<X>
if (isOptional(aType)) {
o = getOptionalValue(o);
@@ -300,13 +301,15 @@
indent -= xIndent;
pop();
out.nl(indent);
- return serializeAnything(out, o2, null, typeName, null, xIndent, false);
+ return serializeAnything(out, o2, null, typeName, null, xIndent, false, false);
}
}
if (cHtml.isXml() || bpHtml.isXml()) {
pop();
indent++;
+ if (nlIfElement)
+ out.nl(0);
super.serializeAnything(out, o, null, null, null, false, XmlFormat.MIXED, false, false, null);
indent -= xIndent+1;
return cr;
@@ -424,14 +427,14 @@
out.cTag();
if (link != null)
out.oTag(i+3, "a").attrUri("href", link.replace("{#}", stringify(value))).cTag();
- ContentResult cr = serializeAnything(out, key, keyType, null, null, 2, false);
+ ContentResult cr = serializeAnything(out, key, keyType, null, null, 2, false, false);
if (link != null)
out.eTag("a");
if (cr == CR_ELEMENTS)
out.i(i+2);
out.eTag("td").nl(i+2);
out.sTag(i+2, "td");
- cr = serializeAnything(out, value, valueType, (key == null ? "_x0000_" : toString(key)), null, 2, false);
+ cr = serializeAnything(out, value, valueType, (key == null ? "_x0000_" : toString(key)), null, 2, false, false);
if (cr == CR_ELEMENTS)
out.ie(i+2);
out.eTag("td").nl(i+2);
@@ -494,7 +497,7 @@
try {
if (link != null)
out.oTag(i+3, "a").attrUri("href", link).cTag();
- ContentResult cr = serializeAnything(out, value, cMeta, key, pMeta, 2, false);
+ ContentResult cr = serializeAnything(out, value, cMeta, key, pMeta, 2, false, true);
if (cr == CR_ELEMENTS)
out.i(i+2);
if (link != null)
@@ -577,7 +580,7 @@
if (cm == null) {
out.i(i+2);
- serializeAnything(out, o, null, null, null, 1, false);
+ serializeAnything(out, o, null, null, null, 1, false, false);
out.nl(0);
} else if (cm.isMap() && ! (cm.isBeanMap())) {
@@ -585,7 +588,7 @@
for (Object k : th) {
out.sTag(i+2, "td");
- ContentResult cr = serializeAnything(out, m2.get(k), eType.getElementType(), toString(k), null, 2, false);
+ ContentResult cr = serializeAnything(out, m2.get(k), eType.getElementType(), toString(k), null, 2, false, true);
if (cr == CR_ELEMENTS)
out.i(i+2);
out.eTag("td").nl(i+2);
@@ -619,7 +622,7 @@
out.cTag();
if (link != null)
out.oTag("a").attrUri("href", link).cTag();
- ContentResult cr = serializeAnything(out, value, pMeta.getClassMeta(), p.getKey().toString(), pMeta, 2, false);
+ ContentResult cr = serializeAnything(out, value, pMeta.getClassMeta(), p.getKey().toString(), pMeta, 2, false, true);
if (cr == CR_ELEMENTS)
out.i(i+2);
if (link != null)
@@ -651,7 +654,7 @@
out.cTag();
if (link != null)
out.oTag(i+2, "a").attrUri("href", link.replace("{#}", stringify(o))).cTag();
- ContentResult cr = serializeAnything(out, o, eType.getElementType(), name, null, 1, false);
+ ContentResult cr = serializeAnything(out, o, eType.getElementType(), name, null, 1, false, true);
if (link != null)
out.eTag("a");
if (cr == CR_ELEMENTS)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlWriter.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlWriter.java
index 29e6eff..21a29bd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlWriter.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlWriter.java
@@ -67,7 +67,7 @@
append(">");
else if (test == '\n')
append(preserveWhitespace ? "\n" : "<br/>");
- else if (test == '\f') // XML 1.0 doesn't support formfeeds or backslashes, so we have to invent something.
+ else if (test == '\f') // XML 1.0 doesn't support form feeds or backslashes, so we have to invent something.
append(preserveWhitespace ? "\f" : "<ff/>");
else if (test == '\b')
append(preserveWhitespace ? "\b" : "<bs/>");
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/NoCloseWriter.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/NoCloseWriter.java
index 0d96649..d1f462e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/NoCloseWriter.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/NoCloseWriter.java
@@ -82,4 +82,9 @@
public void write(String str, int off, int len) throws IOException {
w.write(str, off, len);
}
+
+ @Override /* Object */
+ public String toString() {
+ return w.toString();
+ }
}
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index 2ef487d..872a1e8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -288,13 +288,14 @@
else
sType = eType;
- if (sType.isOptional())
+ if (sType.isOptional())
return (T)Optional.ofNullable(parseAnything(eType.getElementType(), currAttr, r, outer, isRoot, pMeta));
setCurrentClass(sType);
String wrapperAttr = (isRoot && isPreserveRootElement()) ? r.getName().getLocalPart() : null;
String typeAttr = r.getAttributeValue(null, getBeanTypePropertyName(eType));
+ boolean isNil = "true".equals(r.getAttributeValue(null, "nil"));
int jsonType = getJsonType(typeAttr);
String elementName = getElementName(r);
if (jsonType == 0) {
@@ -367,7 +368,7 @@
o = builder != null ? builder.build(this, m.getBean(), eType) : m.getBean();
} else {
BeanMap m = builder != null ? toBeanMap(builder.create(this, eType)) : newBeanMap(outer, sType.getInnerClass());
- m = parseIntoBean(r, m);
+ m = parseIntoBean(r, m, isNil);
o = builder != null ? builder.build(this, m.getBean(), eType) : m.getBean();
}
} else if (sType.isArray() || sType.isArgs()) {
@@ -469,23 +470,25 @@
return UNKNOWN;
}
- private <T> BeanMap<T> parseIntoBean(XmlReader r, BeanMap<T> m) throws IOException, ParseException, ExecutableException, XMLStreamException {
+ private <T> BeanMap<T> parseIntoBean(XmlReader r, BeanMap<T> m, boolean isNil) throws IOException, ParseException, ExecutableException, XMLStreamException {
BeanMeta<?> bMeta = m.getMeta();
XmlBeanMeta xmlMeta = bMeta.getExtendedMeta(XmlBeanMeta.class);
for (int i = 0; i < r.getAttributeCount(); i++) {
String key = getAttributeName(r, i);
- String val = r.getAttributeValue(i);
- String ns = r.getAttributeNamespace(i);
- BeanPropertyMeta bpm = xmlMeta.getPropertyMeta(key);
- if (bpm == null) {
- if (xmlMeta.getAttrsProperty() != null) {
- xmlMeta.getAttrsProperty().add(m, key, key, val);
- } else if (ns == null) {
- onUnknownProperty(key, m);
+ if (! "nil".equals(key)) {
+ String val = r.getAttributeValue(i);
+ String ns = r.getAttributeNamespace(i);
+ BeanPropertyMeta bpm = xmlMeta.getPropertyMeta(key);
+ if (bpm == null) {
+ if (xmlMeta.getAttrsProperty() != null) {
+ xmlMeta.getAttrsProperty().add(m, key, key, val);
+ } else if (ns == null) {
+ onUnknownProperty(key, m);
+ }
+ } else {
+ bpm.set(m, key, val);
}
- } else {
- bpm.set(m, key, val);
}
}
@@ -600,10 +603,17 @@
}
} while (depth >= 0);
- if (sb != null && cp != null)
- cp.set(m, null, sb.toString());
- else if (l != null && cp != null)
- cp.set(m, null, XmlUtils.collapseTextNodes(l));
+ if (cp != null && ! isNil) {
+ if (sb != null)
+ cp.set(m, null, sb.toString());
+ else if (l != null)
+ cp.set(m, null, XmlUtils.collapseTextNodes(l));
+ else if (cpcm.isCollectionOrArray()) {
+ Object o = cp.get(m, null);
+ if (o == null)
+ cp.set(m, cp.getName(), new ArrayList<>());
+ }
+ }
returnStringBuilder(sb);
return m;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index 775e188..fdec1e6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -234,7 +234,7 @@
* @param elementNamespace The namespace of the element.
* @param addNamespaceUris Flag indicating that namespace URIs need to be added.
* @param format The format to serialize the output to.
- * @param isMixed We're serializing mixed content, so don't use whitespace.
+ * @param isMixedOrText We're serializing mixed content, so don't use whitespace.
* @param preserveWhitespace
* <jk>true</jk> if we're serializing {@link XmlFormat#MIXED_PWS} or {@link XmlFormat#TEXT_PWS}.
* @param pMeta The bean property metadata if this is a bean property being serialized.
@@ -250,12 +250,12 @@
Namespace elementNamespace,
boolean addNamespaceUris,
XmlFormat format,
- boolean isMixed,
+ boolean isMixedOrText,
boolean preserveWhitespace,
BeanPropertyMeta pMeta) throws IOException, SerializeException {
JsonType type = null; // The type string (e.g. <type> or <x x='type'>
- int i = isMixed ? 0 : indent; // Current indentation
+ int i = isMixedOrText ? 0 : indent; // Current indentation
ClassMeta<?> aType = null; // The actual type
ClassMeta<?> wType = null; // The wrapped type (delegate)
ClassMeta<?> sType = object(); // The serialized type
@@ -372,7 +372,7 @@
}
// Do we need a carriage return after the start tag?
- boolean cr = o != null && (sType.isMapOrBean() || sType.isCollectionOrArray()) && ! isMixed;
+ boolean cr = o != null && (sType.isMapOrBean() || sType.isCollectionOrArray()) && ! isMixedOrText;
String en = elementName;
if (en == null && ! isRaw) {
@@ -435,21 +435,21 @@
out.append(o);
} else if (sType.isMap() || (wType != null && wType.isMap())) {
if (o instanceof BeanMap)
- rc = serializeBeanMap(out, (BeanMap)o, elementNamespace, isCollapsed, isMixed);
+ rc = serializeBeanMap(out, (BeanMap)o, elementNamespace, isCollapsed, isMixedOrText);
else
- rc = serializeMap(out, (Map)o, sType, eType.getKeyType(), eType.getValueType(), isMixed);
+ rc = serializeMap(out, (Map)o, sType, eType.getKeyType(), eType.getValueType(), isMixedOrText);
} else if (sType.isBean()) {
- rc = serializeBeanMap(out, toBeanMap(o), elementNamespace, isCollapsed, isMixed);
+ rc = serializeBeanMap(out, toBeanMap(o), elementNamespace, isCollapsed, isMixedOrText);
} else if (sType.isCollection() || (wType != null && wType.isCollection())) {
if (isCollapsed)
this.indent--;
- serializeCollection(out, o, sType, eType, pMeta, isMixed);
+ serializeCollection(out, o, sType, eType, pMeta, isMixedOrText);
if (isCollapsed)
this.indent++;
} else if (sType.isArray()) {
if (isCollapsed)
this.indent--;
- serializeCollection(out, o, sType, eType, pMeta, isMixed);
+ serializeCollection(out, o, sType, eType, pMeta, isMixedOrText);
if (isCollapsed)
this.indent++;
} else if (sType.isReader() || sType.isInputStream()) {
@@ -478,7 +478,7 @@
else
out.ie(cr && rc != CR_MIXED ? i : 0).eTag(elementNs, en, encodeEn);
}
- if (! isMixed)
+ if (! isMixedOrText)
out.nl(i);
}
@@ -527,7 +527,7 @@
}
private ContentResult serializeBeanMap(XmlWriter out, BeanMap<?> m,
- Namespace elementNs, boolean isCollapsed, boolean isMixed) throws IOException, SerializeException {
+ Namespace elementNs, boolean isCollapsed, boolean isMixedOrText) throws IOException, SerializeException {
boolean hasChildren = false;
BeanMeta<?> bm = m.getMeta();
@@ -581,9 +581,9 @@
}
} else /* Map */ {
Map m2 = (Map)value;
- for (Map.Entry e : (Set<Map.Entry>)(m2.entrySet())) {
- out.attr(ns, toString(e.getKey()), e.getValue());
- }
+ if (m2 != null)
+ for (Map.Entry e : (Set<Map.Entry>)(m2.entrySet()))
+ out.attr(ns, toString(e.getKey()), e.getValue());
}
} else {
out.attr(ns, key, value);
@@ -609,7 +609,7 @@
hasContent = true;
cf = xbm.getContentFormat();
if (cf.isOneOf(MIXED,MIXED_PWS,TEXT,TEXT_PWS,XMLTEXT))
- isMixed = true;
+ isMixedOrText = true;
if (cf.isOneOf(MIXED_PWS, TEXT_PWS))
preserveWhitespace = true;
if (contentType.isCollection() && ((Collection)content).isEmpty())
@@ -628,46 +628,40 @@
if (! hasChildren) {
hasChildren = true;
- out.appendIf(! isCollapsed, '>').nlIf(! isMixed, indent);
+ out.appendIf(! isCollapsed, '>').nlIf(! isMixedOrText, indent);
}
XmlBeanPropertyMeta bpXml = bpXml(pMeta);
- serializeAnything(out, value, cMeta, key, bpXml.getNamespace(), false, bpXml.getXmlFormat(), isMixed, false, pMeta);
+ serializeAnything(out, value, cMeta, key, bpXml.getNamespace(), false, bpXml.getXmlFormat(), isMixedOrText, false, pMeta);
}
}
}
- if (! hasContent)
+ if (contentProperty == null && ! hasContent)
return (hasChildren ? CR_ELEMENTS : isVoidElement ? CR_VOID : CR_EMPTY);
- out.append('>').nlIf(! isMixed, indent);
// Serialize XML content.
if (content != null) {
+ out.append('>').nlIf(! isMixedOrText, indent);
if (contentType == null) {
} else if (contentType.isCollection()) {
Collection c = (Collection)content;
for (Iterator i = c.iterator(); i.hasNext();) {
Object value = i.next();
- serializeAnything(out, value, contentType.getElementType(), null, null, false, cf, isMixed, preserveWhitespace, null);
+ serializeAnything(out, value, contentType.getElementType(), null, null, false, cf, isMixedOrText, preserveWhitespace, null);
}
} else if (contentType.isArray()) {
Collection c = toList(Object[].class, content);
for (Iterator i = c.iterator(); i.hasNext();) {
Object value = i.next();
- serializeAnything(out, value, contentType.getElementType(), null, null, false, cf, isMixed, preserveWhitespace, null);
+ serializeAnything(out, value, contentType.getElementType(), null, null, false, cf, isMixedOrText, preserveWhitespace, null);
}
} else {
- serializeAnything(out, content, contentType, null, null, false, cf, isMixed, preserveWhitespace, null);
+ serializeAnything(out, content, contentType, null, null, false, cf, isMixedOrText, preserveWhitespace, null);
}
} else {
- if (! isTrimNullProperties()) {
- if (! isMixed)
- out.i(indent);
- out.text(content);
- if (! isMixed)
- out.nl(indent);
- }
+ out.attr("nil", "true").append('>').nlIf(! isMixedOrText, indent);
}
- return isMixed ? CR_MIXED : CR_ELEMENTS;
+ return isMixedOrText ? CR_MIXED : CR_ELEMENTS;
}
private XmlWriter serializeCollection(XmlWriter out, Object in, ClassMeta<?> sType,
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java
index d81666a..4ac369a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xmlschema/XmlSchemaSerializerSession.java
@@ -329,6 +329,8 @@
w.cTag().nl(i);
+ boolean hasAnyAttrs = false;
+
if (! (cm.isMapOrBean() || cm.isCollectionOrArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) {
w.oTag(i+1, "attribute").attr("name", getBeanTypePropertyName(cm)).attr("type", "string").ceTag().nl(i+1);
@@ -343,7 +345,9 @@
for (BeanPropertyMeta pMeta : bm.getPropertyMetas()) {
if (pMeta.canRead()) {
XmlFormat bpXml = pMeta.getExtendedMeta(XmlBeanPropertyMeta.class).getXmlFormat();
- if (bpXml != XmlFormat.ATTR)
+ if (bpXml == ATTRS)
+ hasAnyAttrs = true;
+ else if (bpXml != XmlFormat.ATTR)
hasChildElements = true;
}
}
@@ -376,11 +380,12 @@
if (xmlMeta.getXmlFormat() == COLLAPSED)
hasCollapsed = true;
}
-
}
}
- if (hasOtherNsElement || hasCollapsed) {
+ if (hasAnyAttrs) {
+ w.oTag(i+1, "anyAttribute").attr("processContents", "skip").ceTag().nl(i+1);
+ } else if (hasOtherNsElement || hasCollapsed) {
// If this bean has any child elements in another namespace,
// we need to add an <any> element.
w.oTag(i+1, "choice").attr("maxOccurs", "unbounded").cTag().nl(i+1);
@@ -443,10 +448,12 @@
// Otherwise, it's just a plain attribute of this bean.
else {
- w.oTag(i+1, "attribute")
+ if (! hasAnyAttrs) {
+ w.oTag(i+1, "attribute")
.attr("name", pMeta.getName(), true)
.attr("type", getXmlAttrType(pMeta.getClassMeta()))
.ceTag().nl(i+1);
+ }
}
}
}
@@ -485,10 +492,12 @@
w.eTag(i+1, "sequence").nl(i+1);
}
- w.oTag(i+1, "attribute")
+ if (! hasAnyAttrs) {
+ w.oTag(i+1, "attribute")
.attr("name", getBeanTypePropertyName(null))
.attr("type", "string")
.ceTag().nl(i+1);
+ }
}
w.eTag(i, "complexType").nl(i);
@@ -578,6 +587,6 @@
public ObjectMap toMap() {
return super.toMap()
.append("XmlSchemaSerializerSession", new DefaultFilteringObjectMap()
- );
+ );
}
}
diff --git a/juneau-doc/docs/ReleaseNotes/8.1.3.html b/juneau-doc/docs/ReleaseNotes/8.1.3.html
new file mode 100644
index 0000000..6336107
--- /dev/null
+++ b/juneau-doc/docs/ReleaseNotes/8.1.3.html
@@ -0,0 +1,36 @@
+<!--
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ ***************************************************************************************************************************/
+ -->
+
+8.1.3 (TBD)
+
+<p>
+ Juneau 8.1.3 is a minor release.
+</p>
+
+<h5 class='topic w800'>juneau-marshall</h5>
+<ul class='spaced-list'>
+ <li>
+ Better representation of nulls for XML and HTML content properties.
+ <br>Old: <js>"<myBean><null></myBean>"</js>
+ <br>New: <js>"<myBean nil='true'></myBean>"</js>
+</ul>
+
+<h5 class='topic w800'>juneau-rest-server</h5>
+<ul class='spaced-list'>
+</ul>
+
+<h5 class='topic w800'>juneau-rest-client</h5>
+<ul class='spaced-list'>
+</ul>