3. Cvičenie - Generovanie kódov I. (Úloha 2)

Ciele
  1. Oboznámiť sa so základnými spôsobmi generovania zdrojových kódov - transformácie a šablóny.
  2. Implementovať generátor skriptu pre vytvorenie databázy z modelu.
  3. Oboznámiť sa s nástrojom Velocity engine pre podporu generovania kódov použitím šablón.
  4. Implementovať generátory pre definíciu tried entít, rozhraní a implementácie rozhraní pre operácie CRUD.
  5. V rámci implementácie generátorov vytvoriť šablóny pre generovanie jednotlivých tried.
  6. Otestovať funkčnosť generovacieho systému aj funkčnosť vygenerovanej aplikácie.
Úvod
    Na dnešnom cvičení budeme v prvom kroku používať priamu transformáciu programom na vygenerovanie SQL skriptu pre vytvorenie databázy a v ďalších krokoch budeme prostredníctvom šablón generovať základné triedy aplikácie. Na generovanie prostredníctvom šablón využijeme nástroj Velocity.

    Oboznámte sa s dvoma základnými spôsobmi generovania zdrojových kódov z pohľadu implementácie generátora: transformácia programom, generovanie prostredníctvom šablón (generovanie.pdf)

Postup
  1. Implementujte generátor pre generovanie SQL skriptu pre vytvorenie databázy.
    Úloha: Rozšírte kostru generator1.zip pre generovanie SQL skriptu pre vytvorenie štruktúry databázy.


    Pošli
    Kostra generátora obsahuje nasledujúce triedy:
    • Generator - abstraktná trieda, ktorá je opisom všeobecného generátora, generujúceho výstup na základe modelu reprezentovaného ako graf objektov.
    • DatabaseScriptGenerator - implementácia generátora pre generovanie SQL skriptu pre vytvorenie databázy.
    Obr.: Triedy generátorov
    Poznámka: Doplňte implementáciu metódy void generate() v triede DatabaseScriptGenerator. Podľa uváženia vytvorte ďalšie metódy, ktoré určujú údajový typ stĺpca v tabuľke na základe údajového typu vlastnosti entity.
    Poznámka: V konfiguračnom súbore generátora generator.properties skontrolujte nastavenie cesty ku generovanému projektu. Uveďte autora projektu.
    Otestujte generátor databázového skriptu prostredníctvom triedy Make, ktorú upravte nasledovne.
    
    public class Make {
        public static void main(String[] args) throws Exception {
            //... povôdný obsah
    
            /* Generator - database script */
            new DatabaseScriptGenerator(model).generate();
        }
        //... pôvodný obsah
    }
            
  2. Oboznámte sa s nástrojom na generovanie textových výstupov prostredníctvom šablón - Apache Velocity Project. Pre začiatok tu je krátky tutoriál pre prácu s Velocity šablónami:
    • Príkazy vo VTL (Velocity Template Language) začínajú znakom #.
    • Premenné sa zapisujú v tvare ${nazovPremmenej}.
      Poznámka: V prípadoch, kedy sa za názvom premennej nenachádza ďalší text, je možné použiť skrátený zápis $nazovPremmenej.
    • Ak je v premennej uložený objekt, k jeho verejným členom je pristupovať prostredníctvom znaku bodky ., tak ako v jazyku Java.
      Poznámka: V prípade, že chceme volať bezparametrickú get metódu, môžeme využiť skrátený zápis vynechaním predpony get a zátvoriek.
      
      ${person.getName()}
      ${person.name}
       
    • Inicializovať premennú vo vnútri šablóny je možné pomocou príkazu set.
      
      #set($foo = "bar")
      #set($bar = $foo)
      
    • Na vetvenie využívame klasickú if..elseif..else..end konštrukciu.
      
      #if($fruit == "apple") Fruit is an apple.#else Fruit isn't an apple.#end
      
    • Vo Velocity existuje foreach cyklus. Syntax je nasledujúca:
      
      #foreach($item in $namedItems)
          ${item.name}
      #end 
      
      Poznámka: Vo vnútri cyklu Velocity automaticky sprístupňuje premenné: $velocityCount (počítadlo) a $velocityHasNext (false ak sa nachádza na poslednej položke pri iterácii, inak true)
    • Znovupoužiteľnosť kódu je umožnená príkazom parse, ktorý v danom mieste spracuje určenú šablónu
      #parse("template.vm")
    • Podrobnejšie informácie o vytváraní šablón nájdete v používateľskej príručke.
    Poznámka: Skontrolujte, či máte nastavenú závislosť na knižnici nástroja Velocity v súbore pom.xml v module magsa-generator, kde by sa v elemente <dependencies> malo nachádzať nasledovné nastavenie:
    
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity</artifactId>
        <version>1.7</version>
    </dependency>
    
  3. Oboznámte sa s pripravenou implementáciou generátorov.
    Obr.: Hierarchia tried generátorov
    Abstraktná trieda TemplateGenerator je implementáciou generátora používajúcou Velocity a predstavuje abstrakciu generovania šablón prostredníctvom Velocity. Pre potreby generovania je definovaná metóda
    
        protected void generate(Writer writer, Map<String, Object> params) throws GeneratorException
    
    ktorá generuje na základe šablóny (určená menom v konštruktore) a parametrov (params) pre šablónu výstup do špecifikovaného zapisovača (writer). Trieda JavaTemplateGenerator rozširuje triedu TemplateGenerator, pridáva pomocné metódy uľahčujúce generovanie Java kódu. Zabezpečuje správne umiestnenie triedy na základe balíka. Trieda CollectionTemplateGenerator je rozšírením JavaTamplateGenerator. Pre každý prvok kolekcie generuje samostatnú triedu.
    Poznámka: Pre prvky kolekcie musí platiť, že implementujú rozhranie Named.
    Na základe nasledujúceho zápisu generátor pre každú entitu v modeli (model) generuje použitím šablóny entity_class.java.vm triedu.
    
    new CollectionTemplateGenerator(model, "entity_class", model.getEntities()).generate();
    
    V konfiguračnom súbore generator.properties je pod kľučom entity_class.package určený balík. Kľúčom entity_class.format je určené meno súboru, do ktorého bude generovaný výstup. Kostra generovania prostredníctvom šablón je uvedená v generator2.zip.
  4. Oboznámte sa so štruktúrou generovaných tried a rozhraní a ich vzájomným prepojením s rámcom. Opis jednotlivých tried rámca (univerzálneho kódu) nájdete v prvom cvičení.
    Obr.: Aktuálny stav riešenia po uknočení kroku 5.
  5. Vytvorte šablóny pre generovanie triedy entít, rozhrania definujúce CRUD operácie nad entitami a implementáciu týchto rozhraní. V šablónach môžete využívať nasledovné metódy triedy JavaTemplateGenerator prístupné sú pomocou premennej $generator:
    • String toUCIdent(String ident) - prvý znak reťazca prevedie na veľké písmeno a vráti takto modifikovaný reťazec (to upper case identifier).
    • String toLCIdent(String ident) - prvý znak reťazca prevedie na malé písmeno a vráti takto modifikovaný reťazec (to lower case identifier).
    • String formatName(String name, String template) - získa meno triedy na základe mena entity a zvolenej šablóny (napr. $generator.formatName($name, "entity_class")).
    • String formatQualifiedName(String name, String template) - získa kvalifikované meno triedy (vrátane balíka) na základe mena entity a zvolenej šablóny.
    • Class getJavaClass(String name) - vráti triedu (objekt triedy Class) na základe jej mena
    • String getJavaType(Type type) - prevedie typ jazyka entít na typ jazyka java(kľúčové slovo)
    • String psSetMethod(Type type) - na základe typu odvodí meno príslušnej set metódy triedy pre PreparedStatement
    • String rsGetMethod(Type type) - na základe typu odvodí meno príslušnej get metódy triedy ResultSet
    • String parseStringMethod(Type type, String input) - na základe typu odvodí reťazec s výrazom na transformáciu hodnoty z reťazca na hodnoty uveeného typu.
    Úloha: Upravte šablónu entity_class.java.vm pre generovanie triedy entity tak, aby zohľadňovala údajové typy vlastností entít.


    Pošli
    Úloha: Oboznámte sa so šablónou dao_interface.java.vm pre generovanie rozhrania definujúceho operácie CRUD.


    Pošli
    Úloha: Upravte šablónu dao_impl.java.vm pre generovanie triedy implementujúcej rozhranie definujúce operácie CRUD. Vychádzajte z implementovanej metódy prepareInsertStatement v šablóne.
    Poznámka: Doimplementujte zvyšné metódy okrem metódy test, ktorú budeme implementovať neskôr.
    Poznámka: Pri implementácii metódy prepareUpdateStatement pouzite pre klauzulu WHERE v SQL príkaze metódu getIdent() v triede Entity pre jednoznačné identifikovanie upravovanej entity.


    Pošli
  6. Otestujte generovanie systému na základe vytvoreného modelu. Pre otestovanie doplňte do triedy Make nasledujúci kód.
    
    public class Make {
        public static void main(String[] args) throws Exception {
            //... povôdný obsah
    
            /* Generators -  entity, dao interface, dao implementation */
            new CollectionTemplateGenerator<Entity>(model, "entity_class", model.getEntities()).generate();
            new CollectionTemplateGenerator<Entity>(model, "dao_interface", model.getEntities()).generate();
            new CollectionTemplateGenerator<Entity>(model, "dao_impl", model.getEntities()).generate();
        }
        //...pôvodný obsah
    }
    
    V aktuálnom stave by vygenerovaná aplikácia mala umožňovať vytvoriť tabuľky v databáze použitím vygenerovaného skriptu. Implementácia CRUD rozhraní by mala umožňovať realizovať operácie s entitami v databáze: vytvorenie - create, zmenu - edit, odstránenie - remove, vyhľadanie na základe identifikátora - find, získanie entít konkrétneho typu - selectAll.
  7. Otestujte funkčnosť vygenerovanej aplikácie. Pre otestovanie CRUD operácií je potrebná databáza vytvorená na základe vygenerovaného skriptu.
    Úloha: Vytvorte si databázu, ktorú bude generovaná aplikácia používať. Môžete využiť podporu prostredia NetBeans pre prácu s Java DB (Derby).


    Pošli
    Úloha: Otestujte funkčnosť CRUD operácií so zvolenou entitou. Pre testovacie účely si v generovanom projekte vytvorte triedu Main s metódou main, kde umiestnite testovací kód.


    Pošli
  8. Vymažte súbory z disku a zrušte všetky vami vytvorené nastavenia vo vývojovom prostredí!
Zdroje
  1. Základné spôsoby transformácií:
  2. Nástroj pre generovanie textových výstupov
  3. Zdrojové kódy
    • generator1.zip - kostra kódu pre generovanie SQL skriptu databázy
    • generator2.zip - kostra kódu pre generovanie prostredníctvom šablón
Doplňujúce úlohy
    Úloha: Implementujte do šablóny entity_class.java.vm generovanie metódy String toString(), ktorá vytvorí reťazec s názvami a hodnotami všetkých vlastností.
    UkončenáPoznámka


    Pošli
Doplňujúce zdroje
  1. Natívna podpora prostredia NetBeans pre databázy Java DB (Derby)
  2. Prídavné moduly pre farebné zvýrazňovanie syntaxe velocity súborov pre jednotlivé vývojové prostredia:
comments powered by Disqus