Cocoon v příkladech: Úvod

5. 11. 2003
Doba čtení: 10 minut

Sdílet

Chcete vytvořit webovou aplikaci? Máte jeden či více zdrojů dat ve formátu XML? Chcete oddělit obsah a prezentaci? Potřebujete více různých formátů prezentace (např. HTML, WML, PDF, ...) nebo více jazykových verzí jednoho obsahu? Jste přesvědčeni, že vytváření a užívání jednoduchých a opakovaně použitelných komponent je ta správná cesta vývoje? Pak je tady pro vás Cocoon.

Cocoon (cocoon.apache­.org/2.1) je „open source“ framework pro vytváření webovských aplikací založených na XML. Je jedním z hlavních „open source“ projektů vyvíjených v rámci iniciativy XML Apache. Cocoon toho obsahuje opravdu hodně. Cílem tohoto článku a jeho pokračování je ukázat, na čem je Cocoon založen, jakým způsobem se v něm pracuje, k čemu se hodí více a k čemu méně, jaké vám může přinést výhody a s čím se budete pravděpodobně potýkat. Co k tomu budete potřebovat? Pro začátek je nutná dobrá znalost XML (včetně jmenných prostorů) a alespoň průměrná znalost XSL. Později se bude také hodit alespoň částečná znalost programování v Javě. Budete-li chtít uváděné příklady sami zkoušet a modifikovat, budete potřebovat také rozumně výkonný počítač (hlavně dostatek paměťi a místa na disku).

Jak pracuje Cocoon

Cocoon je obyčejný servlet naprogramovaný v Javě. I když vlastně zas tak úplně obyčejný není, protože rozhraní, které nabízí, daleko přesahuje běžné funkce servletového API i možnosti JSP. Cocoon může navíc běžet nejen v prostředí servletového kontejneru, ale i samostatně z příkazového řádku. To se velmi hodí, pokud Cocoon využijete pro generování statických webových stránek.

Pro webového klienta nemají webové stránky generované Cocoonem žádná úskalí – jeví se skoro jako soubor statických stránek s nějakou strukturou adresářů. Ačkoliv Cocoon může bez problémů zasílat webovým klientům i statické HTML stránky, obvykle se stránky generují z dat ve formátu XML. Celý proces transformace původního XML na výsledné HTML (či jiný požadovaný formát) je založen na principu roury (pipe – viz obrázek).

Obrázek 1: Princip roury

Máte-li zkušenosti s Unixem, určitě znáte rouru na příkazovém řádku. Složitý příkaz se zde sestavuje řetězením jednoduchých příkazů (resp. spustitelných programů), přičemž první příkaz generuje textový výstup, který je předáván na vstup dalšího, ten jej nějak pozmění a předá na vstup třetího atd. Roura v Cocoonu funguje podobně. Když přijme Cocoon HTTP požadavek webového klienta (např. Mozilla, MS Internet Explorer a další), rozhodne, která roura jej zpracuje. První komponenta v rouře musí vygenerovat počáteční XML data (přesněji řečeno události SAX), která jsou předána na vstup další komponentě, ta data nějak transformuje, předá další komponentě, až poslední komponenta data (resp. události SAX) serializuje do výstupního proudu, který je zaslán zpět webovému klientovi.

Jednotlivé komponenty zajišťují širokou paletu činností od zpracování dat nejen z XML zdrojů až po práci s relačními databázemi (Cocoon samotný obsahuje i databázi hsqldb), LDAP, SAP, se strukturovaným textem a další. Bohatá nabídka serializací umožňuje efektivně vytvářet výsledné prezentace ve formátech HTML, XHTML, WML (WAP stránky pro mobilní telefony ), CHTML (compact HTML pro některá mobilní zařízení), PDF a dalších datových zdrojích. Dá se říci, že Cocoon integruje to nejlepší z XML technologií, a pokud by někomu něco chybělo, lze jej velmi snadno rozšířit.

Mapa

V možná poněkud nudné teorii budeme ještě chvíli pokračovat, protože roura je v Cocoonu opravdový základ, bez kterého se neobejdete. Výběr roury má na starosti důležitá komponenta nazvaná mapa (sitemap). Najdete ji nejčastěji jako XML soubor (případně více souborů) s názvem „sitemap.xmap“. Mapa obsahuje hlavně deklarace a konfigurace použitých komponent (pokud nepoužijete vestavěné) a dále konfigurace jednotlivých rour.

Velmi jednoduchý soubor sitemap.xmap by mohl vypadat například takto:

<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
  <map:pipelines>
    <map:pipeline>

      <map:match pattern="smerovaci-cisla.html">
        <map:generate src="psc.xml"/>
        <map:transform src="psc2html.xsl"/>
        <map:serialize/>
      </map:match>

    </map:pipeline>
  </map:pipelines>
</map:sitemap>


Všimněte si střední části mapy, která je oddělena od úvodních, spíše deklarativních elementů prázdným řádkem. Popisuje se zde, že pokud webový klient bude chtít soubor „smerovaci-cisla.html“, tak Cocoon přečte soubor „psc.xml“, pak jej transformuje na HTML za pomocí stylesheetu „psc2html.xsl“ a nakonec jej serializuje do výstupního proudu a zašle klientovi. Pokud by chtěl klient soubor s jiným názvem, Cocoon vrátí chybu, neboť neví, co má v takovém případě udělat. Výběr roury (nebo její části) zajišťuje v mapě element map:match. Ve výše uvedeném příkladu vybíráme rouru podle konkrétního jména souboru, v praxi se však více používají kombinace s žolíkovými znaky (wildcards) nebo regulární výrazy.

Všimněte si, že první komponenta v rouře musí být vždy tzv. generátor (generator), poslední komponenta serializátor (serializer) a mezi nimi pak mohou být transformátory (transformer). Mapa může být podstatně složitější a později se podíváme na další typy komponent, které lze použít. Generování XML dat tak, že se přečtou ze souboru, není ovšem jediný způsob, jak rouru začít, nicméně zde použitý implicitní File Generator patří k opravdu nejužívanějším. Podrobněji se na některé možnosti podíváme hned v následující kapitole.

Mapa nejen deklaruje a konfiguruje komponenty a roury, ale také vlastně vytváří virtuální jmenný prostor pro klienta, který nemá nic společného se skutečnými soubory na disku serveru. Ve výše uvedeném příkladu klient požaduje soubor „smerovaci-cisla.html“, žádný takový soubor na serveru však neexistuje. Vytvoření tohoto virtuálního jmenného prostoru je jedním z cílů návrhu mapy pro danou webovou aplikaci. Výběr roury mapou je velmi flexibilní, takže ve jmenném prostoru klienta je možné vytvářet virtuální adresáře, více či méně obvyklé přípony ve jménech souborů nebo si vymyslet něco zcela originálního – třeba, že typ souboru budou určovat předpony nebo nějaký řetězec uprostřed jména souboru.

Generátory

Generátory jsou komponenty, které na začátku každé roury generují XML data ve formě událostí SAX. Cocoon obsahuje řadu vestavěných generátorů, z nichž nejdůležitější jsou­:

File Generator
čte XML soubor z disku a předává jej následující komponentě v rouře. Je to implicitní generátor.
XPath Generator
čte fragment XML souboru specifikovaný pomocí XPath a předává jej další komponentě v rouře.
Directory Generator
vypisuje obsah zadaného adresáře. Výpis je převeden do XML a předán další komponentě v rouře.
Image Directory Generator
pro soubory s bitmapovými obrázky rozšiřuje výše uvedený generátor o atributy výšku a šířku obrázku.
Request Generator
předává v XML hodnoty hlavičky a parametrů HTTP požadavku.
Server Pages Generator
důležitý generátor pro XSP (XML Server Pages – obdoba Java Server Pages), kterými se budeme zabývat později.

Pokud si z vestavěných generátorů ani při využití všech možností jejich konfigurace nevyberete, můžete naprogramovat vlastní generátor v jazyce Java. Ale po pravdě řečeno, programovat vlastní generátor je potřeba velmi zřídka.

Transformátory

Transformátor dostane na svůj vstup XML data (ve formě událostí SAX), tato data nějakým způsobem transformuje a pošle je na svůj výstup (opět jako události SAX). Transformátor nemůže být ani první, ani poslední komponenta v rouře. Cocoon obsahuje řadu vestavěných transformátorů, z nichž nejzajímavější jsou­:

XSLT Transformer
je implicitní a také nejužívanější transformátor. Na základě XSL dokumentu přečteného z disku nebo z libovolného URL aplikuje XSL transformaci na vstupní data. Výbornou vlastností je, že tomuto transformátoru můžeme předat přes mapu parametry – například hodnoty parametrů HTTP požadavku.
SQL Transformer
se umí dotázat SQL databáze. Dotaz specifikují XML data na vstupu transformátoru, výsledek dotazu je převeden do XML a odeslán na výstup transformátoru.
LDAP Transformer
se umí dotázat LDAP databáze. Princip je podobný jako u transformáto­ru SQL.
CInclude/XInclude Transformer
umí do XML dat ze vstupu vložit text nebo další XML elementy z vnějšího zdroje. Transformátor XInclude používá specifikaci XInclude.
Session Transformer
umí do transformovaných XML dat začlenit hodnoty z kontextu uživatelské relace (session) nebo naopak z transformovaných dat zapsat hodnoty do kontextu relace. Hodí se například pro nastavení implicitních hodnot webových formulářů.
Write/Read DOM Session Transformer
může zapsat do kontextu uživatelské relace (session) část DOM (Document Object Model: stromová reprezentace XML dat) transformovaných dat (Write DOM Transformer), resp. jej umí z kontextu relace přečíst a začlenit do transformovaných dat (Read DOM Transformer). Tato dvojice transformátorů je podobná předchozímu transformátoru.
I18n Transformer
umožňuje internacionalizaci aplikace. Označené texty jsou nahrazovány z katalogu podle aktuálně nastaveného jazyka.
Paginator
umožňuje efektivně rozdělit na více „stránek“ data, která by jinak při zobrazení byla příliš rozsáhlá. Je konfigurovatelný, takže můžete například nechat zobrazovat rozsáhlou tabulku na počítačích typu desktop po sto řádcích, na PDA po dvaceti a na WAP stránkách pro mobilní telefony po pěti řádcích.

Pokud si z vestavěných transformátorů nevyberete, můžete naprogramovat vlastní transformátor v jazyce Java. Na rozdíl od generátorů jsou speciální transformátory programovány poměrně často.

Serializátory

Serializátory slouží k serializaci vstupních XML dat (resp. událostí SAX) na výstupní proud, kterému rozumí webový klient, případně který může byt zpracován jinak, ale nezávisle na Cocoonu (například uložen na disk). Cocoon opět obsahuje množství vestavěných serializátorů, z nichž pro webové aplikace jsou nejzajímavější ty­to:

HTML/XHTML Serializer
serializuje vstupní data XML na HTML nebo XHTML. Pozor, vstupní XML data už musí obsahovat značky (X)HTML, žádná transformace se zde už nekoná. Jde skutečně jen o serializaci událostí SAX do proudu. Tento serializátor je implicitní a také nejčastěji používaný.
XML Serializer
nechává data v XML, nicméně není zbytečný, jak by se mohlo na první pohled zdát. Opět serializuje události SAX do proudu.
WAP/WML Serializer
se používá pro vytváření WML stránek pro WAP prohlížeče mobilních telefonů.
Text Serializer
vytváří obyčejný text.
PDF Serializer
vytváří PDF. Zajímavý serializátor, PDF lze použít například na skutečně „printer-friendly“ variantu webových stránek.

Cocoon dále obsahuje i několik serializátorů pro serializaci SVG obrázků například do formátu JPEG, PNG nebo TIFF. Pokud si z vestavěných serializátorů nevyberete, můžete naprogramovat vlastní v jazyce Java.

Webová aplikace

Cocoon dovoluje navrhnout webovou aplikaci se skutečně moderní architekturou MVC (Model-View-Controler), kdy modelem mohou být počáteční XML data, ale i XML reprezentace databázových dat. Pohled (view) je vytvářen transformacemi. Jako kontrolér slouží v jednodušších případech sama mapa, komplexnější případy lze řídit skriptem.

Přístup, který Cocoon nabízí, je neuvěřitelně flexibilní. Ve výše uvedeném příkladu je jak soubor „psc.xml“, tak stylesheet „psc2html.xsl“ čten z disku. Ale jako zdroj může být uveden nejen soubor na disku, ale libovolné URL. Tak proč by třeba stylesheet „psc2html.xsl“ nemohl být také virtuální soubor vygenerovaný Cocoonem? Může. Navíc jsem v tomto stručném úvodu zatajil další typy komponent, které lze v mapě použít. Akce umožňují manipulovat s parametry, selektory zase přidávají konstrukci „select-case“ nebo"if-then-else", chcete-li. Agregeace pak umí spojit několik XML zdrojů.

Pro ty, kteří si oblíbili JSP (Java Server Pages) má Cocoon alternativu: XSP (XML Server Pages) nabízejí podobný způsob práce, včetně tzv. logicsheetů, které jsou obdobou knihoven značek (tag libraries) v JSP. XSP slouží jako generátory, jejich výstup se pak běžně transformuje a serializuje jako výstup kteréhokoliv jiného generátoru.

Komponenty Cocoonu umožňují opravdový CBD (Component Based Design) či COP (Component Oriented Programming). Jsou relativně malé, specializované, jasně ohraničené, a pokud návrh a vývoj takové komponenty příliš neodfláknete, tak jsou i opětovně použitelné. Vývoj webové aplikace v Cocoonu není ale převaha programování, nýbrž návrh, konfigurace mapy, vytvoření XSL stylesheetů a někdy i něco málo programování v Javě, případně Javascriptu nebo Pythonu..

Pokud sestavujete tým pro větší webovou aplikaci nebo uvažujete o dnes poměrně moderním (módním?) outsourcingu, Cocoon vám přímo nabízí jednotlivé role. Někdo musí dobře ovládat konfiguraci mapy, ale nemusí umět nijak zvlášť XSL nebo programovat v Javě. Tvůrci prezentací musejí umět XHTML a CSS (případně WML nebo jiný prezentační formát, který budete chtít použít), ale nemusejí se nijak zvlášť vyznat v mapě ani Javě. Další členové týmu zde budou pro vytváření XSL stylesheetů. Programování vlastních komponent budou mít na starosti vývojáři ovládající dobře Javu, a pokud bude webová aplikace používat databázové datové zdroje, budou potřeba také znalosti SQL a specialisté na konkrétní databázi.

Na druhé straně, pokud chcete vytvořit webovou aplikaci v „týmu“ jednoho člověka, musíte mít dovednosti všech výše uvedených rolí. Není to sice nemožné, ale ani jednoduché. Ruku na srdce, ovládáte-li třeba Javu do nejjemnějších nuancí, umíte také navrhnout efektivní XSL stylesheet a víte přitom navíc, které verze MS Internet Exploreru (ale i jiných prohlížečů) mají jaké chyby při zobrazování XHTML pomocí CSS?

bitcoin_skoleni

Cocoon nepřeje ani takovému způsobu vývoje, kdy dostanete zadání na webovou aplikaci, sednete si k počítači a prostě to naprogramujete (v horším případě v týmu). V Cocoonu je záhodno nejprve si vše pořádně rozmyslet – udělat návrh. Cocoon jednak nabízí několik variant komponent, které vedou ke stejnému (nebo podobnému) výsledku, jednak jednoduchost či složitost vlastního vývoje závisí i na tom, jak navrhnete prvotní XML data, ale třeba také, jak navrhnete jmenný prostor pro klienta.

Zazvonil zvonec …

a pohádky je konec, ale Cocoonu ještě zdaleka konec není. Příště se podíváme, jak Cocoon nainstalovat v Linuxu a v MS Windows (v těch posledně jmenovaných jsou úskalí, která by mohla leckoho odradit, přesto na nich Cocoon běží celkem spolehlivě) a zkusíme si vytvořit první aplikaci.