Skip to content

Commit 118c421

Browse files
hansonrhansonr
authored andcommitted
method set/get/is with qualifications
1 parent 157a921 commit 118c421

File tree

1 file changed

+150
-65
lines changed

1 file changed

+150
-65
lines changed

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

Lines changed: 150 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,35 @@
1414
import swingjs.JSUtil;
1515
import 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+
*/
1724
class 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

Comments
 (0)