Ugrás a fő tartalomra

Groovy alapok 1

Groovy szkript nyelv amely a JAVA programozást egyszerűsíti.

Én ODI (Oracle Data Integrator) tanfolyamon találkoztam először vele.


 A Groovy a Java platformhoz tartózó scriptnyelv mely használata Java nyelvre építi szintaktikáját és szemantikáját. Tehát a Groovy Java stílusú szintaxisát használja.


 A Groovy nyelv a Java nyelvből hiányolt bizonyos képességekkel is rendelkezik, úgy mint felsorolási típus,
 operátor túlterhelés, closure-ök (vagy névtelen függvények), dinamikus típusok.



 Goovy-ben behozták az AST Makrók néven is futó fordítási idejű metaprogramozás lehetőségét,
 valamint az ehhez kapcsolódó úgynevezett transzformációs annotációkat.


 például:
   @Singleton,
   @Lazy,
   @Immutable (létrejöttük után nem változó objektumok),
   @Delegate.
 
 Valamint nyelvben mengedik a friends operátor használatát is.


 Bevezették még a Grape-et (Groovy Advanced Packaging Engine), a hozzá tartozó grab függvénnyel
 és @Grab annotációval, ezzel lehetővé vált elvileg végtelen sok könyvtárra hivatkozó scriptek fejlesztése,
 amikben az éppen használt könyvtárak csak futási időben töltődnek le a megfelelő oldalakról


 Használási területei:
 - hagyományos értelemben vett(shell) szkriptelésre.
 - beágyazhatjuk Java alkalmazásokba, hogy kiterjeszthetővé tegyük azt.
 - Java alkalmazások egyes részeit írhatjuk Groovyban (pl. servletek, tesztek)
 - önálló alkalmazásfejlesztésre is alkalmas.


 Java nyelttől 10 fő eltérések összefoglalása:


 1. A következő csomagokat nem kell importálni a forráskódban, mert alapértelmezettként importálva vannak a Groovy kódba:
a. java.io.*
b. java.lang.*
c. java.math.BigDecimal
d. java.math.BigInteger
e. java.net.*
f. java.util.*
g. groovy.lang.*
h. groovy.util.*
(Groovy scriptre az érvényes, hogy ezeket nem kell importálni)


2. 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ó.
foo.is(bar)
Természetesen csak nem null objektumokra hívható, ezért előtte érdemes ellenőrizni az objektum null voltát:
foo == null


3. Az 'in' kulcsszó, nem használható változó neveként.


4. Tömb deklarációjánál nem írható a következő:
int[] a = {1,2,3};
Helyette ez írható:
int[] a = [1,2,3]


5. A hagyományos ciklus szintaxisa mellett
for (int i=0; i < len; i++) {...}
használhatók a következők is:
for (i in 0..len-1) {...}
for (i in 0..<="">

len.times {...}


6. A pontosvessző használata nem kötelező.


7. A 'return' kulcsszó opcionális.


8. Statikus metódusokban is használható a this kulcsszó.


9. Az osztályok és függvényeik alapértelmezettként publikusak.


10. A Groovy szkriptekben a Javával ellentétben nem kell minden kódot osztályokba ágyaznunk,
definiálhatunk függvényeket és kiadhatunk utasításokat.
A Groovy az ilyen kódot tartalmazó szkriptet is egy osztállyá fordítja, és a kódot egy run nevű metódusba rakja.


A Groovy használathoz tehát JAVA telepítése és JAVA_HOME környezeti váltózó beállítása szükséges.




























Telepítő készlet elérése : Groovy link

Használatba vétel kicsomagolás és környezeti változó beállítása (GROOVY_HOME) után már indítható is a groovyConsole.bat -ot.





















Parancs soros használat:


--- Hello.groovy file tartalma
def name = 'Groovy szkript'
def greeting = "Hello ${name}"
println greeting


-- Meghívása (hello.groovy filenek)
groovy hello



ODI- t használó groovy előkészítése:


  1. ODI Jar állományok előkészítése:
c:\Oracle\ODI122\odi\sdk\lib\odi-core.jar
>> 
c:\Users\kecskemetil\Documents\kl_p\prg\groovy-2.5.2\lib\odi-core.jar
---
c:\Oracle\ODI122\odi\sdk\lib\oracle.odi-sdk-jse.jar
>> 
c:\Users\kecskemetil\Documents\kl_p\prg\groovy-2.5.2\lib\oracle.odi-sdk-jse.jar

  2. teszetelés
-- ipmort parancs
import oracle.odi.domain.project.finder.IOdiProjectFinder
  
-- válasz (OK: Hiba üzenet nélkül végrehejtja !!): 
groovy> import oracle.odi.domain.project.finder.IOdiProjectFinder
















ODI -n belüli groovy használat:




















SQL használati minta:


import groovy.sql.Sql
// import oracle.odi.domain.project.finder.IOdiVariableFinder
// import oracle.odi.domain.project.finder.IOdiSequenceFinder
import groovy.swing.SwingBuilder
import java.sql.Connection
import java.sql.DriverManager
import java.util.HashMap

(CONNECT_DATA=(SID=DBT10)))
url  = "jdbc:oracle:thin://@localhost:2126/DBT10"
user = "teszt_user"
pw   = "KLjs_1234_kl"

// --- Van-e oracle JDBC driver???
assert Class.forName("oracle.jdbc.driver.OracleDriver") != null

// kapcsolódás az adatbázishoz
conn = DriverManager.getConnection(url,user, pw)
def  stmt1 = conn.createStatement()

// Lekérdezés összeállítása
def sql1 = """
  select yyyymmdd, yyyy, c.* from CALENDAR c where yyyy='2019' and WEEK_OF_YEAR_NUM =1
   """

// Lekérdeés futtatása
def rs1 = stmt1.executeQuery(sql1)

// Eredmény kiolvasása amig van következő sor
while (rs1.next()) {
  print rs1.getString(1)
  print ' | '
  print rs1.getString('HOLIDAY_DESC')
  print ' | '
  println rs1.getString(3)
  
}

// Lezárások
stmt1.close()
conn.close()

///----- VÉGE

>>>>>>>> 

20190101 | UJEV | 2019-01-01 00:00:00
20190102 | null | 2019-01-02 00:00:00
20190103 | null | 2019-01-03 00:00:00
20190104 | null | 2019-01-04 00:00:00
20190105 | SZOMBAT | 2019-01-05 00:00:00
20190106 | VASÁRNAP | 2019-01-06 00:00:00
20190107 | null | 2019-01-07 00:00:00






Forditás használata:

Groovy szkripteket bájtkóddá fordíthatunk a groovyc ant-task segítségével a javac-hez hasonlóan.
Ekkor minden Groovy osztály egy normális Java osztállyá válik, amit használhatunk a Java kódunkban,
ezek az osztályok megvalósítják a GroovyObject interfészt.



Nyelvi elemek a groovy -ban:


Sztring literálok

•  Sztring literálok egyszeres és kétszeres idézőjelekkel is definiálhatók:

assert 'hello, world' == "hello, world"
assert "Hello, Groovy's world" == 'Hello, Groovy\'s world'
assert 'Say "Hello" to the world' == "Say \"Hello\" to the world"

•  Visszaperjellel karaktereket a kódjukkal is megadhatjuk:

assert '\b' == '\010' //backspace
assert '\t' == '\011' //horizontal tab
assert '\n' == '\012' //linefeed
assert '\f' == '\014' //form feed
assert '\r' == '\015' //carriage return



•  Több soron átívelő sztringek definiálhatók háromszoros idézőjellel:

---1. verzió:
assert '''hello,
Lajos''' == 'hello,\nLajos'

---2. verzió:
def text = """\
Hello Lajos 1.
Hello Lajos 2.
Hello Lajos 3."""


Használhatjuk hagyományos módon, ekkor minden sor végére kell egy visszaperjel:

assert 'hello, \
world' == 'hello, world'





Megjegyzések jelölése a program kódban :
•  '//'-től a sor végéig tart
 //ez már a megjegyzés tartozik /ez is//ez is     ...... és ez is

•  '/*'-tól a következő */-ig tart a megjegyzés, ez több soron is átívelhet.

Figyelem: Nem lehet egymásba ágyazni megjegyzéseket. 


 Változók deklarációja

A kódban bárhol lehet változókat deklarálni.
Ezt a def kulcsszóval tehetjük meg.
Ilyenkor dinamikusan rendelődik típus a névhez, ami változhat új definíciónál.

def a //a változó létrehozása; ekkor még nincs értéke
def b = 1 //a változó deklarálva, és definiálva
def a //fordítási hiba, a már definiált
b = 'valami'//új típusú értéket kap; ez megengedett
 Megadhatjuk a változó statikus típusát is. Ha más típusú értéket próbálunk adni neki,
 akkor az érték automatikusan konvertálódik a változó típusára, ha ez nem lehetséges,
 akkor kivétel (GroovyCastException) váltódik ki.

int i //integer
i = 5 //i == 5
i = 'A' //i == 65, A automatikusan integer értékére konvertálódik



Kifejezések Operátorok
Groovyban a Java-val ellentétben az operátorok viselkedése testreszabható, megváltoztatható.


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.



Gyűjtemények operátorai:
'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

Safe Navigation Operator '?.': NullPointerException elkerülésére használható. Általában, ha van egy referencia egy objektumra, akkor ellenőrizni kell, hogy null-e, mielőtt bármilyen tagját(adat/metdus) megpróbálnánk elérni. Ez az operátor null-t ad vissza NullPointerException dobása helyett:

def user = User.find( "admin" )           //null lehet, ha az 'admin' nem létezik
def streetName = user?.address?.street    //az utca neve null lesz, ha a user vagy user.address null, és ekkor nem dobódik kivétel


Operátorok:

 - Elvis operator (?:)
displayName = user.name ? user.name : 'Anonymous'
displayName = user.name ?: 'Anonymous'


 - Biztonságos (NULL // NullPointerException ) művelet operator (?.) 
def person = null
def name = person?.name                 
assert name == null


 - Közvetlen mező elérés operator (.@) 
class User {
public final String name                 
User(String name) { this.name = name}
String getName() { "Name: $name" }       }
def user = new User('Bob')
assert user.name == 'Name: Bob'
assert user.@name == 'Bob'





Megjegyzések