Ugrás a fő tartalomra

Groovy alapok 3.

 

Műveletek

Futtatás script-ként

groovy Main.groovy


Fordítás Class-ba

groovyc Main.groovy

 

Futtatás java Class-ként

java -cp .;c:\Users\kecskemetil\Documents\prg\groovy-3.0.8\lib\* Main

 

Fordítás JAR-ba

jar cvf myclasses.jar -C classes

 

Groovy konzol használata

Szerkesztés és futtatás




























Minta XML (file)

 
def ErsteBankStatements = new XmlSlurper().parse(new File('c://Temp//kl//ebhtsym3//utl_file_ebhtsym3_20220103//STTD_20220103_001ZIR_EM_EHEH_1_EBE_F_E.xml'))
for (Setting in ErsteBankStatements.Setting) {
 println "${Setting.BANK_NAME} "
}
for (Statement in ErsteBankStatements.Statement) {
 println "${Statement.STMT_SEQ}  "
}
 
for (Account in ErsteBankStatements.Statement.Account) {
 println " ${Account.ACCOUNT_NO} "
}
 
 

Minta XML (stuktura)

 
def text = '''
<customers>
 <corporate>
    <customer name="Lajos Kecskeméti" company="ERSTE" />
    <customer name="Kakab Gipsz" company="OTP" />
    <customer name="Ödön Vödör" company="K_H" />
 </corporate>
</customers>
'''
 
def customers = new XmlSlurper().parseText(text) 
for (customer in customers.corporate.customer) {
 println "${customer.@name} works for ${customer.@company}"
}
 

Minta SQL (otracle)

import groovy.sql.*
url = "jdbc:oracle:thin:@AI:1525:K10"
user = "HN_user"
pw = "Jelszo"
driver = "oracle.jdbc.driver.OracleDriver"
sql = Sql.newInstance(url, user, pw, driver)
rowNum = 0
def md2
try {
//------ kiírás próba közvetlen megadással
    sql.eachRow("select * from KL_KIV_TABLE WHERE TABLE_NAme ='HAFC_M' "){ row ->
    def md = row.getMetaData()
    println row[0] +' | ' + row[1]
    rowNum++
    }
    println rowNum
 //-----------------------
 def output = ""
 //--- fejléc
   sql.eachRow("select * from KL_KIV_TABLE WHERE TABLE_NAme like 'HAFC_M%' "){ row ->
     meta = row.getMetaData()
     numCols = meta.getColumnCount()
     headings = (1..numCols).collect{meta.getColumnLabel(it)}
     output = headings.join("|") + "\n"
     println headings.join("|")
    }   
//--- adattartalom
  sql.eachRow("select * from KL_KIV_TABLE WHERE TABLE_NAme like 'HAFC%' "){ row ->
      meta = row.getMetaData()
      numCols = meta.getColumnCount()
      vals = (0..<numCols).collect{row[it]}      
      output += vals.join("|") + "\n"
      println vals.join("|")
    }
 
//--- csv fileba írás    
  def file = new File("c:/Temp/test.csv")
  file.text = output  
    
    
 } finally {
//---- adatkapcsolat lezárás
     sql.close()
 }
 
 
Jellemzők

A Groovy egy a JVM-re épülő "dinamikus" nyelv mely a Java platformhoz tartozó scriptnyelvként is használható.

 

Felhasználási területei

1.            Felhasználhatjuk hagyományos értelemben vett(shell) szkriptelésre.

2.            Beágyazhatjuk Java alkalmazásokba, hogy kiterjeszthetővé tegyük azt.

3.            Java alkalmazások egyes részeit írhatjuk Groovyban (pl. servletek, tesztek)

4.            Alkalmas önálló alkalmazásfejlesztésre is.

Itt lehet már transzformációs annotációkat, úgy mint, @Singleton, @Lazy, @Immutable (létrejöttük után nem változó objektumok).

 

Az == operátor: érték szerinti egyenlőséget definiál objektumokra is (ellentétben a Javával, ahol objektumok azonosságát jelentette). Tehát a Java equals()-al azonos. Objektumok azonosságára a .is() használható.

 

Aritmetikai operátorok:

a + b                       a.plus(b)

a - b                       a.minus(b)

a * b                       a.multiply(b)

a ** b                     a.power(b)

a / b                        a.div(b)

a % b                     a.mod(b)

a | b                        a.or(b)

a & b                      a.and(b)

a ^ b                       a.xor(b)

a++ or ++a             a.next()

a-- or --a a.previous()

a[b]                        a.getAt(b)

a[b] = c   a.putAt(b, c)

a << b                    a.leftShift(b)

a >> b                    a.rightShift(b)

switch(a) { case(b) : } b.isCase(a)

~a                           a.bitwiseNegate()

-a                           a.negative()

+a                           a.positive()

 

Logikai operátorok:

a == b                    a.equals(b) or a.compareTo(b) == 0

a != b                     ! a.equals(b)

a <=> b   a.compareTo(b)

a > b                       a.compareTo(b) > 0

a >= b                    a.compareTo(b) >= 0

a < b                       a.compareTo(b) < 0

a <= b                    a.compareTo(b) <= 0

Nem érzékenyek a null-okra, azaz ha az operandus null, a kiértékelés nem dob NullPointerException-t.

 

 

'spread' operátor:

 segítségével egy összetett objektum minden elemén végrehajtható egy művelet.

 

               parent*.action                                                       //ugyan az, mintha minden elemre meghívnánk:

               parent.collect{ child -> child?.action }

 

 

Objektumokhoz kapcsolódó operátorok:

'.': (pont) operátor  : tagfüggvény hívására, adattagok/propertyk elérésére használható.

'.&'                                        : referencia operátor

'as'                                         : típus kényszerítés

'=='                                        : a java-s equals(), érték szerinti egyenlőséget vizsgál. Objektumok azonosságára használható az 'is' operátor.

'instanceof'                           : mint Java-ban. Megadja, hogy az objektum az adott típusú-e.

 

További operátorok:

'getAt()'/satAt()'    : iteratív adatszerkezeteknél adott pozíción lévő adat lekérése, beállítása.

tartomány operátor '(..)'

Elvis operator '?:'  : akkor használható, ha hamis vagy null értéknél szeretnék használható információt visszaadni pl.:

               def megjelenítendőNév = felhasznalo.neve ?: "Anonymous" //azaz ha neve adattag nem létezik, vagy false, akkor a '?:' után értéket adja vissza

 

 

 

 
Automatikusan importálás
 
Az alábbi csomagokat automatikusan importálja:
groovy.lang.*, groovy.util.*, java.lang.*, java.util.*, java.net.*, and java.io.*,
java.math.BigInteger valamint a BigDecimal.
 
Kiértékelés ellenőrzés
assert(true) 
assert 1 == 1 
def x = 1 
assert x == 1 
def y = 1; assert y == 1
 
assert ('text' * 3 << 'hello').size() == 4 * 3 + 51
 
=>
assert ('text' * 3 << 'hello').size() == 4 * 3 + 51
               |   |           |      |    |   |
               |   |           17     |    12  63
               |   texttexttexthello  false
               'texttexttext'
 
assert 'xxxxx' == '12345'.replaceAll(/\d/, 'x')
assert '12345' =~ /\d+/
 
def x = 1 
def y = 2 
assert x + y == 3
assert x.plus(y) == 3 
assert x instanceof Integer
 
 
 
 
Objektumok
 
class Book { 
 private String title 
 Book (String theTitle) { 
 title = theTitle 
 } 
 String getTitle(){ 
 return title 
 } 
} 
Book kl = new Book('Groovy teszt') 
assert kl.getTitle() == 'Groovy teszt' 
assert getTitleBackwards(kl) == 'tzset yvoorG' 
String getTitleBackwards(book) { 
 String title = book.getTitle() 
 return title.reverse() 
}
 
 
 
Összetett adat típusok  (Kollekciók)
 
Listák, halmazok
 
def roman = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII'] 
assert roman[4] == 'IV' 
roman[8] = 'VIII' 
assert roman.size() == 9
 
[1, 2, 3].each{ println "Item: $it" }
['a', 'b', 'c'].eachWithIndex{ it, i -> println "$i: $it" }
 
 
Tömbök, Range 
 
def x = 1..10 
assert x.contains(5) 
assert !x.contains(15) 
assert x.size() == 10 
assert x.from == 1 
assert x.to == 10 
assert x.reverse() == 10..1
 
range = 5..<8
assert range.size() == 3
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert ! range.contains(8)
 
 
 
import java.awt.* 
Point topLeft = new Point(0, 0)     // classic 
Point botRight = [100, 100]         // List cast 
Point center = [x:50, y:50]         // Map cast 
assert botRight instanceof Point 
assert center instanceof Point 
def rect = new Rectangle() 
rect.location = [0, 0]              // Point 
rect.size = [width:100, height:100] // Dimension
 
 
 
MAP-ek
 
Map típusú objektumokat(kulcs kollekció párok) 
 
def map = [name:"Gromit", likes:"cheese", id:1234]
assert map.get("name") == "Gromit" 
assert map.get("id") == 1234
assert map["name"] == "Gromit" 
assert map['id'] == 1234
assert map instanceof java.util.Map
 
 
Ciklusok és elágazások
 
 
if (false) assert false 
 
if (null) 
{ 
 assert false
}
else
{
 assert true
}
 
def i = 0 
while (i < 10) { 
 i++ 
} 
 
assert i == 10 
def clinks = 0 
for (remaining in 0..9) { 
 clinks += remaining 
} 
assert clinks == (10*9)/2 
 
def list = [0, 1, 2, 3] 
for (j in list) { 
 assert j == list[j] 
} 
 
list.each() { item -> 
 assert item == list[item] 
} 
 
switch(3) { 
 case 1 : assert false; break 
 case 3 : assert true; break 
 default: assert false 
}
 
[1, 2, 3].each { entry -> println entry   }
 
 
def totalClinks = 0
def partyPeople = 100
1.upto(partyPeople) { guestNumber ->
 clinksWithGuest = guestNumber-1
 totalClinks += clinksWithGuest 
}
println totalClinks // == (partyPeople * (partyPeople-1)) / 2
 
 
 
Szöveg feldolgozás
 
(60 * 60 * 24 * 365).toString();
 
assert "abc" - "a" == "bc"
 
assert 'ABCDE'.indexOf(67) == 2
 
 
println  1.plus(1)    // 2
 
'x' as char 
'x'.toCharacter()
 
def me = 'Lajos' 
def you = 'Ildikó' 
def line = "me $me - you $you" 
assert line instanceof GString
assert line.strings[0] == 'me ' 
assert line.strings[1] == ' - you ' 
assert line.values[0] == 'Lajos' 
assert line.values[1] == 'Ildikó' 14
String greeting = 'Hello Groovy!' 
assert greeting.startsWith('Hello') 
assert greeting.getAt(0) == 'H' 
assert greeting[0] == 'H' 
assert greeting.indexOf('Groovy') >= 0 
assert greeting.contains('Groovy') 
assert greeting[6..11] == 'Groovy' 
assert 'Hi' + greeting - 'Hello' == 'Hi Groovy!' 
assert greeting.count('o') == 3 
assert 'x'.padLeft(3) == ' x' 
assert 'x'.padRight(3,'_') == 'x__'
assert 'x'.center(3) == ' x ' 
assert 'x' * 3 == 'xxx'
 
 
def greeting = 'Hello'
greeting <<= ' Groovy' 
assert greeting instanceof java.lang.StringBuffer
greeting << '!' 
assert greeting.toString() == 'Hello Groovy!'
greeting[1..4] = 'i' 
assert greeting.toString() == 'Hi Groovy!'
 
 
 
Reguláris kifejezések
 

Reguláris kifejezés operátorai:

a?

0-szor vagy 1-szer fordul elő az *a*

'a' vagy üres sztring

a*

0-szor vagy többször fordul elő az *a*

üres sztring vagy 'a', 'aa', 'aaa', stb.

a+

1-szer vagy többször fordul elő az *a*

'a', 'aa', 'aaa', stb.

a|b

*a* vagy *b*

'a' vagy 'b' -

.

bármilyen egyhosszú karakter

'a', 'q', 'l', '_', '+', stb

[woeirjsd]

a felsoroltak közül bármelyik előfordul

'w', 'o', 'e', 'i', 'r', 'j', 's', 'd'

[1-9]

az intervallumba esők közül bármelyik előfordul

'1', '2', '3', '4', '5', '6', '7', '8', '9'

[^13579]

bármilyen karakter, ami nincs a felsorolásban

even digits, or any other character

(ie)

kifejezés csoportosítása (más operátorral való használathoz)

'ie'

^a

*a* előfordul egy sor elején

'a'

a$

*a* előfordul egy sor végén

'a'


Olyan reguláris kifejezés esetén amely olyan karaktert is tartalmaz, ami egyben operátor is, akkor '\'-t kell tenni a karakter elé:

 

A Groovy Closure speciális programegység. Tekinthetjük egy függvényre mutató pointernek vagy egy "kód blokk"nak is.

Megint más megfogalmazásban: egy névtelen függvény, ami hivatkozhat a lexikális szkópjában található változókra. A Groovy által bevezetett closure a Ruby és Smalltalk blokkjának és a Lisp lambdájának felelnek meg.

Gyakori, hogy a Groovy programozók ugyanúgy használják a closure-okat mint a java névtelen beágyazott osztályokat.

 
 

Closures - szintaktika

 
 { [closureArguments->] statements }
 A kapcsos zárójelről a Groovy fordítója tudja, hogy a benne lévő kifejezést programkódként kezelje. 
Egy egyszerű paraméter nélküli példa, ahol bemutatjuk, hogy egy closure használhat a belsejében definiált lokális változókat is: 
 
  printer = { def localString = "Hello, world!"
 
              println localString     
 
  }
 A fenti closure, mint egy függvény, "printer()" híváskor kiírja a képernyőre hogy "Hello world!". 
Következő példa: paraméter-használat: 
 
 square = {x -> x*x}
 closure deklaráció és definíció után a square(9) hívás 81-et fog adni.
 
 
myMap = ["asdf": 1 , "qwer" : 2, "sdfg" : 10]  
result = 0                                   
myMap.keySet().each( { result+= myMap[it] } )  
println result                               
 A fenti kód a myMap-ben tárolt értékeket adja össze.
 
 
 
 
A closureok funkcionalitása helyettesíti a beágyazott osztályok funkcionalitását, 
sőt sokkal nagyobb a kifejező erejük, mint amit a beágyazott osztályok nyújtanak. 
  •      A closure-oknak egyetlen implicit metódusuk van, amit doCall()-nak hívnak.
  •     Egy closure-t végrehajthatunk a call() metódusának meghívásával, vagy a speciális szintakszissal, a () névtelen invokációval. Mindkét fajta hívást a Groovy egy doCall() hívássá fordít.
  •      A closure-oknak 1..N argumentumuk lehet, amik opcionálisan lehetnek statikusan típusosak. Az első paraméter elérhető egy implicit típus nélküli argumentumon keresztül, ha nincs explicit argumentum megadva. Ennek neve it. Ha nincs paraméter deklarálva és a hívó nem ad meg egyetlen argumentumot sem, akkor az it értéke null lesz.
  •      Természetesen, ha megadunk paramétereket, akkor az első paraméter a paraméterlista első eleme lesz és nem az it.
  •      A closureoknak mindig van visszatérési értékük. Ez jöhet egy explicit return utasításból, vagy a closure törzsének utolsó utasításából (azaz az explicit “return” utasítás opcionális).
  •     A closure hivatkozhat bármely változóra a lexikális szkópjában. Az ilyen változókra azt mondjuk, h a closurehoz vannak kötve.
  •      A closurehoz kötött változók elérhetőek a closure számára akkor is, ha a closure objektumot a létrehozását tartalmazó szkópon kívül hívják meg
  •     A closureok normális objektumok a Groovyn belül, és mindig a Closure osztályból származnak. A kód ami closureokat használ típus nélküli vagy Closure típusú változóként hivatkozhat rájuk.
  •      A closureok törzse csak explicit hívásnál hajtódnak végre, azaz a closureok nem hívódnak meg definiálásukkor.
  •      A closureoknak le lehet fixálni az argumentumait és így specializált closureokhoz jutunk (currying)

 
 
Program szálak, Thread
 
        import java.util.concurrent.atomic.AtomicInteger
        
        def counter = new AtomicInteger()
        synchronized out(message) {
               println(message)
        }
        def th = Thread.start {
               for( i in 1..8 ) {
                       sleep 30
                       out "thread loop $i"
                       counter.incrementAndGet()
               }
        }
        for( j in 1..4 ) {
               sleep 50
               out "main loop $j"
               counter.incrementAndGet()
        }
        th.join()
        assert counter.get() == 12
 
 
 
 
 




Megjegyzések