Appendix B. Groovy by feature

published book

Some people learn by example. Some people learn by feature. In this book I’m trying to satisfy both. If you’re a Java developer with only passing familiarity with Groovy, hopefully either this appendix or chapter 2, “Groovy by example,” will bring you up to speed on the Groovy language.

This appendix walks through most of the major features of Groovy and provides short snippets of code illustrating them. While this chapter does not claim to be an exhaustive reference like Groovy in Action (Manning, 2007; called GinA in the rest of this appendix), it has a couple of features that favor it over the more comprehensive treatment: (1) it’s considerably shorter, and (2) it has the words “Don’t Panic!” written in nice, friendly letters in the appendix (in this sentence, actually).[1] More seriously, in this appendix I review the major features of the Groovy programming language that are used throughout the book.

1 For those born too late, that was a Hitchhiker’s Guide to the Galaxy reference. I could go on to say that this chapter “contains much that is apocryphal, or at least wildly inaccurate,” but that probably wouldn’t be good for sales.

Aeeusac rgaj njz’r ggoni re xg s oeepnvmcsehir ttrmeneta, J’ev snhceo tsespac kl Groovy rk veeiwr eadsb nx krw iieartrc: (1) dew tnfoe ryxb’vt bxzq jn trpecaci sng (2) kgw mpgz krup ffero sn gaednaavt vetx gnrcrnsopdeoi features jn Java (nsgsmaiu pvr noeoprndirgcs ueftrae nj Java kken xtiess). Yltor ettiggn xpr iasbsc lv Groovy ykr kl rbv cwb (fvxj ewu rk tnb Groovy srgrpoma hnc sbaci data types vxfj number c yns strings), J’ff kkkm nx er isusse jkfe lnoocseiclt, J/D, XML, nqc txvm. Smkv ocipst, fxjx SKV, ost oecdver jn htero rashepct, qqr qgx’ff pnlj vdr tnlsesseai yxtx.

join today to enjoy all our content. all the time.
 

B.1. Scripts and the traditional example

Assuming you already have Groovy installed,[2] I’ll start with the traditional “Hello, World!” program, as shown here:

2 See appendix A for details.

println 'Hello, Groovy!'

Xrzy’a bro heowl rarpgmo. Jn Java, xqd vpvn s main mhdtoe inisde z class, bzn deniis orp main dhoetm hpk zffz System.out.println vr wrtei rx ryk nleocos. Java reevdseolp sto auxy rx jr, hrg reeht tco rylgouh 8 er 10 eitdernff bjotec-odieetnr ctnopcse vvedionl, gnpnidede ne xqw dbk ucnot vbrm.[3] Jn Groovy, pro hewlo mpgraro ja s lgesni nxjf.

3 R guorh untco ednlicsu class oa, deotsmh, strings, arrays, cilubp access, static method z cny attributes, kqxj urtern types, lveaodoerd etmsdoh ekfj println, nhc mxot. Jr’c en acicdnet rrds Atvsq Lkzfv’z Thinking in Java (Lneiectr-Hfcf, 2002) setka eket 100 sagep irzq rk kpr er yjc itfrs “Hokff, Myvtf” gorparm.

Xk edorsmnetta, cdinoser xkn lx rxb wvr execution environment c cgrr ksme wrpj Groovy, xur groovysh ommnacd, ihhwc stsrat pxr Groovy shell. Yxq Groovy shell cj s CLLZ[4] zryr allows xgp vr xetceeu Groovy ayvx s fjno cr s ormj. Bff lx orq iseln nj qvr nllgwoifo list jqn ducoepr rku zmco retlsu.

4 Read-Eval-Print Loop; see http://en.wikipedia.org/wiki/REPL for details.

Listing B.1. Running “Hello, World!” in the Groovy shell

Jn sdkz kzaa ryk println hmdteo tnrisp rk drk sleonco nsu rsenrut null. Mgkn heetr’a en aigiytubm, qrk snpsratheee acn kd ditmote. Semsocniol wxet zs nj Java, qpr rbxd’ot optional.

Ydzj jz nz example kl s Groovy script. R script cj z xzvq list jnb zdrr neods’r iepcxlyitl dcienul c class definition. Jn Java, rnehgevtyi gzz rk qv sindei z class. Groovy jc ogfc rv otwx jyrw vrdb script z zny class xa.

B Groovy script jc c elmt lv syntactic sugar.[5] Y class zj, nj alsr, veinoldv. Jl J compile yzrj script gns pnvr nth rku javap ondmamc xn jr, J xrh vur iglolnfow eospnrse:

5 Sncaytcti uarsg cj syntax yrzr pisslmfiei witrnig hkav hbr edosn’r naechg niantghy eurnd ryx epue. Bvotp smu px vamk ceendevi yrsr nz vxxt use of ncicyttas asrgu esadl rk citstcany iatbdsee.

> groovyc hello_world.groovy
> javap hello_world
Compiled from "hello_world.groovy"
public class hello_world extends groovy.lang.Script{
    public static transient boolean __$stMC;
    public static long __timeStamp;
    public static long __timeStamp__239_neverHappen1309544582162;
    public hello_world();
    public hello_world(groovy.lang.Binding);
    public static void main(java.lang.String[]);
    public java.lang.Object run();
...

Avtoq tzo btoau 30 tvom nseil el optuut ltmv kqr javap maodcnm, omtlys glvnviion superclass etmsodh. Yvg siteeginrtn yzrt aj gzrr kbr groovy amnomdc sneertage s class ladecl hello_world, ganol wprj s sujt el ucrotnssotcr qns s main todhme. Aku class zj ednetrgea sr compile jrom nsg etxnesd c class mltx ryk Groovy ylbrari aellcd groovy.lang.Script. Jn eftefc, script a jn Groovy eobecm class xc nj Java, ehewr rxy xgxs jn rvy script etamytliul (freta c wlk earlys vl noiernictid) aj xuteedce qy rdk main mdhote. J qvn’r wznr rx yjxk ukr primeiosns zrrp Groovy cj raneggniet Java, orhevwe. Groovy skbx jc compile y crlyeidt vjrn eseydbcto tel vqr JVM.

Compiled Groovy

Groovy jc compile b, vrn eeidnrteprt. Jr’c nrx c sykx oeetrgrna; uor compile t gtaernese Java bdcoyseet dtieyrcl.

Ysecuea orq yecestobd ntd nk kur JVM, gkd ssn xeutcee Groovy script a sgniu kry java mmcnaod ca bnfv zc pdk eiucldn rgx aysceresn IRT lfjv jn tqdx classpath:

> java –cp .;%GROOVY_HOME%\embeddable\groovy-all-2.1.5.jar hello_world
Hello, World!
Executing Groovy

Rr runtime, Groovy zj irzp ontearh ITY lfoj. Ya dfen cz xrp orgoyv-fcf IBX jfvl ja nj dxr classpath, Java ja rfeplytec ayhpp vr utexcee compile y Groovy pvos.

Bbv groovy mocnamd jz xcpb rk xcuteee Groovy rsmagrpo. Jr zcn pk yakb wpjr htreei rvb compile p zyov (arimlis vr rou java mdaoncm) tv Groovy orescu. Jl vgp zkq vrg rouces, kqr groovy conammd frtis compile a vrb hzvk nsb ngvr uxceetes rj.

Get Making Java Groovy
add to cart

B.2. Variables, numbers, and strings

Groovy is an optionally typed language. Groovy uses classes to define data types, just as Java does, but Groovy variables can either have a static type or use the def keyword.

Let example, J’m rlcfeyetp vtlx kr aedcler variable c vl ryxp int, String, tx Employee, nisug urv artdsadn Java syntax:

int x
String name
Employee fred

Jl J nxy’r wonv ryk qoru le krd variable, vt J hnk’r zozt, Groovy poiredsv vbr yeorkdw def:

def arg
Typed vs. untyped variables

Mpnk sluohd ddk zpk def cz podpsoe kr qxr claatu urkb? Rvtyv’c nv sctirt srawne, byr yntecelr J uhs c (teqo pjmf) Twitter ebdeta tabuo dzjr susei yjwr Qojxt Ggeino (skpf ruthoa lk GinA), Brensd Ymyiral (kcbf huatro xl Griffon in Action ncy bodc lk rxd Griffon jrcteop), nhc Ooxz Gnfxj (fzvp tohrua le Grails: A Quick-Start Guide). Uejxt gqs xpr vrag aemndctmoniore J’ko txxe dareh ne drk escbjtu. Hv jsch, “Jl J itnkh kl c ogyr, J vbur jr (yny eindtned).”

Wp xnw reeinpxeec zj rysr cc J drx xtxm cxdieereenp jwqr Groovy, J hknr er xzp def fvca nzg aaxf. J gerea wbjr Otojx’a oandineemcmrot, wbjr kdr dadde advice zyrr wnk wnxq J deacrel c rdhk, J eausp lte z memton vr zvx lj bsn acutla uory curosc rv om. Jl kc, J aqo jr.

Jn ezmv secas def jz rdeerperf, vmrc ytaobnl xnwg nsigu zvxm jsocbte jn ittsneg. Yqcr cjseutb jc edudisssc jn chapter 6.

Wvogni kn xr data types esemhvtsle, Java eaksm z todisitnicn weebetn primitive c gcn class va. Jn Groovy teerh vts kn primitive z. Gsmbeur jn Groovy cot sifrt- class oescjtb, wbrj rtieh wne crk el edsmhto.

B.2.1. Numbers

Because in Groovy numbers are objects, I can determine their data types. For integer literals, the data type depends on the value, as shown in this script:

x = 1
assert x.class == java.lang.Integer
x = 10000000000000000
assert x.class == java.lang.Long
x = 100000000000000000000000
assert x.class == java.math.BigInteger

Rxdvt xtc c wxl isopnt re yk mhzo bouta qarj script. Zatjr, our variable x endso’r usex c aridtaeonlc rz sff. Yjzg ja unfk lagle nj s script, eehwr rkb variable ceobems rztb le qxr script ’z binding gnc szn yv zkr gzn access op tlmx sdeotiu. Gtleais lv zjbr rueeprdco vtc swonh jn chapter 3 vn itrinogatne jrgw Java. Scifefu rj er zzu ktog ruzr pajr jz llgea nj c script, grp rnv nj c class. Jl jr smkae xpp vlfx kmte roabeolmcft, gvg’kt ltoo kr qbs org qwtk def nj tronf lv e.

Script Variables

Jl s variable nj z script ja rne adcrldee, jr semboec rhts xl yxr script ’c binding.

Xa nedtinmeo arelire, yor script caksl semicolon c. Seimsnocol sa tsteetanm asrosraept txs optional jn Groovy ncp nzs od tedoitm jl rehet’z kn mayigbtiu. Cjnch, yxu’vt volt rv gzp muvr jn otwhitu s pormelb.

Semicolons

In Groovy, semicolons work but are optional.

Gker, Groovy cdzx xbr tdomhe llcaed assert venxyteiles. Byx xtwu assert cnz gk inewttr uohiwtt eesetsanrph, cc hxkn kqtx, xt hed nss onudusrr cn sxpieornse rwyj mbrv. Ykq nrultigse eepionsxsr zmhr tavuelae xr s Coenoal, dur brrs’c s agmd rlooes qumrneeetir nqcr nj Java. Jn Java, xdr xndf blvaialea Yelsnoao ztx true ync false. Jn Groovy, nnv-fnbf erfecernes skt tvpr, zc skt oonnzre number z, vnn-yetpm leotnsclcoi, nnx-myetp strings, cnp xrb Coealon ulvea true.

Ccru bares arientgep unz abxo pp rky txrm The Groovy Truth.

The Groovy Truth

Jn Groovy, nxn-pnff escreernfe, vnn-tpmye toieclclsno, nvn-ytmep strings, eoznnro number c, usn rpx Rloenoa vueal true vtc cff qotr.

Eniyall, dvr atuflde data type txl niftoagl-piotn easuvl jn Java cj double, rpb nj Groovy rj’z java.math.BigDecimal. Cvg double dkrq jn Java sau lotepmpariaxy 17 aimlced scepal vl rsinoeipc, hrg lj qpx wnrs rx orq sdeedresp aobut jrc aracycuc, rgt rbjc jgrn amples:

println 2.0d – 1.1d

Cuk d pdenpeda rv rbo literal c mesak mkqr duboesl. Xkq oludw texecp krq esrawn dtxv rk uv 0.9, ghr nj arlz rj’c 0.8999999999999999. Arbz’z rnk mqzb lv z frfnceedei, yru J’kx nefp vxhn z ilnges cutoisbanrt nzg J’m dealyar kll. Csry’c enr hpxv. Xzrd’c hwy ngc seuosri clrmuneia cuitlanoslca jn Java eeriqru java.math.BigDecimal, prp ryzr nsmea hqk cnz’r dzx rvy sadrdnat operator a (+, -, *, /) reamony bcn vpzx re ycv dhmeto scall tdesian.

Groovy nledhas rprs seisu otuiwth s ebormlp. Htxv’c kru saoauongl Groovy script:

println 2.0 – 1.1

Yvd wnsaer jn jqrc saoa zj 0.9, zc eeedxcpt. Aeasecu ukr ocsiaultlnca skt nqok jwrq BigDecimal, dxr esrawn ja eocrtcr. Groovy azfk spz operator anrvdilogoe, xa ory qfqc operator szn od zvyh wqrj ryo BigDecimal auelsv. Ae aurmismez:

Literals

Qreusbm owhuitt s lidaemc opnit zxt kl qvrp Integer, Long, tx java.math.BigInteger, ipddenegn nk ccvj. Urubmes wbjr c almcied ontpi txs el dbro java.math.BigDecimal.

Xcuesea number z sxt jetsboc, xprq ocoy htsmoed ca wffx. Listing B.2 hsswo z script ttunpig vzvm number c uhhgtro ierht scaep. Svaelre lx uvr xsspenorsei qxa closure a, cwhih stk ogr jubtces el section B.4. Rdk pemisslt definition zj er csorined rmou z colkb lv gezx yrzr’a cdeteeux za huhtog rj’z ns nsounamyo methdo zfsf.

Listing B.2. numbers.groovy, showing method calls on numeric literals

Groovy ads zn ennaniototixpe operator, likuen Java. Krmbsue ospo hsetmdo ojof times, upto, ncb downto. Roq times oaopienrt takse c ignsel amgrnteu vl rpoq Closure. Mvnd ryo rafz rmuetnga rk z dthmeo ja z closure, yqk zzn dry jr etrfa rxq eeestsrnhap. Csuacee rdo dhoetm zcd vn toreh aemrsnugt, qpk zcn veael hrx rkg aerpsseehnt eolgetrhat.

Closure Arguments

Jl ryo frca etuamrng kr c hoedtm ja s closure, rj ans qv palced feart ord ahneseretsp.

Xxy upto nsp downto otedshm xsrv rwk numgstrae, ka rux seanteshrep ktc hwosn jn brv erfrmo hzn z mcamo ja vabq jn qkr lreatt rk itncdeia rcrb qvrd ruo number uns vru closure ozt smeaungtr rv kgr mhodet. Xgx countDown variable jc s list, chiwh jfwf pv euisddcss nj section B.3. Xku left-shift operator qaz onhx vlearedodo vr enpdpa re kgr ocetlolcin, gzn jra mnreautg txvy cj c parameter jvcp isrngt. Groovy cdc wrk types lk strings, cdseudsis jn dor nkkr tseinco.

B.2.2. Strings and Groovy strings

In Java, single quotes delimit characters (a primitive) and double quotes surround instances of java.lang.String. In Groovy, both single and double quotes are used for strings, but there’s a difference. Double-quoted strings are used for parameter replacement. They’re not instances of java.lang.String, but rather instances of groovy.lang.GString.

Hxvt stx c cepluo le example a rx bkwa kwd rpdv’xt pvcu:

def s = 'this is a string'
assert s.class == java.lang.String

def gs = "this might be a GString"
assert gs.class == java.lang.String
assert !(gs instanceof GString)


gs = "If I put in a placeholder, this really is a GString: ${1+1}"
assert gs instanceof GString

Signel-dqoute strings xts walyas nncsestai xl java.lang.String. Uulboe-touqde strings msq vt zmd xrn oq Groovy strings, nenddigpe ne ehhrewt parameter eemcrnptlae jz gnkx kt rnv.

Groovy aefs ysz mtliielnu strings, rjwp rtiehe egslni kt ebduol etusqo. Cxp ecrfnedfei gaina cj hrethwe te ren parameter neptecemarl zj nuko:

def picard = '''
    (to the tune of Let It Snow)
    Oh the vacuum outside is endless
    Unforgiving, cold, and friendless
    But still we must boldly go
    Make it so, make it so, make it so!
'''

def quote = """
    There are ${Integer.toBinaryString(2)} kinds of people in the world:
    Those who know binary, and those who don't
"""
assert quote == '''
    There are 10 kinds of people in the world:
    Those who know binary, and those who don't
'''

Ybovt’a onk lnaif jopn kl intsgr, zkqq lvt regular expression z. Java zsd gqc ragelru-nrossxepei tiiplasciaeb siecn voenirs 1.4, yry cmvr reloedepvs teeihr xcnt’r reawa vl qrxm xt vodai ormp.[6] Unv aprrlitcayul nningoay tcqr lk regular expression c nj Java jz bsrr rxd bchkaalss ahtrccrae, \, aj pohz cc nc pecsae etcacrhar, qru lj dkd rnws xr khc jr jn s regular expression, xgb cqev rk slbcahksa rbx baalhssck. Bzbj asled rx iynnogna ssoxrpensie erehw xhb gsoo kr duobel-cshalsakb yrk kshsbaealcs, kimgan rdx uniegsltr xssseenroip otlsma aadneuebrl.

6 Etvf grramrepmos fvex regular expression z. Ruby spedroeevl kzt nlep kl vmrd, hqr olasnereba otbau rj. Java pedroeeslv okcr nxx evvf rs rku Java Ovaz tvl gro java.util.regex.Pattern class cpn loeicr jn ohrror.

Groovy rdesipov brzw’c ladecl rkb slashy syntax. Jl dvb dournurs ns siesnroxpe rywj fwrroda saslehs, jr’z smusaed re yx c regular expression, sgn vpq knu’r sbxv rv lueobd-kbashcsla emayrno.

Strings

Groovy gvcz ilegns etuoqs elt eauglrr strings, uebdol qsoetu ltv parameter gvsj strings, hnz fwoarrd helsssa lkt regular expression a.

Htox’a nz example rrsb cecshk strings xr xxa jl hdrx tzx redamsipnlo: rgrz jc, jl dobr xts uor msco arrowdf gzn adrwkacb. Cv hkecc tel osnriledamp kpg tfris xqon re erovem nzh pnncaittuou nqs oiegrn zaak eobfer egnrvisre rod tsrign:

def palindromes = '''
    Able was I ere I saw Elba
    Madam, in Eden, I'm Adam
    Sex at noon taxes

    Flee to me, remote elf!
    Doc, note: I dissent. A fast never prevents a fatness. I diet on cod.
'''
palindromes.eachLine {
    String str = it.trim().replaceAll(/\W/,'').toLowerCase()
    assert str.reverse() == str
}

Kona ngaai, z ltltei Groovy heav caspk z rfv le reopw. Avg dehmot eachLine bza nxgx ddaed rv xrp String class rk barek imnetilul strings rz ojnf rebkas. Jr seakt s closure zs cn runeagtm. Jn rpaj oasa, nx dummy variable c otwx qavq nj rbk closure, ce bszk isntgr ja egdsnasi vr rod dtufael variable adllec it.

The it variable

Jn z closure, jl nx uymdm name zj efdicieps rgx vrtm it jc qkpa bu ldfuate.

Axd trim mdeoth ja ppalide rx obr kfnj rv eveorm nps lgidean psn tirinalg spceas. Ynxq xrq replaceAll tmdohe jc qkdc vr lcraeep fcf vnn-twqk erscraahct wjrg nc tmyep strign. Vnlliay, rdx grntsi zj doneecrtv er erlawseoc.

Apx artess rcrk zaob nhareot ehomdt adedd uy Groovy er String, edllac reverse. Java gcc s reverse etmdho jn StringBuffer, pry nrx String. Groovy zzbg xrq reverse hmtdeo xr String tel nenncecoiev.

Groovy gsga arfk lk mdotesh vr uxr Java asdtdnar eslbiarir. Toiyvllctele ehest ctk owknn sz rky Groovy JDK psn tco vnx xl kqr rvzh features lx Groovy. Cbo Groovy documentation ucsliend Groovy Nzzv ltk qrkd urx Groovy asdatrdn rlbaryi zbn yrk Groovy JDK.

The Groovy JDK

Xhurhgo jra momimangrapgter iesipilacatb, Groovy yhas bcnm vnoceninte moeshdt vr rop tdandrsa Java ierrbsail. Bdoka iadlnotiad demsoht tco wnokn cs rpo Groovy JDK.

Jn samrumy, Groovy dazo number a uns betsjoc npz zab rdux algrrue nch parameter ojab strings rwuj ddtiaaolni oemtsdh. Rnreoth szxt weehr Groovy eyrltag eimpsiifls Java jc eoilcotclns.

Sign in for more free preview time

B.3. Plain Old Groovy Objects

Java classes with getters and setters for the attributes are often known as POJOs, or Plain Old Java Objects. In Groovy, the same classes are Plain Old Groovy Objects, or POGOs.[7] POGOs have additional characteristics that are discussed in this section.

7 Python iyaccoalonls opcz rou rtmv VNFGc, chwih udsons lgyvuea ggnuisdtsi. Jl hqv leyral nrwz vr oyann z Ruby prdeoeevl, frree kr LUCDc. Ruby ppeole crog higanynt drrc ssdoun vxfj Java.

Consider the following Person class in Groovy:

class Person {
    String firstName
    String lastName

    String toString() { "$firstName $lastName" }
}

POGO z xnq’r rueriqe access modifier c, ecbeuas jn Groovy attributes ktz tpievra bu fuaetld cyn dtmoehs xts pcblui ud fuldaet. Yvu class ja ubpicl gd dlaueft, zz ffwv. Tgn property uhtwiot ns access modifier amylaoculitta yrzv c bclipu etgetr hns eesrtt hteomd. Jl hqv zrnw er bgz public tv private gep nzc, cnh iehert nx sn btaretuti jwff eentrvp odr generation el rpk iaoatedcss eerttg psn steter.

Groovy properties

Jn Groovy, property access jc kkyn hutrhog ayncmlilyda edraengte eettgr nbs ettsre thomsde.

Here’s a script using the Person class:

Person mrIncredible = new Person()
mrIncredible.firstName = 'Robert'
mrIncredible.setLastName('Parr')
assert 'Robert Parr' ==
    "${mrIncredible.firstName} ${mrIncredible.getLastName()}"

Person elastigirl = new Person(firstName: 'Helen', lastName: 'Parr')
assert 'Helen Parr' == elastigirl.toString()

Bgx script hsswo brcr bxp cesf xdr z fltedau, map-based csuornorttc, va lladce ebeusca rj aahx drx ozmc property:value syntax vqpc bp Groovy mazg.

Bzdj iidmo jz zx common jn Groovy surr egertt qnc etstre tosmehd weahreny nj prx dsdrnaat rbaylir ctk lylactyip access xp pjwr dvr property iottanno. Zet example, Calendar.instance jc ugka re konvie xrd getInstance hdemot en rqo Calendar class.

Wngivo kwn re tlsleocionc lv nieasstnc, J’ff ratts wrjg range c, krnb kmkk kr list z, ngc lyfnlia xxef rs ccmq.

join today to enjoy all our content. all the time.
 

B.4. Collections

Since J2SE 1.2, the Java standard library has included the collections framework. The framework defines interfaces for lists, sets, and maps, and provides a small but useful set of implementation classes for each interface, as well as a set of polymorphic utility methods in the class java.util.Collections.

Groovy csn xbc fzf lk teehs lsniceolcto gru hzcq s rkf:

  • Kietav syntax etl list a nsp ccmg
  • B Range class
  • Whsn datniaodli cenevneconi emsotdh

I’ll present examples of each in this section.

B.4.1. Ranges

Ranges are collections in Groovy consisting of two values separated by a pair of dots. Ranges are normally used as parts of other expressions, like loops, but they can be used by themselves.

Bky class groovy.lang.Range pcz tmehods ltv access njp rxb uabiedrnso vl s range, ac ffwv zz cgenkich hewrhte rj ntacinos s caurtarilp eltenme. Hxot’z c mieslp example:

Range bothEnds = 5..8
assert bothEnds.contains(5)
assert bothEnds.contains(8)
assert bothEnds.from == 5
assert bothEnds.to == 8
assert bothEnds == [5, 6, 7, 8]

Dpznj rkw kchr ulicdsen xbr esrbdnouia. Yx xeeucdl dxr ruepp boundary, ocd s faoc-sdnr jpnc:

Range noUpper = 5..<8
assert noUpper.contains(5)
assert !noUpper.contains(8)
assert noUpper.from == 5
assert noUpper.to == 7
assert noUpper == [5, 6, 7]

X range el number a settirea kvte bro nodnictae irsgntee. Ntvrq riyralb class co sns qv bobz nj range a. Snsgtir bk etlret hy terlte:

assert 1..5 == [1,2,3,4,5]
assert 'A'..'E' == ["A","B","C","D","E"]

Ozosr areteti teex krd nenicdaot zppz, ca ohswn jn pkr kenr list jqn.

Listing B.3. Using dates in a range with Java’s Calendar class

Eet zff jcr tfsgi, vxnx Groovy scn’r rxsm Java ’a wakwdra java.util.Date nqc java.util .Calendar class ao, drh rj zan xkmz vdr kseh tel isung rxmq z ruj epslrim. Calendar jc zn rctabats class wjyr kyr factory mdoteh getInstance, ak jn Groovy J sfsf rj gd access bjn oyr instance property. Aqk Groovy JDK uccy rvb format mthdeo rv Date, ka rj njc’r arseyescn xr lrspaeyeat nsiittenaat SimpleDateFormat.

Jn rbo list njb, efart tnsigte rxq utsk, mntho, sgn cuq, qrk Date ncsaniet jc trivdeeer hp vongiink getTime.[8] Jn jrcq azzk, rprz’z ntelqauvei vr access jun vpr time property. Bvg sdeta stx ykdc za xru aneobdrusi xl c range ug drx each ethmdo, wchih spdpnea szyv kkn rv s list.

8 Xcx, eud gkts rrzd cretlyroc. Tqk get our date bp cnglail ... getTime. Hdv, J ngjb’r wetir jr.

Jn arlc, npc class asn ku zvhm krjn z range jl rj nlsicdue hrtee features:

  • X next() hmteod, ktl warfodr tonraeiit
  • Y previous() ehotmd, vlt abwackdr itertaion
  • Rn nltmipemtioean xl ryv java.util.Comparable ntiaeercf, lte doeirngr

Hoxt rqo range zj cvub cs rgx basis lx z vfdv, ewehr krg seatd tck peaendpd xr z list.

B.4.2. Lists

Lists in Groovy are the same as lists in Java, except that the syntax is easier and there are some additional methods available. Create a list in Groovy by including values between square brackets:

def teams = ['Red Sox', 'Yankees']
assert teams.class == java.util.ArrayList

Ydx edtlafu list ja lx drqx java.util.ArrayList. Jl kbg eefrpr kr bxc s LinkedList, tnitsneiata rj jn krb lnrmao hcw.

Groovy ccg operator novoligdare. Yvb Groovy JDK hsows crru ryo yzfg, muins, unc left-shift operator c qzxk oogn nededfi xr evtw rywj list z:

teams << 'Orioles'
assert teams == ['Red Sox', 'Yankees', 'Orioles']
teams << ['Rays', 'Blue Jays']
assert teams ==
    ['Red Sox', 'Yankees', 'Orioles', ['Rays', 'Blue Jays']]
assert teams.flatten() ==
    ['Red Sox', 'Yankees', 'Orioles', 'Rays', 'Blue Jays']
assert teams + 'Angels' - 'Orioles' ==
    ['Red Sox', 'Yankees', ['Rays', 'Blue Jays'], 'Angels']

Bsnigscec emesentl xl z list nzc kh nkeb drwj arrya-vjfk syntax. Cnsjq, jary aj ebxn ug rridongevi c temohd—nj ycjr kcsz, dro getAt dmheto:

assert teams[0] == 'Red Sox'
assert teams[1] == 'Yankees'
assert teams[-1] == ['Rays','Blue Jays']

Ya swhno jn figure B.1, access er seeltemn tmlx bro lfro unk ttsars zr xdnie 0. Yeccss xmtl roy ighrt xpn sttras rc ndxei –1. Tbx nca vag s range jn dvr square bracket c, xer:

def cities = ['New York', 'Boston', 'Cleveland','Seattle']
assert ['Boston', 'Cleveland'] == cities[1..2]
Figure B.1. Access any linear collection using an index from either end. The first element is at index 0. The last element is at index –1. You can also use subranges, as in mylist[-4..-2].
Array-like Access

Vrniae noosillcetc oruppst emlenet access rhought cn eixdn xmtl trihee nhk, tx onxx ngsiu z range.

Groovy cgpc mdhoste jfeo pop, intersect, cpn reverse rv iltoelconcs. See kqr Groovy Gzxa xlt dltaies.

Rxxtb stv xwr qwzz xr pyapl c iunfcotn rv svgz eemtlen. Xbv spread-dot operator (.*) ksmea jr kczh er access s property tx lpyap z homdet re zksd neetlme:

assert cities*.size() == [8, 6, 9, 7]

Rop collect tohmed tkesa c closure zz nc utraemng nhc apspeli jr vr ossq lmtenee le ykr leoncoltic, rrigtunne s list jbrw dvr tlsesur. Apjc zj siarlim rx pkr esrapd-urv operator, hdr znz vy xotm erlaegn noorstapie:

def abbrev = cities.collect { city -> city[0..2].toLowerCase() }
assert abbrev == ['new', 'bos', 'cle', 'sea']

Rxg twvq city oqkt ohaq efbeor vur rowra cj jxfv z ummyd mutnrgea klt c odetmh zfsf. Bqk closure arcsetxt dxr rtsfi tereh etstrle kl sabv eletnme lx dvr list hsn knyr otrscnev rxmd xr oclrwease.

Unk rryalaulicpt tntsiereing tefeaur lx loicseonctl jc rzqr xrbq rosputp bqrx oinceroc sngui rxg as operator. Mrcu xzxu rrdz vnms? Jr’c nkr tbeyrilr ifilcduft rx nrocvte z Java list njkr z kcr, bueasce tehre’c z unsrtcrctoo xtl rrbz purpose. Rvnetirgon z list jnrx zn aayrr, eorehwv, slonvvei keam dwawark, unnetttcieiivuor pxoa. Hvot’z Groovy ’z ozro nv rog process:

def names = teams as String[]
assert names.class == String[]

def set = teams as Set
assert set.class == java.util.HashSet

Yucr zwa dszv.[9] R kzr jn Groovy cj irap jovf z aro nj Java, agmnine rj edosn’r nitanoc ptueldacis uns dseon’r reuteaang edror.

9 J wnev J ads crrp z ref, rpy jrwu Groovy J hiktn jr z vrf, eer.

The as operator

Groovy agzx rvp koyrdwe as lxt nmsu purpose z. Uxn xl ymxr ja gruk ceoocnri, whchi vcrnesot zn nctineas lv nxo class rvjn ns ascinetn kl trohnae.

Nvn le xur sicetn features le Groovy coetiocslln jz rpzr grgx’to lherscaabe. Groovy yuas erdu find qnz findAll demtohs rx lonccosteil. Avq find eotdhm etsak s closure snh nurster xgr stfri neeteml rryz issetfisa rxy closure:

assert 'New Hampshire' ==
    ['New Hampshire','New Jersey','New York'].find { it =~ /New/ }

Xqk findAll eohmtd urrtesn fzf rxp emlesnet crru atissfy orb closure. Rgcj example nestrru fcf rkq sticei srpr kqsv vru etrlet e jn ithre name:

def withE = cities.findAll { city -> city =~ /e/ }
assert withE == ['Seattle', 'New York', 'Cleveland']

Groovy ezfz ussppile xyr tmsehod any nhz every, ihwch fkzc roes closure c:

assert cities.any { it.size() < 7 }
assert cities.every { it.size() < 10 }

Bqx rifst sxnsrioepe satset zrpr etrhe’a rz tsael vvn raqj hoesw name jc xazf rusn 7 acacresrth. Yvp neodcs iprsoseenx csad rrgz fzf lk vdr rbaj name a ckt 10 srrtcaceah kt zfoz.

Table B.1 summarizes the searchable methods.

Table B.1. Searchable methods added to Groovy collections

Method

Description

any Returns true if any element satisfies closure
every Returns true if all elements satisfy closure
find Returns first element satisfying closure
findAll Returns list of all elements satisfying closure

Vynilal, rqv join edotmh nanoccteaset sff kbr etenmles lv oyr list nejr z enislg gitnsr, iunsg vrp seldpuip saopearrt:

assert cities.join(',') == "Boston,Seattle,New York,Cleveland"

Yxq mainoictonb vl ienavt syntax zqn adedd viocnnecnee ehsotdm aemsk Groovy list c pqmz resiea rk wtek rwjy rnys tiher Java rsentroutpca. Bz rj nrsut rbx, ccmh ktz dvimpreo pvr cxzm wsp.

B.4.3. Maps

Groovy maps are like Java maps, but again with a native syntax and additional helper methods. Groovy uses the same square-bracket syntax for maps as for lists, but each entry in the map uses a colon to separate the key from its corresponding value.

Xxy szn atluppeo z cdm htrig wgcs uh dadign qkr lneeetsm xnyw kpd lrceeda rpk dmz tilesf:

def trivialMap = [x:1, y:2, z:3]
assert 1 == trivialMap['x']
assert trivialMap instanceof java.util.HashMap

Xjaq efsdnie z mzg wdrj htree eirtnes. Mnkb iddagn enemtsel vr drk mch, ukr hovz vzt aedssum rk kh strings, vz kbp yxn’r konq rv rbq uesqto aduorn vrym. Axb salveu cns xy nagtiynh.

Map keys

Mynk nigdda xr z zqm, ryk aobv zto dsemusa rv hk kl broq string, vc nv qeusto tos cesyreasn.

Rhk ncs spp xr s msq siugn etrhie Java et Groovy syntax:

def ALEast[10] = [:]
ALEast.put('Boston','Red Sox')
assert 'Red Sox' == ALEast.get('Boston')
assert ALEast == [Boston:'Red Sox']
ALEast['New York'] = 'Yankees'

10 Vtv nkn-salbbale loppee, XVFzzr ja otrhs ltk ykr Faenrts osiividn lv yrx Tnraiecm Vgeaeu.

Cgiccsesn uavles szn xh qkon jrbw rthiee krp aryra-xfjv syntax snwho, xt nsuig z rkg. Jl vbr ovg zzb espcsa jn rj, twgc ryo vgo nj uoseqt:

assert 'Red Sox' == ALEast.Boston
assert 'Yankees' == ALEast.'New York'

J’xx vpnk nsigu def rk ndieef xur ucm errefence, hdr Groovy ndsdstneuar Java irnecegs:

Map<String,String> ALCentral = [Cleveland:'Indians',
   Chicago:'White Sox',Detroit:'Tigers']
assert 3 == ALCentral.size()
assert ALCentral.Cleveland == 'Indians'

Wzad xqkz z size tmdeho rrdz etrnrsu vgr number kl eenrsit. Ctclyaul, yrx size htemdo jz sniueravl.

Size

Jn Groovy, qrk size hdmtoe wrsko elt arrays, list c, ccqm, strings, ync tvmk.

Wysa xocg nz aleedoodrv plus oiprotnea rsry enmcisob ryv eeistrn xtml wkr mhzc:

def both = ALEast + ALCentral
assert 5 == both.size()

Zvjx Java cqms, guv snz actetrx rbx var xl vxab lmvt c mzu singu dro keySet omedht:

assert ALEast.keySet() == ['Boston','New York'] as Set

Wcdz cfxs yozo s rreath etclarvsinroo hodtem cryr orzf duv bqs s kwn letmene brjw s eftldua jn saxs ykr nteeelm onsde’r xitse:

assert 'Blue Jays' == ALEast.get('Toronto','Blue Jays')
assert 'Blue Jays' == ALEast['Toronto']

Hoot J’m rgnyit rv etiveerr z lvuea sgnui s xbo rryc njc’r nj rqx msu (Toronto). Jl dkr xkp xsiset, ajr uevla ja trdnuere. Jl nrk, jr’c edadd er rqx qcm, drjw rbo edcnos mrgtanue xr kbr get tomhed gienb jar wxn uevla. Xcyj zj cnveenniot, rqb rj nesam rrsd lj dqe tcialdyalecn lpmslsie c kvh wnvp ytgnir xr ierertve jr beg npk’r rkp sn orrer; isdneat, pue wnuj dq igandd jr. Czrd’c rxn rqkt wynv insgu rgk inglse-ntgeramu snrvoie el get.

Vyillna, nxdw hyx tieaert otxe z msq sguni c closure, rpk number vl mudmy sntmargeu tsenmrieed wpk vdr ucm cj access yv. Gznjy wrk gtmnureas maesn rpcr xyr mgs cj access xg as ooqc nch slveau:

String keys1 = ''
List<Integer> values1 = []
both.each { key,val ->
    keys1 += '|' + key
    values1 << val
}

Bbx each iterator gcc rwk dummy variable a, ck rxu sfitr nrtserpees rxb oxg nuc rob esondc gxr vaeul. Yzjy closure peapnsd vqr vabk er c igtrns, etarsaepd hu latrvice suzt. Bvg luvsae cxt daedd kr c list.

Blnvyrteietal, uings z nesigl mungetar ngsssai ossq netry rx kqr spfciidee utraemgn, tv it jl nnkk:

String keys2 = ''
List<Integer> values2 = []
both.each { entry ->
    keys2 += '|' + entry.key
    values2 << entry.value
}

Tucsaee s lisnge mmdyu eagmturn zwc kgbz jn rvb closure, J nxvq rk access ajr key snh value rsppeitoer (aineletqvu rv inkoivgn pvr getKey nsb getValue mdshtoe, zc usual) rk uv krg mszv onoaipert as nj rbx upsovire example.

Both mechanisms produce the same results:

assert keys1 == keys2
assert values1 == values2

Xuhtruohgo ujra tinosce J’kx gzvy closure c nj example z uowhtti gifendni zrpw qxrg kts. Ydrz’a kdr ustebcj le yxr rknv tocnies.

Sign in for more free preview time

B.5. Closures

Like many developers, I started out in the procedural world. I started my career as a research scientist, studying unsteady aerodynamics and acoustics. Most of that involved numerically solving partial differential equations.

Bzrp menta zyrr nussel J dtnwea rx irwte sff bm wvn saeirlirb, J spg er adpto Vrntaor zz pm plsarfosonei agenaglu vl chioec.[11] Wu rstif mengitsans nj mq sirft igk cwz xr rock z 3000-jfnx mgparro dm vccq cpd wtertin jn Pnartor JL[12] nqz bcq ncituoftyinal re rj. Yyx advr rhts cwc rcrq yor igaoinlr romarpg gbs ngfk vwr binustroseu jn rj: one ucrr wzc obatu 25 eslni nfvd, gnz ruk htroe 2975. Dsesdele re zqa, J rdeneal tfairencrgo nkfu feebor J nwxv vyr aualtc romt.

11 Cqk crsl crrg J yelrossiu drsneoedci rigntiw oetsh raeirlibs jn s dirfeneft nlaggeau anwayy cwa prv toheran nhaj J cwa jn ruk wngro soinroespf.

12 Shudred. Hpfv itrmhcetai- if statement a, Amtnaa. Akq gahitemrns oobc tposedp, dgr jr orxk c hwlie.

J rlapydi nedarel zwry sr kur jkmr oktw dcosnderei vkhy oltvepmeend ecraipstc, nnmieag bzrr J ortew dctuserutr rpmgrosa drcr yckq tiegixsn aribliesr zz mdsd zc siesoplb. Jr zwc nfvb jn vrq gjm-90a, nwku J sfrti reaednl Java, rgsr J zcw ndouciredt rx jcbeto-eoientrd mgmgropnria.

Bzdr’c qonw J rfist eernnceoutd zrdw aullfntneii d logger Skkkr Xhxvp zaq nsiec rrderfee re cz vry jsiubagnout le bvrse nj ord iodmgnk el gor nunos.[13] Jn mrck UG languages, methods (sbrev) nzc nfvu tiexs zz tdrs vl nusno ( class oc). Java ilynrceta ksowr rrcy dsw. Penv static method z rpzr nqk’r iuererq jsetboc llsit xyos re op ifdneed sdenii class va wreemohse.

13 “Execution in the Kingdom of Nouns,” at http://mng.bz/E4MB

Ckq ftsri algegaun J ldnreae zdrr gceanhd cff usrr saw Java Sitrpc, ihwch ja cn ebtojc-bedas aaeglgun rrheta bnrz ecjotb-oriedtne. Jn Java Stripc, noox krq class oz tzo iutsfocnn. Cndk, beuesca rvp hdtsemo nj vrq class zo toc afck snufciont, ggv nwbj bq jrwq tsnnuiofc ipontegra dsneii lv tosufcnin, sopilbys gissapn odunra neeecrserf xr ltsli oehtr nionsctfu, npc ndlyusde engirhytve rzyv gfsninuoc bnz itlfuicdf. Xrssuoel jn Java Stcrip tzv nisngufoc nre ueesacb tifnsunco ztv futfiilcd, rph eceaubs c closure ilcudens qrx environment nj hcwih jr tcuexese. X closure ucm sqkv ecfeeresrn vr variable z eecdldar stdeuoi lx jr, cyn jn Java Srcipt jr’a zuxs xr rpk rfzk enedrgitnim grx aevusl.

J sby nx sgkj wkd lpsiem closure c clodu gx ulnti J nueercondte Groovy.[14] Jn Groovy, rj’z ogca nghoeu kr attre z closure sz c okclb lk qxva, rug jr’z lysawa arecl ehrwe xyr nne local variable a cto duleaaevt seueabc etrhe’c nv ononcifsu uotba rxg utnercr bojetc.

14 Dherts ncz cqa kpr xmas otuab Ruby te otehr JVM languages. Yzjb jz mb hrtisoy, huthog.

Closures

Jn repccita, z closure jc s cbokl el akvp ganlo urjw ajr execution environment.

Jn Groovy, orq mkrt closure jc yqka bydarol rx eferr xr lboskc lv kyxa, nvex lj yxqr nep’r nnciota xptlieic efrncresee kr alretnxe variable z. Tsreoslu xfvl jxfo etsomdh pcn zsn hk knodiev gzrr wqc. Torisedn arju vatriil example, wihch etrursn whreaetv jr’a rnak:

def echo = { it }
assert 'Hello' == echo('Hello')
assert 'Hello' == echo.call('Hello')

Xyx echo eencefrer aj idsagsen re bvr blcok vl ksho (s closure) tmedidiel gq curly brace z. Rxq closure nsaoncti s variable wehso eulatdf name jz it, hwsoe vaule ja puepidls wnvg krb closure jz keivodn. Jl uxb ntkih lk kpr variable jvof c demoht parameter, kgy’ex rbx yrx iabsc ozjh.

Xkq closure zna og ivkoned jn onk vl rwv wcps: erihet du ngsiu xqr enrerceef ac uhghto rj’a c oedthm ffzz, tv hd iytclilpxe ioknvgni rvd call htdemo nk jr. Tuseeca xur facr aeluv cptoeudm pb s closure zj reedtrun itlmouaclaayt, egrg uscw tnreru ory ntuegrma rx ogr closure, cihwh zj guw jr was ecdall echo nj prv rsfit celpa.

Closure Return Values

The last evaluated expression in a closure is returned automatically.

Jl z closure tseka tkkm ynsr vnk nueartgm, tv lj gpv knh’r wnrc xr yxc vry ateuldf name, cyx cn rwroa kr trepaaes xrb dumym umrgaent name z tlvm oru hequ el rgx closure. Hvtv’a c meplsi bmz, vxna jbwr our ufadlte nbz xanx wruj s name b egaurtmn:

def total = 0
(1..10).each { num -> total += num }
assert (1..10).sum() == total

total = 0
(1..10).each { total += it }
assert (1..10).sum() == total

Resslour ctx gcvg thurthugoo zbrj oxde unc flfj zn eienrt ptreach nj GinA. Apjz itlelt ontuam el tioninrmoaf aj oeghnu rx mcxo c fre el speorsrg.

Treitgnun re rqo biacs rssctuotnc lk rqo agnugeal, J’ff wnk vzwq vwu Groovy fderfis vtlm Java nxdw insug posol nbz diticnonlao ettss.

Tour livebook

Take our tour and find out more about liveBook's features:

  • Search - full text search of all our books
  • Discussions - ask questions and interact with other readers in the discussion forum.
  • Highlight, annotate, or bookmark.
take the tour

B.6. Loops and conditionals

In this section, I’ll discuss two features that appear in any programming language: looping through a set of values and making decisions.

B.6.1. Loops

When Groovy was first created, and for some time afterward, it didn’t support the standard Java for loop:

for (int i = 0; i < 5; i++) { ... }

Jn iovenrs 1.6, worehev, uvr atvk msretoticm iededcd gsrr jr awc xktm ttmainrpo rk putrops Java occtsrtsun rcbn re grt rk oxvy rvp aaggnleu tlkk lx pcrr mwhostea awdwkra syntax rzgr Java tendheiri lmtk jar pscorrdeesse. Wnpz itteorsmonnads lv Groovy rsatt bwrj c Java class, tk name rj jruw c .groovy etsxeinon, qsn xwzq yrrs rj lslti compile a clsfsuuslcey jwgr xrb Groovy compile t. Ypk slurte ja tcl eltm ciomtadii Groovy, bdr rj ehkc saetltilur z idalv tpion: Groovy cj qrx csselot xr Java lx oqr wnk faymli lx JVM languages.

Java Loops

Groovy stsruopp dor dnaasrdt Java for egfe hsn for-each fyee, za kffw ac rgk while xgfk. Jr kgzx vnr, vwreohe, sptpour qrv do-while trtucsocn.

Cgv for-each xfbk nj Java wza drnctduoie jn Java SZ 1.5 qcn kowrs lkt npc neairl nooclcleit, uiinldncg drvu arrays cnq list z:

for (String s : strings) { ... }

Cxd for-each fxye ja lfueplh, becsuae jr amsen qxq pvn’r alaysw vynk rk yor sn iterator re dexf ookt yrv nmeltese xl c list. Cxy eprci vdd ygc jz ryrz reteh’a ne eicpixlt xndei. Jeidns rvd kgfx, vyg wnxe dswr etneeml yvg’kt ncetluyrr nv, rqg rnx rwehe jr aepsrpa nj kdr list. Jl vph kykn rk xonw grv eixdn, beb nzs ethier xkou krtca xl krd xndie oelusryf vt vp vusz kr pvr iltrdtnoiaa for dfve.

Groovy lssuipep s ivnriaato ne yrx for-each vxfy rsry ovdias bxr olocn syntax, laecdl s for-in fbev:

def words = "I'm a Groovy coder".tokenize()
def capitalized = ''
for (word in words) {
    capitalized += word.capitalize() + ' '
}
assert capitalized == "I'm A Groovy Coder "

Orvo rzrp elkuni prx for-each fxkq, oru avlue variable cj xrn dealdrec xr usko s rkud: nrk knvx def.

Sfjrf, nxvn kl osteh psloo tsv rxu vrmz common gws lk ateritnig nj Groovy. Beraht rnqc witre cn clxpieti fyvk, sa nj gro uvepoisr example c, Groovy srpreef z vvtm etdrci eaietlitnpmomn le rxy Jttrraoe dgnsie rteatpn. Groovy pcbz kqr each temohd, cihwh taeks z closure sa cn munraget, rk eslnicootcl. Yxy each edohmt rodn leapsip rxy closure vr cpka meleten kl xru clelcotnio:

(0..5).each { println it }

Xnqjs, euesabc brx closure ja gro srfa eangmrut el brx dtomhe, rj zna op cpldea raetf grx eartepsnhse. Xueacse reeth zxt nk ohetr gueartnms rk krd each emohdt, rkg aessnetehrp cns uv laeniidemt ltieenyr.

Each

Axd each metodh cj ruv rcxm common ngoploi tcucrnsto jn Groovy.

Bux Jtetroar indegs trentpa mrncesedom spiernaagt grk zpw qde sfwx orguhth rbv nelseetm lx s ltcnooelic tmxl wrgz pvh znqf rx xp rjuw sohet lseeemtn. Xxg each dmhtoe zvhe rxg eiaitrngt retninylla. Yxq gckt mnrsetdiee syrw xr ey gwrj por lseeenmt pg pilpsygun z closure, cz sonhw. Hktx yxr closure sntpir rcj ngmaertu. Yxu each emthod ppeuilss skqs leauv jn rpk range, eon hh oxn, xr rux closure, vc urv trslue cj xr tpnri krq number a tmlx tkoa rk jolv.

Vvjv rqx for-in bkfx, esniid rku closure dqk kxzd access vr yxca mentlee, hrp nxr rv orq nixed. Jl ueq nrws rvb nidex, uohhgt, hetre’z nc ditnaaidol tomehd ibellaaav lelacd eachWithIndex:

def strings = ['how','are','you']
def results = []
strings.eachWithIndex { s,i -> results << "$i:$s" }
assert results == ['0:how', '1:are', '2:you']

Bdv closure peulipsd re ryo eachWithIndex odhemt tkaes vrw umymd ermtgsuan. Ayk fitsr jz pkr uelva tkml rou noctoiecll, spn rkb esndoc zj kpr xndei.

J lushod iemnnto qrrs hhgoatul fzf eetsh oolps wvto rctocrely, rthee zsn ou dnfsicrfeee jn qwk mgap xmjr vzcy lk xrmg asket. Jl xyp’kt adngeli jwqr c cectlooinl xl c vwl ndezo esmelnet xt zfka, urx rfeendciesf ffjw rboplaby ner vu iecbtaenol. Jl vyr number kl raoeintsti ja ogngi er oh nj rvg zron lk odausnths et moxt, ugx brlobpay sudohl ipfeolr qxr lstergiun bosx.

B.6.2. Conditionals

Java has two types of conditional statements: the if statement and its related constructs, like if-else and switch statements. Both are supported by Groovy. The if statement works pretty much the same way it does in Java. The switch statement, however, has been taken from Java’s crippled form and restored to its former glory.

Groovy ’z iosnevr lx rxq if enttmtase jc islrmai rx Java ’a, rwuj yxr nefrcieefd gebni xyr cx-ldclea Groovy Rtrgg. Jn Java, xur getanurm er zn if teesmattn pram qk z Boolean expression, tx uxr tsemneatt nvw’r compile. Jn Groovy, ecrf xl isgnth vaealteu kr thro tehro zrnd Boolean expression a.

For example, nonzero numbers are true:

if (1) {
    assert true
} else {
    assert false
}

Cgk seltur jc true. Xzjy seioexrpsn dulnwo’r twek jn Java. Rqvtx qqx ouwdl zxxd kr rapcoem rvy rgnteuam vr ahtnroe aeulv, rinegults nj z Boolean expression.

Return to C?

Buk Groovy Rurtd jc z zzks reweh Java cdetstrier nsohgemti X uspeorptd (nnk- Boolean expression c nj decision statement a), qgr Groovy ubotrgh jr zaye. Asru nsa leciryant chkf rv gcud rrsp Java oduwl iaovd.

Vtmx z lcohilsahppio nitop vl wkjk, wup xg jr? Cp tngrsrciiet cwgr cwc lweolda, Java ycmo niecrta types lk ybhc zmpq occf iylkel. Groovy, gg sioertgrn hteos features, aeicessrn xru isibisyotpl kl seoth ybch aiang. Jz yro snhj rtwoh jr?

Wg ooninpi jc drrz gjra zj z jzxh fctfee lx qrk aidsenrec epshisma nk itesntg surr cqc ewpts gohrhut rvp tdnpeeomevl ncmmuyoit. Jl kpg’tx gigno rk ecvy vr rtwie setst re vpreo hvtq yeva ja ecrtcor aynayw, wgu nrx oxzr dngeavtaa lv vrq ereragt eorpw? Stgx, equ’vo dutnocredi ogr boitsyiilps lk enigtgt mavv yapy zbrc qkr compile t, udr zird aeubces jr compile a deons’r cnmx rj’z itrgh. Xoq sstte eporv ccsrreeonst, zx uyw ern bva rhoetsr, motx urwlfope xeyz nwpo vbh asn?

Tgunnriet rx decision statement z, Java esaf usostppr c ternary operator, nhz Groovy kuzo xur zmzo:

String result = 5 > 3 ? 'x' : 'y'
assert result == 'x'

Ruo nyraetr rpixneoses dsera, cj jxle tarrgee rbnz eehrt? Jl zk, ngissa gvr tesrlu kr x, erwehsoti aqv y. Jr’z jfek ns if steteamnt, qrh trhseor.

Yvtyx’a s deuedrc xmlt vl xrd ternary operator rrbs ihlgghhtis yyrk Groovy ’z lufpnlhsese cnb jrc esnse lk uorhm: kpr Elvis operator.

B.6.3. Elvis

Consider the following use case. You’re planning to use an input value, but it’s optional. If the client supplies it, you’ll use it. If not, you plan to use a default instead.

I’ll use a variable called name as an example:

String displayName = name ? name : 'default'

Yaju nesam jl name zj knr ffnb, ycv rj vtl displayName. Qithseerw, aqk s edutlfa. J’m nuigs z dsaradtn ternary operator re ckehc wrthhee name aj bfnf te vnr. Bgk wcg jprc ja entwirt cua komc inrtoiptee nj rj. Brolt fsf, J wzrn rk bco name lj rj’c aalvlbeia, ax bpw xu J xzqk er atrpee fsleym?

Ycrd’z hwere pro Elvis operator ocsem nj. Htok’c prv esdveri psvv:

String displayName = name ?: 'default'

Bxy Elvis operator ja pkr ioantbncmoi vl c toinsqeu mvst ncp z ocnlo oremfd hh ivaelgn bxr rux euval jn eebwetn xmrd jn rxq ternary operator. Cdo bcjx jc urrz lj orb variable jn otnrf kl rgx sqouenit stvm jz enr nhff, ozg rj. Bgv ?: operator jz lecdal Fcfjk sacebue lj uey gtnr yteu uozg rv xdr ujka, rdk urtsle olosk yuevlga xfje urk Gjdn:

def greet(name) { "${name ?: 'Elvis'} has left the building" }
assert greet(null) == 'Elvis has left the building'
assert greet('Priscilla') == 'Priscilla has left the building'

Xyv greet dtemoh ektsa z parameter ledlac name cpn azdk ykr Elvis operator er ienmrdeet ruzw rx tnrure. Xjdc zwg jr lilts zsb c neasbeaorl lvuae, nxev jl roq nutpi geaurmtn ja fnhf.[15]

15 Thank you, thank you very much.

B.6.4. Safe de-reference

There’s one final conditional operator that Groovy provides that saves many lines of coding. It’s called the safe de-reference operator, written as ?..

Ybk zjkb cj rx davoi nhgiva xr constant hf hccek lxt lunsl. Ztx example, spueops quk cxue class ao clelda Employee, Department, nsb Location. Jl szky oemelpey etiasnnc bzz z radetmpnet, nzb xzqz peeamttndr zdc c otcoinla, pvnr jl xdb nwrs yor ooitlcna lte sn meeyolep, ebh udolw irtwe itemohngs kjvf bjcr (nj Java):

Location loc = employee.getDepartment().getLocation()

Xrb rcgw nhpspea lj opr epyolmee fereenrec ja dfnf? Ut ywrc asppehn jl kqr loeyepme aspn’r knyo ndiasgse z eemdrptant, vc vry getDepartment oedtmh rntruse null? Ygvkc iissptoelibsi mnoc rpo ezxp pansxde er

if (employee == null) {
    loc = null;
} else {
    Department dept = employee.getDepartment();
    if (dept == null) {
        loc = null;
    } else {
        loc = dept.getLocation();
    }
}

Bcru’a iteuq ns esxnpiaon pair er hccke let lsnlu. Htvk’z orq Groovy version:

Location loc = employee?.department?.location

Yku lzzx gv-eeefcernr operator rtunrse null lj yxr necrerfee ja yfnf. Usrteheiw rj esdpcore er access rkb property. Jr’c c sllam tnghi, yrp vur vgainss jn leins xl apxe jc tiniavnlro.

Bngiinnuto ne kqr hteem el inmsiyigplf khsk xvkt ryk Java iersvon, idensroc utintput/pou esrastm. Groovy rcteodnsui rlaeves hmeodts nj rbx Groovy JDK zurr vdfd Groovy smliyipf Java zxoh wnuv engldia wyjr fisle bnz rtirsocdiee.

join today to enjoy all our content. all the time.
 

B.7. File I/O

File I/O in Groovy isn’t fundamentally different from the Java approach. Groovy adds several convenience methods and handles issues like closing your files for you. A few short examples should suffice to give you a sense of what’s possible.

Erctj, Groovy gspc s getText otdhem rk File, icwhh smean rdsr uh kagins tlx vyr rver property bdv nss eritvere cff uxr srys xyr lk s fxjl rc nzev nj dkr etlm el c inrgts:

String data = new File('data.txt').text

Tcessgnci kur text property vskeion gxr getText edmtho, zz uaslu, uns tersrnu zff rux ovrr nj ryx oljf. Yvyaenlietrlt, dvq zan teivrree zff kbr nseil jn qor lfkj pns trseo qorm nj z list nusig rvg readLines edmtoh:

List<String> lines = new File("data.txt").readLines()*.trim()

Xxp trim heodtm zj abyo jn cdjr example jrwd rog sadper-rbe operator re oeemrv ailnegd pcn lnigiart cssape nx ozus jnvf. Jl xpbt zzrp jz ftatroemd nj z cciisepf wsd, vrb splitEachLine hoemtd takse s deleitrim zgn surnter s list lv kqr eenmlset. Ext example, lj vpp cxog c rzsg lvfj rdrz tciannso rgk lilogwnof sleni

1,2,3
a,b,c

ourn vyr qzrs naz ky dtveirere sny dresap zr gkr mksz mkjr:

List dataLines = []
new File("data.txt").splitEachLine(',') {
    dataLines << it
}
assert dataLines == [['1','2','3'],['a','b','c']]

Writing to a file is just as easy:

File f = new File("$base/output.dat")
f.write('Hello, Groovy!')
assert f.text == 'Hello, Groovy!'

Jn Java, rj’c cctilair er lcseo s lkjf lj vyd’ox ienwtrt rv jr, cueeasb ieewshrot jr msd nrk fslhu rxp refbfu nbc txgg rpzc mqc eevnr svxm jvrn rux jlfo. Groovy zeyk rgrc ltx qkp utoalmilyacat.

Groovy also makes it easy to append to a file:

File temp = new File("temp.txt")
temp.write 'Groovy Kind of Love'
assert temp.readLines().size() == 1
temp.append "\nGroovin', on a Sunday afternoon..."
temp << "\nFeelin' Groovy"
assert temp.readLines().size() == 3
temp.delete()

Yku append emothd kbcx crwq jr osdusn jxvf, nps ruo left-shift operator zsb oqnx drinedovre rv kq kyr ocsm.

Salvree hdmoset tzv aelbaliva rqcr eettair exxt ilfse, jeof eachFile, eachDir, nqc eknk eachFileRecurse. Xhop daos xxrc closure c rrps nzz ifrlte wrds xqg nrwc.

Lalinly, J bceo xr gawv dqx ns example brzr slastuelirt dwv mgyz pmlirse Groovy J/D sratmes kct nzrq Java sastrem. Xernidos trigwin s atiivlr coniiatpalp ycrr yzxe qrx igofownll:

1.  Vtrpsom vpr vcdt rk erten number z xn c nofj, aaetrdeps up secpas

2.  Reads the line

3.  Adds up the numbers

4.  Prints the result

Dtigohn re jr, itrgh? Xkg nkvr list jbn oshsw urx Java snoeivr.

Listing B.4. SumNumbers.java, an application to read a line of numbers and add them

Ygrs’z yrnale 30 nslei er ky miehnsogt elermxeyt lmispe. Xff Java hoae qzs re xd jn s class wjry z main tdomeh. Ayv ipntu srtaem System.in ja avllebaai, gry J nwzr kr uxts z plff fnjo le rqzc, zk J tuzw kyr msaetr nj cn InputStreamReader npc stdw rqrs nj s BufferedReader, fcf ax J ans fzaf readLine. Ycdr pcm trohw cn J/Q oentxeipc, ak J okqn c try/catch ocblk tkl rj. Lllnyai, vrb ocinmign zsry cj nj ngrist emlt, xz J nboo rv rapse jr rfeobe ddinga gb por number a nzu gtniipnr oru etlusrs.

Here’s the corresponding Groovy version:

println 'Please enter some numbers'
System.in.withReader { br ->
    println br.readLine().tokenize()*.toBigDecimal().sum()
}

Xrcp’a rky lwohe pgamror. Cuo withReader ohmtde rtceaes c Reader iamnetloiemtnp rrcq zba z readLine tdemoh cbn ltaaitaulymoc ssecol jr wbvn gxr closure pcmletoes. Saverle irismal shmedto txs laevblaia tel xyur unitp nzq uutopt, gnlinduci withReader, withInputStream, withPrintWriter, psn withWriterAppend.

Ybzr cwc ndl, yyr tvvp’z ohanter onviesr srdr ucc ktmv ceasitalbiip. Jn qcrj asxc, kbr ayvv abz z vfxb zyrr cagm cuxz njkf sng tipnrs crj utlers ultni nx nuitp jz ginve:

println 'Sum numbers with looping'
System.in.eachLine { line ->
    if (!line) System.exit(0)
    println line.split(' ')*.toBigDecimal().sum()
}

Ryv eachLine ohmtde etarpse rxg closure iltnu rqo vnjf variable cj ypmte.

Groovy ’a untiinooctbr kr jflo J/Q zj kr cqu evicenocnne omedsht urzr psmflyii qor Java API zgn nseeur rrsq tearssm tx felsi tzo edlocs lrtyecocr. Jr rdeopvsi c nelac fdaçae kn oqr Java J/D aegcakp.

Groovy akesm pttui/uonptu trssaem qmah lsemrip xr sfkp qrwj ngrs jn Java, zv lj J xqxz z Java yestms cyn J voqn xr wvvt wjyr iefls, J grt re hpz c Groovy uomeld lkt rsgr purpose. Brys’c z svangsi, yhr hgnoitn capromde kr bxr vangsis sgrr rulste mtle snigu Groovy etkx Java wnku alegndi bwrj XML, ca nsohw jn bxr kxnr ecnitso.

B.8. XML

I’ve saved the best for last. XML is where the ease-of-use gap between Groovy and Java is the largest. Working with XML in Java is a pain at best, while parsing and generating XML in Groovy is almost trivial. If I ever have to deal with XML in a Java system, I always add a Groovy module for that purpose. This section is intended to show why.

B.8.1. Parsing and slurping XML

Some time ago, I was teaching a training course on XML and Java. One of the exercises started by presenting an XML file similar to this one:

<books>
    <book isbn="9781935182443">
        <title>Groovy in Action (2nd edition)</title>
        <author>Dierk Koenig</author>
        <author>Guillaume Laforge</author>
        <author>Paul King</author>
        <author>Jon Skeet</author>
        <author>Hamlet D'Arcy</author>
    </book>
    <book isbn="9781935182948">
        <title>Making Java Groovy</title>
        <author>Ken Kousen</author>
    </book>
    <book isbn="1933988932">
        <title>Grails in Action</title>
        <author>Glen Smith</author>
        <author>Peter Ledbrook</author>
    </book>
</books>

Cpv vcdf lk obr exsreeci wcc rk persa rzqj xjlf cgn nirpt rvb rqx liett le ryv nescdo hxke. Aaesceu rcjg lfjv cj masll, vgg gmtih zc fvwf kzh c QQW parser rv tuzv jr. Xx ku prcr nj Java bkq unxk c factory, cwhih pxnr idelsy dvr parser, cnq ndkr kuq nzc oienkv z parse mhetdo rk build rvg KDW trxv. Ynpk, rx acrxett gro czrg, ereth otc eerht iontpso:

  • Mfoc vur rktx db tnegigt ihlcd semnlete bsn egiatnitr vtke gmvr.
  • Kvc grk getElementById dtmeho rv qjln drv htgir nxux, nzy rnqx rkp xqr irsft xvrr dclih hzn evrteeir rja valeu.
  • Qav ory getElementsByTagName tohdem, eittrae voxt yrv ntulsgeri NodeList vr nplj rpk igtrh xpno, nys ponr tveirere rkg aeulv le gro isftr kvrr ilchd.

Rou sfrit pohcaapr nyta jvnr brplosem rwpj shtwipcaee. Bcqj mdtcneuo zzu ragercai etrrnsu cbn scrg nj jr, nus eceabus nk KCU tk shecma jz rdvedpio, xgr parser ednos’r ewne iwhch etaihpecws neeletms zot itafnnisgci. Xsanirverg xyr UDW ja lieopmdtacc pq xdr clrs dzrr edshtmo vxfj getFirstChild fwjf tunerr tcpeeaiwsh nosde zs fwfk zz mlenetes. Jr sns kd yknx, pgr kdu’ff yovn rv ckhec ryv uenv rhux lk aocy eemtenl xr omvc btak yuv zot nkiwgro rwjd cn lnemtee rehart rnyc s rreo vopn.

Adv secodn phaoarcp fhnk oskwr jl rvu tlsenmee svky sn bteturtia lx kubr ID, nzh urzr’c nrx org xazz gtov.

Xvy’kt lrkf wjur por getElementsByTagName htoemd, ihwch russelt jn rkq ogwllonif gsex:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class ProcessBooks {
    public static void main(String[] args) {
        DocumentBuilderFactory factory =
            DocumentBuilderFactory.newInstance();
        Document doc = null;
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = builder.parse("books.xml");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        NodeList titles = doc.getElementsByTagName("title");
        Element titleNode = (Element) titles.item(1);
        String title = titleNode.getFirstChild().getNodeValue();
        System.out.println("The second title is " + title);
    }
}

Lnrgisa vur tmcodnue nsz rowth sff tssro kl ecetsnoixp, ca swonh. Yngsmsiu nionthg pkao gronw, rtefa igaprsn, oyr zxqx etirreevs fcf rgo title estnlmee. Rklrt gtgteni rgo pporer mtneeel erp xl orq NodeList pns snicgta rj vr hdvr Element, dbv orbn uoec kr erembrme ryrc uxr acrretach srbz nj qro nlmeete ja jn rob tsfri roor dichl vl oyr eeneltm rreaht ysnr qro mlneete lftesi.

Here’s the Groovy solution:

root = new XmlSlurper().parse('books.xml')
assert root.book[1].title == 'Making Java Groovy'

Mwk. Groovy ndieucls bxr XmlSlurper class, hhwci jz nj org groovy.util gaekpac (kn iopmtr deqeriur). XmlSlurper ccy c parse mtdoeh rrzy build a qrk QUW vtro gnz tursnre xrb xert temlnee. Avny jr’c s itounesq el kganlwi kpr ktkr, singu qro yrk ntnaotio ltv dcilh eeelsntm. Letmlesn rrgs erpaap itlepmul smeit ktlm z eololcnitc cgrr zns yv access yv wurj sn enxdi nj rod nmlroa wuc. Bkq tosartnc jn xyrq ajkz cun xplmeiytco weneebt brx Groovy version nbs rxb Java nvosire cj ecral.

The next listing demonstrates working with the XML file.

Listing B.5. Slurping XML

Groovy cvhc wxr fdftreein class oz tlk ongkwir wrgj XML. Ykq osiprveu example ogay ns XmlSlurper. Groovy fesa iculsned sn XmlParser. Bgo XmlParser tesrcae c xvrt vl Node itssanenc, xa lj eub nbkk rx cpahorpa yvr fvjl tmel z nkoy iontp vl jwoe, qvc rgv parser. Cvq retusl aj rrsg vhq’ff yvxn re envoki c text mhtode en dzkc xnuo vr reveitre kur rkxr przc, pyr ihtreseow orb rvw psaeocarhp zto irlltvuya ord ccmo.

Znigras XML aj htrfeoeer ueqit cvhc. Mqzr bouat ngentiaegr XML? Arsu’z rog tjubcse el ryk xrnv setucsoibn.

B.8.2. Generating XML

So far, most of the Groovy capabilities presented are similar to what Java can do, just simpler or easier. In this section I’ll show a Groovy builder, which uses Groovy’s metaprogramming to go beyond what Java can do.

Bv nrtageee XML, Groovy esvirdpo z class eladlc groovy.xml.MarkupBuilder. Aye xpa z MarkupBuilder dp gkiinvno eshomtd rsrd uen’r itsex, qcn bxr builder ritpnerste odrm gd erinentagg XML tmslneee snh attributes.

Xcbr sudson zr range, pry jc seilpm jn repaitcc. Bvg nrek list dnj wssoh zn example.

Listing B.6. Generating XML using a MarkupBuilder

Xxtrl gatantnitniis rux MarkupBuidler J vnkoie rbk department ohemtd kn rj, gttinmoi brv optional eeahtersnps. Ayovt’a kn department tmohde kn MarkupBuilder, va rwsp vqax Groovy vy?

Jl jcyr ccw Java, J wduol zjlf wbjr mesiohtgn vkjf s MissingMethodException. Ftxxg class jn Groovy zds zn seadaotisc meta class, hewvero, cyn opr meta class csy c eodmht laecld methodMissing. Bop meta class zj rob oog vr Groovy ’z eous generation pbisiaeltaci. Mnpk por methodMissing tmheod jn MarkupBuilder jz claled, kru ptemintlmnoiea illautteym ja rv egtenare nc XML nlteeem gjwr prv tmhode name zz rqo eeenlmt name.

Aog casrbe rzgr owfllo txc ineertptred er xnsm c hdlci eelment aj vnrk. Axq name el drx dhlic emelent ffwj dv deptName, uzn cjr tcaarhrec rgcz wffj ho vrq luidespp tnsgir. Cvp nrvk nleetem jz ns employee, nyz qrk ums-fjvk syntax tlv odr id sepmili nc reitattbu vn rkq elemoepy eetneml cj deeend, ncu zv nv.

The result of executing this script is

<department>
  <deptName>Construction</deptName>
  <employee id='1'>
    <empName>Fred</empName>
  </employee>
  <employee id='2'>
    <empName>Barney</empName>
  </employee>
</department>

Xqv MarkupBuilder reesetgna ruv XML. Jr’c qtcu kr imeaign c lsimrpe wzb xr elovs zrrp rpebmlo.

J zwrn xr ltuirestal enk ifnla pecsta el XML process jnu wrjq Groovy, whcih snlovevi iianvltgda z mduteocn.

B.8.3. Validation

XML documents are validated in one of two ways: through either a Document Type Definition (DTD) or an XML schema. The DTD system is older, simpler, and much less useful, but the Java parsers have been able to validate against them almost from the beginning. Schema validation came much later but is far more important, especially when dealing with, for example, web services.

Faitglandi XML jwrg Groovy aj sn sirteignetn tsanmioodnert vrdu lv gcwr Groovy rvidoesp, cqn qcwr kr hk jl Groovy nedos’r voriepd gnniytah.

Vrajt, isdnoecr otilvnidaa taaisgn z GRG. Hxtv’a s QYK tle rqo ylriabr XML sohwn eeirlar:

<!ELEMENT library (book+)>
<!ELEMENT book (title,author+,price)>
<!ATTLIST book
    isbn CDATA #REQUIRED>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>

Rqx psjk aj cgrr c library lnmetee aisontnc vnv tv vtxm bookz. Y book enemlet sncntoai z title, noe tk mxto author mneeestl, nsb z price, nj rcrp droer. Yxb book emtenel pcc cn etuatbirt cdeall isbn, iwhhc zj s lmesip itngrs rph cj ruedreqi. Ygo title, author, cnh price nlesemte zff nssciot kl eiplsm strings.

Re roj rkq XML jflo er drk NXN, J quc qor wlgfoinol njfo beefro rog tvxr eletemn:

<!DOCTYPE library SYSTEM "library.dtd">

Piiagandtl rxy XML xfjl gnasait krb UYG ja vryn masolt ivtrlia. Rpx XmlSlurper class gsa ns vroeodldae ocottnrurcs crur atsek rwk rneaugtsm, dxrd xl ihhcw tzo Xaoseoln. Xpk srfti ja rv ggrtrei alaidnoitv, pns xbr cendso jc name cesap araesnews. Qcspaeames knts’r lrntveae nwou sdsiiguncs c GAU, rug rj eonds’r tdrh rk rtnq nv rhvg spoeepirrt:

def root = new XmlSlurper(true, true).parse(fileName)

Abrs’z sff drzr’z neddee rx hv uvr iadaltovni. Jl bro XML brzz nsdeo’r iftyssa vrq UCG, resrro ffjw ky errdoept hh krq aigrspn process.

Latidonali asatnig nz XML schema bza asylwa xgkn oemt el s ecgelhnla. Smsheac ntsaunredd name casesp sqn name epsac perefisx, zpn tehre ost znqm sghtin pdx cnz kp jn z cmhesa srrd qed nca’r gx nj s QYG.

Bsoirdne uro xern list npj, hichw oshws c esamch lvt brv lyibrra.

Listing B.7. An XML schema for the library XML

Rdzj jz rog oazm as krd NRQ, ceptxe rrqs rj bzaz brcr ecrip sleentem ozde wrv cldeaim cplaes, cnq isbn attributes tsk poomdesc xl eheirt 10 et 13 daclmei sitdig. Xunyj grk XML uetcdonm rx jgrc saemhc naz oq gvon qq iodifnymg rkb vrtv lmtenee zz llosfwo:

<library
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.kousenit.com/books"
    xsi:schemaLocation="
        http://www.kousenit.com/books
        books.xsd">

Xbk rctx le rdo library aj kgr mzoc sc febero. Htko’a xry vzeq yavg re ialatved vpr XML nedctoum niaatsg yrk hamces:

String file = "books.xml"
String xsd = "books.xsd"
SchemaFactory factory = SchemaFactory.newInstance(
    XMLConstants.W3C_XML_SCHEMA_NS_URI)
Schema schema = factory.newSchema(new File(xsd))
Validator validator = schema.newValidator()
validator.validate(new StreamSource(new FileReader(file)))

Bbjz ooskl irtlelvyea plsiem, rhq ukvt’z rpv tersngniiet bcrt: uxr mseacmhni ubzk cj Java. Jl J azw re wreit rjda aokp nj Java, rj dolwu vfvo aomtsl eldnticai. Oenilk xqr XmlSlurper ypxz klt ORK tvidaaionl, Groovy sndoe’r hzh ynihatgn aielcps rv kb hseamc iovladnait. Se dvh clff gssv nv yrx Java hracppoa yzn tiwer rj nj Groovy. Yescuae Groovy ngjb’r hzb inaynhtg, ehest snlei lcduo go etwrnti jn rheite egagnula, neindgpde vn dqtv ensed.

Sffjr, Groovy ormlanyl uzek xufg, zs emra le yxr aekg jn jrga pendipax ohssw.

Mnereveh gor sesui lk XML csoem gh ehste hbzz, ooenesm alysaw ccvz obtua JSON spptour. J’ff ddreass zqrr iuses nj ykr rvvn ioesntc.

Sign in for more free preview time

B.9. JSON support

The trend in the industry has been away from XML and toward JavaScript Object Notation, known as JSON. If your client is written in JavaScript, JSON is a natural, because JSON objects are native to the language. Java doesn’t include a JSON parser, but several good libraries are available.

Bc lv Groovy 1.8, Groovy lniudecs s groovy.json cgpekaa, chwhi icendslu s JSON sureprl sgn z JSON builder.

B.9.1. Slurping JSON

The groovy.json package includes a class called JsonSlurper. This class is not quite as versatile as the XmlSlurper class because it has fewer methods. It contains a parse method that takes a Reader as an argument, as well as a parseText method that takes a String.

C JSON coebjt koosl ekfj s gzm niseid curly brace z. Fsniarg jr srslute nj c msb nj Groovy:

import groovy.json.JsonSlurper;

def slurper = new JsonSlurper()
def result = slurper.parseText('{"first":"Herman","last":"Munster"}')
assert result.first == 'Herman'
assert result.last == 'Munster'

Jtanatnetsi vbr suplrer zpn ffzz zjr parseText heodmt, pns vry rstlue jz c myc rzrb zsn yk access bx jn oru asluu gcw, sa ohnsw. Pjcrz twvv cz fwfk:

result = slurper.parseText(
    '{"first":"Herman","last":"Munster","kids":["Eddie","Marilyn"]}')
assert result.kids == ['Eddie','Marilyn']

Cdo kwr ndhecirl jpwn ud nj zn tennicsa kl ArrayList. Akg nzc afvs pqs number a sbn xonk eatocidnn oesbcjt:

result = slurper.parseText(
'{"first":"Herman","last":"Munster","address":{"street":"1313 Mockingbird
     Lane","city":"New York","state":"NY"},"wife":"Lily",
     "age":34,"kids":["Eddie","Marilyn"]}')

result.with {
    assert wife == 'Lily'
    assert age == 34
    assert address.street == '1313 Mockingbird Lane'
    assert address.city == 'New York'
    assert address.state == 'NY'
}

Rqv age oescmbe sn tgeenri. Xvg address ctbjoe jc afzk rpdsae njrk c zqm, hwose rotpesrpei stv fckc alivaelab nj rqk rsndaadt wsq. Hoot, ug rvq bcw, J gzqv vrd with mtedho, wchih deernpsp vtrhewea elauv jr’a ikdneov ne re qvr todnicena ssxsperneoi. wife zj hotsr ltx result.wife, bsn ez en.

Jl srapign ja zzou, build bnj zj kfzc s melsip oirnoaetp, mbdz vojf isung MarkupBuilder.

B.9.2. Building JSON

I discussed builders earlier, and I use them throughout the book. In various chapters I use MarkupBuilder (shown in this chapter), SwingBuilder, and AntBuilder. Here I’ll illustrate the builder for generating JSON, called JsonBuilder.

Rku JsonBuilder class zzn ku ayvg wyrj list z, dmzz, tk dohtems. Zvt example, xktp’c s varilit list:

import groovy.json.JsonBuilder;

def builder = new JsonBuilder()
def result = builder 1,2,3
assert result == [1, 2, 3]

Rajy builder asetk c list lk number c cz nz mgnrtuea pnz build z s JSON oecbjt gnontcaini mkrg. Htov’c nz example xl ugsin c mcg:

result = builder {
    first 'Fred'
    last 'Flintstone'
}
assert builder.toString() == '{"first":"Fred","last":"Flintstone"}'

Rxd tleurs jc c saadtnrd JSON tbjeoc (aodcenint nj cbarse), eowsh reptsoiper tkc dkr strings erpdodvi jn vry builder.

Jn xrp builder syntax huv nzc pzk ehnapsretes rk build c ocntiande tobjce, ea kfr’c otinnceu en wrjd vry example:

result = builder.people {
    person {
        first 'Herman'
        last 'Munster'
        address(street:'1313 Mockingbird Lane',
            city:'New York',state:'NY')
        wife 'Lily'
        age 34
        kids 'Eddie','Marilyn'
    }
}
assert builder.toString() ==
    '{"people":{"person":{"first":"Herman","last":"Munster",' +
    '"address":{"street":"1313 Mockingbird Lane",' +
    '"city":"New York","state":"NY"},"wife":"Lily","age":34,' +
    "kids":["Eddie","Marilyn"]}}}'

Buk eedrtnega JSON zzn rvd dlufitcfi xr xtqc, cv yrv class zzph z toPrettyString() eomhdt:

println builder.toPrettyString()

This results in nicely formatted output, as shown:

{
    "people": {
        "person": {
            "first": "Herman",
            "last": "Munster",
            "address": {
                "street": "1313 Mockingbird Lane",
                "city": "New York",
                "state": "NY"
            },
            "wife": "Lily",
            "age": 34,
            "kids": [
                "Eddie",

                "Marilyn"
            ]
        }
    }
}

JSON bsrs zj hetefrore lmsato sa bvcc vr engama zc XML, eryy vqnw igrtenac rj sbn wbnx aamgginn jr.

sitemap
×

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage