1414import swingjs .JSUtil ;
1515import swingjs .api .js .DOMNode ;
1616
17+ /**
18+ * A simplified class that acts as a repository for critical JAXB XML
19+ * and Java information, both for the marshaller and unmarshaller.
20+ *
21+ * @author hansonr
22+ *
23+ */
1724class JSJAXBField {
1825
1926 private Object javaObject ;
20- Object entryValue ;
27+
28+ // Marshaller only
29+
30+ Object entryValue ;
31+
32+ // Unmarshaller only
33+
2134 DOMNode boundNode ;
2235 List <Object > boundListNodes ;
2336 String xmlCharacterData ;
2437 String xmlAttributeData ;
2538 Attributes xmlAttributes ;
2639 String xmlType ;
2740
41+ /**
42+ * prior to re-use in unmarshalling
43+ *
44+ * @param javaObject
45+ */
2846 public void clear (Object javaObject ) {
2947 this .javaObject = javaObject ;
3048 this .entryValue = null ;
@@ -58,12 +76,14 @@ public void setNode(DOMNode node) {
5876 }
5977 boundNode = node ;
6078 }
79+
80+ // marshaller and unmarshaller
6181
6282 int index ;
6383
6484 String text ;
6585 String javaName ;
66- String methodName ;
86+ String methodNameGet ;
6787 String javaClassName ;
6888
6989 boolean isAttribute ;
@@ -83,6 +103,8 @@ public void setNode(DOMNode node) {
83103 String typeAdapter ;
84104 String mimeType ;
85105
106+ private String methodNameSet ;
107+
86108 private static final Map <String , String > namespacePrefixes = new Hashtable <String , String >();
87109 private static int prefixIndex = 1 ;
88110
@@ -93,15 +115,25 @@ private static String getPrefixFor(String namespace) {
93115 return prefix ;
94116 }
95117
96- JSJAXBField (JSJAXBClass t , Object [][] adata , Object javaObject , int index , List <String > propOrder ) {
118+ /**
119+ * @param jclass
120+ * @param adata
121+ * @param javaObject
122+ * @param index
123+ * @param propOrder
124+ */
125+ JSJAXBField (JSJAXBClass jaxbClass , Object [][] adata , Object javaObject , int index , List <String > propOrder ) {
97126 this .javaObject = javaObject ;
98127 this .index = index ;
99128 javaName = (String ) adata [0 ][0 ];
100129 javaClassName = (String ) adata [0 ][1 ];
101130 isByteArray = javaClassName .equals ("byte[]" );
102- isArray = !isByteArray && javaClassName .indexOf ("[]" ) >= 0 ;
103- String [] javaAnnotations = (String []) adata [1 ];
131+ isArray = !isByteArray && javaClassName .indexOf ("[]" ) >= 0 ;
104132 attr = new Hashtable <String , String >();
133+ readAnnotations (jaxbClass , (String []) adata [1 ], propOrder );
134+ }
135+
136+ private void readAnnotations (JSJAXBClass jclass , String [] javaAnnotations , List <String > propOrder ) {
105137 text = "" ;
106138 for (int i = 0 ; i < javaAnnotations .length ; i ++) {
107139 String data = javaAnnotations [i ];
@@ -112,25 +144,46 @@ private static String getPrefixFor(String namespace) {
112144 if (pt >= 0 && data .indexOf ("=" ) >= 0 )
113145 addXMLAttributes (tag , data , attr );
114146 if (javaName != null && javaName .startsWith ("M:" )) {
115- methodName = javaName .substring (2 );
147+ methodNameGet = javaName .substring (2 );
116148 // annotation can be on set... or get... or is...
117- if (methodName .startsWith ("set" )) {
118- methodName = "get" + methodName .substring (3 );
149+ // qualifications getXxxx$() and setXxxx$mytype_escaped(xxx)
150+ if (methodNameGet .startsWith ("set" )) {
151+ methodNameSet = methodNameGet ;
152+ methodNameGet = "get" + methodNameGet .substring (3 ) + "$" ;
153+ methodNameGet = methodNameGet .split ("$" )[0 ] + "$" ;
154+ boolean haveGet = false ;
155+ /**
156+ * @j2sNative haveGet = !!javaObject[methodName];
157+ */
158+ if (!haveGet )
159+ methodNameGet = "is" + methodNameGet .substring (3 );
160+ } else {
161+ methodNameSet = "set" + methodNameGet .substring (methodNameGet .startsWith ("is" ) ? 2 : 3 );
162+ /**
163+ * Looking here for a match to the first $
164+ *
165+ * @j2sNative
166+ *
167+ * for (var a in javaObject){if (a.startsWith(this.methodNameSet)) {
168+ * this.methodNameSet = a;break; } }
169+ */
119170 }
120- javaName = getJavaNameFromMethodName (methodName );
171+ javaName = getJavaNameFromMethodName (methodNameGet );
121172 }
122- processTagName (t , tag , data , propOrder );
123-
173+ processTagName (jclass , tag , data , propOrder );
124174 }
125- if (javaName != null ) {
175+ // ensure that we have a qualified name if appropriate
176+ if (javaName != null ) {
126177 setDefaults ();
127178 if (qualifiedName .getLocalPart ().length () == 0 )
128- qualifiedName = new QName (qualifiedName .getNamespaceURI (),
129- JSJAXBClass .getXmlNameFromClassName (javaName ),
130- qualifiedName .getPrefix ());
179+ qualifiedName = new QName (qualifiedName .getNamespaceURI (),
180+ JSJAXBClass .getXmlNameFromClassName (javaName ), qualifiedName .getPrefix ());
131181 }
132182 }
133183
184+ /**
185+ * Set a few defaults. The xmlSchema "hexBinary" does not work.
186+ */
134187 private void setDefaults () {
135188 if (xmlSchema == null && typeAdapter == null ) {
136189 if (javaClassName .equals ("byte[]" ))
@@ -201,16 +254,16 @@ else if (data.indexOf("PROPERTY") >= 0)
201254 xmlSchema = null ;
202255 typeAdapter = "HexBinaryAdapter" ;
203256 }
204- // e.g.
205- // @XmlSchemaType(name="date")
206- // public XMLGregorianCalendar cal;
207- //
208- // @XmlSchemaType(name="hexBinary") <-- does not work with JAXB
209- // https://jinahya.wordpress.com/2012/11/08/printing-binary-as-hexbinary-not-base64binary-with-jaxb/
210- // public byte[] hexBytes;
211- //
212- // @XmlSchemaType(name="base64Binary")
213- // public byte[] base64Bytes;
257+ // e.g.
258+ // @XmlSchemaType(name="date")
259+ // public XMLGregorianCalendar cal;
260+ //
261+ // @XmlSchemaType(name="hexBinary") <-- does not work with JAXB
262+ // https://jinahya.wordpress.com/2012/11/08/printing-binary-as-hexbinary-not-base64binary-with-jaxb/
263+ // public byte[] hexBytes;
264+ //
265+ // @XmlSchemaType(name="base64Binary")
266+ // public byte[] base64Bytes;
214267 break ;
215268 case "@XmlJavaTypeAdapter" :
216269 // typically CollapsedStringAdapter.class
@@ -240,13 +293,26 @@ else if (data.indexOf("PROPERTY") >= 0)
240293 }
241294 }
242295
296+ /**
297+ * Prepend @Xml......: to the tag name to avoid internal collision when
298+ * combining all annotations into one.
299+ *
300+ * @param tag
301+ * @return
302+ */
243303 private QName getName (String tag ) {
244304 String name , namespace ;
245305 name = attr .get (tag + ":name" );
246306 namespace = attr .get (tag = ":namespace" );
247307 return new QName (namespace , name == null ? "" : name , namespace == null ? "" : getPrefixFor (namespace ));
248308 }
249309
310+ /**
311+ * There are rules here...
312+ *
313+ * @param methodName
314+ * @return
315+ */
250316 private String getJavaNameFromMethodName (String methodName ) {
251317 String javaName = methodName .substring (methodName .startsWith ("is" ) ? 2 : 3 );
252318 String lcaseName = javaName .substring (0 , 1 ).toLowerCase () + javaName .substring (1 );
@@ -262,11 +328,24 @@ && getJSType(name = lcaseName.substring(javaName.length() - 8)).equals("undefine
262328 return name ;
263329 }
264330
331+ /**
332+ * read the JavaScript type of this object -- array, etc.
333+ * @param javaName
334+ * @return
335+ */
265336 private String getJSType (String javaName ) {
266337 return (/** @j2sNative ( typeof this.javaObject[javaName]) || */
267338 null );
268339 }
269340
341+ /**
342+ * Use the built-in jQuery XML parser here (as well as in JSSAXParser)
343+ * to do the simple conversion of annotation expressions.
344+ *
345+ * @param tag
346+ * @param data
347+ * @param attr
348+ */
270349 private void addXMLAttributes (String tag , String data , Map <String , String > attr ) {
271350 data = "<__ " + removeCommas (data ) + " />" ;
272351 // System.out.println(data);
@@ -277,7 +356,7 @@ private void addXMLAttributes(String tag, String data, Map<String, String> attr)
277356 attr .put (tag + ":" + names [i ], node .getAttribute (names [i ]));
278357 }
279358
280- private String removeCommas (String s ) {
359+ private static String removeCommas (String s ) {
281360 boolean escaped = false ;
282361 for (int i = 0 ; i < s .length (); i ++) {
283362 switch (s .charAt (i )) {
@@ -302,22 +381,6 @@ private String removeCommas(String s) {
302381 return s ;
303382 }
304383
305- @ SuppressWarnings ("unused" )
306- public Object getValue () {
307- if (entryValue != null )
308- return entryValue ;
309- String javaName = this .javaName ;
310- Object obj = this .javaObject ;
311- boolean isMethod = (this .methodName != null );
312- /**
313- * @j2sNative
314- *
315- * obj = (isMethod ? obj[this.methodName]() : obj[javaName])
316- *
317- */
318- return obj ;
319- }
320-
321384 public String toString () {
322385 return "{" + javaName + "}" + index ;
323386 }
@@ -356,51 +419,73 @@ private boolean simplePackages() {
356419 public Class <?> getJavaClassForUnmarshaling () throws ClassNotFoundException {
357420 return Class .forName (javaClassName );
358421 }
422+
423+ /**
424+ * Retrieve the Java value using the method or directly
425+ *
426+ * @return
427+ */
428+ @ SuppressWarnings ("unused" )
429+ public Object getValue () {
430+ if (entryValue != null )
431+ return entryValue ;
432+ String n = this .javaName ;
433+ Object o = javaObject ;
434+ String m = methodNameGet ;
435+ /**
436+ * @j2sNative
437+ *
438+ * o = (m ? o[m]apply(o, []) : o[n]);
439+ *
440+ */
441+ return o ;
442+ }
443+
444+ public Object getObject () {
445+ Object o = javaObject ;
446+ String x = javaName ;
447+ String m = methodNameGet ;
448+ /**
449+ * return (m ? o[m].apply(o, []) : o[x];
450+ */
451+ return null ;
452+ }
453+
454+
359455 /**
360456 * NOTE: This will not work for private set methods
361457 *
362458 * @param value
363459 */
364460 @ SuppressWarnings ("unused" )
365461 public void setValue (Object value ) {
366- String m = this . methodName ;
367- String j = this . javaName ;
368- Object o = this . javaObject ;
462+ String m = methodNameSet ;
463+ String j = javaName ;
464+ Object o = javaObject ;
369465 /**
370466 * @j2sNative
371467 *
372- * if (m)
468+ * if(m)
373469 * o[m].apply(o, [value]);
374470 * else
375471 * o[j] = value;
376472 */
377473 }
378474
475+ /**
476+ * Get the (default) adapter. TODO: generalize this. A bit of a hack
477+ *
478+ * @return
479+ */
379480 public XmlAdapter getAdapter () {
380481 if (typeAdapter == null )
381482 return null ;
382- String adapterClass = "javax.xml.bind.annotation.adapters." + typeAdapter ;
483+ String adapterClass = (typeAdapter .indexOf (".xml." ) < 0 ?
484+ "javax.xml.bind.annotation.adapters." : "" )
485+ + typeAdapter ;
383486 return JSJAXBClass .getAdapter (adapterClass );
384487 }
385488
386- public Object getXMLValue () {
387- if (xmlAttributeData != null )
388- return xmlAttributeData ;
389-
390- // TODO Auto-generated method stub
391- return null ;
392- }
393-
394- public Object getObject () {
395- Object o = javaObject ;
396- String x = javaName ;
397- /**
398- * return o[x];
399- */
400- return null ;
401- }
402-
403-
404489 /*
405490 * notes
406491 *
0 commit comments