------=_Part_1859450_1427808343.1417346766163
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Hey Vojtech,
How are you?, please see my reply inline.
On Friday, November 28, 2014 5:26 PM, Vojtech Szocs <vszocs(a)redhat.co=
m
wrote:
=20
Hi guys,
since the initial (small, working & well-tested) version of oVirtJS
JavaScript SDK is finished [*], I've started working on GWT wrapper
for oVirtJS.
While analyzing/reverse-engineering oVirt Java SDK, some thoughts
came to my mind, and I wanted to share them with you.
[*] TODO(vszocs) upload new patchset with all recent changes
First, the way XJC (JAXB binding compiler that generates Java beans
out of REST XSD schema) is invoked looks a bit weird to me, as Java
SDK's XsdCodegen does this:
=C2=A0 Runtime.getRuntime().exec(command)
Why not simply use existing Maven plugins to invoke XJC?
- either:
https://github.com/highsource/maven-jaxb2-plugin
[MP] sdk was using jaxb to begin with, it was replaced with XJC just recent=
ly,
btw Juan, what was the motivation behind this?=20
(REST api uses jaxb as well so we used to have 1x1 mappings)
=C2=A0
- or:
http://mojo.codehaus.org/jaxb2-maven-plugin/
[MP]=C2=A0same.
Second, and most importantly, what's the point of having "group"
entities? I'll give an example - api.xsd contains this:
=C2=A0 <xs:complexType name=3D"DataCenters">
=C2=A0 =C2=A0 <xs:complexContent>
=C2=A0 =C2=A0 =C2=A0 <xs:extension base=3D"BaseResources">
=C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:sequence>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:annotation>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:appinfo>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <jaxb:property name=
=3D"DataCenters"/>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </xs:appinfo>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </xs:annotation>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:element ref=3D"data_center" minOccur=
s=3D"0" maxOccurs=3D"unbounded"/>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </xs:sequence>
=C2=A0 =C2=A0 =C2=A0 </xs:extension>
=C2=A0 =C2=A0 </xs:complexContent>
=C2=A0 </xs:complexType>
(Same as above for Hosts, Clusters, VMs, etc.)
This results in following (IMHO rather meaningless) Java class
being generated by XJC:
public class DataCenters extends BaseResources {
=C2=A0 =C2=A0 @XmlElement(name =3D "data_center")
=C2=A0 =C2=A0 protected List<DataCenter> dataCenters;
=C2=A0 =C2=A0 public List<DataCenter> getDataCenters() {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (dataCenters =3D=3D null) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dataCenters =3D new ArrayList<Dat=
aCenter>();
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return this.dataCenters;
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 public boolean isSetDataCenters() {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ((this.dataCenters!=3D null)&&(!this.dat=
aCenters.isEmpty()));
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 public void unsetDataCenters() {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 this.dataCenters =3D null;
=C2=A0 =C2=A0 }
}
Instead, we could use @XmlElementWrapper as described in [1]
to avoid generating "group" entities altogether.
[1]
https://github.com/dmak/jaxb-xew-plugin
The fact that Java SDK provides decorator for each specific
resource collection (like DataCenters), instead of having ONE
resource collection type, greatly complicates overall design
and code-gen aspect.
[MP]=C2=A0Well, i guess now is speaking JS constraints ghost, am i right?,
in any case, the reasons for having decorator per collection are:
1. compliance with REST API (all SDKs and REST api are sharing same well kn=
ow architecture)
2. "decorator" is a well known and commonly used java design pattern
3. having one resource type serving all collections would create a bottlene=
ck
(well it might depend on how you implementing it, but still in my view it's=
less convenient/readable
than dedicated collection with own context, verbs and behavior),=C2=A0
after all the purpose of sdk is being java client serving application in "J=
ava" way(i.e type-safe + well bounded interface),=C2=A0while JS use-cases &=
paradigms are totallydifferent,=C2=A0just consider:
[1] java-sdk stile
Disk snapshotDisk =3D api.getVms().get('my-vm').getSnapshots().get('my-snap=
shot').getDisks().get('my-disk')
[2] JS style you propose
Disk snapshotDisk =3D getCollections().get(new Params[] { Disk.class, 'my-v=
m', 'my-snapshot', 'my-disk'})
notice:=C2=A0=3D=3D=3D=3D=3D
in [2] you have a bunch of parameters disconnected form any context where o=
rderis *important* (other way you heuristic guesses what user meaning by th=
ese params won't work),obviously it's fragile and error prone,
while [1] is readable, well bounded, defending it's consumers from potentia=
ls errors(exactly what SDK should look like),
hope it helps.
=20
On Friday, November 28, 2014 5:26 PM, Vojtech Szocs <vszocs(a)redhat.com=
wrote:
=20
Hi guys,
since the initial (small, working & well-tested) version of oVirtJS
JavaScript SDK is finished [*], I've started working on GWT wrapper
for oVirtJS.
While analyzing/reverse-engineering oVirt Java SDK, some thoughts
came to my mind, and I wanted to share them with you.
[*] TODO(vszocs) upload new patchset with all recent changes
First, the way XJC (JAXB binding compiler that generates Java beans
out of REST XSD schema) is invoked looks a bit weird to me, as Java
SDK's XsdCodegen does this:
=C2=A0 Runtime.getRuntime().exec(command)
Why not simply use existing Maven plugins to invoke XJC?
- either:
https://github.com/highsource/maven-jaxb2-plugin
- or:
http://mojo.codehaus.org/jaxb2-maven-plugin/
Second, and most importantly, what's the point of having "group"
entities? I'll give an example - api.xsd contains this:
=C2=A0 <xs:complexType name=3D"DataCenters">
=C2=A0 =C2=A0 <xs:complexContent>
=C2=A0 =C2=A0 =C2=A0 <xs:extension base=3D"BaseResources">
=C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:sequence>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:annotation>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:appinfo>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <jaxb:property name=
=3D"DataCenters"/>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </xs:appinfo>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </xs:annotation>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <xs:element ref=3D"data_center" minOccur=
s=3D"0" maxOccurs=3D"unbounded"/>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </xs:sequence>
=C2=A0 =C2=A0 =C2=A0 </xs:extension>
=C2=A0 =C2=A0 </xs:complexContent>
=C2=A0 </xs:complexType>
(Same as above for Hosts, Clusters, VMs, etc.)
This results in following (IMHO rather meaningless) Java class
being generated by XJC:
public class DataCenters extends BaseResources {
=C2=A0 =C2=A0 @XmlElement(name =3D "data_center")
=C2=A0 =C2=A0 protected List<DataCenter> dataCenters;
=C2=A0 =C2=A0 public List<DataCenter> getDataCenters() {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (dataCenters =3D=3D null) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dataCenters =3D new ArrayList<Dat=
aCenter>();
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return this.dataCenters;
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 public boolean isSetDataCenters() {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ((this.dataCenters!=3D null)&&(!this.dat=
aCenters.isEmpty()));
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 public void unsetDataCenters() {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 this.dataCenters =3D null;
=C2=A0 =C2=A0 }
}
Instead, we could use @XmlElementWrapper as described in [1]
to avoid generating "group" entities altogether.
[1]
https://github.com/dmak/jaxb-xew-plugin
The fact that Java SDK provides decorator for each specific
resource collection (like DataCenters), instead of having ONE
resource collection type, greatly complicates overall design
and code-gen aspect.
In oVirtJS GWT wrapper, we'll avoid above complication through
single resource collection type (having common methods like
get(id), list() etc) for all resources.
Regards,
Vojtech
_______________________________________________
Devel mailing list
Devel(a)ovirt.org
http://lists.ovirt.org/mailman/listinfo/devel
------=_Part_1859450_1427808343.1417346766163
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div style=3D"color:#000; background-color:#fff; font-family:HelveticaNeue-=
Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grand=
e, sans-serif;font-size:16px"><div
id=3D"yui_3_16_0_1_1417345481659_9805"><=
span></span></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_14173454816=
59_9941">Hey <font face=3D"Arial" class=3D""
style=3D"">Vojtech,<br class=
=3D"" style=3D""><br class=3D""
style=3D""></font></div><div class=3D"" sty=
le=3D"" id=3D"yui_3_16_0_1_1417345481659_9944"><font
face=3D"Arial" class=
=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9943">How are you?, pleas=
e see my reply inline.<br class=3D""
style=3D""></font></div><div class=3D"=
" style=3D"" id=3D"yui_3_16_0_1_1417345481659_9922"><div
class=3D"" style=
=3D"" id=3D"yui_3_16_0_1_1417345481659_9921"><span
class=3D"" style=3D"" id=
=3D"yui_3_16_0_1_1417345481659_9938"><br class=3D""
style=3D""><blockquote =
class=3D"" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,=
204,204);padding-left:1ex"
id=3D"yui_3_16_0_1_1417345481659_9937"><div styl=
e=3D"font-family: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial,
'Lucid=
a Grande', sans-serif;" class=3D""
id=3D"yui_3_16_0_1_1417345481659_9936"><=
div class=3D"" style=3D""></div><div class=3D""
style=3D"" id=3D"yui_3_16_0=
_1_1417345481659_9942"><br class=3D"" style=3D""><br
class=3D"" style=3D"">=
</div> <div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9935"> =
<div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9934"> <div cla=
ss=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9933"> <div dir=3D"ltr"=
class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9940"> <font face=
=3D"Arial" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9939"> On=
Friday, November 28, 2014 5:26 PM, Vojtech Szocs <<a href=3D"mailto:vsz=
ocs(a)redhat.com" target=3D"_blank" class=3D""
style=3D"">vszocs(a)redhat.com</=
a>> wrote:<br class=3D"" style=3D""> </font>
</div> <br class=3D"" styl=
e=3D""><br class=3D"" style=3D""> <div
class=3D"" style=3D"" id=3D"yui_3_16=
_0_1_1417345481659_9932">Hi guys,<br class=3D""
style=3D""><br class=3D"" s=
tyle=3D"">since the initial (small, working & well-tested) version of
o=
VirtJS<br class=3D"" style=3D"">JavaScript SDK is finished [*],
I've starte=
d working on GWT wrapper<br class=3D"" style=3D"">for
oVirtJS.<br class=3D"=
" style=3D""><br class=3D"" style=3D"">While
analyzing/reverse-engineering =
oVirt Java SDK, some thoughts<br class=3D"" style=3D"">came to
my mind, and=
I wanted to share them with you.<br class=3D""
style=3D""><br class=3D"" s=
tyle=3D"">[*] TODO(vszocs) upload new patchset with all recent changes<br
c=
lass=3D"" style=3D""><br class=3D""
style=3D"">First, the way XJC (JAXB bin=
ding compiler that generates Java beans<br class=3D""
style=3D"">out of RES=
T XSD schema) is invoked looks a bit weird to me, as Java<br class=3D"" sty=
le=3D"">SDK's XsdCodegen does this:<br class=3D""
style=3D""><br class=3D""=
style=3D""> Runtime.getRuntime().exec(<wbr class=3D""
style=3D"">com=
mand)<br class=3D"" style=3D""><br class=3D""
style=3D"">Why not simply use=
existing Maven plugins to invoke XJC?<br class=3D""
style=3D"">- either: <=
a
href=3D"https://github.com/highsource/maven-jaxb2-plugin"
target=3D"_blan=
k" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9931">https://git=
hub.com/highsource/<wbr class=3D""
style=3D"">maven-jaxb2-plugin</a><br cla=
ss=3D""
style=3D""></div></div></div></div></div></blockquote><div
class=3D=
"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_10278"><br class=3D"" style=
=3D""></div></span><div class=3D""
style=3D"" id=3D"yui_3_16_0_1_1417345481=
659_9930" dir=3D"ltr"><font size=3D"4" class=3D""
style=3D"" id=3D"yui_3_16=
_0_1_1417345481659_9929">[MP] sdk was using jaxb to begin with, it was repl=
aced with XJC just recently,<br class=3D""
style=3D""></font></div><div cla=
ss=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9928"><font size=3D"4" =
class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9927">btw Juan, what=
was the motivation behind this? <br class=3D"" style=3D"">(REST
api uses j=
axb as well so we used to have 1x1 mappings)</font><br class=3D""
style=3D"=
"></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_10277">=
</div><blockquote class=3D"" style=3D"margin:0px 0px 0px
0.8ex;border=
-left:1px solid rgb(204,204,204);padding-left:1ex" id=3D"yui_3_16_0_1_14173=
45481659_9920"><div style=3D"font-family: HelveticaNeue, 'Helvetica
Neue', =
Helvetica, Arial, 'Lucida Grande', sans-serif;" class=3D""
id=3D"yui_3_16_0=
_1_1417345481659_9919">- or: <a
href=3D"http://mojo.codehaus.org/jaxb2-mave=
n-plugin/" target=3D"_blank" class=3D"" style=3D""
id=3D"yui_3_16_0_1_14173=
45481659_9918">http://mojo.codehaus.org/<wbr class=3D""
style=3D"">jaxb2-ma=
ven-plugin/</a><br class=3D""
style=3D""></div></blockquote><div class=3D""=
style=3D"" id=3D"yui_3_16_0_1_1417345481659_9923"><br
class=3D"" style=3D"=
"></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9924"><=
font size=3D"4" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_1029=
0">[MP] same.</font><br class=3D""
style=3D""></div><div class=3D"" st=
yle=3D""><div class=3D"" style=3D""><div
id=3D"q_14a003ec78624219_3" class=
=3D"" style=3D""><div class=3D""
style=3D""></div></div></div></div><div cl=
ass=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9926"><br></div><div c=
lass=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_9926"><div class=3D""=
style=3D"" id=3D"yui_3_16_0_1_1417345481659_14459"><div
class=3D"" style=
=3D"" id=3D"yui_3_16_0_1_1417345481659_14458"><blockquote
class=3D"" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex" id=3D"yui_3_16_0_1_1417345481659_14457"><div
style=3D"font-famil=
y: HelveticaNeue, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande',
sans=
-serif;" class=3D""
id=3D"yui_3_16_0_1_1417345481659_14456"><br class=3D"" =
style=3D"">Second, and most importantly, what's the point of having
"group"=
<br class=3D"" style=3D"">entities? I'll give an example -
api.xsd contains=
this:<br class=3D"" style=3D""><br class=3D""
style=3D""> <xs:com=
plexType name=3D"DataCenters"><br class=3D""
style=3D""> &l=
t;xs:complexContent><br class=3D"" style=3D"">
<x=
s:extension base=3D"BaseResources"><br class=3D""
style=3D""> &nbs=
p; <xs:sequence><br class=3D""
style=3D""> =
<xs:annotation><br class=3D""
style=3D""> =
<xs:appinfo><br
class=3D"" style=
=3D"">
<jaxb:prop=
erty name=3D"DataCenters"/><br class=3D""
style=3D"">  =
; </xs:appinfo><br class=3D""
style=3D""> =
</xs:annotation><br
class=3D"" style=3D""=
<xs:element ref=3D"data_center" minO=
ccurs=3D"0"
maxOccurs=3D"unbounded"/><br class=3D""
style=3D""> &n=
bsp; </xs:sequence><br class=3D""
style=3D""> &nb=
sp; </xs:extension><br class=3D""
style=3D""> <=
;/xs:complexContent><br class=3D"" style=3D"">
</xs:complexType=
><br class=3D"" style=3D""><br class=3D""
style=3D"">(Same as above for =
Hosts, Clusters, VMs, etc.)<br class=3D"" style=3D""><br
class=3D"" style=
=3D"">This results in following (IMHO rather meaningless) Java class<br
cla=
ss=3D"" style=3D"">being generated by XJC:<br
class=3D"" style=3D""><br cla=
ss=3D"" style=3D"">public class DataCenters extends BaseResources
{<br clas=
s=3D"" style=3D""><br class=3D""
style=3D""> @XmlElement(name =
=3D "data_center")<br class=3D"" style=3D"">
protected List<=
;DataCenter> dataCenters;<br class=3D"" style=3D""><br
class=3D"" style=
=3D""> public List<DataCenter>
getDataCenters() {<br cla=
ss=3D"" style=3D""> if
(dataCenters =3D=3D null)=
{<br class=3D"" style=3D"">
dataC=
enters =3D new ArrayList<DataCenter>();<br class=3D""
style=3D"">&nbs=
p; }<br class=3D""
style=3D""> &nb=
sp; return this.dataCenters;<br class=3D"" style=3D"">
}<br cl=
ass=3D"" style=3D""><br class=3D""
style=3D""> public boolean =
isSetDataCenters() {<br class=3D"" style=3D"">
r=
eturn ((this.dataCenters!=3D null)&&(!this.dataCenters.<wbr class=
=3D"" style=3D"">isEmpty()));<br class=3D""
style=3D""> }<br c=
lass=3D"" style=3D""><br class=3D""
style=3D""> public void un=
setDataCenters() {<br class=3D"" style=3D"">
thi=
s.dataCenters =3D null;<br class=3D"" style=3D"">
}<br class=
=3D"" style=3D""><br class=3D""
style=3D"">}<br class=3D"" style=3D""><br c=
lass=3D"" style=3D"">Instead, we could use @XmlElementWrapper as
described =
in [1]<br class=3D"" style=3D"">to avoid generating
"group" entities altoge=
ther.<br class=3D"" style=3D""><br class=3D""
style=3D"">[1] <a href=3D"htt=
ps://github.com/dmak/jaxb-xew-plugin" target=3D"_blank"
class=3D"" style=3D=
""
id=3D"yui_3_16_0_1_1417345481659_14463">https://github.com/d...
r class=3D"" style=3D"">xew-plugin</a><br
class=3D"" style=3D""><br class=
=3D"" style=3D"">The fact that Java SDK provides decorator for each
specifi=
c<br class=3D"" style=3D"">resource collection (like
DataCenters), instead =
of having ONE<br class=3D"" style=3D"">resource collection type,
greatly co=
mplicates overall design<br class=3D"" style=3D"">and code-gen
aspect.<br c=
lass=3D"" style=3D""></div></blockquote><div
class=3D"" style=3D"" id=3D"yu=
i_3_16_0_1_1417345481659_14464"><br class=3D""
style=3D""></div></div></div=
<div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_14466"><font s=
ize=3D"4"
class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_14465">[MP=
] Well, i guess now is speaking JS constraints ghost, am i right?</fon=
t>,<br class=3D"" style=3D""></div><div
class=3D"" style=3D"" id=3D"yui_3_1=
6_0_1_1417345481659_12513"><font size=3D"4" class=3D""
style=3D"" id=3D"yui=
_3_16_0_1_1417345481659_12514">in any case, the reasons for having decorato=
r per collection are:<br class=3D"" style=3D""><br
class=3D"" style=3D""></=
font></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_1251=
2"><font size=3D"4" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_=
12511">1. compliance with REST API (all SDKs and REST api are sharing same =
well know architecture)<br class=3D""
style=3D""></font></div><div class=3D=
"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12510"><font size=3D"4" clas=
s=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12509">2. "decorator" is=
a well known and commonly used java design pattern<br class=3D""
style=3D"=
"></font></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_=
12508"><font size=3D"4" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481=
659_12507">3. having one resource type serving all collections would create=
a bottleneck<br class=3D""
style=3D""></font></div><div class=3D"" style=
=3D"" id=3D"yui_3_16_0_1_1417345481659_12506"><font
size=3D"4" class=3D"" s=
tyle=3D"" id=3D"yui_3_16_0_1_1417345481659_12505">(well it might
depend on =
how you implementing it, but still in my view it's less convenient/readable=
<br class=3D"" style=3D"">than dedicated collection with own
context, verbs=
and behavior), </font></div><div class=3D""
style=3D"" id=3D"yui_3_16=
_0_1_1417345481659_12506"><font size=3D"4" class=3D""
style=3D""><br></font=
</div><font size=3D"4" class=3D""
id=3D"yui_3_16_0_1_1417345481659_12521" =
style=3D"">after
all the purpose of sdk is being java client serving applic=
ation in "Java" way</font></div><div class=3D""
style=3D"" id=3D"yui_3_16_0=
_1_1417345481659_9926" dir=3D"ltr"><font size=3D"4"
class=3D"" style=3D"">(=
i.e type-safe + well bounded interface), </font><font
size=3D"4" class=
=3D"" id=3D"yui_3_16_0_1_1417345481659_12521" style=3D"font-size:
large;">w=
hile JS use-cases & paradigms are totally</font></div><div
class=3D"" s=
tyle=3D"" id=3D"yui_3_16_0_1_1417345481659_9926"
dir=3D"ltr"><font size=3D"=
4" class=3D"" style=3D"font-size:
large;">different</font><span class=3D"" =
id=3D"yui_3_16_0_1_1417345481659_16206">, </span><span
style=3D"font-s=
ize: large;">just consider:</span><div class=3D""
style=3D"" id=3D"yui_3_16=
_0_1_1417345481659_12506"><font size=3D"4" class=3D""
style=3D""><br></font=
</div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506" d=
ir=3D"ltr"><font size=3D"4" class=3D""
style=3D"" id=3D"yui_3_16_0_1_141734=
5481659_16215">[1] java-sdk stile</font></div><div
class=3D"" style=3D"" id=
=3D"yui_3_16_0_1_1417345481659_12506" dir=3D"ltr"><font
size=3D"4" class=3D=
"" style=3D""><br></font></div><div
class=3D"" style=3D"" id=3D"yui_3_16_0_=
1_1417345481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" style=3D"" i=
d=3D"yui_3_16_0_1_1417345481659_12981">Disk snapshotDisk =3D api.getVms().g=
et('my-vm').getSnapshots().get('my-snapshot').getDisks().get('my-disk')</fo=
nt></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506"=
dir=3D"ltr"><font size=3D"4" class=3D""
style=3D""><br></font></div><div c=
lass=3D"" style=3D"" id=3D"yui_3_16_0_1_1417345481659_12506"
dir=3D"ltr"><f=
ont size=3D"4" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12991=
">[2] JS style you propose</font></div><div class=3D""
style=3D"" id=3D"yui=
_3_16_0_1_1417345481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" styl=
e=3D""><br></font></div><div class=3D""
style=3D"" id=3D"yui_3_16_0_1_14173=
45481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" style=3D"" id=3D"yu=
i_3_16_0_1_1417345481659_12988">Disk snapshotDisk =3D getCollections().get(=
new Params[] { Disk.class, 'my-vm', 'my-snapshot',
'my-disk'})<br></font></=
div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506" dir=
=3D"ltr"><font size=3D"4" class=3D""
style=3D""><br></font></div><div class=
=3D"" style=3D"" id=3D"yui_3_16_0_1_1417345481659_12506"
dir=3D"ltr"><font =
size=3D"4" class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_13000">no=
tice: </font></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_14173=
45481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" style=3D"">=3D=3D=
=3D=3D=3D</font></div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345=
481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" style=3D""><br></font=
</div><div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506" d=
ir=3D"ltr"><font size=3D"4" class=3D""
style=3D"" id=3D"yui_3_16_0_1_141734=
5481659_13698">in [2] you have a bunch of parameters disconnected form any =
context where order</font></div><div class=3D""
style=3D"" id=3D"yui_3_16_0=
_1_1417345481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" style=3D"" =
id=3D"yui_3_16_0_1_1417345481659_13001">is *important* (other way you heuri=
stic guesses what user meaning by these params won't
work),</font></div><di=
v class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506" dir=3D"ltr"=
<font size=3D"4" class=3D""
style=3D"" id=3D"yui_3_16_0_1_1417345481659_14=
446">obviously it's fragile and error
prone,</font></div><div class=3D"" st=
yle=3D"" id=3D"yui_3_16_0_1_1417345481659_12506"
dir=3D"ltr"><font size=3D"=
4" class=3D""
style=3D""><br></font></div><div class=3D""
style=3D"" id=3D"=
yui_3_16_0_1_1417345481659_12506" dir=3D"ltr"><font
size=3D"4" class=3D"" s=
tyle=3D"" id=3D"yui_3_16_0_1_1417345481659_13697">while [1] is
readable, we=
ll bounded, defending it's consumers from potentials
errors</font></div><di=
v class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506" dir=3D"ltr"=
<font size=3D"4" class=3D""
style=3D"" id=3D"yui_3_16_0_1_1417345481659_18=
064">(exactly
what SDK should look like),</font></div><div class=3D"" style=
=3D"" id=3D"yui_3_16_0_1_1417345481659_12506"
dir=3D"ltr"><font size=3D"4" =
class=3D"" style=3D""><br></font></div><div
class=3D"" style=3D"" id=3D"yui=
_3_16_0_1_1417345481659_12506" dir=3D"ltr"><font size=3D"4"
class=3D"" styl=
e=3D"" id=3D"yui_3_16_0_1_1417345481659_17133">hope it
helps.</font></div><=
div class=3D"" style=3D""
id=3D"yui_3_16_0_1_1417345481659_12506" dir=3D"lt=
r"><font size=3D"4" class=3D""
style=3D""><br></font></div><div class=3D"" =
style=3D"" id=3D"yui_3_16_0_1_1417345481659_12520"><font
size=3D"4" class=
=3D"" style=3D""><br class=3D""
style=3D""></font></div><div class=3D"" sty=
le=3D"" id=3D"yui_3_16_0_1_1417345481659_12522"><br><div
class=3D"" style=
=3D"" id=3D"yui_3_16_0_1_1417345481659_12976"><div
data-tooltip=3D"Hide exp=
anded content" aria-label=3D"Hide expanded content" id=3D":g8"
class=3D"" r=
ole=3D"button" tabindex=3D"0" style=3D""><img
class=3D"" src=3D"https://ssl=
.gstatic.com/ui/v1/icons/mail/images/cleardot.gif" style=3D""
data-id=3D"cc=
22cabd-7587-31ae-35b3-0bad76861607"></div></div></div></div><div
class=3D""=
style=3D"" id=3D"yui_3_16_0_1_1417345481659_9926"><br
class=3D"" style=3D"=
"></div></div></div> <div
class=3D"qtdSeparateBR"><br><br></div><div class=
=3D"yahoo_quoted" style=3D"display: block;"> <div
style=3D"font-family: Hel=
veticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, L=
ucida Grande, sans-serif; font-size: 16px;"> <div style=3D"font-family:
Hel=
veticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; fo=
nt-size: 16px;"> <div dir=3D"ltr"> <font size=3D"2"
face=3D"Arial"> On Frid=
ay, November 28, 2014 5:26 PM, Vojtech Szocs &lt;vszocs(a)redhat.com&gt; wrot=
e:<br> </font> </div> <br><br> <div
class=3D"y_msg_container">Hi guys,<br>=
<br>since the initial (small, working & well-tested) version of oVirtJS=
<br>JavaScript SDK is finished [*], I've started working on GWT
wrapper<br>=
for oVirtJS.<br><br>While analyzing/reverse-engineering oVirt Java SDK, som=
e thoughts<br>came to my mind, and I wanted to share them with
you.<br><br>=
[*] TODO(vszocs) upload new patchset with all recent changes<br><br>First, =
the way XJC (JAXB binding compiler that generates Java beans<br>out of REST=
XSD schema) is invoked looks a bit weird to me, as Java<br>SDK's XsdCodege=
n does this:<br><br>
Runtime.getRuntime().exec(command)<br><br>Why no=
t simply use existing Maven plugins to invoke XJC?<br>- either: <a
href=3D"=
https://github.com/highsource/maven-jaxb2-plugin"
target=3D"_blank">https:/=
/github.com/highsource/maven-jaxb2-plugin</a><br>- or: <a
href=3D"http://mo=
jo.codehaus.org/jaxb2-maven-plugin/"
target=3D"_blank">http://mojo.codehaus=
.org/jaxb2-maven-plugin/</a><br><br>Second, and most importantly,
what's th=
e point of having "group"<br>entities? I'll give an example - api.xsd
conta=
ins this:<br><br> <xs:complexType
name=3D"DataCenters"><br>&nbs=
p; <xs:complexContent><br>
<xs:extensio=
n base=3D"BaseResources"><br>
<xs:sequence=
><br>
<xs:annotation><br> =
<xs:appinfo><br> &nbs=
p; <jaxb:property
name=3D"DataCenters=
"/><br>
</xs:appinfo><br>=
</xs:annotation><br> =
<xs:element ref=3D"data_center"
minOccurs=3D"0" max=
Occurs=3D"unbounded"/><br>
</xs:sequence&g=
t;<br>
</xs:extension><br> </xs:c=
omplexContent><br>
</xs:complexType><br><br>(Same as above f=
or Hosts, Clusters, VMs, etc.)<br><br>This results in following (IMHO rathe=
r meaningless) Java class<br>being generated by XJC:<br><br>public class
Da=
taCenters extends BaseResources {<br><br>
@XmlElement(name =3D=
"data_center")<br> protected
List<DataCenter> dataCente=
rs;<br><br> public List<DataCenter>
getDataCenters() {<b=
r> if (dataCenters =3D=3D null)
{<br> &nbs=
p; dataCenters =3D new
ArrayList<DataCenter&=
gt;();<br> }<br>
retu=
rn this.dataCenters;<br> }<br><br>
public boolean=
isSetDataCenters() {<br> return
((this.dataCent=
ers!=3D null)&&(!this.dataCenters.isEmpty()));<br>
}<b=
r><br> public void unsetDataCenters() {<br>
 =
; this.dataCenters =3D null;<br>
}<br><br>}<br><br>Inst=
ead, we could use @XmlElementWrapper as described in [1]<br>to avoid genera=
ting "group" entities altogether.<br><br>[1] <a
href=3D"https://github.com/=
dmak/jaxb-xew-plugin"
target=3D"_blank">https://github.com/dmak/jaxb-xew-pl=
ugin</a><br><br>The fact that Java SDK provides decorator for each
specific=
<br>resource collection (like DataCenters), instead of having ONE<br>resour=
ce collection type, greatly complicates overall design<br>and code-gen aspe=
ct.<br><br>In oVirtJS GWT wrapper, we'll avoid above complication
through<b=
r>single resource collection type (having common methods like<br>get(id), l=
ist() etc) for all
resources.<br><br>Regards,<br>Vojtech<br>_______________=
________________________________<br>Devel mailing list<br><a
ymailto=3D"mai=
lto:Devel@ovirt.org"
href=3D"mailto:Devel@ovirt.org">Devel@ovirt.org</a><br=
">http://lists.ovirt.org/mailman/listinfo/devel</a><br><br><br></div>
</di=
v> </div> </div> </div>
------=_Part_1859450_1427808343.1417346766163--