Groovy


Co to jest Groovy?

Groovy jest dynamicznym językiem skryptowym dla Wirtualnej Maszyny JAVA (Java Virtual Machine). Groovy doskonale integruje się z istniejącymi klasami/bibliotekami napisanymi w JAVIE. Kod źródłowy napisany w Groovy kompiluje się do bytecode'u JAVA stąd funkcjonalności napisane w tym języku można bez żadnego problemu używać w środowiskach JAVOWYCH.

Składnia języka Groovy w dużej mierze jest podobna do składni języka JAVA. Poza pewnymi wyjątkami kod napisany w JAVA poprawnie kompiluje się w kompilatorze Groovy. W języku Groovy został wprowadzony szereg "udoskonaleń" dla języka JAVA, które ułatwiają programiście pisanie oprogramowania.

Poniżej umieszono odnośniki do artykułów z dokumentacji Groovy, które są najbardziej istotne z puntku widzenia programisty zaczynającego swoją przygodę z Groovy.

Integracja Groovy z jPALIO

W celu integracji jPALIO z Groovy został wprowadzony specjalny typ obiektu jPALIO - Groovy. Kod zawarty w obiektach tego typu jest kompilowany przez kompilator Groovy. W obiektach tych można umieszczać kod analogicznie jak w przypadku obiektów typu jPALIO. Obiekty te mogą przyjmować argumenty i zwracać określoną wartość. Dodatkowo w obiektach typu Groovy można definiować klasy.

Obiekty jPALIO wszystkich typów przechowywane są w bazie danych. Na potrzeby obsługi klas zdefiniowanych w obiekcie typu Groovy został stworzony specjalny class loader, który rozszerza funkcjonalność domyślnego class loadera serwera aplikacyjnego o możliwość wyszukiwania tych klas.

W obiektach typu Groovy można korzystać z istniejących funkcjonalności platformy jPALIO. W celu maksymalnego uproszczenia korzystania z nich została stworzona klasa palio.Groovy, która pełni funkcję pośrednika pomiędzy Groovy a jPALIO. Między innymi umożliwia ona wywoływanie innych obiektów jPALIO (niekoniecznie typu Groovy) w obiektach typu Groovy oraz realizuje dostęp do modułów jPALIO.

Skrypty

Obiekty tego typu pełnią rolę funkcji. Przyjmują argumenty, wykonują jakąś operacje, a następnie zwracają wartość będącą zazwyczaj wynikiem wykonanej operacji. Możliwe jest wywołanie obiektu bez podawania argumentów. Obiekt nie musi zwracać żadnej wartości.

Każdy obiekt tego typu posiada predefiniowaną tablicę o nazwie args, w której przechowywane są przekazane do obiektu argumenty. Odwołanie do pierwszego argumentu wygląda w sposób następujący:

args[0]

Obiekty typy Groovy, tak jak wszystkie inne obiekty jPALIO, można przypisać do strony jPALIO. Takie obiektu posiadają predefiniowaną mapę parametrów globalnych jPALIO (w tym także parametrów wysłanych z formularza) o nazwie params.

Poniżej przedstawiono przykład obiektu realizującego proste operacje arytmetyczne. Jako pierwszy argument przyjmuje operator jaki ma zostać użyty, a jako dwa kolejne - wartości jakie mają zostać użyte przy danej operacji. Obiekt zwraca wynik działania operatora.

def operator = args[0]
def firstOperand = args[1]
def secondOperand = args[2]

switch (operator) {
case "+":
return firstOperand + secondOperand
case "-":
return firstOperand - secondOperand
case "*":
return firstOperand * secondOperand
case "/":
return firstOperand / secondOperand
default:
throw new UnsupportedOperationException(operator)
}

 

Przykładowe wywołanie tego obiektu w języku jPALIO

$=(@firstOperand, 40)
$=(@secondOperand, 50)

$=(@operator, null)
$for(@operator, ["+", "-", "/", "*"], {
$@firstOperand $@operator $@secondOperand = $*samples.doSomeArithmeticOperation($@operator, $@firstOperand, $@secondOperand)
})

 

To samo w języku Groovy

import palio.*

def firstOperand = 40
def secondOperand = 50

for(operator in ["+", "-", "/", "*"]) {
println "$firstOperand $operator $secondOperand = " +
Groovy.object("samples.doSomeArithmeticOperation", operator, firstOperand, secondOperand)
}

Klasy

W obiektach typu Groovy można umieszczać definicje klas.

Aby stworzyć klasę palio.sample.SimpleClass należy stworzyć obiekt jPALIO typu Groovy o kodzie palio.sample.SimpleClass. Zalecane jest umieszczenie tego obiektu w katalogu palio->sample. W treści definicji klasy należy pamiętać o zadeklarowaniu pakietu klasy. W naszym przypadku jest to pakiet palio.sample. Nazwa pakietu powinna odpowiadać hierarchii katalogów w której umieszczony został obiekt z definicją klasy.

Przykładowa klasa:

package palio.sample;

public class SimpleClass {
public static String someStaticMethod(String someArgument) {
return someArgument
}

public String someMethod(String someArgument) {
return someArgument
}
}

 

W przypadku gdy w innym obiekcie typu Groovy chcemy skorzystać z funkcjonalności zaimplementowanej w danej klasie należy zaimportować cały pakiet w której jest dana klasa lub konkretną klasę.

import palio.sample.*

lub

import palio.sample.SimpleClass

Wyjątkiem są obiekty Groovy umieszczone w tym samym katalogu (pakiecie). Dla tych obiektów import nie jest wymagany.

Poniżej przedstawiono przykład użycia przykładowej klasy w skrypcie Groovy (umieszczonym w tym samym pakiecie)

package palio.samples;

println SimpleClass.someStaticMethod("Static method...")
println new SimpleClass().someMethod("Method...")

 

Przykład użycia przykładowej klasy w innej klasie (umieszczonej w innym pakiecie)

package palio.samples.somepackage;

import palio.samples.*;

public class SecondSimpleClass {

SimpleClass simpleClass

public SecondSimpleClass() {
this.simpleClass = new SimpleClass()
}

public static String someStaticMethod(String someArgument) {
return SimpleClass.someStaticMethod(someArgument)
}

public String someMethod(String someArgument) {
return getSimpleClass().someMethod(someArgument)
}
}

 

Ciekawą funkcjonalnością, dającą spore możliwości, jest wywoływanie obiektu jPALIO zawierającego definicję klasy. Aby było to możliwe, klasa ta musi mieć zdefiniowaną metodę run:

public static Object run(Object[] args)

Przykład klasy z metodą run:

package palio.samples;

public class SimpleClassWithRunMethod {

private static String somePrivateStaticMethod(String someArgument) {
return someArgument
}

public static Object run(Object[] args) {
return SimpleClassWithRunMethod.somePrivateStaticMethod(args[0])
}

}

oraz przykładowe wywołanie obiektu zawierającego daną klasę:

$*palio.samples.SimpleClassWithRunMethod("Hello jPALIO!")

Klasa palio.Groovy

Klasa palio.Groovy udostępnia zestaw metod ułatwiający dostęp do podstawowych cech jPALIO z poziomu obiektów Groovy.

Poniżej przedstawiono, krótki opis oraz przykłady zastosowań wybranych metod.

 

Dostęp do modułów jPALIO 

Dostęp do modułów jPALIO jest realizowany z pomocą poniższych dwóch metod. Pierwsza zwraca bezpośrednio referencję do instancji modułu o podanej nazwie. W przypadku drugiej metody w podanym kontekście tworzone są zmienne o nazwach odpowiadającym nazwom modułów przekazanych jako argument. Zmienne te zawierają referencje do odpowiednich modułów.

public static Module module(String module)
public static void modules(GroovyObject object, String ... modules)

Przykładowe użycie:

import palio.*

// Invoking method now from time module
println Groovy.module("time").now()

// Binding modules time and sql to local variables
Groovy.modules(this, "time", "sql")

println time.now()

sql.read("select ID, CODE from P_PAGES order by ID").each {row -> 
    println row
}


Wywoływanie obiektów jPALIO

Wywoływanie obiektów jPALIO jest możliwe przy użyciu metody object. Jako pierwszy argument należy podać kod obiektu jPALIO. Kolejne argumenty są przekazywane jako argumenty do danego obiektu.

public static Object object(String code, Object ... params) throws PalioException

Przykładowe użycie:

// Invoking samples.doSomeArithmeticOperation object
def result = Groovy.object("samples.doSomeArithmeticOperation", "+", 20, 30)

 

Konwersja Closure do PalioCode

Część metod z modułów jPALIO ma zadeklarowany argument/argumenty typu PalioCode. Jest to typ wbudowany w język jPALIO. Aby można było korzystać z tych metod w języku Groovy została stworzona metoda realizująca konwersję Groovy Closure na PalioCode.

public static PalioCode asPalioCode(Closure closure) 

Przykład użycia:

Groovy.modules(this, "time", "sql")

sql.transaction(Groovy.asPalioCode {
   sql.write("update SOME_TABLE set SOME_DATE_FIELD=?", [time.now()] as Object[]) 
})

 

Wykorzystanie MarkupBuilder

MarkupBuilder pozwala tworzyć w łatwy i szybki sposób dokumenty HTML i XML. Więcej informacji o MarkupBuilder znajdziesz na stronach języka Groovy.
Poniżej prosty przykład, który generuje tabliczkę mnożenia w HTML'u:

Groovy.xout().html {body {table(border:"1") {
	tr {
		td()
		for (int x = 1; x <= 10; x++) th(x)
	}
	for (int y = 1; y <= 10; y++) tr {
		th(y)
		for (int x = 1; x <= 10; x++) td(x*y)
	}
}}}


Dostęp do klas

Dostęp do klas jest realizowany za pomocą metody getClass. W odróżnieniu od Class.forName metoda ta widzi także klasy zdefiniowane w obiektach jPALIO. Dzięki tej metodzie jest możliwy dostęp do klas zdefiniowanych w obiektach jPALIO poza obiektami jPALIO. Zdecydowanie metoda ta powinna być używana tylko przez programistów zaawansowanych.

public static Class getClass(String groovyClass) throws ClassNotFoundException