Skip to content

Commit beedf11

Browse files
hansonrhansonr
authored andcommitted
JAXB fix for unmarshalling objects
1 parent 928951b commit beedf11

5 files changed

Lines changed: 86 additions & 94 deletions

File tree

sources/net.sf.j2s.java.core/src/swingjs/xml/JSJAXBClass.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,16 +322,29 @@ QName finalizeFieldQName(QName qName, String defaultName, int type) {
322322
return this.qname = qname;
323323
case JSJAXBField.TYPE_XML_TYPE:
324324
return this.qname = qualifiedTypeName = qname;
325+
default:
325326
case JSJAXBField.TYPE_ATTRIBUTE:
326327
case JSJAXBField.TYPE_ELEMENT:
327328
return qname;
328329
}
329-
// not possible
330-
return null;
331330
}
332331

333332
private boolean haveXMLTypeNamespace = true;
334333

334+
/**
335+
* Get the default namespace depending upon type.
336+
*
337+
* RootElement: packageNamespace unless the namespace has been set in the annotation
338+
*
339+
* XMLType: the name from the RootElement
340+
*
341+
* XMLAttribute: empty string (surprise!)
342+
*
343+
* XMLElement: the enclosing class's XMLType, if it exists, or the package namespace
344+
*
345+
* @param type
346+
* @return
347+
*/
335348
private String getDefaultNamespace(int type) {
336349
switch (type) {
337350
case JSJAXBField.TYPE_ROOT_ELEMENT:
@@ -341,11 +354,10 @@ private String getDefaultNamespace(int type) {
341354
return qname.getNamespaceURI();
342355
case JSJAXBField.TYPE_ATTRIBUTE:
343356
return "";
357+
default:
344358
case JSJAXBField.TYPE_ELEMENT:
345359
return (haveXMLTypeNamespace ? qname.getNamespaceURI() : packageNamespace);
346360
}
347-
// not possible
348-
return null;
349361
}
350362

351363
public JSJAXBClass clone() {

sources/net.sf.j2s.java.core/src/swingjs/xml/JSJAXBField.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -493,10 +493,9 @@ public String toString() {
493493

494494
boolean isSimpleType(String javaClassName) {
495495
return (javaClassName != null ? simplePackages(javaClassName)
496-
: isNil || isAttribute
497-
|| asList || isByteArray
498-
|| isArray || qualifiedWrapName != null
499-
|| simplePackages(this.javaClassName));
496+
: isNil || asList || isByteArray || isArray || qualifiedWrapName != null ? true
497+
: xmlType != null ? false
498+
: isAttribute || simplePackages(this.javaClassName));
500499
}
501500

502501
static boolean simplePackages(String javaClassName) {

sources/net.sf.j2s.java.core/src/swingjs/xml/JSJAXBUnmarshaller.java

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ private void start(DOMNode node, QName qName, Attributes atts) {
355355
String text = JSSAXParser.getSimpleInnerText(node);
356356
if (doc == null) {
357357
doc = node;
358-
setDocAttributes(text, atts);
358+
setDocAttributes(qName, text, atts);
359359
return;
360360
}
361361
// /**
@@ -370,7 +370,7 @@ private void start(DOMNode node, QName qName, Attributes atts) {
370370
}
371371
}
372372

373-
private void setDocAttributes(String value, Attributes atts) {
373+
private void setDocAttributes(QName qName, String value, Attributes atts) {
374374
if (jaxbClass.xmlValueField != null) {
375375
jaxbClass.xmlValueField.setCharacters(value);
376376
jaxbClass.xmlValueField.setNode(doc);
@@ -384,6 +384,9 @@ private void setDocAttributes(String value, Attributes atts) {
384384
if (qname.equals("xmlns") || qname.startsWith("xmlns:") || qname.startsWith("xsi:")) {
385385
continue;
386386
}
387+
// attribute assumes uri of tag if "" -- NO!
388+
// if (uri.length() == 0)
389+
// uri = qName.getNamespaceURI();
387390
QName qn = getQnameForAttribute(uri, localName, qname);
388391
JSJAXBField field = getFieldFromQName(qn);
389392
if (field != null) {
@@ -433,12 +436,18 @@ static JSJAXBClass newUnmarshalledInstance(Class<?> javaClass, Object javaObject
433436
return jjc.clone();
434437
}
435438

436-
public static String needsUnmarshalling(JSJAXBField field, String javaClassName) {
439+
public String needsUnmarshalling(JSJAXBField field, String javaClassName) {
437440
if (field.isSimpleType(javaClassName))
438441
return null;
439442
boolean isMarshalled = false;
440443
if (javaClassName == null)
441444
javaClassName = field.javaClassName;
445+
if (field.xmlType != null) {
446+
String typeClassName = getXMLTypeClassName(field);
447+
if (typeClassName == null)
448+
return null;
449+
javaClassName = typeClassName;
450+
}
442451
try {
443452
isMarshalled = (knownJavaClasses.containsKey(javaClassName)
444453
? knownJavaClasses.get(javaClassName).booleanValue()
@@ -452,6 +461,15 @@ public static String needsUnmarshalling(JSJAXBField field, String javaClassName)
452461
return (isMarshalled ? javaClassName : null);
453462
}
454463

464+
private String getXMLTypeClassName(JSJAXBField field) {
465+
if (field.xmlType.indexOf(":") >= 0 && !field.xmlType.startsWith("xs:")) {
466+
QName qname = getQnameForAttribute(null, null, field.xmlType);
467+
field = getFieldFromQName(qname);
468+
return (field == null ? null : field.javaClassName);
469+
}
470+
return null;
471+
}
472+
455473
void prepareForUnmarshalling(String defaultNamespace) {
456474
jaxbClass.setUnmarshallerDefaultNamespace(defaultNamespace);
457475
List<String> seeAlso = jaxbClass.seeAlso;
@@ -487,11 +505,12 @@ private void bindQName(QName q, JSJAXBField field, boolean isSeeAlso) {
487505
return;
488506
Map<String, JSJAXBField> map = (isSeeAlso ? seeAlsoMap : jaxbClass.unmarshallerFieldMap);
489507
map.put(q.getLocalPart(), field);
490-
String namespace = q.getNamespaceURI();
491508
// if (namespace.length() == 0)
492509
// namespace = jaxbClass.getUnmarshallerDefaultNamespace();
493510
// if (namespace != null)
494-
map.put(namespace + ":" + q.getLocalPart(), field);
511+
String qn = q.getNamespaceURI() + ":" + q.getLocalPart();
512+
map.put(qn, field);
513+
map.put("/lc/" + qn.toLowerCase(), field);
495514
// System.out.println("JSJAXBClass#binding " + namespace + ":" +
496515
// q.getLocalPart() + "->" + field.javaName);
497516
}
@@ -505,6 +524,10 @@ JSJAXBField getFieldFromQName(QName qName) {
505524
f = seeAlsoMap.get(key);
506525
// if (f == null)
507526
// f = seeAlsoMap.get(qName.getLocalPart());
527+
528+
// desparately doing this because I cannot find the capitalization algorithm in JAXB!
529+
if (f == null)
530+
f = jaxbClass.unmarshallerFieldMap.get("/lc/" + key.toLowerCase());
508531
if (f == null)
509532
System.out.println("JSJAXBUnmarshaller could not associate a field with " + qName);
510533
return f;
@@ -519,14 +542,6 @@ private void setFieldValue(JSJAXBField field) {
519542
if (field.isNil)
520543
return;
521544

522-
// complex object -- unmarshal directly
523-
524-
String className = needsUnmarshalling(field, null);
525-
if (className != null) {
526-
field.setValue(unmarshalField(field, field.boundNode, className), javaObject);
527-
return;
528-
}
529-
530545
// char data for field
531546
if (field.asList) {
532547
field.setValue(fillArrayData(field, field.boundNode, field.xmlCharacterData.trim().split(" "),
@@ -560,6 +575,15 @@ private void setFieldValue(JSJAXBField field) {
560575

561576
// qualifiedWrapName is null;
562577

578+
String className = needsUnmarshalling(field, null);
579+
if (className != null) {
580+
581+
// complex object -- unmarshal directly
582+
583+
field.setValue(unmarshalField(field, field.boundNode, className), javaObject);
584+
return;
585+
}
586+
563587
String data = (field.isAttribute ? field.xmlAttributeData : field.xmlCharacterData.trim());
564588
String dataType = (field.xmlType == null ? field.javaClassName : field.xmlType);
565589
field.setValue(convertFromType(field, data, dataType, field.xmlType != null), javaObject);

sources/net.sf.j2s.java.core/src/test/Test_JAXB_NONE.java

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package test;
22

3+
import java.io.BufferedInputStream;
34
import java.io.ByteArrayInputStream;
45
import java.io.ByteArrayOutputStream;
6+
import java.io.InputStream;
57
import java.io.UnsupportedEncodingException;
68
import java.util.Date;
79

@@ -14,6 +16,7 @@
1416
import javax.xml.bind.annotation.XmlRegistry;
1517
import javax.xml.namespace.QName;
1618

19+
import javajs.util.Rdr;
1720
import test.jaxb.Root_NONE;
1821

1922
/**
@@ -25,96 +28,39 @@
2528
@XmlRegistry
2629
public class Test_JAXB_NONE extends Test_ {
2730

28-
// Java read out:
29-
// getPropertyC is =getproPERtyC:propertyC01
30-
// getAToBe
31-
// getAToBe
32-
// getAToBe
33-
// isB2()
34-
// getB3()
35-
// private!getC
36-
// private!getC
37-
// private!getC
38-
// getPropertyAToBe
39-
// getPropertyAToBe
40-
// getPropertyAToBe
41-
//
42-
// <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
43-
// <ns2:RootNone xmlns:ns2="www.jalview.org" ang="?" pi1A="0" pi2A="0" pi3A="3">
44-
// <propertyC>propertyC0</propertyC>
45-
// <AToBe>getAtoBe</AToBe>
46-
// <b2>true</b2>
47-
// <b3>true</b3>
48-
// <c>getC</c>
49-
// <propertyAToBe>getPropertyAtoB</propertyAToBe>
50-
// <propc>=getproPERtyC:propertyC01</propc>
51-
// <propertyc>=getpropertyc:propertyC0</propertyc>
52-
// </ns2:RootNone>
53-
//
54-
// setAToBe:getAtoBe
55-
// setB2()
56-
// setB3()
57-
// private!setC
58-
// setPropertyAToBe:getPropertyAtoB
59-
// setProPERtyC:=getproPERtyC:propertyC01
60-
// setpropertyc:=getpropertyc:propertyC0
61-
// getPropertyAng[].length is 3
62-
// Test_JAXB_NONE OK
63-
64-
// JavaScript read out:
65-
// getPropertyC is =getproPERtyC:propertyC01
66-
// private!getC
67-
// isB2()
68-
// getB3()
69-
// getAToBe
70-
// getPropertyAToBe
71-
//
72-
// <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
73-
// <ns2:RootNone xmlns="www.jalview.org" xmlns:ns2="www.jalview.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" Ang="&#8491;" pi1a="0" pi2a="0" pi3a="3">
74-
// <propertyC>propertyC0</propertyC>
75-
// <c>getC</c>
76-
// <propc>=getproPERtyC:propertyC01</propc>
77-
// <propertyc>=getpropertyc:propertyC0</propertyc>
78-
// <b2>true</b2>
79-
// <b3>true</b3>
80-
// <aToBe>getAtoBe</aToBe>
81-
// <propertyAToBe>=getPropertyAtoB</propertyAToBe>
82-
// </ns2:RootNone>
83-
// private!setC
84-
// setProPERtyC:=getproPERtyC:propertyC01
85-
// setpropertyc:=getpropertyc:propertyC0
86-
// setB2()
87-
// setB3()
88-
// setAToBe:getAtoBe
89-
// setPropertyAToBe:=getPropertyAtoB
90-
// getPropertyAng[].length is 3
91-
// Test_JAXB_NONE OK
92-
93-
@XmlElementDecl(namespace = "www.jalview.org", name = "Root")
94-
public static JAXBElement<Root_NONE> createRootModel(Root_NONE value) {
95-
return new JAXBElement<Root_NONE>(new QName("www.jalview.org", "Root"), Root_NONE.class, null, value);
96-
}
97-
9831
public static void main(String[] args) {
9932
JAXBContext jc;
10033
try {
10134
jc = JAXBContext.newInstance(Root_NONE.class);
10235

10336
Root_NONE root = new Root_NONE("test");
37+
root.setPropertyAng("?");
10438
System.out.println("getPropertyC is " + root.getproPERtyC());
10539
Marshaller marshaller = jc.createMarshaller();
10640
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
10741
ByteArrayOutputStream bos = new ByteArrayOutputStream();
108-
// marshaller.marshal(createRootModel(root), bos);
10942
marshaller.marshal(root, bos);
11043
String s = null;
11144
try {
11245
s = new String(bos.toByteArray(), "UTF-8");
113-
System.out.println(s);
46+
System.out.println(s);
47+
11448
Unmarshaller unmarshaller = jc.createUnmarshaller();
49+
50+
// Class<?> c = Test_JAXB_NONE.class;
51+
// InputStream ris = c.getResourceAsStream("jaxb/Root_NONE.xml");
52+
// s = Rdr.streamToUTF8String(new BufferedInputStream(ris));
53+
//ByteArrayInputStream ris = new ByteArrayInputStream(s.getBytes("UTF-8"));
54+
55+
System.out.println(s);
56+
11557
ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes("UTF-8"));
58+
59+
60+
61+
11662
Root_NONE r = (Root_NONE) unmarshaller.unmarshal(is);
117-
assert(r.getPropertyAng().equals("\u212B"));
63+
assert(r.getPropertyAng().equals("?"));
11864
System.out.println("getPropertyAng[].length is " + r.getPropertyAng().getBytes("utf-8").length);
11965
} catch (UnsupportedEncodingException e) {
12066
// TODO Auto-generated catch block
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<RootNone xmlns="package-namespace" ang="?" pi1A="0" pi2A="0" pi3A="3">
3+
<propertyC>propertyC0</propertyC>
4+
<AToBe>getAtoBe</AToBe>
5+
<b2>true</b2>
6+
<b3>true</b3>
7+
<c>getC</c>
8+
<propertyAToBe>=getPropertyAtoB</propertyAToBe>
9+
<propc>=getproPERtyC:propertyC01</propc>
10+
<propertyc>=getpropertyc:propertyC0</propertyc>
11+
</RootNone>

0 commit comments

Comments
 (0)