netbeans platform jako ejb klient - muni
TRANSCRIPT
Masarykova univerzita
Fakulta informatiky
NetBeans Platform jako EJB klient
diplomová práce
František Holas
ii
Brno, jaro 2009
i
Prohlášení
Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval
samostatně. Všechny zdroje, které jsem při vypracování používal, nebo z nich čerpal, v práci
řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Vedoucí práce: Ing. Petr Adámek
ii
Poděkování
Rád bych poděkoval Ing. Petrovi Adámkovi za jeho vstřícný přístup, cenné rady a připomínky.
Dále všem dotyčným zaměstnancům firmy OXO, kteří mi svými radami a připomínkami
pomáhali specifikovat a optimalizovat požadavky na ukázkovou aplikaci a její rozšíření. Také
bych chtěl poděkovat svojí rodině a především partnerce, která mi byla velikou oporou a
inspirací v době tvorby této práce.
iii
Shrnutí
Tato diplomová práce se zabývá studiem tvorby vícevrstvých aplikací postavených na
architektuře Java Enterprise Edition. Seznámili jsme se s aplikační vrstvou implementovanou
pomocí Enterprise JavaBeans 3.0 a RCP (Rich Client Platform) NetBeans Platform jako
klientskou vrstvu. Pro komunikaci mezi aplikační a klientskou vrstvou aplikace je použit
rámec pro tvorbu propojení aplikační a klientské vrstvy pana Lukáše Krejčího v rámci jeho
bakalářské práce, rovněž z období jaro 2009. Tyto poznatky byly využity při tvorbě ukázkové
aplikace a ve spolupráci s firmou OXO jsme vytvořili aplikaci pro tvorbu zakázek nazvanou
Contractz Platform 2009, která je postavena na těchto principech a technologiích. Koncept
této diplomové práce jsem se snažil zvolit tak, aby každý čtenář neznalý těchto principů a
technologií nabyl postupných vědomostí a zkušeností, které jsem při psaní této diplomové
práce získal. Práce je psána s praktickými ukázkami a postupy, což je velmi užitečné v době,
kdy ještě není k dispozici dostatek dokumentace a publikovaných praktických zkušeností.
Čtenář se tak v závěru práce může rozhodnout, zda jsou popisované postupy a technologie
vhodné pro jeho aplikaci a jak je použít.
iv
Klíčová slova
Rich Client Platform, NetBeans IDE, NetBeans Platform, Enterprise JavaBeans, Java Enterprise
Edition, JasperReports, SwingX, GlassFish V2, API
1
Obsah
Kapitola 1: Úvod .................................................................................................................................. 4
Kapitola 2: Architektura Java EE .......................................................................................................... 5
2.1 Java EE platforma ....................................................................................................................... 5
2.2 Java EE aplikační servery ............................................................................................................ 9
Kapitola 3: Enterprise JavaBeans 3.0 ................................................................................................10
3.1 Entita ........................................................................................................................................11
3.2 Session Bean ............................................................................................................................13
3.3 Message–Driven Bean ..............................................................................................................15
3.4 Volání EJB komponent .............................................................................................................16
Kapitola 4: NetBeans Platform ...........................................................................................................18
4.1 Modulární architektura ............................................................................................................18
4.2 Runtime container ...................................................................................................................21
4.3 Další významná API ..................................................................................................................22
4.4 Výhody NetBeans Platform ......................................................................................................23
4.5 První kroky s NetBeans Platform ..............................................................................................23
Kapitola 5: Tisk v Javě ........................................................................................................................24
5.1 K čemu je to dobré ...................................................................................................................24
5.2 Tvorba výstupu .........................................................................................................................25
5.3 Knihovny ...................................................................................................................................25
5.4 iReport ......................................................................................................................................26
5.5 Práce s JasperReports API ........................................................................................................28
5.5.1 Kompilace a naplnění ........................................................................................................28
5.5.2 Výstup na tiskárnu.............................................................................................................29
5.5.3 Výstup do souboru ............................................................................................................29
5.5.4 Praktická ukázka ................................................................................................................30
5.6 Závěrem ...................................................................................................................................31
Kapitola 6: NetBeans Platform jako EJB klient ..................................................................................32
6.1 Úvodní verze ............................................................................................................................32
2
6.2 Vývojová verze .........................................................................................................................34
6.3 Konečná verze ..........................................................................................................................35
6.3.1 Ukázka souboru layer.xml .................................................................................................37
6.3.2 Ukázka připojení ke kontextu ...........................................................................................37
6.4 Závěrem ...................................................................................................................................38
Kapitola 7: Ukázková aplikace ...........................................................................................................39
7.1 Současný stav ...........................................................................................................................39
7.2 Navrhované řešení ...................................................................................................................40
7.3 Contractz Platform 2009 ..........................................................................................................40
Kapitola 8: Aplikační vrstva ...............................................................................................................42
8.1 Cenová nabídka (Bid) ...............................................................................................................44
8.2 Dodací List (DeliveryNote) ........................................................................................................45
8.3 Faktura (Bill) .............................................................................................................................45
8.4 Příjmový pokladní doklad (Receipt) .........................................................................................45
8.5 Výdajový pokladní doklad (Disbursement) ...............................................................................45
8.6 Reklamace (Reclamation) ........................................................................................................46
8.7 Skladová karta (DefinedItem) ...................................................................................................46
8.8 Klient (Client) ............................................................................................................................46
8.9 Projekt (Project) .......................................................................................................................46
8.10 Další vlastnosti aplikační vrstvy ..............................................................................................47
8.10 .1 Generování ID entitních tříd ...........................................................................................47
8.10.2 Výčtové typy ....................................................................................................................47
8.10.3 Prefix dokumentů ............................................................................................................48
Kapitola 9: Klienstká vrstva ...............................................................................................................49
9.1 Modul Core ...............................................................................................................................50
9.2 Modul DataOutput ...................................................................................................................51
9.3 Modul Nodes ............................................................................................................................53
9.4 Modul TopComponents ...........................................................................................................55
9.4.1 Cenová nabídka (BidTopComponent) ................................................................................56
9.4.2 Dodací list (DeliveryNoteTopComponent) .........................................................................57
9.4.3 Faktura (BillTopComponent) .............................................................................................58
3
9.4.4 Příjmový pokladní doklad (ReceiptTopComponent) ..........................................................60
9.4.5 Výdajový pokladní doklad (DisbursementTopComponent) ...............................................61
9.4.6 Reklamace (ReclamationTopComponent) .........................................................................62
9.4.7 Skladová karta (ItemTopComponent) ...............................................................................63
9.4.8 Klient (ClientTopComponent) ............................................................................................64
9.4.9 Projekt (ProjectTopComponent) ........................................................................................65
9.4.10 Procházení vizuálních dat (ExplorerTopComponent, BrowserTopComponent) ..............66
Kapitola 10: Závěr ..............................................................................................................................68
Literatura ............................................................................................................................................69
Dodatek A ...........................................................................................................................................71
4
Kapitola 1 Úvod
Obecně lze říct, že neznalost vhodných technologií brání programátorům psát snadno
rozšiřitelné a dobře udržovatelné aplikace. Často se setkáváme s lidmi, kteří pracují ve
firmách, kde nepracují s dost pokročilými technologiemi, nebo neprosazují kulturu
pravidelného a systematického vzdělávání svých zaměstnanců. Používají tedy základní
technologie a podle toho také vypadá jejich zdrojový kód a efektivita práce s ním.
S programovacím jazykem Java jsem se seznámil až v době magisterského studia na
Masarykově Univerzitě v Brně, ale okamžitě jsem jej začal preferovat, protože velmi
jednoduchým, přehledným a promyšleným způsobem přináší to, o čem jsem si mohl nechat u
jiných programovacích jazyků, jako například rodina C/C++, jen zdát. Studium v navazujících
předmětech mi ukázalo další promyšlená API1 a já jsem tím pochopil, že jejich vhodnou
kombinací lze ušetřit mnoho času a finančních prostředků. Studium dalších technologií
v rámci této diplomové práce jsem uvítal, protože tyto technologie se mi jeví jako velmi
perspektivní a jejich kombinace je dle mého názoru přínosná.
Pochopil jsem výhody pokročilých řešení, ve kterých je aplikace vhodným způsobem
rozdělena do několika částí, kdy program již nepředstavuje jen tzv. špagetový kód. Ten se
špatně udržuje a ještě pracněji rozšiřuje. Ukazuje to nutnost místo aplikace, která v jednom
kódu spravuje celý cyklus programu a správu všech technologií, programovat aplikace, kde
logiku jednotlivých technologií rozdělíme do vrstev.
Není s podivem, že řešením může být Java EE2 architektura, která je určena pro
rozsáhlé podnikové aplikace, u nichž je vývoj rozdělitelný do vrstev naprosto zásadní.
Podrobnějším studiem Java EE architektury a implementací jednotlivým vrstev se zabývají
následující kapitoly. Tuto myšlenku ještě více rozvineme, protože potřebujeme do vícevrstvé
aplikace zakomponovat jako klientskou vrstvu NetBeans Platform, RCP3 vyvinuté pro
jednovrstvé aplikace. Propojení NetBeans Platform se zbytkem architektury ukázkové
aplikace bude využívat aplikační rámec pana Lukáše Krejčího, který se touto problematikou
zabývá.
Dále předvedeme šikovná API pro tisk sestav a export do známých typů souborů v Javě
a popsané technologie si vyzkoušíme na ukázkové aplikaci. Ta nám mimo jiné prokáže
vhodnost resp. nevhodnost koncepce bakalářské práce pana Lukáše Krejčího a především
vhodnost vícevrstvých aplikací jako takových.
1 API = Application Programming Interface, což znamená rozhraní pro programování aplikací. 2 Java EE = Java Enterprise Edition 3 RCP = Rich Client Platform
5
Kapitola 2 Architektura Java EE
Java Enterprise Edition architektura používá vícevrstvý distribuovaný aplikační model, což
přináší rozdělení systému do několika vrstev nezávislých na sobě.
Obrázek 1: Aplikace rozdělená do vrstev
Tyto vrstvy spolu komunikují přes Java EE API, které definuje rozhraní mezi vrstvami
a komunikaci mezi nimi. Tyto rozhraní jsou standardizované, což přináší řadu výhod.
Umožňuje nám to vyměnit implementaci konkrétní použité technologie, aniž bychom museli
měnit kód v našem programu.
Výhodou pro programátora je snazší programování aplikace, kdy se stará jen o
konkrétní problém ve své aplikaci, zatímco volba konkrétní technologie na libovolné vrstvě je
ošetřena jinde. Je tedy kladen důraz na rozšiřitelnost a udržovatelnost aplikace za
jednoduchých principů programování.
2.1 Java EE platforma
Platforma Java EE byla vytvořena s cílem poskytnout jednoduchý standard při vytváření
rozsáhlých aplikací a podpořit rozsáhlou škálu požadavků při jejich vytváření v souladu s Java
EE architekturou. Je přitom založena na vícevrstvém distribuovaném aplikačním modelu.
Obrovskou výhodou vícevrstvého modelu je možnost využívat nezávislých serverů při
6
poskytování služeb jednotlivých vrstev, ale tyto služby mohou také běžet všechny na jednom
serveru.
Java EE architektura definuje tyto vrstvy:
Klientská vrstva (front-end tier) – podporuje
mnoho různých typů klientských aplikací.
Střední vrstva (middle tier) – poskytuje podporu
klientské vrstvě prostřednictvím Web
kontejnerů nebo např. aplikační logiku pomocí
EJB (Enterprise Java Beans).
Back-end vrstva (back-end tier) – umožňuje
přístup k existujícím informačním systémům a
zdrojům dat (databáze, ERP, …).
Obrázek 2: Interakce vrstev
Java EE aplikace může být složena z různých komponent zajišťujících různou roli:
Klientské komponenty – zpravidla se jedná o
programy programované v jazyce Java, běžící na
klientském počítači uživatele (GUI). Navenek
mají stejnou funkcionalitu jako jiné aplikace,
ovšem umožňují přístup ke střední vrstvě Java
EE aplikace.
7
Webové komponenty – běží na straně serveru a
generují výstup dle požadavků klienta. Jedná se
např. o servlety a JSP stránky.
Business komponenty – zajišťují business logiku
aplikace a práci s daty.
Základní aplikační komponenty:
Servlety – objekt generující HTTP4 odpovědi na
základě HTTP požadavků.
JSP (Java Server Pages) - generování
dynamických dokumentů pro webový prohlížeč.
Do HTML jsou vkládány prvky kódu servetů (JSP
elementy).
JSF (Java Server Faces) – rámec pro
implementaci uživatelského webového rozhraní.
EJB (Enterprise Java Beans) – viz kapitola 3.
JDBC (Java Database Connectivity API) –
aplikační API pro provádění SQL dotazů a
příkazů.
JAX-WS (Java API for XML Web Services) –
podpora webových služeb pomocí JAXB API
mapující XML data na Java objekty.
JPA (Java Persistence API) – provádí ORM
mapování Java objektů. Poskytuje API pro
perzistenci objektů, dotazovací jazyk a potřebná
metadata.
Další (Java Transaction API, Java Message
Service API, JavaMail API, Java Naming and
Directory Interface, Java Authentication and
Authorization Service, …).
Komponentě přitom zajišťují běhovou podporu kontejnery. Kontejner zajišťuje úplné
aplikační prostředí po celý životní cyklus komponenty a poskytuje jí různé služby:
Rozhraní mezi komponentou a platformově
závislým prostředím.
Komponenta je nasazena v kontejneru.
Kontejnery zajišťují komponentám různé služby.
4 HTTP – HyperText Transfer Protocol je internetový protokol pro přenos informací.
8
Typy kontejnerů:
kontejner klientské aplikace;
webový kontejner;
EJB kontejner.
Kontejnery zajišťují:
bezpečnost;
dostupnost;
perzistenci;
rozšiřitelnost;
řízení životního cyklu;
synchronizace;
transakce.
Obrázek 3: Komponenty v kontejneru
Základem Java EE je Java SE (Java Platform, Standard Edition), která poskytuje
komponentám a kontejnerům základní funkční API.
9
2.2 Java EE aplikační servery
Běhovým prostředím pro každou Java EE aplikaci jsou tzv. aplikační servery. Naše aplikace by
měla být teoreticky schopna běžet pod jakýmkoliv aplikačním serverem, který implementuje
příslušnou verzi specifikace. Prakticky každý aplikační server však poskytuje také služby nad
rámec specifikace a aplikace využívající těchto služeb nejsou dále přenositelné.
Aby aplikace mohla být prohlášena za Java EE kompatibilní, je nutno provést
certifikaci u Sun Microsystems Inc. Protože jsou zde i různé politické tlaky, vyskytují se i
servery bez označení kompatibility, které ovšem danou specifikaci splňují.
Open Source Java EE aplikační servery:
Apache Tomcat (částečná implementace);
GlassFish;
JBoss.
Komerční Java EE aplikační servery:
IBM WebSphere;
BEA WebLogic;
Sun Java Systém Application Server;
Oracle AS.
10
Kapitola 3 Enterprise Java Beans 3.0
Enterprise JavaBeans (EJB) je komponentová architektura, sloužící jako aplikační vrstva Java
EE aplikace. EJB komponenty, tvořící vlastní aplikační logiku, implementuje vývojář. Aplikace
napsané pomocí EJB jsou škálovatelné, umožňují transakce a jsou zabezpečeny ve
víceuživatelském prostředí. Většina služeb je řízena kontejnerem a jejich nastavení probíhá
deklarativním způsobem. Mezi nejdůležitější vlastnosti EJB patří interoperabilita nejen mezi
jednotlivými kontejnery a aplikačními servery, ale i s jinými aplikacemi prostřednictvím
protokolu RMI-IIOP.
Obrázek 4: Interakce EJB s okolím
EJB komponenty ke své činnosti vyžadují kontejner, který:
Řídí její životní cyklus.
Zajišťuje autentizaci a autorizaci (JAAS).
Umožňuje distribuci komponent (RMI-IIOP).
Řídí transakce (JTA).
Může zajišťovat perzistenci (JPA).
Poskytuje přístup ke zdrojům a dalším službám.
Nastavení atributů používaných služeb je odděleno od vlastního kódu a řeší se
deklarativním způsobem, v EJB 3.0 nasazením tzv. anotací.
11
Aplikace připravené k používání jsou zabaleny do JAR archivu a nasazeny do
kontejneru aplikačního serveru. Stejná aplikační logika tedy může běžet na více různých
aplikačních serverech. Tyto aplikační servery musí rovněž vyhovovat specifikačním
standardům EJB. Standardizace v této oblasti nám přináší řadu dalších výhod:
Distribuce a vypuštění aplikace jsou
zjednodušeny.
Klíčové vlastnosti mohou být poskytovány
přímo aplikačním serverem.
Interoperabilita, jak mezi komponentami a
aplikačními servery, tak mezi cizorodými
systémy, prostřednictvím RMI-IIOP nebo JMS.
V našem případě využíváme verzi 3.0, která oproti předchozí verzi 2.1 přináší mnohá
zjednodušení, vylepšení a tím i pohodlnější práci. Jedná se zejména o nahrazení entit Entity
EJB ke klasickým POJO entitám a nahrazením dependency injection tzv. anotacemi.
EJB komponenty můžeme vzhledem k jejich variabilitě rozdělit do několika skupin:
entity;
session bean;
message–driven bean.
Cílem použití EJB je přenechat veškerou aplikační logiku na EJB, zatímco klientská
vrstva, která aplikační logiku využívá, se bude starat například o GUI vzhledem ke koncovému
uživateli a s EJB komunikovat přes komponenty typu session bean a message–driven bean.
3.1 Entita
Entity představují objekty, instance příslušných tříd, které jsou pomocí ORM5 mapovány do
úložiště dat, typicky databáze. Entity lze považovat za základ celé aplikační logiky. Například
objekty Lednice a Mikrovlnka jsou instancemi, entitami, entitní třídy Product. Pokud bychom
se podívali do databáze, hledali bychom tabulku Product (není-li pomocí anotací tabulka
explicitně pojmenována jinak) a v ní dva řádky představující jednotlivé instance. Tyto instance
jsou v podstatě serializovány6 místo na disk do databáze. V případě EJB 3.0, které je zároveň
5 ORM = Object Relational Mapping = mapování objektů na položky relační databáze. 6 Serializace = Speciální druh anotace, která říká, že objekt může být transformován na proud symbolů, které reprezentují vnitřní strukturu nějakých informací tak, aby přečtením proudu bylo možno vnitřní strukturu zpětně zrekonstruovat.
12
implementací JPA (Java Persistence API), s entitami pracujeme jako s POJO7 objekty. Pomocí
anotací píšeme do entit speciální metadata, která jsou dostupná pro programátora i pro EJB
kontejner za běhu aplikace.
Každá třída musí splňovat následující:
Být serializovatelná, tedy implementovat
příslušné rozhraní, typicky je to
java.io.serializable.
Mít bezparametrický konstruktor.
Atributy mít přístupné pomocí get a set metod.
Přístup ke sdíleným souborům musí podporovat
souběžnost.
Nastavení atributů používaných služeb je odděleno od vlastního kódu a řeší se
deklarativním způsobem, v EJB 3.0 nasazením tzv. anotací.
Příklad:
@Entity
public class Product implements Serializable {
@Id
private Long rc;
private String name;
public Product() {
rc = (int) System.nanoTime();
surname = “Lednice”;
}
… get a set metody pro proměnné
}
Jak vidíme, i tato velmi jednoduchá ukázka třídy Product obsahuje dvě anotace.
První anotace @Entity označuje, že se jedná o entitní třídu, druhá s označením @Id zase
7 POJO = Plain Old Java Object. Objekt, jehož třída musí obsahovat bezparametrický konstruktor a pro každý atribut musí obsahovat get/set metody, které vrací/vkládají údaje z/do atributů.
13
říká, že proměnná pod touto anotací bude brána jako jedinečný identifikátor v databázové
tabulce. Anotací je samozřejmě mnohem více, pro podrobnosti doporučujeme prostudovat
dokumentaci EJB.
Kromě primitivních datových typů může entita obsahovat i uživatelsky definované
typy objektů, jejich kolekce apod. Tyto typy mohou být doprovázeny dalšími anotacemi, které
říkají EJB, jak mají s danou entitou zacházet, například při tvorbě tabulky relační databáze.
Výhoda entit spočívá především v tom, že s nimi můžeme manipulovat přímo jako
s objekty, aniž bychom museli data manuálně posílat a vyhledávat v databázi. Pro ty, kdo ví,
jak pracné je starat se o tuto činnost manuálně, to jistě představuje výrazné usnadnění.
3.2 Session Bean
Session Bean představuje aplikační logiku. Právě zde jsou implementovány algoritmy pro
práci s entitami, například zpracovávají objednávky, nebo počítají platby. Slouží pro
zpracování požadavků, které na ně klient vznese. Na rozdíl od jiných komponent, session
beany mají poměrně krátký životní cyklus. Ten začíná, jakmile si na něj klient vytvoří
referenci a končí, když tato reference pozbude platnosti. Není zde žádná garance, že příště
dostaneme k dispozici stejnou instanci session bean. Ta může trvat, dokud budeme mít ve
webovém prohlížeči otevřené příslušné okno, než zavřeme okno v klientské aplikaci, nebo než
bude jiný bean používat náš bean.
To představuje rozdíl vzhledem k entitám, které jsou trvale uloženy v databázi. U
komponent typu session bean se tohle neděje. Není třeba mít je někde trvale uloženy. Přesto
ale session beany dělíme na tyto kategorie:
@Stateful – udržuje stavové informace své
instance napříč jednotlivými voláními. Například
vnitřní proměnná má hodnotu, která je
uchována při každé manipulaci s ní. V dané
chvíli s ní nemůže pracovat nikdo jiný. Zabírají
v paměti určité místo, je jich k dispozici méně,
nejsou tedy vhodné pro velké zátěže. Nelze je
použít například ve webových prohlížečích.
@Stateless – naopak neudržuje stavové
informace napříč jednotlivými voláními. Může je
tedy volat více různých tazatelů, a protože jsou
méně náročné na paměť, může jich být více.
14
Session beany představují synchronní variantu komunikace. Na dotaz dostaneme
odpověď. Nevoláme je však přímo, nýbrž pomocí vybraných rozhraní. Tyto rozhraní dělíme do
dvou druhů:
@Local – tuto anotaci použijeme, pokud víme, že
klient bude pracovat ve stejné JVM8, jako naše
EJB. Je to ovšem rychlejší varianta, protože dané
vrstvy spolu komunikují přímo v rámci jedné
JVM.
@Remote – tuto anotaci naopak použijeme
v situaci, kdy víme, že budeme pracovat
v distribuovaném prostředí, tedy že klient bude
pracovat pod jinou JVM, než EJB. Je to ovšem
pomalejší varianta daná tím, že tyto JVM jsou
různé a je zde potřeba komunikace. Této
varianty můžeme využít, i pokud bude klient
nasazen ve stejné JVM jako EJB, ovšem za cenu
menší rychlosti.
Příklad:
@Stateless
public class ProductBean implements ProductRemote {
@PersistenceContext
private EntityManager em;
public void addProduct(Product product) {
em.persist(product);
}
}
@Remote
public interface ProductRemote {
public void addProduct(Product product);
}
8 Java Virtual Machine. Virtuální stroj, pod kterým běží aplikační server.
15
3.3 Message–Driven Bean
Tato komponenta používá asynchronní formu komunikace. My jí posíláme data do fronty, a
jakmile přijdou data na řadu, jsou zpracována. Je to vhodné například pro systémy, kde je
očekávána velká zátěž a jen za té podmínky, kdy nepotřebujeme nějakou odpověď od serveru.
Používáme ji například při zasílání nových dat do databáze. Je při tom využívána technologie
JMS9, kdy jsou data posílána ve formě zprávy. Vytvoříme tedy příslušnou zprávu, odešleme jí
serveru a ten ji zařadí do fronty. Jakmile přijde na řadu dotyčný záznam fronty, předá ji
komponentě typu Message–Driven Bean a ten ji zpracuje.
Příklad:
@MessageDriven(mappedName="jms/Queue")
public class SimpleMessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdc;
public void onMessage(Message inMessage) {
TextMessage msg = null;
try {
if (inMessage instanceof TextMessage) {
msg = (TextMessage) inMessage;
logger.info("MESSAGE BEAN: Message received: "
+ msg.getText());
} else {
logger.warning("Message wrong type: "
+inMessage.getClass().getName());
}
} catch (JMSException e) {
e.printStackTrace();
mdc.setRollbackOnly();
} catch (Throwable te) {
te.printStackTrace();
}
}
}
9 JMS = Java Messaging Service. Služba pro posílání zpráv.
16
3.4 Volání EJB komponent
Ukázali jsme si typické, i když velmi zjednodušené, ukázky komponent v rámci EJB a práci s
nimi. Nicméně tyto komponenty fungují v rámci EJB a my s nimi musíme nějakým způsobem
komunikovat
Pokud používáme aplikačního klienta jako součást Java EE aplikace, můžeme
příslušnou komponentu typu Session Bean volat například takto:
public class Test {
@EJB
private static ProductRemote pr;
public void Test() {
Product product = new Product();
pr.addProduct(product);
}
Jestliže máme samostatný EJB modul a samostatného aplikačního klienta, příslušnou
komponentu typu Session Bean voláme například takto:
public class Test {
private static InitialContext ctx;
private static ProductRemote pr;
public void Test() throws NamingException {
ctx = new InitialContext();
pr = (ProductRemote) ctx.lookup
(ProductRemote.class.getName());
Product product = new Product();
pr.addProduct(product);
}
17
Protože vytváření instancí rozhraní a vytváření kontextu je časově velmi náročný
proces, doporučuje se např. vytvořit speciální třídu, která bude tyto instance spravovat.
Třídám, které tyto instance potřebují, budou přes tuto třídu poskytnuty. Rovněž se tak
zpřehlední zdrojový kód aplikace.
V této podkapitole byl nastíněn pouze velice jednoduchý názorný příklad, jak s EJB
pracovat, nicméně pro prozkoumání možností používání všech výhod, které EJB poskytují,
doporučujeme prozkoumat dodatečné informace, například (4). Tato kniha je velmi dobře a
snadno uchopitelně napsána, takže je možné rychle si osvojit potřebné znalosti. Jsou zde
publikovány základní i pokročilé možnosti např. pro tvorbu inheritance entit, transakční
zpracování, používání webových služeb apod. K většině témat jsou zde publikovány příklady
zdrojového kódu.
18
Kapitola 4 NetBeans Platform
Když se řekne slovní spojení NetBeans Platform, mnozí si jistě řeknou, proč používat další
framework10, když už známe například Swing11 framework. NetBeans Platform nabízí nejen
ucelenou sadu komponent a podpůrných tříd, nýbrž propracovanou modulární architekturu
s konkrétními promyšlenými API, které výrazně urychlí vývoj a správu programů. Křivka
učení není tak strmá, ale jakmile pochopíme základní souvislosti, dostaneme do rukou velmi
mocný nástroj. Množství dokumentace zatím není tak velké, ale postupně se rozšiřuje,
především díky rozšiřujícímu se portfoliu programátorů, kteří si výhody tohoto frameworku
uvědomují. K dispozici jsou například základní tutoriály na oficiálních stránkách NetBeans
Platform. Výborná je také výrobcem doporučená kniha, viz (5).
4.1 Modulární architektura
Jedná se o jeden z nejdůležitějších aspektů programování s NetBeans Platform. Základní
problém dodnes vyvíjených aplikací je tzv. špagetový kód. Toho programátor obvykle dosáhne
postupným rozšiřováním jednoho velkého programu, který se postupným rozšiřováním a
upravováním stává více a více nepřehledným, i když se snažíme program co nejvíce
organizovat, například tříděním do hierarchie balíků. To je ovšem ten lepší případ. Horší
situace nastane, pokud dostane program k přepracování jiný programátor. Ukázkový případ
velkých problémů ale nastane, jakmile je například požadováno část programu vyřešit jiným
způsobem, i když třeba pouze pro tento jeden případ.
Řešením problému může být modularizace, tedy rozdělení programu do modulů, které
spolu budou vhodným způsobem propojeny. Jedná se o velmi důležitou, stěžejní část
pochopení architektury NetBeans Platform, která začátečníkům obvykle chvíli potrvá.
Zkušenosti však ukazují, že každý program může být dekomponován do systému modulů.
Výhody modulárního systému jsou mnohé:
Program je sestaven z nezávislých modulů.
Moduly mohou být vyvíjeny nezávislými týmy
po celém světě.
10 Framework = softwarová architektura, která slouží jako podpora pro programování při vývoji jiných softwarových projektů. 11 Swing = framework pro zjednodušení tvorby GUI aplikací.
19
Pro každého zákazníka lze sestavit program
z jiných modulů.
Modul může být nahrazen jiným ekvivalentem.
NetBeans Platform posunuje modulární architekturu trošku výše. Aktivně se stará o
načítání modulů za běhu programu (pokud jsou takto nastaveny), a vynucuje jejich
deklarovanou minimalistickou verzi. Moduly spojené do výsledné aplikace jsou propojeny
vhodným způsobem:
Modul A závisí na modulu B, pokud má modul B
zveřejněné vybrané balíky12.
Modul A a modul B mohou být nezávislé. K tomu,
aby se modul B dozvěděl o tom, že je potřeba
vykonat nějakou činnost, která probíhá na
modulu A, slouží Lookup API13.
Modul A slouží jako jádro aplikace, například
s definovanými rozhraními. Moduly B, C… jsou
závislé na modulu A, obsahují implementace
vybraných rozhraní modulu A, které jsou
v modulech B, C … zaregistrovány.
Žádné dva moduly nesmí být mezi sebou závislé.
Vzájemná závislost modulů je zakázána, protože se tím především přichází o výhody
používání modularity. Praxe ukazuje, že každá závislost může být dále dekomponována.
Výsledek dekompozice spočívá v tom, že modul A je závislý na modulu B, zatímco modul B
volá funkce modulu A přes Lookup API. Postup může být například tento:
Rozhodneme, který modul se na druhý modul
odvolává více. Řekněme, že modul A je více
závislý na modulu B, než modul B na modulu A.
Modul A tedy bude dále závislý na modulu B.
Modul A, na němž je modul B méně závislý,
vyextrahuje svoje potřebné rozhraní do nového
modulu C, nebo třeba do modulu s jádrem C, jak
jsme uváděli výše.
Třídy v modulu A, které implementují rozhraní
modulu C, zaregistrují v modulu A
12 Balík (angl. package) = logická složka obsahující podsložky nebo soubory, například třídy a rozhraní. 13 Lookup API je zodpovědný za komunikaci mezi moduly, které mezi sebou nemají nastavenou přímou závislost.
20
implementující třídy (vytvořením souboru
v balíku META-INF/services).
Modul B si nastaví závislost na modulu C s
rozhraními.
Volání v modulu B na třídy obsažené původně
v modulu A, budou nyní přístupné přes Lookup
API na rozhraní v modulu C.
Obrázek 5: Odstranění křížové závislosti mezi moduly A, B
Podrobná ukázka je k dispozici na oficiálních webových stránkách portálu NetBeans
Platform, v sekci tutoriály (12), seriál nazvaný WordApp Example.
Moduly ovšem představují také knihovny. Moduly dodané výrobcem představují
knihovny, kterých můžeme využívat ihned. Můžeme vytvářet i knihovny vlastní. Vytvoříme
speciální modul, tzv. Library wrapper. Ten potom obsahuje jednu či více knihoven, které
budeme potřebovat. Modul s kódem, který bude knihovny potřebovat, si na ně, podobně jako
na jiné moduly, nastaví závislost. Je to proto, aby každý modul používal jen ty knihovny, které
potřebuje a tím byl program méně rychlý a kompaktnější.
Cílem této podkapitoly bylo ukázat základní vlastnosti modulárního systému a fakt, že
každý program, i ten sebeprovázanější, lze dekomponovat na systém modulů.
21
4.2 Runtime container
NetBeans Runtime Container není nic jiného než název pro 5 modulů, které musí být u každé
aplikace, kterou programujeme:
Obrázek 6: Základní moduly
Bootstrap – umožňuje kontejneru pochopit co modul
je a jak jej načítat a skládat do výsledné aplikace.
Startup – poskytuje hlavní metody aplikace a kód
potřebný pro její start.
Filesystem API – poskytuje přístup nejen
k souborovému systému, ale je také nástrojem pro
správu abstraktních souborových systémů, které je
možno mapovat jako XML soubory. Můžeme také
deklarativně měnit viditelné vlastnosti programu,
jako uspořádání položek menu, ukládání vlastností,
apod.
Module System API – stará se o životní cyklus
modulů v aplikaci.
Utilities API – poskytuje soubor pomocných tříd,
například třídu Lookup pro komunikaci mezi
moduly.
22
Tyto moduly představují absolutní minimum, které je pro chod aplikace potřebný.
Další API z knihovny rozšiřují možnosti aplikace, proto doporučujeme prozkoumat, jaká API
platforma obsahuje.
4.3 Další významná API
Actions API – rozhraní pro přístup k běžným akcím
používaných v rámci NetBeans Platform. Povoluje
nám deklarovat kontextově závislé akce a menu. Je
to užitečné tam, kde již nestačí standardní Swing
Actions.
Dialogs API – nadstavba uživatelského rozhraní pro
tvorbu dialogů.
Explorer & Property Sheet API – Explorer API slouží
k vykreslování hierarchie uzlů, resp. některé její
podčásti a zajišťuje zobrazovací akce k nim
přidružené. Typ zobrazení je závislý na vybrané
komponentě (BeanTreeView, TableTreeView, …).
PropertySheet API slouží k zobrazování a editaci
vlastností uzlů. Obsahuje dva sloupce, v levém je
název atributu, v pravém příslušný propertyEditor
pro úpravu toho atributu.
Nodes API – slouží k zobrazování objektů do
hierarchie uzlů, ke kterým jsou dostupné akce a
vlastnosti, je tedy úzce svázána s Explorer & Property
Sheet API.
Settings API – rozhraní pro práci s nastavením a
vlastnostmi uživatelské aplikace.
Window Systém API – rozhraní pro zobrazování
vizuálních dat uživateli, nezávislé na konkrétním
operačním systému a služby s nimi spojené, např.
perzistenci pozice okna mezi jednotlivými sezeními
a manipulace s nimi.
Platforma obsahuje desítky dalších zajímavých a praktických modulů. Pro jejich
zobrazení doporučujeme nahlédnout do knihovny modulů ve vytvářené aplikaci.
23
4.4 Výhody NetBeans Platform
Moderní koncept vývoje programů pod touto platformou přináší i další výhody. Na platformě,
která vznikla především pro vlastní vývojové prostředí, existuje spousta vymožeností, které
můžeme ihned začít používat, aniž bychom museli něco podobného vyvíjet sami.
Můžeme využívat výhod pokročilých propracovaných API, používat moduly, které
napsal někdo jiný jako pluginy, které jednoduše přidáme do aplikace. Můžeme používat
možnosti Auto Update, kdy mohou být aktualizovány pouze vybrané moduly. Můžeme se tak,
jak je neustále připomínáno, soustředit na vlastní vývoj.
4.5 První kroky s NetBeans Platform
Naučit se programovat pod NetBeans Platform není tak snadné. Sám jsem před psaním této
diplomové práce neměl s NetBeans Platform žádné praktické zkušenosti. Navíc stále není k
dispozici dostatek materiálů pro samostudium.
Pro začátek doporučujeme podívat se na tutoriály na webových stránkách věnovaným
portálu NetBeans Platform (12), zejména CRUD14 Application Tutorial a Selection Management
Series. K dispozici jsou také videa v angličtině TOP 10 NetBeans API´s.
Bohužel, zatím zřejmě nejucelenější kniha věnující se této problematice, Rich Client
Programming: Plugging into NetBeans Platform (5), napsána přímo lidmi věnujícími se vývoji
NetBeans Platform a NetBeans IDE samotnému, není snadno pochopitelná pro úplné
začátečníky. Navíc většina kapitol není dost podrobná a užitečná jako výše zmíněné tutoriály.
Doporučujeme také navštívit blogy lidí, kteří se věnují vývoji platformy, kde jsou
řešeny mnohé problémy a také užitečné rady s praktickými ukázkami.
Za zmínku stojí také tzv. dvoudenní intenzivní školící kurz NetBeans Platform Certified
Training, pořádaný přímo firmou Sun. Aktuální seznam pořádaných kurzů s daty a místy je k
dispozici na webových stránkách, viz (1). Každý, kdo úspěšně projde kurzem, obdrží jeden ze
tří certifikátů dle výkonnosti, kterou během kurzu prokázal.
14 CRUD = Create Read Update Delete.
24
Kapitola 5 Tisk v Javě
Jedním ze základních problémů, kterým jsme čelili při návrhu ukázkové aplikace, byla vhodná
forma výstupu dat. Každý program zabývající se tématikou jako ukázková aplikace, potřebuje
minimálně tiskový výstup a optimálně také výstup do nějakého vhodného formátu, který by
mohl být případně dále upravován v nějakém externím programu, či například dále rozesílán
obchodním partnerům.
Programovací jazyk Java disponuje rozsáhlým spektrem knihoven pro nejrůznější
oblasti užití. Bohužel, nějakou zásadní vestavěnou podporu pro tisk v Javě bychom hledali
marně. Protože je ale tato oblast pro mnoho vyvíjených aplikací naprosto zásadní, byla
vytvořena ucelená knihovna funkcí s názvem JasperReports.
5.1 K čemu je to dobré
JasperReports je knihovna funkcí pro podporu tisku v Javě, která byla vyvinuta na portálu
JasperForge (2), open-source vývojové komunitě v rámci JasperSoft projektů. Díky velkému
počtu uživatelů i vývojářů postupně vzniká velice robustní nástroj, který se rychle vyvíjí a je
k dispozici zdarma v rámci LGPL15 licence. Tato sada knihoven pracuje s XML dokumenty.
Krom tisku využívá další knihovny, díky nimž umožňuje uložení výstupu do souboru ve
formátech PDF, ODT, RTF, XLS single-sheet, XLS multi-sheet, CSV, HTML či XML.
JasperReports jako celek se skládá z:
Knihovny funkcí JasperReports.
Nástroje pro tvorbu šablon iReport.
Podpůrných knihoven.
V době tvorby této diplomové práce byla k dispozici aktuální verze 3.5.0, která je
použita i v rámci řešení této práce.
15 LGPL = Lesser General Public License. Svobodná licence pro šíření softwaru. Určena k šíření dynamických sdílených knihoven.
25
5.2 Tvorba výstupu
JasperReports produkuje výstup podle vstupní šablony, která je tvořena souborem s příponou
.jrxml. Šablona obsahuje specifické elementy popisující, co bude kde umístěno a jaká data
mají být kam vložena. Tyto šablony můžeme generovat ručně, nebo je svěříme nástroji pro
tvorbu šablon zvaný iReport.
Dalším krokem je kompilace takto vytvořené šablony. Vznikne tak soubor s příponou
.jasper, který představuje serializovanou třídu, která vznikla ze vstupní šablony. Aplikace
následně použije vstupní šablonu, kterou naplníme parametry, datovou kolekcí a dále ji buď
vytiskneme, nebo uložíme v jednom z možných souborových formátů.
Obrázek 7: Ze šablony na výstup
Vřele doporučujeme ověřit si, zda pracujeme se stejnou verzí jak nástroje iReport, tak
celé knihovny JasperReports, protože v minulosti byla struktura šablony několikrát drobně
měněna a výsledná aplikace používající knihovnu ve spojení se šablonou by se mohla chovat
nedeterministicky.
5.3 Knihovny
Knihovna funkcí je k dispozici v aktuální verzi z webových stránek projektu JasperReports (2)
ve formě ZIP archivu. Ten po dekomprimaci pomocí vhodného programu obsahuje kompletní
projekt se zdrojovými soubory a všemi potřebnými knihovnami, se kterým je možno nadále
pracovat například v NetBeans IDE.
26
Celá distribuce zabírá diskový prostor přibližně 50MB, což je pochopitelně příliš
mnoho. Při využití všech zásadních vlastností naštěstí potřebujeme pouze zlomek knihoven,
která distribuce obsahuje:
commons-beanutils.jar
commons-collections.jar
commnos-digester.jar
commons-logging.jar
iText.jar
jdt-compiler.jar
poi.jar
V naší aplikaci používáme pro podporu tisku knihovní modul Jasper35Wrapper, který
obsahuje výše zmíněné podpůrné knihovny a také poslední sestavenou distribuci ze
staženého ZIP archivu.
5.4 iReport
Hned v úvodu stojí za zmínku zajímavost, že nástroj iReport je od léta 2008 plně integrován do
vývojového prostředí NetBeans Platform, což jen dokazuje popularitu výše zmíněné
platformy.
Jak již bylo řečeno, iReport je nástroj pro snadnou tvorbu šablon. Obsahuje editor se
stránkou rozdělenou do několika sekcí:
Title – titulek stránky. Zobrazuje se pouze na
první stránce.
Page Header – hlavička stránky. Zobrazuje se
v záhlaví každé stránky.
Column Header – hlavička sekce Detail.
Zobrazuje se před sekcí detail na každé stránce.
Detail – hlavní obsah stránky. Zobrazuje
opakující se údaje datového zdroje, který právě
generuje.
Column Footer – patička sekce Detail. Zobrazuje
se po sekci detail na každé stránce.
Page Footer – patička stránky. Zobrazuje se
v zápatí každé stránky.
27
Summary – sekce pro závěrečné součty a
shrnutí. Na sestavě se zobrazí před Column
Footer, bezprostředně za místem, kde končí tisk
sekce Detail.
Do příslušných sekcí vkládáme komponenty z panelu Palette metodou Look & Feel16.
Mezi nejdůležitějšími stojí za zmínku například TextField pro vkládání dat při kompilaci
šablony, Static Text pro vkládání statických dat a další.
Jakmile rozmístíme a upravíme vzhled a tvar polí pro data, musíme specifikovat jejich
text, datový typ, optimálně kódování pro PDF formát, jestli se bude zobrazovat hodnota null,
pokud nebudou data dodány apod.
Dále musíme nastavit datové objekty. Ty jsou trojího druhu:
Parameter (parametr) – tvar $P{data}.
Jednorázový parametr. Při kompilaci předán
objektem Map<String, Object>, kde
klíčem je data a hodnota je výslednou
hodnotou tohoto výrazu.
Field (pole) – tvar $F{data}. Prvek opakující
se datové kolekce objektů, která je zobrazována
v sekci Detail. Atribut data je název funkce
objektu, ke kterému bude přistoupeno přes
GETTER17 objektu, tedy getData().
Variable (proměnná) – tvar $V{data}. Zde se
nastavuje, co se má počítat! Slouží k tomu
atributy variableExpression, Calculation a
ResetType. U pole, které se odvolává na
proměnnou, je třeba nastavit, kdy má být
proměnná vyhodnocena.
Text vizuálního objektu se musí shodovat s některým předpisem pro datový objekt.
V panelu Report Inspector vytvoříme příslušné datové elementy a nastavíme shodný typ
s typem vizuální komponenty, která se na datový objekt odvolává.
Výsledek naší práce si můžeme prohlédnout přes záložku Preview. Nástroj
automaticky vygeneruje zkompilovanou třídu s příponou .jasper. Jakmile vložíme data pro
parametry, vygeneruje náhled, který uvidíme v následném okně.
16 Look & Feel = Metoda rozvrhování vizuálních komponent tam kam chceme (Look), a jejího chování (Feel). 17 GETTER = metoda vracející hodnotu zapouzdřeného atributu třídy.
28
Doporučujeme zkontrolovat, zdali výsledná sestava vypadá stejně ve všech
poskytovaných výstupních formátech. PDF soubory jsou citlivé na kódování, je nutné nastavit
kódování CP1250 na všech objektech, jinak se mohou vyskytnout problémy s diakritikou.
Výstupní formáty jako HTML nebo XLS mají zase problémy s překrývajícími se objekty.
Například soustava textových polí ohraničena souvislým čtvercem nemusí být zobrazena.
Tento problém je popsán na FAQ stránkách vydavatele (3). Řešením je například tyto objekty
obkreslit soustavou čar, protože kompilátory těchto formátů pracují s formulářem jako se
soustavou gridů18, které se překrývat nesmí, jinak se nezobrazí správně.
Pro podrobnější informace o nástroji iReport doporučujeme prostudovat online zdroje,
viz (2), (3).
5.5 Práce s JasperReports API
5.5.1 Kompilace a naplnění
Jak jsme si již popsali výše, kompilace je transformace vstupní šablony s příponou .jrxml na
soubor s příponou .jasper. Naplnění je pak vložením parametrů sestavy a datového zdroje
do zkompilovaného souboru:
Obrázek 8: Naplnění zkompilované třídy daty
18 Grid = Čtvercový objekt.
29
Jak ukazuje obrázek, datový zdroj je definován pomocí interface JRDataSource,
definovaném v balíku net.sf.jasperreports.engine. Můžeme tedy datové rozhraní
implementovat sami a vytvořit si vlastní datový zdroj, nebo využít v současnosti již 19
hotových implementací, např.:
JRBeanCollectionDataSource
JREmptyDataSource
JRResultSetDataSource
JRTableModelDataSource
JRXmlDataSource
Tyto a další implementace poskytují poměrně variabilní možnosti práce s datovými
zdroji zahrnujícími práci s kolekcemi, výsledky SQL dotazů, modely tabulek, XML soubory
apod. Za zajímavost stojí datový zdroj JREmptyDataSource, který je použit, pokud
v sestavě nebude použita sekce Detail.
Ke kompilaci používáme třídu JasperCompileManager, k naplnění sestavy
parametry a datovým zdrojem zase JasperFillManager, oba definované v balíku
net.sf.jasperreports.engine.
Při distribuci programu se můžeme rozhodnout, zda budeme aplikaci distribuovat
s nezkompilovanými šablonami a každá tvorba výstupu tuto šablonu zkompiluje, nebo
aplikaci dodávat se zkompilovanou šablonou a při tvorbě výstupu používat přímo tuto
šablonu.
5.5.2 Výstup na tiskárnu
Nyní, když sestavu máme již naplněnou, zbývá rozhodnout se, zda ji poslat přímo na tiskárnu,
nebo vytvořit okno s náhledem vytvořené sestavy s možností tisku nebo uložením do výše
uvedených výstupních formátů.
Pro možnost přímého tisku využijeme třídu JasperPrintManager z balíku
net.sf.jasperreports.engine, pro zobrazení náhledu zase třídu JasperViewer
z balíku net.sf.jasperreports.view.
5.5.3 Výstup do souboru
30
V mnoha manuálech a tutoriálech se uvádí použití třídy JasperExportManager z balíku
net.sf.jasperreports.engine, ovšem tato třída umožňuje pouhé ukládání do formátu
PDF, HTML a XML. Pokud bychom chtěli ukládat jiné formáty, museli bychom používat jejich
přímé implementace. Mnohem výhodnější je ale používání rozhraní JRSaveContributor
z balíku net.sf.jasperreports.view.save a jeho známých implementací, které
ovládají nízko-úrovňové výstupní třídy samy. Jmenujme například:
JRCsvSaveContributor
JRHtmlSaveContributor
JRPdfSaveContributor
JRRtfSaveContributor
JRMultipleSheetXlsSaveContributor
Pokud by se nám líbila možnost ukládání výstupu podobně jako přes náhled pro tisk
přes tlačítko pro uložení, kde se nám zobrazí okno pro uložení souboru do všech
podporovaných formátů, pak stojí za zmínku, že tato třída využívá těchto
JRSaveContributorů. Jejich hlavní výhodou je pouhé předání dvou parametrů při volání
metody save(…), tedy parametry naplněná sestava a výstupní soubor. Pro inspiraci si můžeme
prohlédnout zdrojový kód třídy JRViewer v balíku net.sf.jasperreports.view.
5.5.4 Praktická ukázka
Bill bill = getBill();
Collection<Item> items = bill.getItems();
Map<String, Object> params = getParams();
JRSaveContributor jrsc = new JRRtfSaveContributor
(Locale.getDefault(), ResourceBundle.getBundle(„bundle“));
try {
JasperReport jr = JasperCompileManager.compileReport(
„reports/bill.jrxml);
// zkompiluje šablonu
JasperPrint jp = JasperFillManager.fillReport(
jr, params, new
JRCollectionDataSource(items));
// naplníme již serializovanou třídu datovou kolekcí, parametry
JasperViewer.viewReport(jp, false);
31
// náhled s možností tisku či uložení do souboru
JasperPrintManager.printReport(jp, true);
// tisk s možností výběru tiskárny
jrsc.save(jp, new File(„output.rtf“));
// uložení do souboru output.rtf
} catch (JRException ex) {
System.err.println(ex.printStackTrace());
}
5.6 Závěrem
Knihovna JasperReports spolu s nástrojem iReport jsou opravdu šikovní pomocníci pro ty,
kteří chtějí, aby jejich aplikace podporovala výstup na tiskárnu nebo do výstupních souborů
různých formátů. Práce s nimi je pohodlná a intuitivní. V případě problémů doporučujeme
prozkoumat webové stránky vydavatele (2), kde je dostupné diskusní fórum a také FAQ
stránky, viz (3).
32
Kapitola 6 NetBeans Platform jako EJB klient
Na první pohled se může zdát, že propojit Enterprise JavaBeans s NetBeans Platform nemůže
být nic složitého, ale opak je pravdou. Nedostatek dokumentace i v tomto případě situaci ještě
více komplikuje. Mnohdy nezbývá, než se porozhlédnout po internetu a doufat, že najdeme
způsob, jak to udělat.
Naštěstí, jak ukázala například bakalářská práce pana Tomáše Vágnera napsaná
rovněž pod vedením Ing. Petra Adámka na FI MUNI v roce 2007 (18), možnosti propojení
existují, nicméně jejich nastavování se ukazuje být komplikované.
V době psaní této diplomové práce je pod vedením Ing. Petra Adámka na FI MUNI
vyvíjena další bakalářská práce, tentokrát psaná panem Lukášem Krejčím (20). Jejím cílem je,
co možná nejvíce zjednodušit a automatizovat toto propojení. Protože jedním z cílů diplomové
práce bylo vyzkoušet a posoudit vhodnost rámce této bakalářské práce, museli jsme být
pravidelně v kontaktu s autorem a zkoušet přírůstky na vyvíjené ukázkové aplikaci. Bohužel,
mnohdy musel pan Krejčí postupovat zcela od začátku, když bylo jasné, že dorazil do slepé
uličky. I tak v této kapitole probereme všechny tři přístupy propojení klientské a aplikační
vrstvy chronologicky, dle vývoje tohoto aplikačního rámce.
Smyslem jeho bakalářské práce tedy bylo vytvořit rámec, který bude moct každý
programátor použít stejně jednoduše, jako když přes průvodce vytváříme třeba novou třídu.
Nyní ukážeme některé metody, které předcházely konečné verzi aplikačního rámce.
Tyto metody jsou rovněž funkční, ale nedosahují takové čistoty a obratnosti, jak bychom si
přáli. Nakonec předvedeme finální verzi dostupnou v době uzávěrky diplomových prací. Jako
aplikační server byl použit GlassFish V2.
6.1 Úvodní verze
Úplně první verze propojení mezi EJB a NetBeans Platform nepředstavuje nic nového.
V podstatě ukazuje možnost propojení natvrdo, která spočívala ve vytvoření 2 modulů
sloužících jako knihovny:
EJBwrapper – v něm je uložen JAR archiv celé
aplikační vrstvy.
JavaEEwrapper – obsahuje soubor javaee.jar
s kompletní specifikací Java EE.
33
Na těchto knihovnách musí mít nastavenou závislost všechny moduly, které s EJB
komunikují.
Dále byl modifikován soubor project.properties, nacházející se ve složce
Important Files klientské aplikace, konkrétně atribut run.args.extra:
run.args.extra=-J-da -cp:a "C:/Program Files/glassfish-v2ur2/lib/
install/applications/jmsra/imqjmsra.jar";\
"C:/Program Files/glassfish-v2ur2/lib/appserv-rt.jar";\
"C:/Program Files/glassfish-v2ur2/lib/appserv-ext.jar";\
"C:/Program Files/glassfish-v2ur2/lib/appserv-admin.jar";\
"C:/Program Files/glassfish-v2ur2/lib/appserv-ws.jar";\
"C:/Program Files/glassfish-v2ur2/lib/appserv-deployment-
client.jar";\
"C:/Program Files/glassfish-v2ur2/lib/javaee.jar";\
"C:/Program Files/glassfish-v2ur2/lib/toplink-essentials.jar";\
"D:/Diplomka/EJBContractz/dist/EJBContractz.jar"
Přidáním těchto knihoven manuálně na CLASSPATH19 zajistíme, že aplikace bude ve
vývojovém prostředí fungovat, ale ne mimo ni! Pozor je třeba dát si také na oddělovač
jednotlivých položek. Zde, pod OS Windows, je použit středník, ale pod Unixem je zde naopak
potřeba dvojtečka!
Soubor EJBContractz.jar, zdrojový soubor ukázkové EJB vrstvy aplikace, je
obsažen také v knihovním modulu EJBWrapper.
Soubor imqjmsra.jar, appserv-admin.jar a appserv-ws.jar slouží
k podpoře Message-Driven Beans ukázkové aplikace.
Soubor appserv-rt.jar, appserv-deployment-client.jar a appserv-
ext.jar obsahují běhové prostředí aplikačního serveru a nezbytné doplňkové knihovny.
Soubor javaee.jar obsahuje kompletní specifikaci Java EE a soubor
toplink-essentials.jar je potřeba k využití JPA.
Pokud bychom chtěli, aby byla aplikace takto napsaná funkční i mimo vývojové prostředí
NetBeans IDE, musíme zmíněné knihovny kopírovat do složky /platformx/lib, nebo
umístit odkaz podobně jako v souboru project.properties, ovšem tentokrát ve složce
/etc a souboru .conf, například takto:
default_options="-J-da -cp:a D:/Diplomka/Lib/jaspers.jar"
19 CLASSPATH = Při překladu či spouštění aplikace dáváme na vědomí překladači či zavaděči tříd, ve kterých adresářích má začít hledat přeložené zdrojové kódy tříd potřebných pro překlad či běh programů.
34
Práce uvnitř modulu probíhala následovně:
ctx = new InitialContext();
pr = (ProjectRemote) ctx.lookup(ProjectRemote.class.getName());
Tato verze sice funguje, ale je to nevhodné řešení. Popírá veškeré výhody modularity,
každou distribuci je nutné přenastavit v souboru .conf dané aplikace apod. Nicméně ve
stádiu vývoje klientské aplikace se to ukázalo být dostatečným řešením.
6.2 Vývojová verze
Prvotní řešení propojení EJB s NetBeans Platform z praktického hlediska není vyhovující. Ani
zdaleka nevyužíváme vlastností, které nám platforma poskytuje, což můžeme napravit
například vhodným používáním Filesystems API. Definujeme si soubor vlastností připojení, ke
kterému potom přistupujeme, například takto:
<filesystem>
<folder name="JNDI">
<folder name="GlassFish V2">
<folder name="glassfish">
<attr name="java.naming.factory.initial"
stringvalue="com.sun.enterprise.naming.SerialInitContextFactory"/>
<attr name="java.naming.factory.url.pkgs"
stringvalue="com.sun.enterprise.naming"/>
<attr name="java.naming.factory.state"
stringvalue="com.sun.corba.ee.impl.presentation.rmi.JNDIStateFacto
ryImpl"/>
<attr name="org.omg.CORBA.ORBInitialHost"
stringvalue="localhost"/>
<attr name="org.omg.CORBA.ORBInitialPort"
stringvalue="3700"/>
</folder>
</folder>
</folder>
</filesystem>
35
Tato struktura je definována v souboru layer.xml, v modulu nazvaném
GlassFishJNDIProperties. Dále máme k dispozici nový knihovní modul s názvem GFfiles, který
obsahuje soubory appserv-rt.jar, appserv-ext.jar, appserv-deployment-
client.jar, jmxremote_optional.jar, javaee.jar a EJBContractz.jar.
Dále potřebujeme nainstalovat plugin org-muni-ejbconnector.nbm, který
vyvinul právě Lukáš Krejčí. Po instalaci Vám v systémové nabídce přibude wizard, který
vyvoláme, pokud vybereme akci New a potom komponentu ServerConnector.java. Po výběru
volby ServerConnector.java dokončíme wizard, přičemž ve zdrojovém kódu přibude třída,
která využije atributů souborového systému, popsaného v souboru layer.xml modulu
GlassishJNDIProperties. Modul, ve kterém tedy vytvoříme tuto třídu, musí být závislý jak na
modulu GlassFishJNDIProperties, tak GFfiles.
Předpokládejme, že pomocí wizardu vytvoříme třídu nazvanou GlassFishConnector.
Kód pro zpřístupnění Session Beans bude vypadat následovně:
ctx = new GlassFishConnector(„glassfish“).getInitialContext();
pr = (ProjectRemote) ctx.lookup(ProjectRemote.class.getName());
Tato verze již využívá možností Filesystems API, a především ze souboru
project.properties zmizely všechny parametry z přepínače run.args.extra. Aplikace tak
fungovala bez jakýchkoliv dodatečných zásahů i mimo vývojové prostředí NetBeans IDE.
V této podobě byla definována pouze nastavení pro aplikační server GlassFish
V2ur2, nicméně celkem bez problémů by šly atributy rozšířit i o podporu dalších aplikačních
serverů.
6.3 Konečná verze
Poslední a dle mého názoru nejjednodušší verze. Byla k dispozici měsíc před termínem
odevzdání bakalářské práce Lukáše Krejčího s tím, že již dále nebude měněna.
K dispozici byla ve formě kompletního zdrojového kódu. Podle mého názoru při
náhledu do zdrojového kódu se jedná o zdařilé pokračování předchozí verze s tím, že navíc
implementuje konektory pro připojení k dalším aplikačním serverům. V současné verzi
k těmto:
GlassFish V2
JBoss
WebSphere
36
Každá implementace aplikačního serveru vyžaduje tyto moduly:
Application Server Connector (základní modul,
společný pro všechny aplikační servery).
Xxx AS Client Libraries (potřebné knihovny pro
běh aplikačního serveru).
Xxx Connector (vlastní implementace konektoru,
implementuje rozhraní modulu Application
Server Connector).
V naší aplikaci i nadále využíváme aplikační server GlassFish V2, takže potřebujeme
pouze moduly, vztahující se k tomuto serveru. Postup sestavení spojení probíhá v případě
aplikace, která používá aplikační server GlassFish V2 (případ naší ukázkové aplikace) takto:
1. Sestavíme moduly Application Server Connector,
GlassFish V2 AS Client Libraries a GlassFish V2
Connector do 3 souborů s příponou NBM.
2. Tyto moduly nainstalujeme do vývojového
prostředí.
3. Ve vlastnostech naší aplikace, v komponentě
NetBeans Platform Application, na kartě
Libraries je nutno zatrhnout tyto tři moduly,
které se nachází v uzlu extra.
4. Vytvoříme nový modul. V jeho souboru
layer.xml vytvoříme popis hostitele a portu
připojení k aplikačnímu serveru. Struktura
souboru je identická s vývojovou verzí s tím
rozdílem, že obsahuje pouze atributy
org.omg.CORBA.ORBInitialHost a
org.omg.CORBA.ORBInitialHost. Toto
řešení bylo v době konečné verze nejvhodnější,
protože tyto vlastnosti mohou být na různých
klientských počítačích různé. Popis je
v dokumentaci konektorů.
5. Modul s vlastnostmi aplikačního serveru musí
mít nastavenou závislost na modulech, které
připojení k aplikačnímu serveru využívají.
6. Modul, který využívá připojení k aplikačnímu
serveru, musí mít nastavenou závislost na
importovaném modulu Application Server
Connector. Implementace je volána automaticky,
implementuje totiž potřebná rozhraní, která si
37
rovněž zaregistrovala v META-INF balíku svého
modulu.
7. Dále již pracujeme s třídou ApplicationServer.
6.3.1 Ukázka souboru layer.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN"
"http://www.netbeans.org/dtds/filesystem-1_1.dtd">
<filesystem>
<folder name="JNDI">
<folder name="GlassFishV2">
<file name="glassfish">
<attr name="org.omg.CORBA.ORBInitialHost"
stringvalue="localhost"/>
<attr name="org.omg.CORBA.ORBInitialPort"
stringvalue="3700"/>
</file>
</folder>
</folder>
</filesystem>
6.3.2 Ukázka připojení ke kontextu
Context ctx;
ApplicationServer appServer;
appServer = new ApplicationServer(ApplicationServer.GlassFishV2,
"glassfish");
ctx = appServer.getInitialContext();
Oproti vývojové verzi nám tedy ubyla práce s tvorbou wizardu pro konektor serveru a ubyl
modul GFiles, ve kterém se nacházely podpůrné knihovny pro správu připojení mezi
klientskou a aplikační vrstvou, a knihovnu s EJB vrstvou aplikace. Tyto knihovny jsou totiž
obsaženy v importovaném modulu xxx AS Client Libraries, kde xxx je název aplikačního
38
serveru. Naopak nám přibyl knihovní modul EJBContractz, který obsahuje pouze EJB logiku
aplikace.
6.4 Závěrem
Naše ukázková aplikace využívá této poslední vývojové verze a funguje spolehlivě. Jako přínos
této práce bych rád vyzdvihnul jednoduchost a až na manuální vytvoření modulu
s nastavením aplikačního serveru je to právě unifikovaná manipulovatelnost se sadou modulů,
na jakou jsme zvyklí při vývoji aplikací pod RCP NetBeans Platform. Nastavení souboru
layer.xml v modulu popisující nastavení hostitele a portu aplikačního serveru obnáší pouhé
zjištění dvou atributů připojení, zbytek již obsahuje implementace konektoru tohoto
aplikačního serveru. Navíc pro toto řešení hovoří také skutečnost, že změna nastavení obnáší
pouhou úpravu textového souboru, takže není nutno aplikaci znovu sestavovat.
Jako velkou nevýhodu bych v současné době označil velikost modulů aplikačního
serveru. Při přechodu na konečnou verzi ukázkové aplikace vzrostla velikost distribuce
skokově o plných 20MB dat. A to jen při aplikovaných modulech pro připojení na aplikační
server GlassFish V2.
Celkově je tato bakalářská práce přínosná a lze ji doporučit všem, kteří uvažují o
propojení klientské a aplikační vrstvy těchto technologií. Pro podrobnější informaci
doporučujeme prostudovat kompletní bakalářskou práci pana Lukáše Krejčího ze semestru
jaro 2009 (20).
39
Kapitola 7 Ukázková aplikace
Jedním z hlavních úkolů této diplomové práce bylo vytvořit aplikaci, jejíž aplikační vrstva
bude postavena na EJB 3.0 a klientská vrstva zase na NetBeans Platform 6.5. Cílem je ukázat
vhodnost frameworku naprogramovaného v rámci bakalářské práce pana Lukáše Krejčího a
také dokázat, že NetBeans Platform může kvalitně fungovat i jako klientská vrstva vícevrstvé
aplikace.
Přestože jsem s RCP NetBeans Platform pracovali poprvé v rámci této diplomové práce, celý
rámec působil uceleným dojmem a chtěl jsem tak poznat, zda opravdu splňuje to, co si
předsevzal, tedy usnadnit práci vývoje klientské aplikace. Jak lépe poznat možnosti
nepoznané technologie, než si tyto vlastnosti vyzkoušet v praxi na nějaké netriviální aplikaci.
Ve spolupráci s instalatérskou firmou OXO plus s.r.o. jsme tedy vyvinuli aplikaci
nazvanou Contractz Platform 2009, která představuje systém pro správu zakázek. Firma
OXO plus s.r.o. (dále je OXO) funguje na trhu už 25 let a v současné době se plně věnuje
poskytováním služeb v oboru voda-plyn-topení, zednickým a obkladačským pracím. Nabízí
také non-stop havarijní službu. Současná administrativa je decentralizovaná a jednotlivé
programy mezi sebou nespolupracují. Contractz Platform (dále CP2009) má tuto situaci
změnit…
7.1 Současný stav
V současné době se administrativa skládá z několika aplikací:
PeliCo Kalkul 11 – pro tvorbu faktur a vedení
účetních podkladů.
MS WORD – tvorba tlakových zkoušek, smluv
o dílo, reklamací.
MS EXCEL – tvorba cenových nabídek,
dodacích listů.
FORM STUDIO – příjmové a výdajové
pokladní doklady.
Tato sada aplikací v současné době slouží obsluze zodpovědné za administrativní
provoz služeb poskytovaných firmou OXO. Značnou nevýhodou je izolovanost jednotlivých
40
aplikací. Určité činnosti jsou tedy zadávány znovu ve více dokladech. Například tvorba
dodacích listů není provázána s fakturami, faktura se musí na dodací listy pouze slovně
odkazovat. Pokladní doklady nejsou s fakturami nikde provázány, vazba se objeví až
v systému účetního oddělení. Reklamace zase nejsou provázány s fakturami. Produktové
položky se musí do cenových nabídek či dodacích listů opakovaně zadávat, protože skladová
administrativa programu Kalkul 11 je pro tyto potřeby příliš složitá a tedy nevyhovující.
Nikde tedy není centrální prvek, který tyto údaje vhodným způsobem spojuje do
jednoho rámce.
7.2 Navrhované řešení
Na základě studia současného chodu obchodní administrativy firmy OXO a požadavků jejího
vedení, nejen na nalezení vhodného východiska pro aktuální stav, ale také pro možnost
nenáročného rozšiřování aplikace dle budoucích požadavků v souladu s rozvojem firmy i trhu
byl, vytvořen tento návrh.
Jak se ukazuje již v prostých požadavcích na rozšiřitelnost, modularita NetBeans
Platform nám přijde vhod již ve fázi návrhu, protože právě ta, krom vhodného návrhu API, je
důležitou vlastností pro další rozšiřování aplikace.
V první fázi vývoje aplikace, která bude výstupem této diplomové práce, bude náhrada
výkazové logiky současné administrativy, zatímco tvorba smluv o dílo a tlakových zkoušek
bude i nadále vykonávána přes aplikaci Microsoft Word.
Výsledkem návrhu je systém pro správu zakázek nazvaný Contractz Platform 2009,
který implementuje následující řešení:
7.3 Contractz Platform 2009
Aplikační vrstva: EJB 3.0
Aplikační server: GlassFish V2ur2
Klientská vrstva: NetBeans Platform 6.5
Propojení klientské a aplikační vrstvy: bakalářská práce Lukáše Krejčího (20).
Aplikační vrstvu založenou na EJB 3.0 podrobněji rozebereme v kapitole 8, klientskou
vrstvu založenou na NetBeans Platform zase v kapitole 9. K propojení klientské a aplikační
41
vrstvy používáme poslední zdokumentovanou konečnou vývojovou verzi, podrobněji
popsanou v kapitole 6.3.
42
Kapitola 8 Aplikační vrstva
Aplikační vrstva aplikace slouží jako poskytovatel služeb klientské vrstvě, která by měla
těchto služeb využívat a vlastní výpočty či podobné operace by měla provádět pouze pro
potřeby GUI. Zároveň vystupuje v roli konzumenta služeb datové vrstvy, k níž posílá dotazy na
hledaná data, či do ní data ukládá.
Základním kamenem aplikační vrstvy je entitní třída Projekt (Project). Představuje
jednotlivé zakázky, které firma vykonává. Každý projekt spravuje přidružené entity a slouží
tak, jako jejich obálka. Projekt lze snadno rozšiřovat o další entitní třídy, v současnosti jsou to
tyto:
cenová nabídka (Bid);
dodací list (Delivery Note);
faktura (Bill);
klient (Client);
příjmový/ výdajový pokladní doklad (Receipt/
Disbursement);
reklamace (Reclamation).
Obrázek 9: Entitní třídy aplikační vrstvy
43
Jak je vidět z obrázku, mezi entitami je hodně vzájemných závislostí, které jsou zde
především z důvodu efektivního vyhledávání podle vztahu k ostatním entitám.
Třída Document, slouží jako společná nadtřída pro entity Bid, Bill a DeliveryNote. Třída
CashVoucher je společná nadtřída pro entity Receipt a Disbursement. Tyto nadtřídy využívají
anotace zrovna tak jako entitní třídy, které nadtřídy rozšiřují, především anotaci
@MappedSuperclass místo anotace @Entity používané pro entitní třídy. Na tyto třídy se jinak
v žádném dalším zdrojovém kódu neodvoláváme.
Obrázek 9 ovšem zdaleka nepředstavuje celou logiku aplikace. Dalším důležitým
faktorem jsou položky dodacích listů a cenových nabídek. Ty představuje další svébytná
hierarchie tzv. položek (Item), která tuto úlohu zastupuje:
Obrázek 10: Hierarchie položek aplikační vrstvy
Zde, v roli nadtřídy vystupuje třída Item (položka), která definuje základní vlastnosti
každé položky cenové nabídky nebo dodacího listu. Ta je dále rozšířena na třídy DefinedItem
(Definovaná položka) a UndefinedItem (Nedefinovaná položka). Koncept těchto tříd spočívá
v tom, že definované položky uživatel založí do databáze a opakovaně je může používat,
zatímco nedefinované položky jsou použity pouze jednorázově. Třída DocumentItem je
zapouzdřením definovaných a nedefinovaných položek, které obsahují konkrétní data
specifická pro jednotlivé výskyty položek v dokumentu, například konkrétní množství či
marže. Právě kolekci této třídy obsahuje cenová nabídka nebo dodací list, které jsou
podtřídami třídy Document. Tento koncept je použitelný v situaci, kdy určité položky zcela
jistě budou použity pouze jednou a nemá smysl pro ně zakládat kartu. V současné
implementaci ovšem nedefinovaná položka není využívána. Počítá se s ní v jedné z příštích
verzí aplikace.
44
Obrázek 11: Kompletní vazby entitních tříd
Na obrázku 9 je zachycen kompletní diagram entitních tříd aplikační vrstvy. Během
vývoje aplikace se tento model osvědčil a lze jej snadno rozšiřovat o další entitní třídy.
Jednotlivé koncové entitní třídy si postupně rozebereme.
8.1 Cenová nabídka (Bid)
Cenovou nabídku tvoří entitní třída Bid, která rozšiřuje společnou nadtřídu Document. Od ní
dědí některé atributy a metody. Tvoří ji především kolekce položek typu DocumentItem, které
tvoří obousměrnou relaci 1:1. Počet a hodnota těchto položek je využívána metodou pro
výpočet ceny bez DPH, DPH a celkové ceny cenové nabídky. Dále jsou tu především atributy
pro tvorbu vazby na klienta a projekt. Jinak zde není vytvářena žádná vazba a z pohledu
aplikační logiky jde o poměrně samostatnou entitní třídu. Je to dáno především faktem, že
slouží pouze pro předběžnou kalkulaci části nebo celého projektu a v další fázi projektu od ní
není odvíjena žádná činnost.
45
8.2 Dodací List (DeliveryNote)
Entitní třída DeliveryNote, která představuje dodací list, opět rozšiřuje společnou nadtřídu
Document a její struktura je s entitní třídou Bid prakticky shodná. Hlavní rozdíl mezi nimi je
v tom, že s těmito entitami se v dalších fázích projektu počítá a především je nutné říct, že
dodací listy jsou datovými položkami faktur. Výpočet hodnoty dodacího listu je opět počítán
automaticky dle aktuální kolekce položek typu DocumentItem, se kterou tvoří obousměrnou
relaci typu N:1, které dodací list obsahuje.
8.3 Faktura (Bill)
Poslední zástupce tříd rozšiřující společnou nadtřídu Document je entitní třída Bill,
reprezentující fakturu. Rozdíl oproti předešlým dvěma třídám je v tom, že datové položky zde
představují jednotlivé dodací listy, jak bylo popsáno v předchozím odstavci. Jedná se o
obousměrnou relaci typu 1:N. Faktura je tedy chápana jako sestava dodacích listů. Výhody
tohoto řešení jsou prezentovány v kapitole 9.4.3, zabývající se klientskou vrstvou aplikace.
Cena faktury se opět odvíjí od hodnoty dodacích listů, na které je vytvořena vazba. Faktura má
navíc obousměrnou relaci 1:N vzhledem k příjmovým a výdajovým pokladním dokladům.
8.4 Příjmový pokladní doklad (Receipt)
První entitní třída rozšiřující společnou nadtřídu CashVoucher, je třída Receipt, která
představuje příjmový pokladní doklad. Jde o finanční prostředky, které do firmy přicházejí.
Vztahují se k fakturám, se kterými mají vazbu typu N:1. Je to dáno především faktem, že každá
platba se musí vztahovat k předtím vystavené faktuře. Dále obsahuje atributy a metody
zejména pro správu částky, typu platby, sazby DPH a popisného textu příjmového pokladního
dokladu.
8.5 Výdajový pokladní doklad (Disbursement)
Druhá a poslední entitní třída Disbursements představující výdajový pokladní doklad,
rozšiřuje společnou nadtřídu CashVoucher. S entitní třídou Receipts je po stránce atributů i
aplikační logiky prakticky shodná, liší se především významem a přístupem k ní z hlediska
ostatních aplikací. Výdajový pokladní doklad totiž představuje finanční prostředky, které jsou
46
z firmy přesunuty do jiné firmy či fyzické osoby. Přístupové metody, vztah k entitní třídě Bill
spolu s kardinalitou vazby jsou shodné.
8.6 Reklamace (Reclamation)
Reklamace představuje trošku jinou entitní třídu, než se kterými jsme doposud pracovali.
Entitní třída Reclamation obsahuje pouze vazbu na klienta, projekt a slovní popis důvodu
reklamace. Reklamace se v tomto případě vztahuje k projektu jako celku, ne ke konkrétní
faktuře. Je to obvyklý způsob, během reklamace u stavebních oborů se totiž řeší více problémů
v celém spektru vystavených faktur jednoho projektu.
8.7 Skladová karta (DefinedItem)
Skladové karty představuje entitní třída DefinedItem, která rozšiřuje společnou nadtřídu Item.
Důvod pro tvorbu těchto entit spočívá v jejich opakovaném použití entitní třídou, která je
využívá. Nejsou využívány přímo, nýbrž prostřednictvím této třídy. Jedná se o jednosměrnou
relaci vzhledem k entitní třídě DocumentItem s relačním typem 1:N. Definují se zde všechny
atributy a metody pro nastavení a získání dat z entit. Jedná se o název, text, výrobce, kód
výrobce, měrnou jednotku, nákupní cenu, marži, sazbu DPH a záruku v měsících.
8.8 Klient (Client)
Entitní třída Client zapouzdřuje údaje o klientovi v rámci projektu. Každá koncová entitní třída
(kromě rodiny entit Item) obsahuje jedno či obousměrnou vazbu právě s touto entitní třídou.
Je to tedy důležitá entita, podle které jsou mimo jiné vyhledávány dokumenty, které jsou
s klientem v relačním vztahu. Klient obsahuje všechny běžné atributy pro ukládání vlastností
klienta, ať fyzické osoby nebo firmy.
8.9 Projekt (Project)
Projekt a jeho entitní třída Project zapouzdřují dokumenty logicky související s jeho
vykonáváním. Obsahuje obousměrnou relaci 1:N vzhledem k entitním třídám představujícím
cenové nabídky, dodací listy, faktury, klienty, reklamace, příjmové a výdajové pokladní
47
doklady. A dále už jen atributy pro zadání roku vytvoření projektu a identifikační text. Je to
tedy v podstatě obálková komponenta.
8.10 Další vlastnosti aplikační vrstvy
8.10 .1 Generování ID entitních tříd
Entitní třídy musí mít unikátní identifikátor, podle kterého jsou jednotlivé entity jednoznačně
rozlišitelné. V aplikační vrstvě z tohoto pohledu rozlišujeme dva typy entitních tříd:
Entity s ID závislým na datu vzniku.
Entity s ID bez závislosti na datu vzniku.
Každá entitní třída má v databázové tabulce nazvané Counter, která obsahuje položky
typu klíč – hodnota, řádek s posledním generovaným ID. Ať již generujeme ID pro jakoukoliv
entitní třídu, inkrementujeme tuto hodnotu na příslušném řádku.
První typ entitních tříd, zejména entitní třídy Client, DefinedItem a UndefinedItem mají
entity nezávislé na datu vzniku. Jejich ID jsou generovány automaticky ze strategie generování
z tabulky.
Z obchodních a účetních důvodů je nutné u určitých dokladů, například faktur,
zohlednit rok generování tohoto dokumentu. Zde ID generujeme metodou, která se nachází
v komponentě typu Session Bean, kterou má každá entita jednu pro svoji potřebu. Nachází se
zde metoda assignId(), která dodá entitě nové ID v závislosti na aktuálním roce. Na rozdíl od
entit nezávislých na datu musí naopak tyto závislé entity o přidělení ID explicitně požádat.
8.10.2 Výčtové typy
Aplikační vrstva obsahuje tři druhy výčtových typů:
SalaryType určuje typ platby (hotově,
převodem).
TaxType pro sazby daně z přidané hodnoty
(9%, 19%).
UnitType pro druhy měrných jednotek (ks,
bm, m2, m3, …).
48
Tyto výčtové typy mají vlastní podporu pro převod těchto typů do jiných forem a zpět.
Jednotlivé výčtové typy jsou definované v ResourceBundle s názvem
settings.properties. Lze je tedy jednoduše změnit pouhou změnou textového souboru
bez nutnosti znovu sestavovat aplikační vrstvu. Je možné rovněž tyto hodnoty lokalizovat.
8.10.3 Prefix dokumentů
Je maximálně rozumné jednotlivé druhy dokumentů odlišit nejen jejich názvem, ale i
mnemotechnickou zkratkou sdruženou s jejím pořadovým číslem. Z těchto důvodů jsou v
ResourceBundle s názvem settings.properties k dispozici položky typu klíč–
hodnota . Lze je opět měnit pouhou změnou textového souboru a lokalizovat je. V současnosti
používáme tyto prefixy pro všechny jazykové verze:
CN = cenová nabídka;
DL = dodací list;
FA =faktura;
PJ = projekt;
PPD = příjmový pokladní doklad;
VPD = výdajový pokladní doklad;
RM = reklamace.
49
Kapitola 9 Klientská vrstva
Klientská vrstva aplikace využívá kvalitní a dobře zavedené RCP NetBeans Platform, nyní ve
verzi 6.5. I když jsem v programování pod platformou nováčkem, snažím se v ukázkové
aplikaci využívat co možná nejširšího spektra jejich vlastností, tedy promyšlenou modularitu a
vhodná API.
Jedním ze základních pilířů NetBeans Platform je modularita. Tento koncept spočívá
ve skládání částí (modulů) do celku (funkční aplikace, sestavy modulů). Modularitu se
snažíme uchopit i my v naší klientské aplikaci, která je z modulů sestavena. Contractz Platform
2009 je sestavena z těchto modulů:
Core – jádro aplikace, které bylo použito
k odstranění křížové závislosti mezi moduly.
Tato problematika je popsána v kapitole 4.1.
DataOutput – modul zajišťující výstup aplikace
na tiskárnu nebo do souboru několika
rozšířených formátů.
Nodes – modul zajišťující logiku pro zobrazení
dat ve vizuální podobě spolu s jejich vlastnostmi
a kontextově závislými akcemi.
TopComponents – modul s GUI a jím potřebnými
modely a renderery.
Tyto jsou závislé jednak na modulech integrovaných ve vývojovém prostředí NetBeans
Platform, ale také na modulech, které jsme museli dodat externě:
EJBContractz – knihovní modul obsahující
aplikační vrstvu v podobě distribuce zabalené
v JAR archivu. Naše moduly potřebují tuto
knihovnu pro znalost API, na kterém je aplikační
logika postavena.
GlassFishJNDIProps – obsahuje soubor
layer.xml, který obsahuje popis připojení
k aplikačnímu serveru, na kterém je aplikační
vrstva nasazena.
Jasper35Wrapper – knihovna poskytující
distribuci JasperReports 3.5 společnosti
50
JasperSoft Inc. s podpůrnými knihovnami. Obsah
knihovny je popsán v kapitole 5.3.
SwingXWrapper - knihovna SwingX organizace
SwingLabs verze 0.9.2, obsahující rozšíření
Swing komponent.
Obrázek 12: Moduly v rámci Contractz Platform 2009
Obrázek 12 ukazuje hierarchickou strukturu námi vytvořených modulů Core,
TopComponents, DataOutput a Nodes spolu s knihovními moduly EJBContractz,
SwingXWrapper, Jasper35Wrapper a modulem nastavení aplikačního serveru
GlassFishJNDIProps v aplikaci Contractz Platform 2009.
9.1 Modul Core
Modul Core, jak název napovídá, představuje komunikační jádro aplikace. Byl vytvořen pro
odstranění nepovolené křížové závislosti mezi moduly. Obsahuje převážně veřejné balíky
rozhraní pro:
tisk (contractz.dataoutput.print);
výstup do souboru
(contractz.dataoutput.save);
uzly (contractz.nodes.api).
Dále potom balíky s třídami pro:
EJB – připojení a správa Session Beans
(contractz.ejb);
nastavení aplikace (contractz.settings);
51
start aplikace (contractz.init).
Modul Core je závislý pouze na knihovně EJBContractz, protože právě tento knihovní
modul spravuje připojení k aplikační vrstvě. Přítomnost pouze jedné závislosti je způsobena
faktem, že modul deklaruje převážně rozhraní, které musí implementovat moduly jiné a tím
umožnit jejich výměnu za alternativní řešení, aniž by se tím musely měnit ostatní moduly.
Krom odstranění křížové závislosti je to stěžejní důvod pro tvorbu komunikačního modulu.
Podrobnějším popisem modulů pro tisk, výstup do souboru a podporu uzlů se zabývají
následující kapitoly.
Balík pro nastavení aplikace v současné době obsahuje pouze třídu OurCompany a
ResourceBundle20, jež společně slouží jako podpora pro správu údajů o firmě. Tyto údaje
nejsou uloženy v databázi, takže je lze měnit ručně, manipulací se souborem
Bundle.properties daného balíku, zatímco třída OurCompany načítá obsah tohoto
ResourceBundle a poskytuje tak podporu například pro hlavičku dokumentů k výstupu do
souboru nebo na tiskárnu.
A konečně balík pro start aplikace obsahuje také jen jednu třídu, která naplní databázi
testovacími daty, kdykoliv je vyvolána komponenta ExplorerTopComponent modulu
TopComponents. Toto řešení bylo použito z důvodu rychlejšího načítání aplikace, kterého je
dosaženo nepoužitím komponenty ModuleInstaller, která je náročná na výpočetní výkon
stanice, pod kterou klientská aplikace poběží.
9.2 Modul DataOutput
Každá aplikace potřebuje vhodnou formu výstupu dat. Vzhledem k problematické zabudované
podpoře tisku v Javě byla použita knihovna funkcí nazvaná JasperReports, nyní v aktuální verzi
3.5. Tato distribuce a další potřebné open–source knihovny jsou obsaženy v knihovním
modulu Jasper35Wrapper. V rané fázi projektu byla použita verze 3.1.4 a během přechodu na
novější verzi nedošlo z pohledu Contractz Platform 2009 k žádné změně API a stačilo tak
pouze vyměnit knihovní modul. Je to další ukázka toho, jak je modularita užitečná.
Modul DataOutput se stará o:
Tisk na tiskárnu přes tiskový dialog daného
operačního systému.
20 ResourceBundle = Soubor s údaji klíč-hodnota. Používá se například pro internacionalizaci aplikace.
52
Výstup do souboru formátu CSV, XLS single-
sheet, XLS multi-sheet, PDF, RTF, ODT, XML a
HTML.
Podrobnějším popisem procesu tisku přes knihovny JasperReports se zabývá kapitola
5, kde jsou i praktické ukázky. My se soustředíme na popis práce tohoto modulu. Proces
výstupu probíhá takto:
1. Byla zavolána přípravná metoda modulu, která
nachystá data pro tvorbu výstupu v závislosti na
entitě, jejíž detaily mají být výstupem a na
způsobu výstupu.
Obrázek 13: Náhled pro tisk
2a. Je vyvolán náhled pro tisk se zobrazením detailu
výsledné tiskové sestavy s možností tisku, kdy se
zobrazí formulář pro volbu tiskárny a pak už tisk.
Viz obrázek 13.
53
Obrázek 14:Dialog pro uložení do souboru
2b. Je vyvoláno dialogové okno s možností výběru
typu výstupního souboru a možností volby umístění
výsledného souboru a pak uložení. Viz obrázek 14.
Modul DataOutput je závislý především na knihovním modulu Jasper35Wrapper, dále
na modulu EJBContractz a na modulu Core, jehož rozhraní pro výstup do souboru a do
tiskárny implementuje. Na modulu DataOutput naopak závislý žádný modul není. Opět je tak
možné poměrně snadno vyměnit tento modul za jiný, pokud tento modul bude implementovat
příslušná rozhraní modulu Core.
9.3 Modul Nodes
Modul Nodes slouží jako logika pro zobrazování dat ve vizuální podobě. Využívá především
zabudovaných API RCP NetBeans Platform jako Nodes API, Actions API a Explorer & Property
Sheet API. Jak název modulu napovídá, zobrazení dat bude ve formě stromové struktury,
kterou považujeme z hlediska vyhledávání a orientace v datech za optimální volbu.
54
Obrázek 15: Zobrazení dat ve vizuální podobě
My jsme se snažili jít o trošku dál, takže náš strom není statický, nezobrazuje tedy
prostou strukturu typu Cenové nabídky -> cenová nabídka 20090001 apod. Statické jsou
pouze 2 první úrovně stromu – kořen a uzly, které vyjmenovávají typy entit a zobrazují jejich
potomky. Tím ale možnosti nekončí. Každou entitu lze dále rekurzivně rozevírat do dalších
podúrovní a zobrazovat tak všechna data, která se vztahují k těmto entitám. Tyto data lze opět
dále rekurzivně rozevírat. Jedná se tedy o nekonečný strom, pomocí kterého velmi snadno a
hlavně intuitivně zobrazíte všechna data, která hledáte.
K položkám a vybraným rozhodovacím podstromům se vztahují kontextově závislé
akce, které umožňují tvorbu nových entit, jejich úpravy či odstranění. Veškeré další úpravy již
probíhají v rámci jednotlivých TopComponent21 modulu TopComponents.
Jednotlivé entity mají také svoje vlastnosti (properties), které, pokud je okno
zobrazeno, zobrazují hodnoty atributů jednotlivých entit. Entity zde nelze měnit, pouze
prohlížet. K manipulaci s daty slouží jednotlivé TopComponenty modulu TopComponents.
Možnost změny na více místech by tak byla redundantní.
Aplikační logika modulu je rozdělena do několika balíků dle druhů činnosti. Mezi
základní balíky patří:
actions (kontextově závislé akce);
21 TopComponent = Obdoba Swing komponenty Form v NetBeans Platform.
55
nodes (kořen stromu a třída pro obnovení
stromu, která implementuje rozhraní modulu
core);
properties (vlastnosti).
Z hlediska hlavní náplně modulu jsou nejdůležitější balíky, které mají prefix nodes:
nodes (kořen stromu);
nodes.data (datové položky stromu);
nodes.level0 (první úroveň stromu,
zobrazuje základní kategorie stromu, např.
FAKTURY, REKLAMACE, …);
nodes.levelx (zanořené úrovně stromu,
které jsou zobrazeny při rekurzivním průchodu
datových položek a zobrazují tak entity, které
jsou v nějakém vztahu k rozevírané entitě);
nodes.years (zobrazuje entity setříděné
podle roků, kdy entity vznikly).
Modul Nodes je závislý na modulech Core, EJBContractz a TopComponents. Modul Core
obsahuje rozhraní pro obnovení stromu, které modul Nodes implementuje. Knihovní modul
EJBContractz slouží jako knihovna pro entity a session beany, které se v modulu nacházejí a
modul TopComponents je zde z důvodu volání jednotlivých TopComponent při aktivaci
kontextově závislých akcí. Na modulu Nodes naopak závislý žádný modul není, opět jej tak lze
poměrně snadno vyměnit.
Finální vzhled vizuálně zobrazených dat určuje jedna ze dvou k tomu určených
TopComponent modulu TopComponents, jež bude popsána v následující kapitole.
9.4 Modul TopComponents
Z hlediska aplikace Contractz Platform 2009 se jedná o hlavní modul, protože v sobě skrývá
právě tu aplikační logiku, která se stará o životní cyklus projektů v rámci organizace. Obsahuje
jednotlivé GUI celé aplikace, přičemž se snaží dát jim jednotnou formu, takže aplikace působí
vyváženě. Jednotlivé TopComponenty si podrobněji rozebereme.
56
9.4.1 Cenová nabídka (BidTopComponent)
Cenová nabídka představuje počáteční kroky každého projektu. Klient obvykle přijde do
dodavatelské firmy se žádostí o zpracování cenové nabídky, v rámci které se rozhoduje o
uskutečnění či neuskutečnění díla, které cenová nabídka popisuje. Cenových nabídek
v projektu může být několik a nemusí být žádná. Slouží tedy jako pouhý podklad pro spuštění
projektu (např. součást smlouvy o dílo) a do dalších etap správy projektu nemá v rámci
aplikace žádnou návaznost. Cenová nabídka se vztahuje vždy ke konkrétnímu projektu.
Cenové nabídky jsou zde upravovány, nebo vytvářeny nové. Předpokladem pro tvorbu
nové cenové nabídky je vytvořený klient, založený projekt a definované položky.
Obrázek 16: Aplikace s aktivovanou Bid TopComponentou
Komponenta je rozdělena do tří panelů. První panel umožňuje výběr či tvorbu cenové
nabídky podle vybraných klientů a jejich projektů. Druhý panel obsahuje tabulku, u níž
můžeme měnit, nebo odebírat její přidané položky. U položek lze měnit pouze počet či cenu
vybrané položky, tedy data, která nemodifikují vzorovou položku DefinedItem, ale pouze
atributy položky cenové nabídky, které jsou pro tuto položku unikátní. Třetí záložka umožňuje
výběr definovaných položek s možností vyhledávání v jejich názvech, textu, výrobci či kódu
výrobce. Označená položka naplní poslední, čtvrtý panel, kde nastavíte konečné vlastnosti
57
nově přidávané položky a možnost přidat ji do tabulky položek. Přidávat lze pouze položky,
které ještě v seznamu položek dodacího listu nejsou.
Komponenta obsahuje cookies22 pro tisk či uložení do souboru přes modul
DataOutput. Každá přidaná položka vyvolá reorganizaci stromu dat, aby byl pokud možno
stále konzistentní za cenu co nejmenší spotřeby paměti klientského počítače.
9.4.2 Dodací list (DeliveryNoteTopComponent)
Dodací list plní v kontextu aplikace několik významných úloh, některé z nich budou více
zřejmé v kapitole 9.4.3, zabývající se komponentou Faktura (BillTopComponent). V prvé řadě
slouží dodací list jako základní část výkazové činnosti projektu. Jednotlivé skladové položky
stejně jako rozpis služeb (lidská práce, autodoprava, recyklace) jsou vystaveny pomocí
dodacího listu. Dodací list obsahuje položky v rámci kolekce položek DocumentItem.
Obrázek 17:Aplikace s aktivovanou DeliveryNote TopComponentou
Při vkládání položky do dodacího listu, v případě definovaných entit, používáme
výhody tohoto konceptu, kdy jsou již u každé položky nastaveny podrobné údaje, stejně jako
22 Cookie = v prostředí NetBeans Platform slouží pro podmíněné akce. Tyto nejsou dostupné vždy, ale pouze pokud je splněna nějaká podmínka. Například pokud je aktivní uzel, na kterém jsou cookies definovány.
58
vhodné koeficienty marže, které lze v případě potřeby samozřejmě měnit. Využití tohoto
systému nám v budoucnu umožní snadný vývoj nového modulu, který bude vyhodnocovat
finanční výnosy jednotlivých projektů a přímo tak usnadní výpočet ziskovosti celé firmy.
Dodací listy se vztahují k projektu i faktuře. Mezi projekty je dodací list nepřenositelný.
Podobně jako cenová nabídka, i dodací list tvoří z pohledu uživatele totožnou
komponentu se stejným rozvržením. Hlavní rozdíl je v tom, že dodací list už má návaznost na
další etapy tvorby projektu, zatímco cenová nabídka ne. Cenová nabídka a dodací list jsou
naprosto samostatné entity bez přímé vazby. Obrázek 17 potvrzuje, že je tomu skutečně tak. I
vizuální podoba komponenty je totiž v podstatě identická. Pro detailnější studium
komponenty, viz předchozí kapitola.
Komponenta obsahuje cookies pro tisk či uložení do souboru přes modul DataOutput.
Každá přidaná položka vyvolá reorganizaci navigačního stromu dat, aby byl pokud možno
stále konzistentní za cenu co nejmenší spotřeby paměti klientského počítače.
9.4.3 Faktura (BillTopComponent)
Faktura slouží jako hlavní výstup aplikace pro účely platby za dodané produkty a vykonané
služby, dohodnuté v cenové nabídce (pokud se nejedná o dodatečně dohodnutou dodávku).
Tvorba faktury je v podstatě plně automatizovaná, což představuje významné zlepšení oproti
logice původního systému fakturace firmy OXO. Faktura totiž obsahuje kolekci dodacích listů,
které představují její položky. Při tvorbě či editaci faktury máme k dispozici seznam dodacích
listů, které nejsou přiřazené jednotlivým fakturám. Jakmile je vybereme, jsou automaticky
nedostupné jiným fakturám. Faktura, ke které je dodací list přiřazen, automaticky navyšuje
svoji fakturační částku o částku v dodacím listu. Jakmile zrušíme vazbu faktury na dodací list,
je dostupný dalším fakturám v rámci projektu.
Tento koncept byl vyžádán přímo firmou OXO, kde z praxe vyplývá problém například
s dodatečným přáním zákazníků fakturu rozdělit mezi více jiných faktur nebo modifikace
jednotlivých dodacích listů. Ve většině případů se totiž jedná o úpravu či přenos celé řady
položek dodacích listů mezi fakturami. Přenositelnost dodacích listů tento problém výrazně
usnadňuje. Nemusí se tak měnit řada dokumentů, protože změna například v dodacím listu se
propaguje do změny faktury. V každém případě se jedná o velmi prospěšnou a užitečnou
možnost, jak efektivně spravovat a přenášet celé bloky položek mezi fakturami v rámci
jednotlivých projektů.
Dodací list je tedy přenositelný v rámci projektu, ovšem ne mezi projekty. Faktura je
nepřenositelná, je to totiž v podstatě pouze obálka pro dodací listy s dodatečnými
informacemi.
59
Obrázek 18: Aplikace s aktivní Bill TopComponentou
Faktura představuje z pohledu programátora jednu z nejsložitějších komponent
programu, z hlediska uživatele je tomu tedy přesně naopak. První panel obsahuje 3
komponenty typu ComboBox pro výběr klienta, jeho projektu a potom faktury, pokud ji
upravujeme, nebo možnost vytvořit fakturu novou.
Druhý panel slouží k upřesnění podrobností o faktuře, jako datum splatnosti nebo
textový popisu faktury, který bude zobrazen ve výstupu z aplikace.
Třetí panel obsahuje tabulku s již nastíněným konceptem pro výběr dodacích listů,
které budou ve faktuře zahrnuty. Pokud chceme dodací list použít v jiné faktuře, musíme jej
nejprve z tabulky odebrat odkliknutím vazby na příslušném řádku tabulky. V opačném
případě se dodací list v nabídce jiné faktury nezobrazí a nebudeme jej moci do této faktury
zahrnout.
Komponenta obsahuje cookies pro tisk či uložení do souboru přes modul DataOutput.
60
9.4.4 Příjmový pokladní doklad (ReceiptTopComponent)
Každá faktura musí být zaplacena, což ale samo o sobě nestačí. Musí být k dispozici doklad,
nejen pro účetní oddělení, ale také pro klienta. Potvrzujeme tím, že jsme od něj finanční částku
přijali (hotově, převodem, …). Faktura může být placena v několika menších částkách. Musíme
tedy uchovávat informaci, kolik plateb a v jaké výši již klient uhradil. Právě k tomuto účelu
slouží příjmový pokladní doklad. Vztahuje se k jednotlivým fakturám v rámci projektu a je
jakýmkoliv způsobem nepřenositelný. Je to tedy obdoba tištěného příjmového pokladního
dokladu, který je běžně prodejný například v papírnictví, ovšem s tím, že je zde většina
činností již automatizovaná. Stačí tedy zadat především přijatou částku a popřípadě další
doplňující údaje, jako účel platby a druh platby.
Obrázek 19: Aplikace s aktivovanou Receipt TopComponentou
Jak ukazuje obrázek 19, komponenta je opět rozdělena do několika panelů. První panel
opět slouží k výběru existujícího, nebo založení nového příjmového pokladního dokladu.
Oproti dříve představeným komponentám, tento panel obsahuje navíc volbu faktura, protože
k faktuře se vždy pokladní doklady, ať příjmové či výdajové, vztahují.
61
Druhý panel slouží k nastavení detailu dokladu, obdobně jako v komponentě faktura,
tedy zadání slovního popisu příjmového pokladního dokladu, který bude zobrazen na
výstupním médiu, uhrazené částky a způsobu platby.
Třetí a poslední panel zobrazuje všechny příjmové a výdajové pokladní doklady, které
se dané faktury týkají společně s automatickými součty přijatých a výdajový pokladních
dokladů, celkové částky faktury a uhrazený/neuhrazený rozdíl. Je to výhodné a není potřeba
žádných pomocných výpočtů, např. při kalkulaci kolik má klient ještě doplatit. Vše je hezky po
ruce. Rozdíl mezi příjmovým a výdajovým pokladním dokladem poznáme podle prefixu
dokumentu a podle toho, zda částka v tabulce je kladná či záporná. Příjmové pokladní doklady
peníze do organizace přináší, proto kladná částka. Výdajové pokladní doklady zase
z organizace peníze odčerpávají, proto záporná částka.
Komponenta obsahuje cookies pro tisk či uložení do souboru přes modul DataOutput.
Každá přidaná položka vyvolá reorganizaci navigačního stromu dat, aby byl pokud možno
stále konzistentní za cenu co nejmenší spotřeby paměti klientského počítače.
9.4.5 Výdajový pokladní doklad (DisbursementTopComponent)
Obrázek 20: Aplikace s aktivovanou Disbursement TopComponentou
62
Protože se například může stát, že zákazník fakturu přeplatí, nebo dojde v rámci reklamace
k vrácení finančního obnosu, je třeba tuto skutečnost zaevidovat. A opět, nejen kvůli účetní
agendě, ale také kvůli zákazníkovi. Logickým krokem byla tvorba entity výdajový pokladní
doklad, který tak tvoří prakticky stejnou logiku jako příjmový pokladní doklad, ovšem s tím
rozdílem, že peníze od přijatých prostředků odepisuje. Z obrázku 20 je patrné, že komponenty
příjmového a výdajového dokladu jsou prakticky stejné. Je to dáno faktem, že se jedná o
prakticky stejné operace, pouze s opačnou matematickou logikou. Komponenta je tedy
vizuálně skoro stejná, její logika je ovšem odlišnější.
Komponenta obsahuje cookies pro tisk či uložení do souboru přes modul DataOutput.
9.4.6 Reklamace (ReclamationTopComponent)
Tato z hlediska návaznosti na cenové nabídky či faktury čistě nezávislá entita, která si dává za
úkol pouze evidovat reklamace, které mohou vzniknout např. v kvalitě vykonaných služeb či
dodaných materiálů. Slouží tedy jako formulář pro soupis škod, které má dodavatel za úkol do
státem stanovené lhůty odstranit.
Obrázek 21: Aplikace s aktivovanou Reclamation TopComponentou
63
Tentokrát jsou zde pouhé dva panely. První opět umožňuje volbu existující nebo vytvoření
nové reklamace u příslušného klienta a jeho projektu. Druhý panel slouží k zadání textu, který
popisuje důvod reklamace. Jedná se tedy o čistě dokumentační komponentu, která nemá
žádnou přímou návaznost na faktury či pokladní doklady. Tuto záležitost musí obsluha vyřešit
manuálně.
Komponenta obsahuje cookies pro tisk či uložení do souboru přes modul DataOutput.
9.4.7 Skladová karta (ItemTopComponent)
Definované položky jsou vytvořeny pro ulehčení práce s opakovaně zadávanými položkami,
např. materiály či službami. Nedisponují přímou vazbou se skladem, pouze poskytují údaje o
produktu.
Obrázek 22: Aplikace s aktivovanou Item TopComponentou
Komponenta ItemTopComponent obsahuje pouhé dva panely. První panel obsahuje
tabulku se všemi definovanými položkami v databázi. Ty můžeme dále měnit, aniž bychom
porušili konzistenci dokladů, které jsou na položkách závislé. Jakmile je totiž položka přidána
64
do cenové nabídky nebo dodacího listu, její účetní atributy jsou převzaty do atributů entitní
třídy DocumentItem. Je to dáno také tím, že pro různé zakázky můžeme požadovat například
různé marže nebo sazby DPH. Po jejím přiřazení jsou tedy používány její popisné části. Pokud
již dále položku nechceme používat, prostě vytvoříme novou a nadále používáme tu. Položky
v tabulce můžeme měnit nebo je úplně odebrat. Odebrat je lze pouze, pokud nejsou používány
žádnou instancí entitní třídy DocumentItem.
Druhý panel nabízí možnost tvorby nové položky. Jakmile zadáme požadovaná kritéria
a stiskneme tlačítko na panelu, položka je vložena do databáze, což se ihned promítne
v tabulce a lze ji používat v dodacích listech a cenových nabídkách.
9.4.8 Klient (ClientTopComponent)
Klientela je důležitou součástí nejen projektu, ale řady jím vlastněných entit, protože to
umožňuje snadné a efektivní vyhledávání v databázi. Jak název napovídá, entitní třída definuje
klientelu, která je přenosná i mezi jednotlivými projekty.
Obrázek 23: Aplikace s aktivovanou Client TopComponentou
65
Tato komponenta se skládá ze čtyř panelů. První slouží pro výběr existujícího klienta
nebo založení nového. Druhý panel obsahuje základní vlastnosti fyzické osoby a její adresy.
Třetí panel zase obsahuje pole pro zadání kontaktních informací a konečně čtvrtý panel slouží
pro zadání firemních údajů, pokud je klient podnikatelský subjekt.
Snažíme se tedy jednotlivé údaje vhodným způsobem rozdělit a jiné zase vhodným
způsobem přiblížit k sobě. Protože podobných formulářů bylo vytvořeno mnoho, více či méně
zdařilých, snažili jsme se nejen v této komponentě přijít s něčím novým a zároveň se poučit
z chyb a dobrých nápadů konkurenčních řešení.
9.4.9 Projekt (ProjectTopComponent)
Projekt, jak už bylo řečeno, všechny zmíněné entity zaštiťuje a poskytuje tak kontejner pro
jejich třídění. Je to logické, protože projekty představují disjunktní množiny v rámci výrobního
procesu firmy OXO a není třeba vytvářet mezi nimi nějaké další vazby.
Ve formě komponenty klientské aplikace představuje krom role obálky pro jednotlivé
dokumenty i jakousi formu rekapitulace.
Obrázek 24: Aplikace s aktivovanou Project TopComponentou
66
Komponenta obsahuje dva panely. První z nich slouží pro výběr existujícího projektu
nebo založení nového. Druhý panel obsahuje vlastnosti projektu. Rekapituluje zde počty a
čísla o jednotlivých dokumentech. Zde si lze udělat představu o tom, o kolik jsme překročili
cenové nabídky, jaká částka dodacích listů ještě není vyfakturována, či kolik peněz k nám ještě
od zákazníka nedorazilo.
9.4.10 Procházení vizuálních dat (ExplorerTopComponent,
BrowserTopComponent)
Jak lépe lze pochopit logiku dat, se kterými pracujeme, než si je vizuálně spodobnit. Přínos
tohoto řešení je dle našeho názoru neocenitelný a je to jedna z klíčových výhod grafických
vlastností klientských aplikací současné generace. My jsme se snažili jít dále a naše data vložit
do stromu. Popisu aplikační logiky modulu Nodes, který je za správu dat zodpovědný, jsme se
věnovali v kapitole 9.3. Tyto komponenty tuto logiku používají.
Obrázek 25: Aplikace s Explorer TopComponentou v levém okně, Browser TopComponentou v okně pravém
67
Na obrázku vidíme obě komponenty a způsob vizuálního spodobnění zadaných dat.
V levém okně aplikace vidíme komponentu ExplorerTopComponent, která využívá pohledu
BeanTreeView, který je rozšířením komponenty JScrollPane23. V pravém okně vidíme trošku
odlišnou formu zobrazení, která se liší především zobrazením horizontálních linek mezi daty,
které slouží jako řádky. JScrollPane této TopComponenty využívá rozšíření TreeTableView. Je
zde samozřejmě možné využívat i jiných pohledů na strukturu uzlů dat, vyžaduje to ale
nasazení jiné třídy.
23 JScrollPane = Zpřístupní vodorovné a svislé posuvníky, pokud se viditelná oblast dat nevejde do
vymezeného okna.
68
Kapitola 10 Závěr
Během této diplomové práce jsme blíže prozkoumali Java EE technologii pro tvorbu
vícevrstvých distribuovaných aplikací. Jako aplikační vrstvu jsme zvolili Enterprise JavaBeans
3.0, s nimiž jsme si vyzkoušeli základní operace s entitami, session beany a rovněž pokročilejší
práci například s dědičností entit jejich a kolekcemi. Jako klientskou vrstvu jsme zvolili
NetBeans Platform a studovali jsme její modularitu, práci se základními API a získané
poznatky jsme si prakticky vyzkoušeli na ukázkové aplikaci. Ta používá NetBeans Platform
jako klientskou vrstvu a Enterprise JavaBeans 3.0 jako aplikační vrstvu. Pro uložení dat
používáme databázi Derby. Aplikační rámec pana Lukáše Krejčího, který jsme vyzkoušeli, byl
snadno nastavitelný a pro účely ukázkové aplikace se ukázal jako funkční. Jako výstup dat
z aplikace ve formě tiskové sestavy nebo výstup do souborů známých formátů se osvědčila
sada knihoven JasperReports 3.5, již jsme podrobněji probrali v kapitole 5.
Práce na ukázkovém programu prokázala přínos ve zjednodušení vývoje ať už
rozdělením jednovrstvé aplikace do vícevrstvé pomocí vhodné architektury s vhodnou
implementací vrstev a další zjednodušení v klientské vrstvě díky její modularitě. Pokud tedy
například zákazník bude chtít použít jinou klientskou vrstvu, nyní je tato možnost
proveditelná snadněji než kdykoliv dříve. Pokud chce klient použít jinou variantu zobrazení
dat například jinou sadou komponent pro manipulaci s daty, opět stačí vyměnit jeden modul
v rámci klientské vrstvy.
Celkově je spojení NetBeans Platform s Enterprise JavaBeans 3.0 efektivní, snadno
udržovatelné a především funkční právě díky bakalářské práci pana Lukáše Krejčího. Cíle této
diplomové práce jsou splněny a věřím, že tento text stejně jako ukázkové aplikace ukáže
začátečníkům v této oblasti možnost tvorby vícevrstvých aplikací s těmito technologiemi.
Pro další studium těchto témat doporučujeme především bakalářskou práci pana
Lukáše Krejčího (20), zabývající se především propojením NetBeans Platform s Enterprise
JavaBeans 3.0, napsanou v semestru jaro 2009. Dále Je tu práce pana Tomáše Vágnera (18) ze
semestru jaro 2007, která se zabývá podobnou problematikou jako tato diplomová práce,
věnuje se ovšem především navázání spojení mezi NetBeans Platform a Enterprise JavaBeans
3.0, kterou překonává práce pana Lukáše Krejčího, a práci ve víceuživatelském prostředí.
Poslední práci, kterou si můžete prostudovat, je bakalářská práce pana Tomáše Kyjovského
(19) ze semestru Jaro 2006, která je převážně aplikačně orientovaná, ovšem pouze s využitím
NetBeans Platform verze 5.5.
Java EE architektura a implementace jejích vrstev je dle mého názoru velmi zajímavá a
rád bych se jí věnoval ve svém povolání nebo v případném navazujícím studiu.
69
Literatura
1) NetBeans Platform komunita: NetBeans Platform Learning Trail, NetBeans Platform,
dostupné online http://edu.netbeans.org/courses/nbplatform-
certified-training/.
2) Komunita JasperForge.org: JasperReports Project Home, JasperSoft Inc., dostupné
online http://jasperforge.org/projects/jasperreports.
3) Komunita JasperForge.org: JasperReports FAQ, JasperSoft Inc., dostupné online
http://jasperforge.org/website/jasperreportswebsite/trunk/
faq.html?group_id=252.
4) Sriganesh, Rima Patel - Brose, Gerald - Silverman, Micah. Mastering Enterprise
JavaBeans 3.0. Indianapolis: Wiley Publishing, Inc., 2006. 685 s. ISBN 978-
0471785415.
5) Boudreau, Tim – Tulach, Jaroslav – Wielenga, Geertjan. Rich client programming:
plugging into the NetBeans platform. Upper Saddle River, NJ: Prentice Hall, 2007. 604
s. ISBN 0132354802
6) Přispěvatelé Wikipedie: Java EE, Wikipedia, The Free Encyclopedia, dostupné online
http://cs.wikipedia.org/wiki/J2EE.
7) Přispěvatelé Wikipedie: GNU Lesser General Public License, Wikipedia, The Free
Encyclopedia, dostupné online http://en.wikipedia.org/wiki/
GNU_Lesser_General_Public_License.
8) Přispěvatelé FI Wiki: Enterprise JavaBeans, FI MUNI, dostupné online
http://kore.fi.muni.cz:5080/wiki/index.php/EJB.
9) Ebenlendr, Tomáš: Java 2 Enterprise Edition, MFF CUNI, dostupné online
http://artax.karlin.mff.cuni.cz/~ebik/nju/linuxem/J2EE/
J2EE.html.
10) Rychlý, Marek: Java Platform, Enterprise Edition, FIT VUTBR, dostupné online
http://www.fit.vutbr.cz/research/grants/index.php?
file=%2Fproj%2F378%2Fslides-javaee.pdf&id=378.
11) Ježek, Kamil: JasperReports – tisk v Javě, Java Portál, dostupné online
http://java.cz/detail.do?articleId=6795.
12) NetBeans komunita: EJB & Web Service Applications Learning Trail, NetBeans
Tutorials, Guides and Articles, dostupné online
http://www.netbeans.org/kb/trails/java-ee.html.
13) NetBeans Platform komunita: platform, NetBeans Platform, dostupné online
http://platform.netbeans.org.
14) Pitner, Tomáš: Java – začínáme programovat, FI MUNI, dostupné online
http://www.fi.muni.cz/~tomp/java/ucebnice/.
15) Wielenga, Geertjan: SaveCookie (Part 1), Geertjan´s blog, dostupné online
http://blogs.sun.com/geertjan/entry/savecookie
70
16) Sun Microsystems Inc.: Trail: JavaBeans, Java Tutorials, dostupné online
http://java.sun.com/docs/books/tutorial/javabeans/.
17) Jelínek, Lukáš: Java (32) – tiskové služby, Linux Software, dostupné online
http://www.linuxsoft.cz/article.php?id_article=1433.
18) Vágner, Tomáš: NetBeans Platform jako EJB klient [bakalářská práce], FI MUNI,
dostupné online http://is.muni.cz/th/143266/fi_b/?lang=cs.
19) Kyjovský, Tomáš: Integrace slovníků do prostředí platformy NetBeans [bakalářská
práce], FI MUNI, dostupné online http://is.muni.cz/th/72682/fi_b/.
20) Krejčí, Lukáš: NetBeans Platform jako EJB klient [bakalářská práce], FI MUNI,
dostupné online http://is.muni.cz/th/207393/fi_b/.
71
Dodatek A Příloha DVD-ROM
Součástí této práce je DVD-ROM médium obsahující zdrojové kódy a potřebnou dokumentaci
k ukázkové aplikaci. Pro přehlednost je médium rozčleněno do několika adresářů:
Source – obsahuje zdrojové kódy aktuální verze
ukázkové aplikace.
Dist – připravená distribuce aktuální verze se
všemi potřebnými částmi, sestavená pro
aplikační server GlassFish V2.
Model – Podklady pro UML modelování aplikace.
Backup – Důležité zálohy aplikace v průběhu
vývoje.
Text – Veškerá dokumentace a její podklady.
AsConnectors – Poslední dostupné sestavené
pluginy bakalářské práce pana Lukáše Krejčího,
připravené pro použití v ukázkové aplikaci.
Reports – Tiskové sestavy pro JasperReports.
Pro spuštění aplikace se předpokládá nasazení JAR archivu aplikační vrstvy na
aplikačním serveru GlassFish V2 v operačním systému MS Windows v případě použití
sestavené distribuce. V případně nasazení v jiném prostředí je nutné upravit údaje k připojení
na aplikační server v souboru layer.xml, v modulu GlassFishJNDIProps, v případě jiného OS
znovu sestavit aplikaci. Postup byl odzkoušen a je funkční.