| Hrvatski       | English    
QED 2010
Q.E.D. 2010
IBM beacon Awards finalist
Follow us on twitter
knjigalica.com

Jedan od projekata na kojima sudjeluje CROZ posvećen je izradi aplikacije s bogatim klijentom (Rich Client Application). Kao platforma za izradu klijentske strane odabran je Eclipse Rich Client Platform (Eclipse RCP) čija je ključna karakteristika da omogućuje XML-ovsku konfiguraciju korisničkog sučelja. Platforma automatski upravlja različitim vizualnim elementima kao što su izbornici, vrpce s alatima, okviri za pregled (View) ili uređivanje (Editor) itd. Korisnik platforme (tj. razvijatelj aplikacije) mora se brinuti samo o ključnom poslu koji obavlja neki element – npr. o akciji koju treba obaviti na odabir stavke u izborniku ili o sadržaju okvira za pregled. O svemu ostalome brine se platforma – npr. za okvir, njegovo pozicioniranje i veličina, otvaranje/zatvaranje, minimiziranje/maksimiziranje, docking, stacking itd. Razvoj je time znatno ubrzan, a i puno je lakše održavati konzistentan izgled aplikacije. U XML-ovskoj konfiguraciji korisničkog sučelja tipično se navodi ime klase koja brine o pojedinom vizualnom elementu. Tipičan izgled konfiguracijskog elementa:

<extension point="org.eclipse.ui.views">
  <view id="net.croz.coolView" class="net.croz.CoolView" position="left"/>
</extension>

Osnovni način rada jest da platforma upravlja instanciranjem tih klasa i konfiguriranjem instanci pa korisnik putem XML-ovske konfiguracije ima utjecaj samo na one aspekte klase koji proizlaze iz njezine uloge kao vizualnog elementa kojim barata Eclipse RCP. Na primjer, tipično je da će klasa za pregledni okvir imati ovisnosti o nekim izvorima podataka koje treba vizualizirati. Za sve takve stvari autor klase prepušten je vlastitim rješenjima. S druge strane, CROZ već ima tradiciju korištenja Springovog IoC-a za konfiguraciju objekata, tako da se prirodno nametnula potreba za rješenjem koje će omogućiti da se upravljanje instanciranjem i konfiguracijom objekata preseli s Eclipse RCP-a na Springov IoC kontejner. Na svu sreću, Eclipse RCP barata koncepcijom Factory Object – ako je u XML-u navedeno ime klase koja implementira odgovarajuće Factory sučelje, RCP će instancirati tu klasu i zatim toj instanci prepustiti kreiranje konačnog objekta koji upravlja vizualnim elementom.

Još jedna značajna karakteristika platforme Eclipse RCP jest da omogućuje modularnost aplikacije iznad razine koju nudi sam jezik Java. Ustvari, upravo ta modularnost bila je glavna motivacija za uvođenje XML-ovske konfiguracije. Osnovni pristup je sljedeći: sam RCP sastoji se od skupa modula (Eclipseov termin za „modul“ je „plugin“ pa ćemo ga nadalje koristiti) od kojih je npr. jedan posvećen upravljanju vizualnim elementima. On deklarira točke proširenja ( extension point) za svaku vrstu elementa, npr. točka views za pregledne okvire. Plugin koji razvija korisnik platforme definira svoje proširenje za tu točku time što u XML-ovskoj konfiguraciji navede ime svoje klase i druge parametre koji se tiču prikaza okvira. Samim dodavanjem svojeg plugina skupu pluginova koji sačinjavaju aplikaciju postižemo da on aplikaciji doprinese svoje vizualne elemente, bez pisanja upravljačkog koda u Javi.

Zahtjev za modularnošću aplikacije odražava se i na Springovu konfiguraciju. Jasno je da se ne može centralizirano izgraditi cijeli aplikacijski kontekst jer bi to značilo da neki „glavni“ plugin unaprijed mora znati za sve ostale plugine i konfigurirati njihove objekte. Dakle, svaki plugin mora imati svoj vlastiti kontekst, a poželjno je i da se taj kontekst može nadovezati na neki zajednički, globalno definiran kontekst koji sadrži objekte od šireg značenja za cijelu aplikaciju.

Na Webu smo pronašli open-source projekt [1] (zvat ćemo ga ESpring) koji omogućuje rješavanje ovih pitanja na prilično elegantan način. Dotični projekt ostao je u prilično rudimentarnom stanju i više predstavlja proof-of-concept nego konačan proizvod, tako da smo ga u priličnoj mjeri doradili i debagirali, ali ključne ideje su ostale.

Projekt se sastoji od jednog plugina koji deklarira svoju točku proširenja. Aplikacijski pluginovi vežu svoja proširenja na tu točku tako da doprinesu svoj aplikacijski kontekst centralnom registru kontekstâ. Kontekst se u registar upisuje pod ID-jem definiranim u proširenju. Pri izgradnji svojeg aplikacijskog konteksta plugin može od ESpringa po ID-ju zatražiti proizvoljan drugi aplikacijski kontekst da ga iskoristi kao svojeg roditelja. Primjer definicije proširenja za ESpring:

<extension point="net.croz.espring.appContextContributors">
 <appContextContributor id="coolPluginContext" parent="rootContext"
    class="net.croz.coolplugin.ApplicationContextContributor"/>
</extension>

Svi registrirani konteksti dostupni su na svakom mjestu u Eclipseovoj konfiguracijskoj datoteci plugin.xml, gdje se uobičajeno navodi ime klase vizualnog elementa. Umjesto imena klase objekta koji želimo, navedemo ime posebne klase iz plugina ESpring koja implementira Factory sučelje i koja će platformi dostaviti objekt konfiguriran u aplikacijskom kontekstu:

<extension point="org.eclipse.ui.views">
 <view id="net.croz.coolView" 
   class="net.croz.espring.GetBean:coolPluginContext/coolView"
   position="left"/>
</extension>

Ovdje ulazi u igru još jedna važna mogućnost Eclipse RCP-a bez koje ovaj pristup ne bi mogao zaživjeti: nakon imena Factory-klase možemo nadovezati dvotočku i iza nje string koji će biti proslijeđen instanci te klase. Na taj način možemo prenijeti ključne podatke potrebne Factoryju da locira odgovarajući aplikacijski kontekst i objekt unutar njega.

Pažljivom analizom arhitekture opisanog rješenja moglo bi se prigovoriti da je kreiranje aplikacijskog konteksta nepotrebno zakomplicirano: nije dovoljno navesti samo lokaciju konfiguracijske datoteke, već je potrebno kreirati klasu ApplicationContextContributor koja sama obavlja kreiranje aplikacijskog konteksta. Razlog ovome jest ranije natuknuta modularnost RCP-ovih pluginova „iznad razine koju nudi sam jezik Java“: naime, jedan plugin vidi samo one klase drugog plugina koje je on eksplicitno deklarirao „javnim“. Stoga je nužno da kreiranje aplikacijskog konteksta odradi klasa u klijentskom pluginu.

[1] Neil Bartlett, projekt „Eclipse RCP Spring Support“, http://sourceforge.net/projects/eclipse-spring