Hlavní navigace

Kylix (8) - XML, třívrstvá architektura, WebSnap

4. 6. 2002
Doba čtení: 9 minut

Sdílet

Dnes nás čeká závěrečný díl seriálu o Kylixu. Podíváme se na zoubek implementaci XML v Kylixu (včetně zapouzdření XML do tříd Object Pascalu), dále napíšeme vícevrstvou (multitier) databázovou aplikaci a na závěr si krátce ukážeme, jak se dá také psát webový server. No a nakonec malý bonus.

Kylix a XML

Jak jistě pozorujete, dnes XML hýbe světem. Pokud vás zajímá, jak je na tom Kylix s podporou XML, jste na správné adrese.

XML za pomocí komponent

Kylix obsahuje komponentu TXMLDocument, která umí s XML pracovat a je umístěna na paletě komponent v záložce Internet. Tato komponenta umí XML načíst ze souboru, streamu nebo třeba z paměti. Dále obsahuje vlastnost DOMVendor, která určuje, čí implementace DOM (Document Object Model) bude použita. V současnosti jsou v Kylixu 2 dvě implementace DOM od IBM a Open XML. Pokud bychom chtěli mít jinou implementaci, musíme implementovat následníka TDOMVendor. Uvedu jednoduchý XML soubor, se kterým budeme pracovat.

<?xml version="1.0" standalone='yes'?>
<Nakup Datum="25.5.2002">
  <Polozka Jmeno="Maslo" Cena="24.50" />

  <Polozka Jmeno="Maso" Cena="80.00" />
  <Polozka Jmeno="Med" Cena="100.00" />
  <Polozka Jmeno="Mleko" Cena="12.80" />
</Nakup>

Jak je vidět jedná se o jednoduchý nákupní lístek (ceny jsem si vymyslel).

Jak k tomu budeme přistupovat? Na formulář si vložíme komponentu

TXMLDocument (samozřejmě ji také můžeme vytvořit za běhu) a tlačítko. Do komponenty XMLDocument vložíme XML (nebo ho můžeme za běhu nahrát ze souboru) a napíšeme obsluhu tlačítka OnClick.

ShowMessage(XMLDocument1.DocumentElement.ChildNodes[0].Attributes['Jmeno']);

Uvedený příklad zobrazí text „Maslo“, protože DocumentElement je kořenem XML, dále je vybrán první podřízený uzel a v seznamu jeho atributů je podle jména „Jmeno“ nalezena jeho hodnota. Samozřejmě, že je možno dokumentem libovolně procházet, mazat a přidávat uzly, celý XML uložit (stream, soubor …) atd.

XML jako objekty Object Pascalu

Výše uvedené je hezké, ale silně to popírá podstatu Object Pascalu (přísná typová kontrola). Když se například upíšete ve jménu atributu, tak máte vystaráno. Prostě to chce ještě něco jiného, a to něco je XML Data Binding. V podstatě to značí, že se XML převede jako třídy Object Pascalu, což je docela náročné, pokud ovšem nepoužijeme dalšího z řady „wizardů“, který všechnu práci udělá za nás a příslušné třídy nám vytvoří. Wizard se nachází v menu New – XML Data Binding a po spuštění a zadání jména XML souboru nám nabídne mezi jinými i volbu nativních typů pro jednotlivé atributy (standardně je string).

Poznámka: schválně jsem vybral tento příklad, protože zde narážíme na problém lokalizace a já jsem záměrně zadal ceny špatně (měly být s čárkou a ne s tečkou). Tudíž u ceny nemůžeme zadat typ double, musíme ponechat string, ale zato si můžeme ukázat něco jiného.

Takže kouzelníček nám vygeneroval unit, který zde nebudu uvádět, jelikož je kapánek delší, ale můžete si ho stáhnout se všemi zdrojáky zde a prozkoumat.

Unit v podstatě obsahuje deklarace dvou rozhraní IXMLNakupType = interface(IXMLNo­deCollection) a IXMLPolozkaType = interface(IXMLNode) a deklarace a implementace dvou tříd, které implementují chování XML TXMLNakupType = class(TXMLNode­Collection, IXMLNakupType) a TXMLPolozkaType = class(TXMLNode, IXMLPolozkaType). Všechny třídy jsou potomky bázových tříd, které implementují obecné funkce.

Poslední věcí ve vygenerovaném unitu jsou tři funkce sloužící

  • k načtení objektu z kompatibilního zdroje (jako je např. náš XML soubor) – LoadNakup
  • k vytvoření nového prázdného XML dokumentu – NewNakup
  • pro získání dat z existujícího zdroje – GetNakup

Jak je vidět, jména funkcí (ale i tříd) se generují podle XML, takže můžeme mít několik různých tříd pro různé XML.

A jak se s tím pracuje? Vytvořte nový projekt a přidejte do něj vygenerovaný unit. Na formulář vložte tlačítko (btnLoad) a komponentu ListBox, do uses předejte odkaz na vygenerovaný unit a do části public formuláře přidejte proměnnou Nakup:IXMLNakup­Type;. Nakonec napište obsluhu OnClick tlačítka

procedure TForm1.btnLoadClick(Sender: TObject);
var
  i:Integer;
begin
  DecimalSeparator:='.';
  Nakup:=LoadNakup('pokus.xml'); //načti data z XML
  ListBox1.Items.Clear; // smaž staré položky
  for i:=0 to Nakup.Count-1 do //projdi všechny položky
  begin
    ListBox1.Items.Add(Format('%s stojí %f',
      [Nakup.Polozka[i].Jmeno, StrToFloat(Nakup.Polozka[i].Cena)]));
  // a přidej Jmeno a Cenu do ListBoxu
  end;
end;

Myslím, že je to jasné, až na ten DecimalSeparator. Jedná se o jednu z globálních proměnných, které jsou čteny z locales. Obsahuje oddělovač desetinných míst a pro češtinu je tam „,“. Jelikož všechny konverzní rutiny jako StrToFloat, FloatToStr … reagují na nastavené locales, byl jsem nucen toto nastavení uměle přehodit (mám v XML tečky).

Poslední věcí ohledně XML je program XMLMapper, který se nainstaluje i s Kylixem a umožňuje s XML různé transformace.

Vícevrstvá (multitier) aplikace

Kylix Enterprise lze využít na vytváření elegantních třívrstvých aplikací (např. databázových). Třívrstvá aplikace znamená rozdělení problému do tří vrstev (demonstrovano na příkladu DB):

  • Relační DB server (Postgresql, Firebird …), který spravuje vlastní databázi
  • Aplikační server, který bere data z DB serveru a zprostředkovává je klientům
  • Tenký klient(i), který přebírá data z aplikačního serveru a zprostředkovává je uživateli

Výhodou tohoto řešení (oproti dvouvrstvé architektuře) je větší modularita. Například při dobře navržené struktuře se v případě změny databázového serveru změní pouze aplikační server a klienta se tato změna nedotkne (nebo můžeme mít více aplikačních serverů pro různé databázové servery, které ale mají společné klienty).

Poznámka: modularita je cílem veškerého snažení v programování. Vezměme si např. vývoj programovacích technik. Na začátku byl program jedna velká nudle, pak se přišlo s moduly a oddělenou kompilací, následovalo objektové programování, poté komponentní programování, nyní se do toho začínají plést objekty v XML a kdo ví, co nás čeká.

Kylix 2 Enterprise používá pro komunikaci mezi aplikačním serverem a klientem SOAP (viz minulý díl).

Aplikační server via SOAP

Postup tvorby serveru je strašně jednoduchý. Použijeme dva wizardy z palety WebServices a to Soap Server Application a Soap Server Data Module. První nám vygeneruje kostru serveru (viz minulý díl) a druhý nám vygeneruje datový modul (což je nevizuální kontejner na komponenty), který je následníkem TSoapDataModule a já jsem ho pojmenoval

BioLifePresenter. Celý projekt se jmenuje BioSoap.

Do datového modulu vložíme komponentu ClientDataSet, která nám bude určovat naši databázi (v našem případě se nebude připojovat na žádný DB server, pouze bude číst lokální databázi – takže to nebude až tak multitier). Jako databázi použijeme moji oblíbenou (viz díl o databázích) tabulku BioLife, takže u komponenty ClientDataSet nastavíme vlastnost FileName na cestu k databázi (nezapomeňte, že pokud zadáváte relativní cestu, musí být relativní vzhledem k adresáři, kde bude program nakonec uložen).

Teď do datového modulu přidáme komponentu TDataSetProvider a nastavíme u ní propojení na náš ClientDataSet (vlastnost DataSet) a jméno na dspBioLife. Toto jméno bude veřejné. A tímto krokem jsme se serverem hotovi. Poznámka: ve skutečnosti je lepší data dynamicky zavádět, resp. je to nutné, pokud data nejsou jen ke čtení. V přiložených zdrojových kódech využívám události vytvoření datového modulu (OnCreate) pro načtení dat ze zadaného souboru.

Překompilovanou aplikaci nahrajeme do adresáře pro CGI u Apache a zadáním URL, kde za jméno našeho serveru připojíme /wsdl, zjistíme, zda náš program funguje a generuje WSDL popis.


Tenký klient

Napsat klienta také není vůbec těžké. Předpokládám, že jste četli díl o databázích, protože náš klient bude prakticky stejný (pokud ne, určitě to napravte). Databázové komponenty tedy nebudu nijak rozvádět, pouze uvedu, jak se propojíme s aplikačním serverem.

Propojení je realizováno pomocí komponenty SoapConnection, na kterou je navěšena komponenta ClientDataSet, a pak již klasicky

DataSource – (vše nevizuální komponenty).

Hlavní práci odvádí SoapConnection, u kterého musíme nastavit URL, kde je dostupný náš aplikační server. V mém případě to bylo http://localhos­t/protected-cgi-bin/BioSoap/so­ap/IBioLifePre­senter, kde BioSoap je jméno serveru (binárky) a IBioLifePresenter je rozhraní, které jsme definovali.

Následně, pokud náš aplikační server běží, si ve vlastnosti ProviderName u našeho ClientDataSetu vybereme službu (v našem případě dspBioLife, kterou jsme publikovali komponentou DataSetProvider u serveru). A nakonec nastavíme u ClientDataSetu vlastnost Active na True, čímž otevřeme komunikaci.

Pokud to nefunguje, je ještě možné, že server nemá dostupné knihovny. Nápravu provedeme v konfiguračním souboru Apache (httpd.conf). Samozřejmě pozor na bezpečnost. Já jsem to vyřešil přidáním řádku SetEnv LD_LIBRARY_PATH adresář_kylixe/bin a restartem Apache. Je samozřejmě vhodnější exportovat jen některé knihovny, ale to je jen pro účely ladění.

Pro inspiraci uvádím snímek obrazovky v návrhovém módu (databáze je aktivní). Na něm lze vidět všechny použité komponenty (a nesmím zapomenout na zdrojové kódy).


Webové aplikace za pomoci WebSnap

V minulém dílu jsem ukázal, jak psát aplikace pomocí WebBroker, a dnes opravdu jen nastíním, co umožňuje WebSnap z Enterprise.

WebSnap je framework pro vývoj internetových aplikací za co nejmenší námahy. Navíc umožňuje integrovat různé internetové služby (pomocí komponent Indy z instalace nebo např. Synapse) a nabízí podporu Java skriptů (na straně serveru, tj. vygenerované stránky jsou čistě v HTML).

Celý projekt se skládá jak z kódu v Object Pascalu, tak v IDE generovaných HTML stránek, které lze upravovovat a které aplikace zpracovává a předkládá klientům. V IDE je navíc možnost zobrazit výslednou HTML stránku. K tomu účelu je nainstalován a do IDE integrován preview jako widget z Mozilly.


Na obrázku vidíte preview aplikace napsané pomocí WebSnap.

Mezi klíčové komponenty pro psaní WebSnap aplikací patří TAdapterPagePro­ducer. Tato komponenta generuje HTML soubor podle požadavků a podle zadaných „adapterů“. Požadavky se specifikují jako strom položek, kde každá položka může mít specifikované vlastnosti (viz obrázek, kde je popsán HTML soubor z předchozího obrázku). Adaptéry jsou například na přihlášení, na sessions …

Na obrázku lze pozorovat, že komponenta AdapterPageProducer vlastní AdapterForm1, ten vlastní mřížku (v pravém okně jsou sloupce databáze) a ta má seznam povolených příkazů (to jsou ta tlačítka v předchozím obrázku).

Komponent TAdapterPagePro­ducer může být v aplikaci vícero (další by byla např. na editaci konkrétního záznamu napojená na tlačítko Edit).

Zdrojové kódy jsou tady. Jsou pouze pro zajímavost, protože jsem tam nenapsal ani řádek kódu (všechno jsem naklikal).

Nejlepší je nainstalovat trial verzi a zkusit si všechno sám. V instalaci je mnoho demo příkladů, které jsou mnohem obsažnější než ty moje.

Bonus

Pro ty, co dočetli až sem, následuje malá odměna.

Nejen vážnou prací živ je člověk. Proto pokud chcete napsat nějakou gamesku (a kdo by nechtěl), musíte určitě navštívit JEDI-SDL Home Page (Open GL, SDL, OOP sprite engine, tutoriály). Existují i další stránky, ale ty ostatní jsou hlavně pro Delphi (jako www.DelphiGamer­.com.

Příkladem takové hry (samozřejmě včetně zdrojových kódů) je síťová 3D

DeathTrucktion.

Závěr

Tímto dílem končí seriál o Kylixu. Snažil jsem se vám přiblížit Kylix tak, jak ho vidím, a ukázat, jak se v něm programuje a co se mi na něm líbí. Určitě jsem ani zdaleka nepopsal vše, co Kylix umí (Developer Guide Kylixu 2 má 800 stran), ale snad se mi povedlo alespoň trefit většinu oblastí (kromě vývoje komponent, ale to bych rád snad ještě někdy napravil jedním článkem). Doufám, že jste si vytvořili názor sami.

Pokud budete mít nějaký problém (samozřejmě ohledně Kylixu), zkuste nejdříve Internet, konferenci Delphi (www.delphi.cz) a nakonec, až vše selže, tak třeba mě (pokud budu vědět, ale odpovídám pomalu).

UX DAy - tip 2

Rád bych uvedl, že Kylix existuje teprve chvilku a pevně věřím, že příští verze bude ještě kvalitnější a přinese opět něco nového (horké informace například zde – kromě jiného: Kylix 3 bude i s C++ kompilátorem a další).

Úplně na závěr bych moc rád poděkoval všem, co se zdrželi flame war. Děkuji.

Byl pro vás článek přínosný?