Message Catalog – proč jej používat?

Krátké zamyšlení věnované mechanismu message catalogů, na co se dají využít a jaké jsou jejich výhody. Dále je pak popsáno jejich jednoduché použití na platformě Seam používané pro CzechIdm.

Většina vývojářů se pravděpodobně shodne na tom, že psát textové řetězce (jako jsou například popisky v uživatelském rozhraní nebo chybové hlášky) přímo do kódu programu není úplně nejlepší zvyk. Způsobuje to mnoho nepříjemností při práci na aplikaci a často přináší i hodiny archeologického procházení kódu a hledání všech míst, kde je potřeba poupravit vypisovaný text. Jaké jsou ale alternativy?

Nejpřijatelněji se jeví varianta, ve které by byl veškerý text, se kterým přijde uživatel do styku, oddělený od programu a v programové části byl jen na patřičných místech doplňován z externího souboru. To je myšlenka message catalogů. Ačkoli se jejich konkrétní implementace liší v závislosti na platformě, jejich funkce je stále stejná: vyvořit seznam (katalog) zpráv, který bude mimo veškerý kód a tím bude snadno spravovatelný a aktualizovatelný. Ke každé zprávě je v katalogu přiřazen klíč, přes který se pak při běhu programu vkládají zprávy na správná místa.

Jaké jsou výhody Message catalogů?

Jednou z nejočividnějších výhod této metody je znovupoužitelnost a s ní spojená snadná editace a aktualizace jednotlivých zpráv. V případě, že chceme stejnou řádku textu použít v naší aplikaci na několika místech, není nutné ji všude vypisovat (nedejbože aby měla více než pět slov, pak by už jen statisticky byl v jedné variantě této zprávy určitě ukrytý překlep), ale stačí nám pouze na vkládat odkaz na jednu řádku v katalogu. Následně v okamžiku, kdy se rozhodneme zprávu upravit, ji stačí upravit na jednom místě a máme jistotu, že ve všech místech výskytu dotyčného textu bude jeho aktuální podoba a není třeba prohledávat skrytá zákoutí v kódu.

Klasická implementace message catalogů pak pracuje s možností vázaných proměnných. V praxi to vypadá tak, že do zprávy v katalogu umístíme identifikátory parametrů, které jsou pak za běhu nahrazeny dodanými hodnotami.

Lokalizace

Lokalizace softwaru (překlad do jiných jazyků je jedním ze zásadních argumentů, proč message catalogy používat a nevkládat text přímo do kódu aplikace. V případě, že by veškerý text byl natvrdo zapsán v kódu by totiž jedinou možností jak aplikaci lokalizovat do jiného jazyka bylo projít ručně všechna místa v kódu, kde je cokoli vypisováno a přepsat to do nového jazyka, což je v zásadě nadlidský úkol, který bych nepřál ani nejhoršímu nepříteli. A aby toho nebylo málo, stále tím není vyřešena otázka dalšího vývoje aplikace… Tam máme poté, co jsme manuálně vytvořili cizojazyčnou verzi svého programu, na výběr ze dvou možností – buď provedeme změny v jedné verzi, a tu následně musíme znovu přeložit nebo můžeme provádět změny simultánně ve dvou variantách programu. Obě možnosti znamenají cestu do pekla. Pokud se rozhodneme, že chceme aplikaci distribuovat ve více jazycích než ve dvou, pak se nám všechny výše popsané radosti násobí.

Naproti tomu pokud se rozhodneme použít variantu, kde text je oddělený od kódu programu, stane se překlad aplikace rázem o mnoho snesitelnějším. Stačí nám vytvořit novou variantu katalogu zpráv a poté bude program vždy v té jazykové verzi, který katalog mu předhodíme. V průběhu dalšího vývoje stačí zajistit, aby zůstaly všechny katalogy aktuální (tj. Provádět změny ve všech současně). Oproti předchozí variantě se jedná o poměrně triviální práci.

Použití v Seam

Seam je platforma pro vytváření internetových aplikací v jazyce Java a jestli je někde důležité mít svou aplikaci vícejazyčnou, pak je to právě na internetu.

Soubory zpráv

Soubory zpráv v tomto systému message catalogů nejsou nic jiného než hash-mapy vylité do souborů. Jsou k tomu použity soubory s koncovkou .properties, jejichž formát je jednoduchý na čtení i editaci. Jeden řádek obsahuje vždy jednu zprávu zapsanou ve tvaru ‚klíč = hodnota‘, kde klíč je používán přímo v kódu a hodnota je text na místech klíče dosazovaný.

hello=Hello world
bye=Bye-bye world

Seam používá standartní název pro soubor zpráv ‚messages‘, což znamená, že náš základní soubor zpráv se bude jmenovat messages.properties. Kromě tohoto základního souboru pak můžeme mít několik dalších lokalizovaných souborů odlišených pomocí koncovek. Druhý soubor zpráv pojmenujeme messages_cs.properties a jeho obsah bude následující:

hello=Ahoj svete
bye=Sbohem svete

Nyní, když by se někdo připojil k naší aplikaci přes internet a jeho prohlížeč měl nastavenu češtinu jako používaný jazyk, Seam sám by poznal, že má použít specializovaný katalog. Pro všechny ostatní jazyky bude nadále použita základní (anglická) verze katalogu, dokud se nerozhodneme rozšířit repertoár naší aplikace o další jazyky.

Kódování

Standardním kódováním pro katalogy zpráv je ASCII, což pro některé jazyky není dostatečná znaková sada. Všechny znaky, které chceme v textech své aplikace použít, musí být proto buď ASCII znaky, nebo musíme použít Unicode escape kódy. V prostředí Javy je používán formát \uXXXX, kde XXXX je hexadecimální reprezentace znaku. Symbol ‚ě‘ je reprezentován kódem \u011B a pokud bychom chtěli českou verzi našeho katalogu češtinářsky správně, musela by vypadat následovně

hello=Ahoj sv\u011Bte
bye=Sbohem sv\u011Bte

Naštěstí pro nás (a pro čitelnost katalogů) umožňují některé vývojové nástroje jako například Eclipse práci přímo s háčky a čárkami a na hexadecimální kódy je převádějí samy.

Vlastní jméno souboru

Nastavením konfigurace Seamu (vlastnost org.jboss.seam.core.resourceLoader.bundleNames) můžeme změnit standardní jméno používané pro soubory katalogů, nebo můžeme dokonce určit seznam několika zdrojových jmen, která budou postupně prohledávána při doplňování textu do aplikace

<core:resource-loader>
     <core:bundle-names>
         <hodnota> mycompany_messages </value>
         <hodnota> standard_messages </value>
     </ core: svazek-jména>
</ core: resource-nakladač>

tímto jsme dosáhli toho, že můžeme mít dvě sady oddělených katalogů. Jednu pro standardní zprávy (soubory standard_messages.properties a standard_messages_cs.properties) a jednu pro obsahující firemní popisky (soubor mycompany_messages.properties, překlad není třeba :-) )

Použití v kódu

Nyní, když jsou soubory zpráv vytvořeny a Seam má nakonfigurovánu cestu, můžeme k nim v kódu jednoduše vkládat popisky následujícím způsobem

<h:outputText value="#{messages['hello']}"/>

nebo

<h:outputText value="#{messages.hello}"/>

Ještě lepší je, že zprávy samy o sobě mohou obsahovat EL výrazy:

hello=Hello, #{user.firstName} #{user.lastName}

Závěr

Doufám, že se mi podařilo alespoň zhruba nastínit problematiku oddělení textu od porgramu, co může způsobit za problémy a jak se s ní vypořádat pomocí techniky zvané Message catalogy. V případě jakýchkoli dotazů mne neváhejte kontaktovat na adrese tomas.blovsky@bcvsolutions.eu.