\chapter{Použité technologie} Jako implementační jazyk aplikace jsme zvolili jazyk Java~\cite{gosling05java-langspec-3}. Tento výběr ovlivňuje volbu jednotlivých knihoven a frameworků, které nám budou poskytovat a zprostředkovávat různé technologie. Z povahy aplikace vyplývá, že většina netriviálních úloh bude probíhat na serverové části, tam také použijeme nejvíce knihoven. \section{Poskytovatel platformy} Pro běh serverové části potřebujeme server(y), na kterých poběží naše aplikace. Na výběr jsme měli možnost pronájmu vlastního (virtuálního) serveru, nebo využít služby některého z poskytovatelů \zkratka[Cloudu]{Cloud computing}{model poskytování prostředků založený na internetu; obvykle je zpoplatněno využití služby namísto klasické platby za software}. Virtuální server sice poskytuje největší svobodu, ale za cenu nutné vlastní konfigurace systému. Tomu jsme se chtěli vyhnout a zaměřit své úsilí na samotný vývoj aplikace. Další jeho nevýhodou je nemožnost automatického škálování. Až na výjimky\footnote{Jedinou nám známou výjimkou je poskytovatel \url{http://4smart.cz/}} se za pronájem účtuje paušální měsíční poplatek. Naopak cloudoví poskytovatelé nabízí hotovou platformu, na níž je možné rovnou začít stavět aplikaci. Serverovou část aplikace tedy budeme provozovat v cloudu, to nám umožní efektivní správu prostředků, možnost trvalé expanze a škálovatelnost aplikace. Pro volbu konkrétního cloudového poskytovatele jsme měli (v době zahájení práce) na výběr z následujících možností: \begin{itemize} \item \projekt{Amazon EC2}{http://aws.amazon.com/ec2/} \item \projekt{Google AppEngine}{http://appengine.google.com/} \end{itemize} Jelikož jsme již měli zkušenost s posledním zmíněným, a tedy jeho architektura nám byla známá, zvolili jsme jej. \section{Platforma Google AppEngine} Google AppEngine je platforma pro vývoj a hostování webových aplikací napsaných v jednom z několika podporovaných jazyků. Je poskytována společností Google; je dostupná široké veřejnosti; pro nenáročné aplikace je zdarma. Platforma umožňuje automatické škálování výkonu podle aktuální potřeby aplikace, tzn. pokud je aplikace hodně vytížená, automaticky spustí další instance. Výběr tohoto poskytovatele nám umožňuje splnit výkonnostní požadavky. Vzhledem k principu fungování této platformy, totiž že výkon se přiděluje podle aktuálních požadavků a účtuje se spotřeba systémových prostředků (počet volání metod poskytovaného API), je relativně levná pro nenáročné aplikace. AppEngine je platforma, která poskytuje několik spolu vzájemně provázaných rozhraní. Čtyři z nich, které jsou pro naši aplikaci důležité, nyní krátce popíšeme. \subsection{Datastore} \projekt{Datastore}{http://developers.google.com/appengine/docs/java/datastore/} je databáze navržená společností Google s cílem výborné škálovatelnosti a extrémní rychlosti. Těchto dvou požadavků se jim podařilo docílit, nicméně za cenu jistých omezení, která mohou být svazující. Nejprve popíšeme, jak databáze funguje, a následně, jaké důsledky to obnáší. Databáze nemá pevné schéma; obdobou tabulek z relačních databází je \verb|kind| -- druh. Každý záznam v databázi je nějakého druhu; všechny záznamy stejného druhu jsou seskupené a lze nad nimi provádět dotazy. Každý záznam může mít jiné atributy, příp. jiné datové typy atributů. Takže je teoreticky možné mít u stejného druhu odlišné typy záznamů; například záznam s atributem pojmenovaným \verb|a|, který má řetězcovou hodnotu \verb|"aaa"| a jiný záznam, který tento atribut vůbec nemá nebo se jedná o číslo \verb|1| nebo se dokonce jedná o seznam dat. Datastore podporuje hodnotu atributů mnoha datových typů, některé z nich jsou neobvyklé, například geografický bod pro určení polohy na Zemi, či hodnocení v rozsahu \mbox{0--100}. To jsou možnosti uložení dat, které databáze poskytuje. Požadavek na vysoký výkon omezuje možnosti manipulací s daty a dotazování. Databáze umožňuje jen následující operace: \begin{itemize} \item získat záznam -- podle klíče najde záznam v databázi a vrátí jeho aktuální hodnotu, \item uložit záznam -- uloží záznam do databáze; přepíše původní hodnotu, pokud již v databázi takový záznam existoval, \item odstranit záznam -- odstraní záznam z databáze; záznam je určen svým klíčem, \item vyhledat záznamy -- vyhledá záznamy daného druhu, které vyhovují filtru seřazené podle některého atributu. \end{itemize} Popsané operace jsou obdobami operací známých z objektových databází. Nejvíce omezené jsou možnosti vyhledávání záznamů; uvedeme některá z nich: \begin{itemize} \item neexistují spojení tabulek, \item neexistují žádné funkce; agregační funkce musí uživatel draze emulovat, \item hodnoty atributů lze porovnávat jen s konstantami, \item dotaz smí obsahovat maximálně jednu nerovnost, \item prvním kritériem pro řazení musí být atribut s nerovností, pokud existuje, \item výsledky dotazu nemusí vždy vyhovovat filtru. \end{itemize} Všechna z popsaných omezení souvisejí se způsobem provádění dotazů. Každý dotaz, který se provádí, neprobíhá proti vlastním záznamům, ale proti jednomu či více indexům. To vlastně znamená, že výsledky všech možných dotazů, které kdy může uživatel databáze provést, jsou předpočítané. S tím také souvisí neaktuálnost dat v indexech, mohou být o několik sekund zpožděné oproti hodnotám vlastních záznamů. Samotný dotaz probíhá v několika krocích: \begin{enumerate} \item nalezení nejlepšího indexu či nejlepší kombinace indexů. Index(y) musí pokrývat všechny atributy uvedené ve filtru; neexistence vhodného indexu způsobí běhovou chybu. \item nalezení klíče v indexu prvního záznamu, který vyhovuje filtru, \item lineární průchod následujících záznamů, dokud vyhovují filtru, \item vrácení záznamů získaných podle klíče. \end{enumerate} Jak je vidět, není v tomto algoritmu místo pro funkcionalitu, která by řešila výše uvedená omezení. \subsection{Task Queues} \projekt{Task Queues}{http://developers.google.com/appengine/docs/java/taskqueue/} realizuje frontu úloh, které jsou postupně vykonávány. Uživatel může do fronty vložit najednou mnoho úloh a fronta se postará o to, že budou spuštěny se stejnou frekvencí, například spustí maximálně pět úloh za sekundu. Toto záměrné zpoždění je vhodné z důvodu snížení aktuální zátěže systému. Další výhodou jsou samostatné limity pro každou úlohu; nestane se, že by série úloh selhala z důvodu, že zpracování všech dohromady přesáhlo maximální časový limit. \subsection{Users} Platforma AppEngine poskytuje službu \projekt{Users}{http://developers.google.com/appengine/docs/java/users/}, která umožňuje přebírat informace o aktuálně přihlášeném uživateli; deleguje tak na sebe celou infrastrukturu okolo registrace, přihlašování, odhlašování, zapomenutého hesla. Pokud uživatel odsouhlasí, že aplikace má přístup k datům uživatele, může aplikace zjistit, jaký je aktuálně přihlášený uživatel pro každý webový dotaz. Obvykle, pokud aplikace detekuje nepřihlášeného uživatele, reaguje zobrazením odkazu, který vede na přihlašovací formulář Google účtu. Jakmile jej uživatel vyplní, odešle a úspěšně se přihlásí, je přesměrován zpět do naší aplikace. Proces odhlášení probíhá analogicky, jen opačně. \subsection{Google Cloud Storage a Blobstore} Jelikož AppEngine poskytuje pouze platformu, na níž běží naše aplikace, není možný přístup k tradičnímu souborovému systému. Není to možné ani technicky: není jasné, na kolika, natož na kterých serverech na celém světě je aplikace právě spuštěná. Aby toto omezení platforma obešla, nabízí své rozhraní a abstrakci souborů. \projekt{Google Cloud Storage}{http://developers.google.com/appengine/docs/java/googlecloudstorageclient/} umožňuje jak klasické vytváření a mazání souborů, tak poskytuje i rozhraní k přímému uploadu souborů uživateli aplikace. Doplňkem tohoto rozhraní je \projekt{Blobstore}{http://developers.google.com/appengine/docs/java/blobstore/}, který poskytuje přístup k těmto souborům, umožňuje přímé streamování dat z úložiště. \section{Slim3} \projekt{Slim3}{http://sites.google.com/site/slim3appengine/} je framework, který zajišťuje mapování databázových entit postrádajících pevné schéma na reálné javové objekty. Je vyvíjen japonským vývojářem \email[Yasuo Higa]{Yasuem Higem}{higayasuo@gmail.com} a je poskytován pod open-sourcovou licencí Apache~2.0~\cite{apache20}. Na rozdíl od jiných \zkratka{ORM}{Object-relational mapping -- slouží k převádění dat mezi dvěma nekompatibilními systémy uložení; tradičně mezi objekty tříd a záznamy v relační databázi} frameworků typu \projekt{Hibernate}{http://www.hibernate.org/}, které mapování provádějí za běhu aplikace rozborem atributů objektu za pomoci javové reflexe, Slim3 předem vygeneruje meta třídy ke všem třídám modelu. Tyto třídy slouží k převádění reprezentace dat mezi objekty modelových tříd a Datastore entitami, poskytují metody \verb|modelToEntity| a \verb|entityToModel| a konstanty, které reprezentují atributy používané během dotazování. \section{ROME} \projekt{ROME}{http://rometools.jira.com/wiki/display/ROME/Home} je knihovna, která poskytuje sadu parserů a generátorů pro různé typy formátů zpravujících o novinkách na webovém zdroji. Jedná se o starší knihovnu, která se nezdá být aktivně vyvíjena, nicméně je běžně používaná a pro nás dostatečně robustní a stabilní; je dostupná pod open-sourcovou licencí Apache~2.0~\cite{apache20}. Knihovna umí pracovat s většinou variant RSS a Atom dokumentů, umožňuje jejich stahování po síti, rozparsování i generování. Poskytuje jednotné rozhraní, přes které je možné dokumenty číst a vytvářet bez ohledu na jejich původní či výsledný formát. \section{Apache HttpComponents} \projekt{Apache HttpComponents}{http://hc.apache.org/} je široce rozšířená knihovna určená pro zajištění komunikace přes \zkratka{HTTP}{Hypertext Transfer Protocol -- bezestavový protokol určený ke komunikaci klienta se serverem při poskytování webových stránek}. Knihovna je vyvíjena Apache Software Foundation a je zdarma poskytovaná pod open-sourcovou licencí Apache~2.0~\cite{apache20}. Knihovna poskytuje znovupoužitelné komponenty pro komunikaci klienta se serverem, řeší nejčastější požadavky, jako jsou autentikace, stavový management (Cookies), řízení spojení. Je široce využívaná a oblíbená na jedné straně pro jednoduchost svého použití a na druhé pro široké možnosti, které nabízí. \section{\texorpdfstring{jsoup\footnote{Název knihovny jsoup je tvořen malými písmeny, toto rozhodnutí autora respektujeme.}}{jsoup}} Knihovna \projekt{jsoup}{http://jsoup.org/} umožňuje rozparsovat HTML stránku do \zkratka{DOM}{Document Object Model -- popisuje obsah HTML nebo XML dokumentů pomocí stromové struktury elementů; specifikace~\cite{Isaacson:1998} definuje i metody pro přístup k elementům a manipulaci} struktury. Vyvíjí ji \email{Jonathan Hedley}{jonathan@hedley.net} a poskytuje ji zdarma pod licencí MIT. Knihovna zvládá zpracování veškerých HTML stránek, i takových stránek, které nevyhovující standardům. V možnostech této knihovny je: \begin{itemize} \item stáhnout a rozparsovat HTML stránku z URL adresy, souboru či řetězce, \item najít a získat data pomocí metod DOM či \zkratka{CSS}{Cascading Style Sheets -- jazyk určený pro popis vzhledu a formátování dokumentů~\cite{Bos:2011}} selektorů, \item manipulace s HTML elementy, atributy a textem prostřednictvím metod, které poskytuje DOM, či CSS selektorů, \item ošetření dokumentu před nebezpečným obsahem, \item vyčištění HTML dokumentu -- náprava chyb \end{itemize} Seznam vlastností jsme převzali ze stránek projektu~\cite{jsoup}. \section{JScience} Knihovna \projekt{JScience}{http://jscience.org/} poskytuje implementaci různých výpočetních algoritmů používaných v matematice a fyzice. Knihovna je vyvíjena pod vedením vývojáře \email[Jean-Marie Deutelle]{Jean-Marie Dautellem}{jean-marie@dautelle.com} a je poskytována zdarma pod vlastní open-sourcovou licencí. Knihovna se skládá z několika modulů, které se zabývají efektivními algoritmy v následujících oblastech: \begin{itemize} \item výpočty s jednotkami a měnami, \item rigorózní zpracování algebraických objektů v javě, \item lineární algebra, výpočty s vektory a maticemi, \item symbolická matematická analýza: integrování, derivování funkcí, řešení rovnic, výpočet výrazů, \item a dalších. \end{itemize} Seznam vlastností jsme převzali ze stránek projektu~\cite{jscience}. \section{Diff Match Patch} \projekt[]{Diff Match Patch}{http://code.google.com/p/google-diff-match-patch/} je malá knihovna, která nabízí robustní algoritmy pro synchronizaci textu. Knihovnu vyvíjí \email{Neil Fraser}{root@neil.fraser.name} a nabízí ji zdarma pod licencí Apache~2.0~\cite{apache20}. Knihovna poskytuje tři základní algoritmy: \begin{itemize} \item porovnání dvou textů -- nalezne rozdíly mezi dvěma vstupními texty; umožňuje zadat jako parametr snahu, kterou má vykonat pro nalezení minimální změny. Výstupem algoritmu může být i HTML dokument, ve kterém jsou zvýrazněné přidané a odebrané části textu. \item nalezení nejpodobnější části textu -- ve vstupním textu nalezne hledaný podřetězec, který se od vstupního textu nejméně liší. Výstupem je pozice -- znak, kde hledaný podřetězec začíná. \item aplikace změn -- snaží se aplikovat sadu změn na vstupní text. Výstupem je změněný text a informace o změnách, které se v pořádku provedly a které naopak selhaly. \end{itemize} \section{Google Web Toolkit} \nomenclature{GWT}{Google Web Toolkit -- knihovna a nástroj pro vývoj klientské části webových stránek v jazyku Java} % \projekt{GWT}{http://www.gwtproject.org/} je nástroj, který umožňuje vytvářet klientskou část aplikace ve stejném jazyku jako serverovou část. Knihovnu vyvíjí společnost Google, poskytuje ji zdarma pod open-sourcovou licencí Apache~2.0~\cite{apache20}. GWT se skládá z několika komponent: \begin{itemize} \item kompilátor z Javy do \zkratka[JavaScriptu]{JavaScript}{formálně ECMAScript~\cite{ECMA-262}, interpretovaný jazyk běžící v internetovém prohlížeči, který umožňuje tvůrci webové stránky interaktivně manipulovat s jejím obsahem}, \item zjednodušená implementace standardní knihovny Javy, \item vlastní knihovna, která umožňuje tvorbu síťových služeb, lokalizace a správu prostředků, \item knihovna grafických komponent: od jednoduchých obalů prvků HTML po komplexní panely rozložení. \end{itemize} Tyto komponenty dohromady umožňují naprogramovat téměř libovolnou klientskou část aplikace v Javě. Pokud by nabízené prostředky Javy nestačily, je možné části kódu naprogramovat v JavaScriptu. Mezi výhody použití GWT v projektu patří: \begin{itemize} \item serverová i klientská část je psána ve stejném jazyku. \item společný kód pro serverovou a klientskou část se napíše jen jednou (a přeloží dvakrát), \item poskytuje základ pro komunikaci mezi klientskou a serverovou částí, stará se o serializaci a deserializaci požadavků, \item stará se o minifikaci kódu odeslaného klientovi, \item poskytuje hotové základní komponenty pro tvorbu uživatelského rozhraní. \end{itemize} \subsection{Vaadin} GWT není jedinou knihovnou zaměřenou na prezentační vrstvu aplikace v prohlížeči. Nejbližší alternativou se nám jeví \projekt{Vaadin}{http://vaadin.com/home}~\cite{Vaadin}, který jsme také z počátku zvažovali. Je taktéž dostupný zdarma pod stejnou licencí: Apache~2.0~\cite{apache20}. Nakonec jsme vybrali GWT, které nám přišlo jednodušší a pro naše účely vhodnější. \section{GWT Eye Candy} \projekt{GWT Eye Candy}{http://code.google.com/p/gwt-eye-candy/} je drobná knihovna, která nabízí kolekci ovládacích prvků do uživatelského prostředí aplikace. Knihovna je určena jako rozšíření GWT, samostatně není použitelná. Vyvíjí ji \email{Gabriel Axel}{guznik@gmail.com} a poskytuje ji pod open-sourcovou licencí Apache~2.0~\cite{apache20}. Knihovna obsahuje následující grafické prvky: tlačítka, přepínací tlačítka, nástrojovou lištu, titulek, výběr barev. \section{Crossrider} Platforma \projekt{Crossrider}{http://crossrider.com/} umožňuje vytvořit jediný doplněk, který bude fungovat shodně v nejrozšířenějších prohlížečích (Internet Explorer 7 a novější, Chrome, Firefox 3.6 a novější)~\cite{crossrider-faq}. Platforma nabízí vlastní API, které poskytuje následující vlastnosti: \begin{itemize} \item trvalou databázi klíč -- hodnota, \item posílat libovolné webové dotazy bez omezení na původ, \item procházet a vytvářet záložky (bookmarks), \item umístit do prohlížeče na lištu tlačítko s ikonou, \item reagovat na klávesové zkratky, \item obsahuje knihovnu \projekt{jQuery}{http://jquery.com/}. \end{itemize} Tvorba rozšíření probíhá v online editoru na stránkách projektu; výstupem práce jsou doplňky instalovatelné do zmíněných prohlížečů. \section{TextExt} \projekt{TextExt}{http://textextjs.com/} je plugin do knihovny jQuery, poskytuje textovou komponentu, kterou lze přizpůsobit mnoha způsoby. TextExt vyvíjí \email[Alex Gorbatchev]{Alexem Gorbatchevem}{alex.gorbatchev@gmail.com} a je poskytován pod open-sourcovou licencí MIT. Knihovna obsahuje jako jádro standardní HTML textové pole, které je obalené vrstvou JavaScriptu, která je zodpovědná za rozšiřující možnosti. Textové pole lze rozšířit několika funkcionalitami, například: \begin{itemize} \item vkládání štítků -- umožňuje vkládat jednoslovné popisky, které jsou graficky zvýrazněné; ve výsledku budou oddělené čárkami, \item automatické doplňování -- umožňuje nabízení vhodných doplnění textu na základě předem známého seznamu možností, \item zobrazení výzvy -- zobrazí text na pozadí pole, který upozorňuje uživatele na možnost akce, \item tlačítko rozbalit -- zobrazí všechny nabízené možnosti k doplnění. \end{itemize}