
------=_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@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@redhat.com=
wrote: =20
<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=
<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" =
</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"=
</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><=
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@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@redhat.com" target=3D"_blank" class=3D"" style=3D"">vszocs@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""= 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/dmak/jaxb-<wb= 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= 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= 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 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 <vszocs@redhat.com> 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=
<a href=3D"http://lists.ovirt.org/mailman/listinfo/devel" target=3D"_blank= ">http://lists.ovirt.org/mailman/listinfo/devel</a><br><br><br></div> </di= v> </div> </div> </div> ------=_Part_1859450_1427808343.1417346766163--