Groovy

Instalacja

  1. Ściągnij Groovy 1.0 ze strony http://groovy.codehaus.org/Download (lub lokalnie)
  2. Ustaw zmienną środowiskową GROOVY_HOME na katalog, gdzie znajduje się rozpakowana dystrybucja
  3. Dodaj GROOVY_HOME/bin do zmiennej PATH
  4. Ustaw zmienną JAVA_HOME tak, by wskazywała na JDK
  5. Uruchom groovysh (konsola) lub groovyConsole (Swing)

Wtyczka do Eclipse'a

http://groovy.codehaus.org/Eclipse+Plugin

Cechy języka

Closures - programowanie funkcyjne

Jest to anonimowy blok kodu wykonywalnego. Może brać argumenty i zwraca wartość jak funkcja. Może korzystać ze zmiennych widocznych w otaczającym kontekście. Można napisać:

{ square -> square * square }

Składnia: { [closureArguments->] statements } closureArguments to opcjonalna lista argumentów oddzielonych przecinkami. Jeśli zostanie pominięta, będziemy mieli closure jednoargumentową (z dostępem do parametru poprzez nazwę it, np. { println it }).

W Javie należałoby zapisać ten kod w otaczającej klasie i metodzie.

Blok można przypisać na zmienną:

Przypisaną na zmienną closure można potem przekazać jako parametr:

Trochę bardziej złożony przykład:

Zmienne związane z closure są dla niej dostępne nawet, gdy zostanie zwrócona na zewnątrz otaczającego kontekstu.

Przykład:

Closures pochodzą od klasy groovy.lang.Closure. Są tzw. First Class Objects.

Z closure można związać na stałe parametry za pomocą tzw. currying'u, np.:

Jak zdefiniować metodę, która bierze closure?

Można teraz wywołać each() z definicją closure poza nawiasami okrągłymi:

Bardziej tradycyjna składnia jest też dostępna. W Groovy'm można unikać nawiasów w wielu sytuacjach, zatem poniższe kombinację są też dopuszczalne:

Zakresy

Zakresy mogą być także użyte w połączeniu ze switch ... case.

Operator *.

assert [1, 3, 5] == ['a', 'few', 'words']*.size()

Indeksowanie

Dynamiczne obiekty (Expandos)

Jest to obiekt, który nie musi mieć z góry zdefiniowanych właściwości i metod.

Wyrażenia regularne

Groovy wspomaga wyrażenia regularne za pomocą wyrażenia ~wzorzec, które kompiluje się do obiektu Javy Pattern z podanego łańcucha znakowego. Groovy posiada też operator =~, które tworzy obiekt Matcher oraz ==~, który dopasowuje wyrażenie regularne.

Iteracja po String'ach, mapach, listach, ...

Switch'owanie po wszystkim

Operator ?.

Gdy przechodzimy po skomplikowanym grafie obiektów i nie chcemy, by rzucany był NullPointerException, możemy użyć operatora ?. zamiast ..

Grails

Cel

Celem Grails jest zapewnienie podobnego do Rails środowiska, które wygląda bardziej znajomo dla programistów Javy, dzięki czemu przejście do tego środowiska ma być łagodniejsze.

Grails bazuje na technologiach takich jak Spring (MVC), Hibernate (mapowanie obiektów i relacji), SiteMesh (interfejs użytkownika).

Inne elementy, na których opiera się Grails, to Dynamic Tag Libraries, Grails Object Relational Mapping, Groovy Server Pages oraz Scaffolding.

Instalacja

  1. Ściągnij Grails ze strony http://grails.codehaus.org/Download (lub lokalnie)
  2. Utwórz zmienną środowiskową GRAILS_HOME i ustaw tak, by wskazywała katalog z rozpakowanym archiwum
  3. Dodaj do zmiennej PATH katalog bin z katalogu GRAILS_HOME
  4. W linii poleceń wpisz grails

Tworzenie projektu

Aby utworzyć projekt należy wpisać w konsoli grails create-app. Grails zapyta o nazwę projektu (w przykładzie będzie to my-project) i utworzy strukturę projektu.

%PROJECT_HOME%
    + grails-app
       + conf                 ---> configuration artifacts like data sources
       + controllers          ---> controller artifacts
       + domain               ---> domain classes
       + i18n                 ---> message bundles for i18n
       + services             ---> services
       + taglib               ---> tag libraries
       + util                 ---> special utility classes (e.g., codecs, etc.)
       + views                ---> views
           + layouts              ---> layouts
   + hibernate              ---> optional hibernate config
   + lib
   + spring                 ---> optional spring config
   + src
       + groovy               ---> optional; location for Groovy source files 
                                   (of types other than those in grails-app/*)
       + java                 ---> optional; location for Java source files
   + war
       + WEB-INF

Grails i Eclipse

Grails automatycznie tworzy Eclipse'owe projekty przy tworzeniu aplikacji.

Bug! Nie należy używać katalogu głównego ani ścieżek ze spacjami.

W Eclipse przejdź do Windows -> Preferences... -> Java -> Build path -> Classpath Variables -> New i dodaj zmienną GRAILS_HOME.

Konfiguracja projektu

Źródła danych

W katalogu grails-app/conf utworzone zostały pliki konfiguracyjne dla źródeł danych. Domyślnie ustawione są na bazę danych HSQLDB działającą w pamięci operacyjnej (zobacz: grails-app/conf/DevelopmentDataSource.groovy).

Jeśli chcemy użyć innej bazy danych, wystarczy zmienić odpowiednie wartości w plikach konfiguracyjnych oraz dodać sterownik bazy danych do katalogu lib projektu.

Domain Classes - encje

Domain class jest to klasa utrwalana w bazie danych. Domyślnie wszystkie jej atrybuty są zapamiętywane.

Aby utworzyć domain class, w katalogu głównym projektu wykonaj polecenie grails create-domain-class. Zostaniesz poproszony o podanie nazwy klasy (wpisz np. Book). Klasa zostanie utworzona w katalogu grails-app/domain.

Można dodać teraz dane testowe. Żeby to zrobić, należy zmienić plik grails-app/conf/ApplicationBootStrap.groovy:

Kontrolery

Kontrolery obsługują zapytania i mapują URL'e.

Aby wygenerować kontroler oraz widok (strony GSP) należy wykonać grails generate-all i wpisać nazwę encji (Book z przykładu). Kontroler zostanie wygenerowany do pliku grails-app/controllers/BookController.groovy. Otwórz ten plik i zmień go w następujący sposób, by wykorzystać dynamiczny scaffolding:

Uruchamianie projektu

Zostanie uruchomiony silnik Jetty na porcie 8080.

Lista książek jest dostępna pod adresem http://localhost:8080/my-project/book/list.

Grails Object Relational Mapping (GORM)

Grails wykorzystuje Hibernate 3, ale nie trzeba nic konfigurować.

Domain Class

Jak widzieliśmy w przykładzie jest to zwykła klasa. W czasie wykonania dostaje jednak dwa dodatkowe atrybuty: id oraz version.

Domyślnie wszystkie atrybuty są obowiązkowe oraz są utrwalane w bazie danych. Aby zmienić to zachowanie, wystarczy stworzyć listy wyjątków w klasie:

Można także ustawić wartości domyślne oraz zmienić nazwę mapowanej tabeli:

Modelowanie związków pomiędzy encjami

Walidacja danych

Ograniczenia na dane nakłada się za pomocą closure constraints, np.:

Walidujemy dane za pomocą metody validate(). Domyślnie waliduje także save().

Wprowadzone ograniczenia mają wpływ na generowany widok, np. zamiast pól tekstowych generowane są listy, lub zakresy wartości

Więcej o kontrolerach

Kontrolery można tworzyć automatycznie za pomocą polecenia grails create-controller. Taki sam efekt będzie miało utworzenie kontrolera ręcznie. Mapowanie URL'i jest automatyczne.

Podczas wykonania kontroler dostaje metody i parametry, pozwalające na dostęp do sesji, czy też parametrów żądania a także na logowanie błędów, itp. Pełny spis metod i parametrów znajduje się tu.

Kontekst "Flash" jest to pomysł wzięty z Rails, polegający na wprowadzeniu tymczasowego składu dla atrybutów, które mają być dostępne tylko przy następnym żądaniu. Przykład użycia:

Kontroler powinien zwrócić pewien model, którego używa widok przy renderowaniu strony. Model jest mapą:

Jeśli nie będzie zwrócony żaden model, użyte zostaną atrybuty kontrolera.

Widoki

Widok realizowany jest za pomocą stron GSP lub JSP. Zasadnicza różnica pomiędzy nimi jest taka, że w stronach GSP skryptlety pisze się w Groovy'm oraz dostępne są dodatkowe tagi. Tutaj znajduje się lista dostępnych tagów.

Za podłączenie widoków do kontrolerów odpowiada mechanizm konwencji. Na przykład dla kontrolera:

odpowiedni widok znajduje się w katalogu grails-app/views/book i ma nazwę list.gsp.

Layouts

Układ strony można stosować w Grails poprzez SiteMesh. Polega to na dodaniu tagu meta z nazwą layout:

Layout nazwany main.gsp należy umieścić w katalogu grails-app/views/layouts.