Table of Contents
Projekt Medulla je OpenSource abstraktní aplikační server s možností transakčního zpracování, logování pomocí knihovny Log4J a generování datové struktury z XML dat.
Modul cz.luboss.medulla - Aplikační server, obsahuje generovanou datovou vrstvu, která může být výstupem modulu spinster.
Modul cz.luboss.medclient - Klient, obsahuje třídy pro zobrazování a editaci objektů, zobrazovaní filtrovaných a tříděných seznamů, tisk pomocí reportovacího nástroje Jasper atd.
Modul cz.luboss.spinster - podle zadého souboru XML vygeneruje příslušné třídy v JAVA souborech. Generátor umožňuje přegenerování, tzn. v každém vygenerovaném souboru je vyhrazený oddíl, který se nepřepisuje a kam je možné vkládat vlastní metody a atributy. V budoucnu se počítá s generováním příslušných SQL skriptů. jeho popis je uveden samostatně.
V celém projektu je každý objekt, který je persistentní, potomkem abstraktní třídy MeItem. Generováním v aplikaci spinster se přepíšou mimo jiné tyto funkce :
int getFieldID() - Vrátí pořadí parametru obsahující ID objektu.
int getID() - vrátí ID parametru
String getNameID() - vrátí jméno parametru s ID
String generateKod() - vygeneruje jedinecny kod pro registraci do transakce
set... a get... metody pro každý atribut
!!! Upozornění !!! Pokud budete editovat parametry přes funce getParam(int nRow) a getParamByID(int nID), je nutné objekt MeItem nejdříve zaregistorovat, pokud toto neuděláte, nebudou tyto změny uloženy. Toto se netýká změn provedených přes funkce set.....
Potomky této třídy generuje program Spinster ze souboru XML. V tomto souboru jsou nadefinovány jednotlivé atributy třídy, SQL příkazy pro SELECT, UPDATE a INSERT do databáze, zobrazení třídy v seznamech, pravidla editace, vazby na podřízené pole typu MeArray atd.
Tato třída reprezentuje pole položek MeItem, a to pro každeho potomka této třídy. Generuje se a přepisuje tuto funkci :
MeItem addItem() - vrátí nový objekt vložený do pole MeArray.
Potomkem této třídy je každý atribut objektu MeItem. Každý atribut má jméno, které je vždy řetězec a pomocí něj se odkazuje např.do databáze, při výpisu tabulek atd. a hodnotu která je pochopitelně pro každý typ různá. Zatím jsou implementovány tito potomci :
MeFieldDATE - pro datové atributy
MeFieldFLOAT - pro desetinné atributy
MeFieldINT - pro celočíselné atributy
MeFieldREF - pro odkazy na jiné objekty typu MeItem
MeFieldSTRING - pro textové atributy
V této třídě jsou implementovány fukce pro zjištění typu, pro nastavení jména a hodnoty atributu a pro výstup s fomátovaným textem buď pro zobrazení nebo pro SQL.
MeSession - je objekt vytvářený pro jednoho přihlášeného uživatele uživatele, ve které jsou informace o uživateli (jazyk, ...) a případně log jeho práce.
MeUniSQLItem - je potomkem třídy MeItem a umožňuje naplnit pole prvk bez předchozíí znalosti atributů, výhodné např. pro výstup ze SQL SELECTu atd.
MeUniSQLArray - pole prvků MeUniSQLItem.
Pro snadnou komunikaci mezi serverem a klientem je zde vytvořena univerzální vrstva umožňující implemenovat jakoukoli technologii. Zatím jsou implementované rozhraní SQL a RMI od Sunu, v plánu mám CORBA a XML-PROC. Každá implementace musí dědit interface cz.luboss.medulla.factory.MeDataMachine :
MeConnect getConnect() - Vrátí konfiguraci připojení.
setConnect(MeConnect dbConnect) - Nastaví configuraci připojení.
MeDataTest sendTest(MeDataTest testing) - Otestuje rozhraní.
MeSession loadSession(String sLogin, String sPassword) - Zaloguje uživatele a vrátí jeho session.
MeArray getActualSessions() - Vrátí všechny aktuání session.
boolean isValidSession(int nSessionID) - Zjistí, zda je session platná.
loadData(int nSessionID, MeItem item, int nID) - Nahraje data do objektu.
loadArray(int nSessionID, MeArray arrayItem, MePodminka podminka) - Nahraje data do pole.
saveTrans(int nSessionID, Collection arrTransData) - Uloží data transakce, tzn pole objektů MeItem.
int addSequenceID(int nSessionID, MeItem item) - Přidělí ID novému prvku.
V metodách jsou použity třídy MeConnect a MeSession, kde MeConnect je pouze interface bez metod pro všechny konfigurace připojení a MeSession je popsán výše. Před vytvářením nových variant doporučuju nastudovat moje implementace.
Pro snadnější implementaci je ve třídě MeDataMachineSQL vazba na potomka třídy MeParamSQL, který pro každý vygenerovaný objekt MeItem vrací SQL příkazy, tzn. při přechodu na jinou databázi stačí generátoru nastavit jiné jméno např PeParamSQL_Oracle a změnit inicializaci továrny
Teto modul je určen jako serverová strana pro spojení RMI.
MeServerRMI - RMI server se základními funkcemi datových továren.
MeColumn - Třída jednoho sloupce jako atributu pro zobrazení seznamu objektů MeItem.
MeConfig - Třída pro načtení konfiguračních hodnot, hodnoty se dotahují přes funkci GetParam(String nazev).
MeContext - Kontext běžící aplikace, obsahuje atributy konfigurace MeConfig, datového připojení MeConnect a továrny MeDataFactory, resource pro jazykové verze ResourceBundle, aktuální session MeSession, transakční kontext MeTransact a nastavení logování Log4J.
MeDataTest - testovací objekt
MeDefine - definované konstanty jazyk, typ datové tovarny ...
MedullaContext - tato třída pouze obaluje objekt třídy MeContext, tak aby bylo možné volat funkce třídy MeContext přes MedullaContext.getRes(......
MePodminka - třída pro vytvoření filtrovací podmínky pro třídu MeArray, umožňuje funkce AND a OR.
MeTransact - transakční kontext, popsán níže.
MeUtils - třída obsahující pomocné statické funkce.
Tento balík je určen k zobrazení, tisk a přímou práci uživatele s daty.
V tomto balíku jsou pomocné funkce pro zobrazování dialogů :
cz.luboss.medulla.McDialog - Dialog pro zobrazeni a editaci objektu třídy MeItem
cz.luboss.medulla.McDlgParam - Dialog pro zobrazeni a editaci objektu třídy MeField
cz.luboss.medulla.McDlgSelect - Dialog pro filtrování a výběr z polí MeArray
Aplikace Medulla využívá pro tisk knihovnu Jasper, OpenSource projekt pro práci s reporty. Umožňuje výstupy do pdf, rtf a přímo tisknout i s náhledem. Pro editaci šablon, které se ukládají v XML, lze použít OpenSource editory např. JReport práce s nimi je velmi podobná např. Crystal Reportu.
Způsob vytváření reportů je dvojí, přes JDBC nebo přímo plnění daty. Při použití JDBC stačí vytvořit report, nastavit SQL dotaz pro plnění a jména parametrů pro filtrování jako součást SQL dotazu. Tento způsob je možno použít pouze pro datovou továrnu SQL, příklad je popsán ve třídě PeProductGrid.
Druhý způsob spočívá v přímém vygenerování pole objektů a jejich vložení do reportu, zájemce odkazuji na Jasper API.
V tomto balíku jsou možné skiny a styly pro zobrazování oken - Mac, Windows, Java, Unix ....
V tomto balíku jsou třídy pro zobrazení třídy MeArray v tabulkách.
cz.luboss.medulla.McGrid - základní tabulka, jako parametr při vytváření se podává naplněný objekt MeArray.
cz.luboss.medulla.McHeaderPanel - panel obsahující potomka třídy McGrid a panel s tlačítky např. Vytvoř nový, smaž .....
cz.luboss.medulla.McItemGrid - univerzální grid pro jakýkoli MeItem, zatím nefunguje!!!
cz.luboss.medulla.McParentGrid - grid, na jehož posun na jiný řádek reaguje jiný grid.
cz.luboss.medulla.TableMap - pomocná třída pro zobrazení.
cz.luboss.medulla.TableSorter - třída umožňující tabulky přímo třídit.
Pro logování je použita knihovna Log4J, dopuručuji nastudovat návod k tomuto projektu. Logují se Exception, funkce potomků třídy MeDataMachine, spuštění serveru a načtení datového zdroje.
Projekt Medulla má pro práci s objekty MeItem vytvořen transakční kontext. Princip práce s tímto kontextem můžeme zjednodušeně popsat jako možnost zahájit transakci, provést s libovolným počtem objektů libovolný počet manipulací (vytvoření, změna nebo smazání) a možnost v kterémkoli okamžiku transakci buď to potvrdit nebo zrušit. Pokud bude transakce potvrzena, budou všechny změny provedené na objektech v transakci uloženy, pokud bude zrušena, budou všechny objekty nastaveny na původní hodnoty. Lze provádět libovolné množství vnořených transakcí, pouze je třeba brát ohled na vyšší paměťové nároky v případě skutečně velkého množství transakcí a objektů.
Transakční kontext se nachází v souboru cz.luboss.medulla.common.MeTransaction, ale jednotlivé metody se spouští přes kontext celé aplikace MeContext nebo jeho potomky.
Celý průběh transakčního zpracování probíhá spouštěním funkcí z kontextu celé aplikace :
startTransaction() - zahájí novou transakci.
MeItem LoadItem(int nID) - nahraje objekt z transakce, pokud v teto transakci neexistuje, dotáhne z podrizene a pokud neexistuje v žádné transakci, nahraje z databáze. Pokud neexistuje ani tam funkce vrátí null. Pokud tuto funkci spustíte ve chvíli, kdy nebude započata žádná transakce, bude vyvolána Exception.
register(MeItem) - zaregistruje objekt do transakce, v projektu se všechny objekty registrují přímo při editaci pomocí meto set a get pro každý atribut. Pokud tuto funkci spustíte ve chvíli, kdy nebude započata žádná transakce, bude vyvolána Exception.
unregister(MeItem) - odregistruje objekt z transakce tzn. pokud ho změníte, nebudou tyto změny po ukončení transakce trvalé. Objekty lze znovu registrovat. !!! Upozornění !!! Pokud objekt unregistrujete, bude po nové registraci dotažen z předchozí transakce nebo z databáze a veškeré změny provedené před registrací budou smazány. Pokud tuto funkci spustíte ve chvíli, kdy nebude započata žádná transakce, bude vyvolána Exception.
commit() - ukončí aktuální transakci a všechny změny uloží do nadřazené transakce, pokud již žádná není, uloží do databáze. Pokud tuto funkci spustíte ve chvíli, kdy nebude započata žádná transakce, bude vyvolána Exception.
rollback() - ukončí aktuální transakci a všechny změny zahodí. Všechny objekty které byli v této transakci změněny, budou mít opět své původní hodnoty, buď z předchozí transakce nebo z databáze. Pokud tuto funkci spustíte ve chvíli, kdy nebude započata žádná transakce, bude vyvolána Exception.
Zde bych chtěl ukázat jednoduchost implementace Medully do nového projektu. Jedná se jednoduchý výrobní systém Pensum, jehož zdrojové kódy jsou rovněž k dispozici.
Modul obsahující pomocné knihovny s kontextem, jazykovými verzemi atd.
cz.luboss.pensum.client.panel.Pc......Panel - zde jsou vytvořeny panely z jednotlivých potomků třídy MeArray.
cz.luboss.pensum.client.view.Pe.....Grid - zde jsou vytvořeny tabulky pro jednotlivé potomky třídy MeArray.
cz.luboss.pensum.client.PenClient - hlavní spouštěcí třída, stará se o zobrazení, nastavení všech počátečních parametrů PensumContext .....
Modul obsahující pomocné knihovny s kontextem, jazykovými verzemi atd.
cz.luboss.pensum.common.PeConfig - Rozšíření kofiguračníhou souboru MeConfig.
cz.luboss.pensum.common.PensumContext - Rozšíření kontextu a nastavení datové továrny (SQL nebo RMI), dotažení konfiguračního souboru ....
cz.luboss.pensum.common.PeResources_cs - Objekt s jazykovými resource, pro ostatní jazyky ..._gr, ..._en.
Modul obsahující rozšíření datové vrstvy o specifické funkce.
cz.luboss.pensum.factory.PeDataMachine - Rozšíření datové továrny o nové funkce aplikace Pensum.
Modul obsahující vygenerované třídy potomků MeItem, MeArray a MeParamSQL.
cz.luboss.pensum.gener.Pe.... - Vygenerované třídy pomocí programu spinster.
Základní modul serveru který je třeba pouze pro připojení RMI, připojení SQL nepotřebuje třídy PeServerRMI a TestPensum.
cz.luboss.pensum.server.PeServerRMI - Běžící server RMI.
cz.luboss.pensum.server.TestPeServerRMI - testovací server, odesílá a příjmá objekt MeDataTest.
Jméno souboru s konfigurací celého projektu se nastavuje v okamžiku inicializace MedullaContext přípaně v potomcích. Hlavní TAG je <CONFIG> ostatní jsou :
<CONNECTSTRING> - přihlašovací řetězec obsahující server, databázi ... např. jdbc:mysql://localhost/pensum?useUnicode=true&characterEncoding=windows-1250
<USERDB> - uživatel DB
<PASSDB> - heslo DB
<REMOTESERVER> - IP adresa RMI serveru
<REMOTECLASS> - RMI třída pro spouštění RMI metod
<LOG4J_FILE> - konfigurační soubor pro Log4J
<LOGDIR> - adresář pro ukládání výpisu jednotlivých Exception, zatím se nepoužívá
<PRINTDIR> - adresář s tiskovými šablonami
<DEBUG_CLIENT> - případné logování funcí pro každého uživatele zvlášť (pokud není, neloguje se)
<VALID_TIME> - čas platnosti jedné session v minutách
Tento modul generuje jednotlivé potomky třídy MeItem. Je jakousi náhradou XSLT transformace, protože se mi nechtělo studovat další jazyk, ale jednou to určitě převedu :-).
Tyto soubory obsahují proměnné {0} .. {X}, kam se při generování budou nahrávat data. Tyto soubory doporučuju editovat až po důsledném studiu.
item.pat - Soubor s vzorem celé třídy MeItem.
item_array.pat - Soubor s vzorem celé třídy MeArray.
item_getcolumns.pat - Soubor s vzorem metody getColumns().
item_getsubarray.pat - Soubor s vzorem metody getSubArray.
item_setgetmetods.pat - Soubor s vzorem metod set.. a get.. pro atributy.
item_sqlparam.pat - Soubor se vzorem třídy pro SQL příkazy.
Spustění programu proveďte jako normální JAVA aplikaci se těmito nutnými parametry :
java cz.luboss.Spinster <xmlfile=jmeno_xml> <sourcedir=jmeno_adresare> <paramclass=jmeno_param_tridy>
Parametry :
jmeno_xml - jméno souboru s definicí tříd.
jmeno_adresare - jméno adresáře, do kterého se ukládají vygenerované soubory.
jmeno_param_tridy - jméno třídy se SQL příkazy.
Zde bych rád popsal XML soubor pro generování potomků třídy MeItem. Jako hlavni TAG je použit <PENSUM_ITEMS> ve kterém jsou umístěny TAGy <ITEM> pro každou třídu. jeho parametry jsou následující :
<NAME> - jméno třídy.
<PARENT> - jméno rodičovské třídy.
<PORADI_ID> - Pořadí paramertu s ID objektu.
<DESCRIPTION> - popis třídy, bude umístěn v komentáři.
<INSERT_TABLE> - jméno SQL tabulky do teré se bude celý objekt ukládat.
<FIELD_SQL> - SQL dotaz pro naplnění objektu.
<FIELD_ARRAY><FIELD> - pole atributů třídy.
<NAME> - jméno atributu, pod tímto jméne bude také ukládán do databáze.
<TYPE> - typ atributu, jsou povoleni všichni potomci třídy MeField.
<DEFAULT> - defaultní hodnota atributu.
<EDIT> - signál zda bude možno atribut editovat uživatelem.
<DESCRIPTION> - popis atribitu.
<REF_CLASS> - odkazovaná třída, platné pouze u typu MeFieldREF.
<REF_NAME> - jméno atributu v odkazované třídě, který se bude zobrazovat, platné pouze u typu MeFieldREF.
<VIEW_ARRAY><VIEW> popisy jednotlivých atributů pro jejich zobrazení.
<NAME> - jméno atributu.
<WIDTH> - šířka sloupce.
<SUB_ARRAY><ARRAY> - Pole podrizenych polí třídy.
<NAME> - jméno subpole.
<DESCRIPTION> - popis subpole.
<ID_NAME> - jméno atributu ve třídě subpole, který bude svázán s ID třídy.
<TYPE> - třída subpole.
Pro práci s dabatabází jsou zde ještě dva hlavní parametry :
<DRIVERNAME> - jméno databázového ovladače
<SEQUENCE_TABLE> - tabulka se SEQUENCEMI pro ID objektů, sloupce se budou jmenovat sqname (VARCHAR50) a sqcounter (INT), zbytek si již program vytvoří sám.
Tímto bych uzavřel tento malý manuál k projektu Medulla. Moje osobní stránky naleznete na adrese http://capaty.nastole.cz, stránky projektu jsou na http://capaty.nastole.cz/index.php?page=frm_medulla, najdete zde poslední verze zdrojových kódů, komentáře atd...