bakalářská práce - Unicorn College
Transkript
BAKALÁŘSKÁ PRÁCE Adobe Flex 4 Adobe Flex 4 Michal Kolesár Un ico rn Co lle ge © 2 011 Un ico rn Co lle ge, V Ka pslo vně 2 76 7/ 2 , P ra ha 3, 13 0 0 0 Ná ze v p rá ce v ČJ: Ná ze v p rá ce v AJ: A do be Fle x 4 A do be Fle x 4 A ut o r: Mich a l K o le sá r A kad em ick ý ro k: 2 01 0/ 2 011 K on ta kt : E -m ail: m ich a l@ ze le n y-ct ve re c. c z Te l. : ( +42 0 ) 77 7 9 97 61 9 Bakalářská práce Adobe Flex 4 Adobe Flex 4 1. ZADÁNÍ Cílem této bakalářské práce představit technologii Adobe Flex, kterou je možné použít na vývoj tzv. bohatých internetových aplikací nebo na vývoj frontendů informačních systémů. Práce si klade za cíl popsat technologii jako takovou, jaké jsou její výhody a nevýhody, její použití na příkladech, jak technologii Adobe Flex propojit s dalšími frameworky a jazykem Java a srovnání s obdobnými technologiemi. Závěr celé práce je završen ukázkou programu Autoškola, který vše demonstruje v praxi. ▪3▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 2. ABSTRAKT Cílem této bakalářské práce je dostat do širšího povědomí technologii Adobe Flex, kterou je možné použít na vývoj tzv. bohatých internetových aplikací (RIA) nebo na vývoj frontendů informačních systémů. Tyto dvě oblasti jsou téměř totožné pouze s rozdílem v nahlížení na bezpečnost a síťovou infrastrukturu. V práci si kladu za cíl popsat technologii Adobe Flex jako takovou, zmínit jaké jsou její výhody a nevýhody, její použití na příkladech. Dále si kladu za cíl popsat, jak technologii Adobe Flex propojit s dalšími frameworky, které mohou ulehčit vývojový proces a jak se napojit na obchodní logiku a datovou vrstvu. Vrstvu obchodní logiky v práci reprezentuje Spring framework a jazyk Java. Datovou vrstvu Hibernate a H2 databáze. Výsledkem je popis samotného SDK, vývojového prostředí Flash Builder, dále seznámení se s jazykem ActionScript3.0 a MXML. V dalších kapitolách Vás seznámím s ovládacími prvky, kontainery a dalšími komponentami, které Adobe Flex nabízí. Popíši také způsoby práce s bindingy, jak pracovat v Adobe Flexu s moduly a jak aplikaci lokalizovat. V další části práce se věnuji různým způsobům napojení na obchocní logiku zpřístupněnou pro Flexovou aplikaci pomocí BlazeDS, implementovanou s využitím Spring frameworku, přičemž podrobněji zpracovávám způsob připojení přes RPC. Pozastavuji se také u způsobu testování pomocí unit testů a automatizovaného funkčního testování aplikací a zmiňuji jak je na tom Adobe Flex, resp. Flash Player s bezpečností. V závěru práce se věnuji srovnání s obdobnými technologiemi od jiných společností, konkrétně Siverligth od Microsoftu, Oracle JavaFX a HTML5 a popsané vlastnosti demostruji na konkrétním příkladu. Součástí práce je ukázka programu Autoškola, která nabízí seznam otázek a testů z autoškoly, uživatel má možnost si procházet otázky v módu výukovém, a také možnost zkusit spustit klasický test. Program obsahuje také část pro administraci aplikace, která je použita na tvorbu samotných otázek a testů. Klíčová slova: Adobe Flex, ActionScript, MXML, Flash Builder, RIA, Rich Internet Application, Spark, BlazeDS, FlexUnit, Cairngorm, FlexMonkey, Hibernate ▪4▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 3. ABSTRACT The objective of this bachelor's thesis is to bring the Adobe Flex technology to the general attention; the technology can be used for the development of the so-called Rich Internet Applications (RIA) or front-end information systems. Both these spheres are almost identical and they differ only in the approach as regards the safety and network infrastructure. It has been my intention to describe the Adobe Flex technology as such, mention its advantages and shortcomings and show its use in practical examples. Furthermore, it has been my aim to describe, how the Adobe Flex technology can be connected with other frameworks making the development process easier and how to connect it to the commercial logic and data layers. In this thesis, the commercial logic layer is represented by the Spring Framework and Java Programming Language, while the data layers by the Hibernate and H2 Databases. The result consists of the description of the SDK itself, Flash Builder Development Environment and familiarisation with the ActionScript3.0 and MXML languages. In the chapters to follow, control elements, containers and other components offered by Adobe Flex are explained. In addition, work procedures with bindings, working with modules in Adobe Flex and localisation of the application are described. In the other part of my thesis, I have focused my attention to various method of connection to the commercial logic made available for the Flex application by the use of BlazeDS, implemented through Spring Framework, where – at the same time – the connection over RPC is processed in detail. Some time is also devoted to testing using the unit tests and automatic functional testing of applications and security aspects of Adobe Flex, or Flash Player as applicable, are discussed. In the end of my thesis, I give some considerations to a comparison with similar technologies, namely Silverligth (by Microsoft), Oracle JavaFX and HTML5, where the described properties are demonstrated by a concrete example. Also, a practical example of the Autoškola (Driving School) Programme is given, where a list of questions and tests used in driving schools is offered to the user, who can browse in it either in the learning mode or launch it as a conventional test. In addition, the programme contains a section for the application administration, which is used for the creation of the questions and tests as such. Keywords: Adobe Flex, ActionScript, MXML, Flash Builder, RIA, Rich Internet Application, Spark, BlazeDS, FlexUnit, Cairngorm, FlexMonkey, Hibernate ▪5▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 4. PROHLÁŠENÍ Prohlašuji, že svou bakalářskou práci na téma Adobe Flex 4 jsem vypracoval samostatně pod vedením vedoucího bakalářské práce a s použitím odborné literatury a dalších informačních zdrojů, které jsou v práci citovány a jsou též uvedeny v seznamu literatury a použitých zdrojů. Jako autor uvedené bakalářské práce dále prohlašuji, že v souvislosti s vytvořením této bakalářské práce jsem neporušil autorská práva třetích osob, zejména jsem nezasáhl nedovoleným způsobem do cizích autorských práv osobnostních a jsem si plně vědom následků porušení ustanovení § 11 a následujících autorského zákona č. 121/2000 Sb. V Praze dne 18. 8. 2011 …….………………. Michal Kolesár ▪6▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 5. PODĚKOVÁNÍ Děkuji vedoucímu bakalářské práce Ing. Marku Beránkovi a dále Mgr. Pavlu Zemanovi za jejich účinnou metodickou, pedagogickou a odbornou pomoc a další cenné rady při zpracování mé bakalářské práce. ▪7▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 6. OBSAH 1.Zadání........................................................................................................................................... 3 2.Abstrakt........................................................................................................................................ 4 3.Abstract........................................................................................................................................ 5 4.Prohlášení.................................................................................................................................... 6 5.Poděkování.................................................................................................................................. 7 6.Obsah............................................................................................................................................ 8 7.Úvod............................................................................................................................................ 10 7.1.Historie WWW.................................................................................................................. 10 7.2.Co je to RIA?.................................................................................................................... 11 7.3.Aplikace „Autoškola“........................................................................................................ 11 8.Co je Flex?................................................................................................................................. 12 8.1.První seznámení s ActionScript3.0...............................................................................13 8.2.První seznámení s MXML............................................................................................... 16 9.Nástroje...................................................................................................................................... 19 9.1.SDK................................................................................................................................... 19 9.2.Flash Builder.................................................................................................................... 20 10.Ovládací prvky, kontajnery, navigátory................................................................................25 10.1.Spark a MX komponenty.............................................................................................. 25 10.2.Ovládací prvky (Controls)............................................................................................ 26 10.3.Kontajnery (Containers)............................................................................................... 28 10.4.Spark Layouty................................................................................................................ 31 10.5.Navigátory (Navigators)................................................................................................ 32 10.6.Grafy................................................................................................................................ 35 11.Práce s Flexem........................................................................................................................ 36 11.1.Data Binding................................................................................................................... 36 11.2.Validátory........................................................................................................................ 37 11.3.Formátery........................................................................................................................ 40 11.4.Label Function................................................................................................................ 44 11.5.Item Renderer................................................................................................................ 46 11.6.Filter Function................................................................................................................ 49 11.7.Lokalizace a multijazyčnost......................................................................................... 51 11.8.Moduly............................................................................................................................. 54 12.Komponenty............................................................................................................................. 65 12.1.Event-Driven architektura............................................................................................ 65 12.2.MXML komponenta........................................................................................................ 66 12.3.ActionScript3.0 komponenta........................................................................................ 68 12.4.Stavy a Přechody (States and Transitions)...............................................................69 13.CSS, skiny............................................................................................................................... 71 13.1.Kaskádové styly............................................................................................................. 71 13.2.Spark skiny..................................................................................................................... 73 13.3.Vytvoření vlastního skinu............................................................................................. 74 14.Datové služby.......................................................................................................................... 76 14.1.Web Service................................................................................................................... 76 14.2.HTTP Service................................................................................................................. 77 14.3.Remote Object............................................................................................................... 78 15.Cairngorm................................................................................................................................ 81 15.1.Vývoj rozsáhlých aplikací............................................................................................. 81 15.2.Popis MVC frameworku Cairngorm.............................................................................81 15.3.ModelLocator................................................................................................................. 82 15.4.Event............................................................................................................................... 83 15.5.Command....................................................................................................................... 84 ▪8▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 15.6.FrontController............................................................................................................... 85 15.7.ServiceLocator............................................................................................................... 86 16.Testování.................................................................................................................................. 88 16.1.FlexUnit – Unit Testy..................................................................................................... 88 16.2.FlexMonkey – Funkční testy........................................................................................ 90 17.Bezpečnost.............................................................................................................................. 92 17.1.Flash Player................................................................................................................... 92 17.2.Vnitřní bezpečnost aplikace......................................................................................... 94 17.3.Síťová bezpečnost........................................................................................................ 96 18.Vrstva obchodní logiky........................................................................................................... 98 18.1.Spring, IoC a DI............................................................................................................. 98 18.2.LCDS, BlazeDS........................................................................................................... 101 18.3.Konfigurace Spring a BlazeDS..................................................................................105 18.4.Ukázka jednoduché Java služby pomocí BlazeDS.................................................108 19.Hibernate pro datovou vrstvu.............................................................................................. 111 19.1.Modelování datových entit.......................................................................................... 111 19.2.Spring a Hibernate...................................................................................................... 112 19.3.Entity............................................................................................................................. 113 19.4.Perzistentní služby...................................................................................................... 113 19.5.Administrace H2 databáze.........................................................................................114 20.Build pomocí Mavenu........................................................................................................... 117 20.1.V čem je dobrý nástroj typu Maven..........................................................................117 20.2.Jak Maven použít........................................................................................................ 117 21.Postup při návrhu aplikace.................................................................................................. 119 21.1.Zadání aplikace „Autoškola“......................................................................................119 21.2.Analýza......................................................................................................................... 119 21.3.Architektura.................................................................................................................. 122 21.4.Návrh a implementace Flexových komponent........................................................123 21.5.Návrh a implementace modelu..................................................................................125 21.6.Návrh a implementace vzdálených služeb..............................................................125 21.7.Návrh a implementace datové vrstvy.......................................................................126 21.8.Finální aplikace........................................................................................................... 126 22.Porovnání Flexu s dalšími technologiemi.........................................................................127 22.1.Flex a Silverlight.......................................................................................................... 127 22.2.Flex a JavaFX.............................................................................................................. 129 22.3.Flex a HTML5.............................................................................................................. 131 23.Závěr...................................................................................................................................... 134 24.Conclusion............................................................................................................................. 136 25.Seznam použité literatury.................................................................................................... 138 26.Seznam použitých symbolů a zkratek...............................................................................139 27.Seznam obrázků................................................................................................................... 141 28.Seznam tabulek.................................................................................................................... 143 29.Seznam příloh....................................................................................................................... 144 Příloha 1 – Seznam kontajnerů................................................................................................ 145 Příloha 2 - Validátory................................................................................................................. 147 Příloha 3 – Formátery................................................................................................................ 149 Příloha 4 - Ovládací prvky........................................................................................................ 150 ▪9▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 7. ÚVOD Důvod proč jsem si téma Adobe Flex vybral je, že s touto technologií již několik let pracuji a mám s ní jisté zkušenosti. Mou snahou bylo ukázat na praktických příkladech, co Adobe Flex nabízí a jak je možné s ním pracovat. Za stěžejní považuji nepředstavit jen samotný Adobe Flex, ale představit jej v kontextu s dalšími frameworky a způsoby integrace s ostatními technologiemi a to vše na praktických ukázkách. V této práci bych se rád věnoval popisu technologie Adobe Flex a způsoby jejího použití v praxi. Adobe Flex je framework postavený jako nadstavba nad známou technologií Adobe Flash. Adobe Flex se snaží využít potenciálu a široké rozšířenosti Flash Playeru a nabídnout ucelenou sadu komponent pro tvorbu RIA aplikací, což v samotném Flashi, který je určen převážně pro tvorbu animací, chybí. Téma je poměrně široké, snažil jsem se jej zpracovat tak, aby nepřesáhlo akceptovatelný rámec. Přesto je práce poměrně obsáhlá a to především díky řadě ukázek zdrojových kódů, obrázků a tabulek. Zvažoval jsem dát kódy do samostatných příloh nebo pouze na přiložené CD, ale nakonec jsem se je rozhodl, z důvodu lepší čitelnosti práce, ponechat. 7.1. Historie WWW Webové stránky jsou v současné době to, co si každý představí a spojí se sítí internet. Možná ještě emailovou komunikaci. Nebylo tomu ale tak vždy. Ještě před dvaceti lety žádné webové stránky neexistovaly, byly pouze základní služby jako E-mail, FTP, Telnet, DNS, a náhražkou webu byl Ghoper. Od doby, co se web, jehož autor je Tim Derners-Lee, v roce 1990 objevil, prošel poměrně rozsálnou změnou. V prvních fázích se jednalo o poměrně jednoduché textové stráky, kde hlavní přidanou hodnotou byl způsob odkazů na další stránky, jednoduché obrázky, osobně bych je přirovnal ke vzhledu, jaký dnes má Wikipedie. Pak se objevovaly další verze, které nabízely možnost kaskádových stylů, podporu dalších tagů a také podpora Ajaxu, které web proměnily k nepoznání směrem k plnohodnotným desktopovým aplikacím. ▪ 10 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 7.2. Co je to RIA? RIA nebo-li Rich Internet Application, také u nás nazývané česky bohaté internetové aplikace, je právě směr, kterým se webové stránky snaží ubírat. Na začátku se jednalo pouze o texty s odkazy. Oproti tomu již tenkrát existovaly grafické desktopové aplikace, které dokázaly interagovat po síti se serverem. Dnešní trend je však takový, aby webové stránky nebyly pouze texty s odkazy a pár obrázky, ale aby se více podobaly právě desktopovým aplikacím. Od webu se očákává stále více možností, jako spolupráce s databází, jistá logika uvnitř stránek a také rychlé reakce při práci s aplikací. Aplikační logiku obecně je možné mít buď na straně serveru a na klienta posílat pouze vygenerovaný HTML kód, jako je tomu např. u PHP, JSP, apod., nebo je možné ji přenést částečně na klienta, např. pomocí implementace JavaScriptových funkcí. A to je právě cílem RIA aplikací. Je zcela jedno, jaká technologie bude řešit na straně klienta aplikační logiku, zda je to JavaScript, Flash, Flex, Silverlight, apod. Důležité je, že aplikace není celá na straně serveru a prohlížeč není jen jednoduchým zobrazovačem neustále stejného obsahu stahovaného ze serveru. RIA aplikace přináší několik výhod, mezi nejzajímavější jsou ulehčení serveru, zpříjemnění práce s aplikací pro uživatele, nabídnutí uživateli nové možnosti např. podpory multimediálního obsahu. Oproti klasickým desktopovým aplikacím je třeba vyzdvihnout jednodušší centralizovanou správu aplikace. Na straně klienta není potřeba aplikaci instalovat, je stažena ze serveru a spuštěna v prohlížeči. Distribuce nových verzí je tím pádem velice jednoduchá. Na druhou stranu je zde vyšší bezpečnostní riziko a aplikace musí být dobře izolovaná od zdrojů operačního systému, aby nebyl napadnutelný. S tím souvisí bezpečnost webového prohlížeče a případných modulů od dodavatelů třetích stran – v našem případě konkrétně plugin Flash Playeru. 7.3. Aplikace „Autoškola“ V práci se budu snažit používat různé ukázky příkladů pro názornější vysvětlení a lepší pochopení tématu. Některé části budou vycházet z aplikace Autoškola, která je součástí práce, některé části budu vysvětlovat na ukázkách nesouvisejících z aplikací. ▪ 11 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 8. CO JE FLEX? V úvodu bychom si měli říct, co vlastně Flex je, k čemu je dobrý a ukázat, jak se používá. Já bych Flex definoval jako sadu knihoven, která je postavena na Flashi, a která byla vyvinuta za účelem zjednodušení vývoje GUI webových aplikací. Podívejme se ale, jak definuje pojem Flex firma Adobe. „Adobe Flex is a software development kit (SDK) released by Adobe Systems for the development and deployment of cross-platform rich Internet applications based on the Adobe Flash platform. Flex applications can be written using Adobe Flash Builder or by using the freely available Flex compiler from Adobe.“1 Z definice je patrné, že Flex je vlastně SDK od Adobe, určený pro vývoj RIA, využívající Adobe Flash platformu. A pro vývoje je možné používat buď komerční nástroj Flash Builder nebo libovolný jiný editor a compiler dostupný v SDK. O samotném SDK a Flash Builderu se blíže zmíním v samostatné kapitole Nástroje. Flex se skládá z několika částí. V první řadě je to knihovna komponent pro tvorbu grafických aplikací. Pod těmito komponentami si můžeme představit ovládací prvky jako např. tlačítka, formulářová okénka, progress bar nebo třeba tabulky. Dále mezi ně patří také kontajnerové komponety, které typicky mohou obsahovat buď ovládací prvky nebo další kontajnery. Jedná se o komponenty reprezentující panel nebo jen logickou skupinu prvků s jasně definovaným layoutem. Mezi další zástupce komponent patří také prvky pro navigaci, což mohou být komponenty reprezentující menu nebo sezam záložek. Ve Flexu je také poměrně rozsáhlá podpora vizualizace dat pomocí grafů. Nyní bychom měli představu o Flexu z hlediska komponent. Pro samotný vývoj jsou potřeba ale další nástroje, jako je debugger, profiler, překladač, wysiwyg editor pro tvorbu GUI, podpora lokalizací a multijazyčnosti. To vše jsou funkce, které nabízí buď samotné SDK nebo zmiňovaný editor Flash Builder. Jednolivé Flexové aplikace nebo komponenty je možné psát buď v ActionScript3.0 (AS3) nebo v MXML. MXML je XML kód, který se ve Flexu používá pro popis daného view. MXML a AS3 je možné také kombinovat. Obě varianty, jak AS3 tak MXML, mají své pro a proti. Tak například v AS3 je možná větší variabilita a širší možnosti programátora, kód je ale méně přehledný a vyžaduje jistou znalost OOP obecně. Pro rychlou definici view není příliš vhodný. Oproti tomu MXML je velice přehledné, je snadno pochopitelné i laikem, dokáže v mnoha věcech plnit stejnou úlohu jako AS3 a navíc umožňuje spolupráci s grafickým editorem uvnitř Flash 1 http://www.adobe.com/ ▪ 12 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Builderu. Ten upravuje a generuje právě MXML kód, který je možné zároveň měnit manuálně a změny na obou stranách jsou vzájemně synchronizovány. Rád bych podotknul fakt, že MXML není nic jiného než popis hierarchické struktury daného view a handlování událostí, a že s každou vizuální Flexovou AS3 třídou je možné pracovat také v MXML. Ve fázi buildovacího plánu je totiž celé MXML nejprve překonvertováno do AS3 a následně přeloženo do bytekódu. Pro úplnost ještě zmíním FXG, což je také forma XML zápisu používaná pro práci s grafickou knihovnou, tudíž základních grafických elementů jako např. obdélník. Ve Flexových aplikacích se používá hlavně při tvoření vlastních Spark skinů pro orámování, stíny, atp. V následujících kapitolách se budu věnovat pouze MXML a AS3. 8.1. První seznámení s ActionScript3.0 ActionScript3.0 (AS3), je dynamický oběktově orientovaný programovací jazyk, který vychází ze standardizované verze jazyka JavaScript, nazvané ECMAScript. Současně je ve verzi 3.0, která je oproti předchozím verzím plně objektová a několikanásobně rychlejší, má vylepšenou podporu práci s XML a model událostí, a také lépe navrhnutou vnitřní strukturu pro práci s obrazovkovými elementy. Jazyk je na pohled velice podobný známým programovacím jazykům jako např. Java a je dobře čitelný. ▪ 13 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ClassExample.as package { public class ClassExample { public function ClassExample() {} public var var1:String = "value"; private var _var2:Number; // using default values for method parameters private function myMethod(value:String, nextParam:String = "default value"):String { return value; } // setter definition public function set var2(value:Number):void { _var2 = value; } // getter definition public function get var2():Number { return _var2; } // example how to use setter and getter public function print():String { var2 = 10; // setter call return var1 + var2; // getter call } } } Z ukázky kódu je zřejmé, že podporuje accessory, dále rozdíl oproti Javě v použití přetěžování metod, kde v AS3 je možné parametry plnit výchozími hodnotami a tím volat různý počet argumentů. Za zmínku stojí práce se settery a gettery. V Javě jsou používány metody, kterými se daná akce volá. Ve Flexu metody obecně nazýváme funkcemi. Gettery a settery jsou speciální funkce a je možné s nimi v kódu pracovat, jako by se jednalo o standardní atributy. V ukázce kódu je var1 standardní atribut, ale var2 je setter/getter. Základní datové typy AS3, jak již bylo řečeno, je plně objektově orientovaný jazyk. To znamená, že všechny typy jsou objekty. Dělí se ale na primitivní a komplexní. Primitivní typy jsou Number, Boolean, unit, int a String. Může být matoucí, že jsou typy uváděny s počátečním písmenem velkým, ale i tak se jedná o primitivní typ. Primitivní typy liší od klasických tříd to, že vnitřně se chovají jako immutable a tudíž se s nimi rychleji pracuje a jsou méně náročné na paměť. Na rozdíl od Javy, která nabízí např. primitivní typ int a k němu zawrapovaný objektový typ Integer tomu tak u AS3 není. Všechny typy jsou objektové. Ekvivalentem tudíž je var someInt:int = 3; var someInt:int = new int(3); ▪ 14 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Rozdíl od komplexních datových typů je také v tom, že primitivní datový typ nemůže nabývat hodnoty null, na rozdíl od komplexních datových typů. Tabulka 1: AS3 - primitivní datové typy Datový typ Popisek Boolean jednoduchý datový typ nabývající hodnotu True a False int 32bitová číselná hodnota v rozmezí -2.147.483.648 až 2.147.483.648 Null datový typ obsahující pouze hodnotu null, což je implicitní hodnota pro datový typ String a všechny další, které definují komplexní datové typy včetně třídy Object Number může reprezentovat číselnou hodnotu integer (viz int), unsigned integer (kladný int) a čísla s plovoucí čárkou; používá 64-bitový formát. String reprezentuje sekvenci 16bitových znaků; interně je uložen jako Unicode znaky využívající kódování UTF–16; předchozí verze Flash používají UTF-8 uint 32bitový číselný datový typ v rozmezí od 0 do 4.294.967.295 void obsahuje pouze jednu hodnotu undefined; v předchozích verzích je undefined výchozí hodnotou u některých datových typů zdroj: http://livedocs.adobe.com Druhou skupinou typů jsou typy komplexní, jedná se už o klasické objekty nebo-li komplexní datové typy. Všechny komplexní datové typy jsou poděděny ze základního typu Object. Těchto typů je celá řada, zmíním pouze ty nejpoužívanější. Tabulka 2: AS3 - komplexní datové typy ▪ 15 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Datový typ Popisek Object je definován třídou Object, která slouží jako základní třída pro definici všech tříd v AS3; Object je v podstatě použit jako asociativní pole, které obsahuje dvojice klíčhodnota, kde klíč je string a hodnota může být jakéhokoli typu Array obsahuje seznam dat; data mohou být uložena jako jakýkoli typ a poté přepsáno jako původní datový typ Vector varianta pole použitelná pouze Flash Playerem 10 nebo vyšším; Vectory jsou typově bezpečné jako pole, ale zpracovávají se rychleji Dictionary varianta objektu, která může obsahovat klíče kterýchkoli dat (klíče jsou definované jako objekt) MovieClip datový typ pro reprezentaci vizuálních objektů Bitmap neanimovatelný vizuální objekt Shape neanimovatelný vektorový vizuální objekt ByteArray obsahuje pole binárních bajtových dat TextField jednoduché dynamické nebo vstupní textové pole; dědí vlastnosti třídy InteractiveObject SimpleButton jednoduché tlačítko se čtyřmi akcemi: Up, Over, Down a Hit Date datový typ zpřístupňující aktuální systémový čas Error generovaný chybový objekt, který umožňuje nahlášení chyb za běhu programu (exceptions) Function základní třída pro všechny definice metod RegExp regulární vyjádření objektu pro řetězec (String) Video objekt pro přehrávání videa podporující přímý nebo přenášený transport; od verze Flash Playeru 9.0.115.0 je podporováno i H.264 (MP4 high-definition video formát) společně s původní FLV videem XML revidovaný XML objekt založený na standardu E4C; uzly a atributy jsou zpřístupněny jinak než v ActionScriptu 2.0 XMLList objekt typu pole pro uložení různého obsahu z třídy XML zdroj: http://livedocs.adobe.com 8.2. První seznámení s MXML Už jsme si v úvodu popsali, že existují zápisy pomocí AS3 a MXML. Velkou výhodou MXML je binding view na model a celková čitelnost. Z toho plyne to, že MXML zápis a tím i Flex je přístupný začínajícím programátorům, kteří nemusí mít vysoké povědomí o OOP a přesto ve Flexu pomocí MXML jsou schopni naprogramovat poměrně slušně fungující aplikace s minimálním úsilím a relativně malým množstvým kódu. Nevýhodou je to, že ne vše se v MXML dá naprogramovat. Jakmile je třeba nějaké funkčnosti, které MXML nepodporuje, je třeba sáhnout po AS3. ▪ 16 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Osobně si myslím, že velkou výhodu mají stávající programátoři z jiných objektově orientovaných jazyků, kteří obecně znají objektově orientované principy a Flex jim nabízí, jak tyto zkušenosti využít k tvorbě hezkého GUI jednoduchým způsobem. Přechod např. z Javy do Flexu je pak záležitost několika dnů. Ve Flexu je možné vytvářet komponenty a tím celé view rozdělit na samostatné celky. Komponentu je opět možné vytvořit buď jako AS3 nebo jako MXML. Využití komponentního vývoje má pak pozitivní dopad na případnou rozšiřitelnost a úspěšnost projektu. MXMLApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Script> <![CDATA[ import mx.controls.Alert; protected function clickHandler(event:MouseEvent):void { Alert.show("Hello!"); } ]]> </fx:Script> <s:Panel title="Title"> <s:Button id="btn" label="Click Me!" click="clickHandler(event)"/> </s:Panel> </s:Application> V jednoduché ukázce MXML aplikace by mělo být i pro neprogramátora, který má povědomí o XML, patrné, co aplikace dělá. Pro jistotu popíši jednotlivé části aplikace. Na prvním řádku je definice XML. Na dalších řádcích je pak definice namespace. Následuje sekce Script, která obsahuje AS3. Je tedy patrné, že se jedná o aplikaci, která kombinuje MXML a AS3 v jednom souboru. V AS3 je pouze import použité třídy a handler události pro tlačítko, který zobrazuje modální alert okno. Následuje definice view začínající tagem Panel. View je jednoduché, obsahuje pouze panel, uvnitř kterého je tlačítko (Button). Po stisku tlačítka se pustí handler clickHandler() definovaný v sekci Script. ▪ 17 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 1: Ukázka spuštěné MXML aplikace (po kliknutí na button) Po spuštění aplikace se zobrazí panel „Title“ a po stisku se zobrazí modální alert okno s hláškou „Hello!“. ▪ 18 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 9. NÁSTROJE 9.1. SDK Nyní se podíváme z blízka na Software Development Kit (SDK). SDK obecně je balík nástrojů a knihoven potřebný pro vývoj aplikací v daném jazyce. V našem případě je to balík obsahující nástroje pro překlad, debugování a knihovny základních komponent. Flex SDK je k dispozici na stránkách 2 společnosti Adobe zcela zdarma a to i pro komerční použití. SDK je vydáváno pod dvěmi licencemi Tabulka 3: Licence Flex SDK Název licence Popis Mozilla Public License, version 1.1 (MPL) Primarily covers the source code of the Open Source Flex SDK including the Flex framework, the compilers, and the debugger. Covers elements that Adobe was not able to release under an open source license including the Adobe® Flash® Adobe Flex SDK license Player, Adobe® AIR™, and other third-party code used by the Flex SDK for specific functions, such as font encoding. zdroj: http://opensource.adobe.com/wiki/display/flexsdk/Legal+Stuff Z výše uvedené licence MPL na Flex framework vyplývá, že součástí SDK jsou také kompletní zdrojové kódy frameworku. SDK je k dispozici pro nejpoužívanější platformy – Windows, Linux, Apple OS X. Srdcem SDK je totiž Java, která je multiplatformní. Z toho také plyne, že podmínkou pro fungování Flexu je mít instalovanou Javu. Pokud zde budu popisovat nějaké nastavení SDK, budu se zmiňovat pouze o platformě Windows. Asi nejdůležitějším nástrojem z SDK je překladač, proto se mu budu podrobněji věnovat. Překladač může být buď součástí čistého SDK nebo pokud se rozhodnete stáhnout si Flash Builder, pak je SDK součástí Flash Builderu. Binárka překladače mxmlc.exe je umístěna v těchto cestách. Překladač samotný je implementovaný v Javě3, pro jeho spouštění je k dispozici binárka mxmlc.exe4. Úkolem překladače je převést .mxml a .as soubory do SWF5 formátu. Pro správný chod překladače je tedy nezbytné, aby na počítači bylo instalováno Java Runtime Environment. 2 3 4 5 http://www.adobe.com/products/flex/ .jar souubry v adresáři lib v SDK Toto platí pouze pro platformu windows. Pro unixové platformy jsou jiné binárky SWF je binární soubor, který je spustitelný v Adobe Flash Playeru ▪ 19 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 V bin adresáři SDK jsou kromě mxmlc.exe ještě compc.exe pro překlad knihoven (SWC souborů) a pro debugování v příkazovém řádku fdb.exe. Žádný z těchto programů nemá GUI, takže je možné je spouštět pouze z příkazové řádky. Všechny parametry překladače jsou k dispozici v dokumentaci6. Je patrné, že mxmlc.exe má celou řadu parametrů a použití standardním způsobem znamená většinou zadávat do příkazové řádky několik parametrů za sebou. Použití může vypadat napřílad takto: c:\> mxmlc.exe -show-coach-warnings=true -use-network=false -o output.swf -file-specs “c:\git\projektXX\src\cz\sample\MyClass.as” Protože k vývoji Flex aplikací se v drtivé většině používá nástroj Flash Builder, nebudu popisovat podrobně celé SDK, ale popíši vlastnosti Flash Builderu, který SDK již obsahuje a značně zjednodušuje jak samotný vývoj, tak překlad a spouštění aplikace. 9.2. Flash Builder V předchozích odstavcích jsem popisoval, že je možné začít vyvíjet Flex aplikace jen za pomoci SDK a standardního textového editoru. Tento způsob vývoje je zcela zdarma, ale v dnešní době, kdy je pro ostatní jazyky k dispozici celá řada nástrojů, které usnadňují vývoj, by se jednalo o značný krok zpět. Proto Adobe nabízí pro vývoj Flex aplikací nástroj, který se jmenuje Flash Builder. Tento nástroj slouží k usnadnění vývoje Flex aplikací. Podívejme se, jak o nástroji Flash Builder píše společnost Adobe na svém webu. „Adobe® Flash® Builder® 4.5 Premium software is an Eclipse™ based development tool for rapidly building expressive mobile, web, and desktop applications using ActionScript® and the open source Flex framework. Use professional testing tools to build higher performing applications.“ 7. Flash Builder nabízí zjednodušenou práci s kódem. Umožňuje v rámci wysiwyg editoru automatický build, spouštět kód v normálním, ale i v debug režimu a profilování. Kód je spouštěn v prohlížeči s instalovaným Flash Playerem. Pro debugování je nutné mít staženou 8 speciální verzi Flash Playeru s podporou debugování. Pak je možná trasovat kód stejně jako známe např. z Javy. Nevýhodou MXML je, že není možné jej debugovat. Debugování je možný pouze v AS3. 6 http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7a92.html 7 http://www.adobe.com/products/flash-builder.html 8 http://www.adobe.com/support/flashplayer/downloads.html ▪ 20 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Na druhou stranu je velice příjemné debugování na straně serveru. Protože většinou se Flex klient připojuje na data nebo obchodní logiku přes aplikační server, na kterém běží Java, je potřeba mít možnost debugovat jak na straně Flexu, tak na straně Javy. A ve Flash Builderu je tato vlastnost velice produktivní. Flash Builder nabízí také funkce code completing a syntax highlighting. Obrázek 2: Flash Builder 4.5 Tento nástroj není zdarma a k dispozici je několik edicí. Ceny9 se pohybují od $249USD do $799USD za plnou verzi jedné licence. Upgrade z předchozích verzí již od $49USD. K licenci je také možné dokoupit emailovou podporu. Pro otestování Flash Builderu je ale možné si stáhnout plně funkční Trial verzi, která je platná po dobu 60 dnů. Flash Builder je možné koupit také jako součást balíku Adobe Creative Suite 5.5 Web Premium nebo Master Collection software. Flash Builder je postaven na platformě Eclipse10 a je k dispozici ve dvou variantách 9 http://www.adobe.com/products/flex/buy/ 10 http://www.eclipse.org ▪ 21 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 • Standalone aplikace – Flash Builder je plně integrován s Eclipse. Tuto variantu ocení začínající programátoři, kteří ještě nemají vlastní instalaci Eclipse a chtějí začít s vývojem Flexu. • Plugin verze – Jedná se o samostatný plugin, který je možné instalovat do samostatné instalace Eclipse. Tuto variantu ocení seniorní programátoři, kteří mají vlastní verzi Eclipse, nakonfigurované prostředí, a chtějí do Eclipse přidat podporu pro Flex. V současné době (05/2011) je k dispozici verze Flash Builderu 4.5. S touto verzí osobně nemám velké zkušenosti. Pracoval jsem především s verzí 4.0 a s předchozími verzemi 2.x a 3.x, které měly název Flex Builder. Název Flash Builder je až od verze 4.x. Přesto se pokusím shrnout vlastnosti, které Flash Builder 4.5 nabízí. • Mobilní aplikace (nově v 4.5) – Flash Builder má nově implementovanou podporu pro mobilní platformu Android, BlackBerry a iOS. • Web RIA – Primární podpora pro vývoj RIA aplikací, které běží ve všech nejpoužívanějších webových prohlížečích, jež mají podporu Adobe Flash Playeru napříč různými platformami. • Desktopové aplikace – Pomocí technologie Adobe AIR je možné ve Flash Builderu vytvářet také desktopové aplikace. Podmínkou je mít na desktopu instalován AIR 11 runtime. • Propojení s nástroji z CS5.5 – Nově nabízí obousměrnou spolupráci nástroje Flash Builder a Adobe Flash Catalyst z balíku CS5.5, který je využíván pro návrh designu Flex aplikací a komponent. • Spouštění, debugování, profiling aplikací – Přímo z Flash Builderu je možné aplikace spouštět a debugovat, optimalizovat jejich výkon, vytvářet memmory snapshoty. • Syntax highlighting, code completion • Generátor zdrojových kódů – Nabízí generování setter/getter, ale také nabízí generování handlerů událostí, item rendererů, refaktoring, doplňování definic z interface nebo ze super class při použití implements/override, a další. • GUI editor – Grafické rozhraní aplikací je možné vytvářet jednoduchým drag-and-drop přesouváním komponent a kontajnerů na pracovní plochu. Integrovaná je také podpora pro definování stavů a kaskádových stylů. Protože je kód generován v MXML podobě, je možné pracovat v GUI režimu nebo v režimu úpravy zdrojového kódu. • Datové služby – Flash Builder nabízí podporu pro LCDS, BlazeDS, WebServices, PHP, .NET, ColdFusion 11 http://www.adobe.com/products/air/ ▪ 22 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 • Testování aplikací – Ve Flash Builderu je integrována podpora FlexUnit pro psaní a spouštění unit testů pro AS3. Přestože Flash Builder, resp. SDK, podporuje plně lokalizaci, je třeba po instalaci vygenerovat lokalizaci pro české nárdodní prostředí. Protože Flash Builder pro překlad projektů využívá jako výchozí lokalizaci tu, ve které je lokalizovaný operační systém a lokalizace cs_CZ není v SDK Flash Builderu předgenerována, bude Flash Builder hlásit překladovou chybu. Řešení je velice jednoduché. Pomocí nástroje copylocale, který je součástí SDK, vytvoříme kopii nějaké existující lokalizace, např. en_US. [sdk]\bin\copylocale en_US cs_CZ Po vygenerování je vytvořeno několik adresářů a definic locale. Tyto locale je pak možné modifikovat tak, aby odpovídaly českému národnímu prostředí. Obrázek 3: Seznam locales v SDK po instalaci Flash Builderu Uvnitř jednotlivých adresářů se nacházejí SWC soubory s definicemi lokalizací. Formát SWC je ekvivalent ZIP. Jejich obsahem jsou properties soubory, které obsahují již samotné definice, které jsou již v textové podobě ve formátu „definice = hodnota“. ▪ 23 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 formatters.properties (framework_rb.swc) # CurrencyFormatter, NumberFormatter rounding=none useNegativeSignInNumber=true useNegativeSignInCurrency=true useThousandsSeparator=true # CurrencyFormatter currencyFormatterPrecision=-1 # NumberFormatter numberFormatterPrecision=-1 # PhoneFormatter areaCode=-1 areaCodeFormat=(###) # formatString phoneNumberFormat=(###) ###-#### validPatternChars=+()#- . # ZipCodeFormatter zipCodeFormat=##### # DateBase am=AM pm=PM dayNamesShort=Neď,Pon,Úte,Stř,Čtv,Pát,Sob # appended with monthSymbol in SharedResources monthNamesShort=Led,Úno,Bře,Dub,Kvě,Črv,Čnc,Srp,Zář,Říj,Lis,Pro # Invalid Format Value Errors defaultInvalidValueError=Invalid value defaultInvalidFormatError=Invalid format Z výše uvedeného je patrné, že jsem upravil pro české národní prosředí např. zkratky názvů měsíců monthNamesShort a obdobně je to se dny. V properties souboru je možné upravit také formát času, překlad chybových hlášek, apod. ▪ 24 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 10. OVLÁDACÍ PRVKY, KONTAJNERY, NAVIGÁTORY Pro vývoj GUI aplikací je velice důležité mít k dispozici sadu základních grafických komponent, které známe např. z windows, jako jsou tlačítka, comboboxy, formuláře, atd. Tyto komponenty jsou většinou umístěné v nějakém kontajneru, který má daný layout 12. Flex pochopitelně nabízí celou řadu komponent, které jsou rozděleny do několika skupin 13. Ovládací prvky jsou aktivní prvky na obrazovce, které buď zobrazují data, nějak s nimi pracují nebo vyvolávají určitou akci. Dále to jsou kontajnery, které mohou obsahovat buď další kontajnery nebo ovládací prvky. Pak jsou k dispozici navigátory, což je vlastně speciální skupna ovládacích prvků určena speciálně pro navigování (menu) propojené s ViewStackem, který zajišťuje změnu obsahu. Další samostatnou skupinou je knihovna grafů. Ta v minulosti nebyla součástí standardních knihoven Flexu, jednalo se o komerční knihovnu, ale tuším od verze 3 již je ve Flexu společně s ostatními komponentami zdarma. Všechny vizuální prvky dědí od třídy UIComponent nebo GraphicElement. 10.1. Spark a MX komponenty Flexové komponenty jsou od verze 4 ve dvou variantách. Jedná se o MX komponenty, které byly i v předchozích verzích a jsou definovány v balíku mx.* a nově také Spark komponenty z balíku spark.*. V současné verzi 4.5 ještě nejsou všechy komponenty v obou provedeních. Např. komponenta DateChooser je stále pouze ve verzi MX. Při vývoji aplikací by se měly využívat pouze komponenty Spark, pokud existují a jsou funkční 14, protože ty postupně MX komponenty nahrazují. Ale existují také komponenty, které jsou typické jen 15 pro MX nebo jen pro Spark. Takže ve finále je Flexová aplikace mixem obou variant komponent. Jaký je mezi nimi rozdíl? Hlavní rozdíl je v práci s CSS a se skiny. Spark komponenty nejsou svázány se skiny tak, jako tomu je u MX. Více o skinech bude v samostatné kapitole CSS, skiny. Zjednodušeně se dá říct, že skin definuje vzhled dané komponenty. Kromě vzhledu je ale v 12 Jedná se o způsob rozvržení komponent uvnitř nějakého kontajneru. Může být definováno pevnou pozicí vnitřních komponent, ale také mohou být řazeny vertikálně pod sebe, horizontálně nebo také kombinovaně nebo zcela jinak, podle toho, jak rozvržení daný layout definuje. 13 Přímo ve Flash Builderu jsou takto komponenty členěny, proto se držím tohoto členění i zde. 14 Například se mi zcela neosvědčila práce s novou Spark komponentou DataGrid, která vykazovala chyby v layoutu. Proto také v aplikaci používám stále MX verzi. 15 Například MX komponenta ViewStack dle mého názoru nemá proč být ve variantě Spark, protože by jí to nepřinášelo žádnou výhodu. ▪ 25 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 komponentě definován datový stav a chování komponenty. Tyto dvě části Spark komponenty mají zcela oddělené. Dále Spark komponenty definují jiný způsob práce s layouty, kdy využívají externích tříd k definici layoutů na kontajnerech. Buď umožňují definovat layout přímo uživateli, jako např. komponenta Group, které je možné předat instanci layoutu nebo jej mají pevně definovaný vnitřně, jako je tomu např. u HGroup a VGroup. Přestože by se mohlo zdát, že HGroup a VGroup jsou stejné jako komponenty v MX variantě VBox a HBox, jsou vnitřně rozdílné. Spark komponenty jsou napsány tak, že žádný layout přímo nedefinují, využívají k tomu externí třídu, i když ji uživatel nemá možnost změnit. MX komponenty mají layout napřímo „vepsaný“ uvnitř dané komponenty. Na závěr jen zmíním, že komponenty Spark nebo MX (někdy také nazývané Halo) poznáme podle namespace nebo také názvu balíčku, ze kterého třída pochází. 10.2. Ovládací prvky (Controls) Controls, nebo-li ovládací prvky, jsou drobné grafické komponenty, které nabízí určitou základní funkci. Typicky se jedná o prvky, které například pracují s daty nebo vyvolávají nějakou akci. Jsou jakýmsi pomyslným vstupem do aplikace. Skládáním ovládacích prvků do kontajnerů, které mají definovaný nějaký layout (více o kontajnerech a layoutech v dalších kapitolách) je utvářena samotná aplikace, resp. její část view z MVC patternu. Níže uvádím nejpoužívanější komponenty. Button Button, nebo-li tlačítko, je jednoduchý ovládací prvek, který umožňuje vyvolat akci stlačením „kliknutím“ nebo také stisknutím mezerníku, pokud je na tlačítku focus. Po stisku tlačítka je spuštěna událost (event), která může být zachycena listenerem a zavolána konkrétní akce. Tlačítko je možné skinovat a stylovat. Typicky obsahuje text a případně také obrázek. <s:Button label="Button" click="button_clickHandler(event)"/> CheckBox CheckBox je prvek, který graficky zobrazuje binární hodnotu (vybráno, nevybráno) <s:CheckBox label="CheckBox" selected="true"/> ▪ 26 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ComboBox Jedná se o druh seznamu (listu), který po rozkliknutí zobrazí seznam hodnot. Je možné definovat také hodnotu vlastní. Zobrazované hodnoty mohou být labely, ale také upravená itemRendererem <s:ComboBox prompt="Vyberte hodnotu"/> DataGrid DataGrid je tabulka s daným počtem řádků a sloupců. Typicky je každý řádek objekt a sloupce jeho atributy. Řádky je možné třídit dle sloupců, zarovnávat. Hodnoty mohou být jak textové, tak upravené itemRendererem <fx:Declarations> <s:ArrayList id="dataColl"> <fx:Object field1="aaa" field2="bbb" field3="ccc"></fx:Object> <fx:Object field1="ddd" field2="eee" field3="fff"></fx:Object> <fx:Object field1="ggg" field2="hhh" field3="iii"></fx:Object> <fx:Object field1="jjj" field2="kkk" field3="lll"></fx:Object> </s:ArrayList> </fx:Declarations> <s:DataGrid dataProvider="{dataColl}" width="200"/> DateChooser DateChooser je MX komponenta kalendáře, ukazuje vybrané datum, je možné si konkrétní datum vybrat, listovat mezi měsíci a roky. V příkladu je vybraný datum nabindovaný na proměnnou dateVariable, která musí být definovaná jako [Bindable]16 <mx:DateChooser selectedDate="{dateVariable}"/> 16 Pokud je proměnná definována v AS3 (v sekci fx:Script), je nutné přidat anotaci [Bindable]. Více o bindingu bude v samostatné kapitole ▪ 27 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Label Label je jednořádkový výstupní text <s:Label text="Label"/> Label List List je seznam hodnot, typicky zobrazení nějaké kolekce objektů 17, a to formou textových záznamů reprezentující konkrétní atribut objektu, popř. kombinaci nebo uživatelsky definovaný výstup pomocí itemRendereru. <s:List dataProvider="{dataColl}" labelField="field1"/> TextInput TextInput je vstupní komponenta pro načtení jednoho řádku řetězce. <s:TextInput text="Vstupní text"/> Tabulku se seznamem ovládacích prvků naleznete v příloze Ovládací prvky. Všechny ovládací prvky, pracující např. s textem nebo čísly je možné přímo bindovat na proměnné. Více o bindingu bude v samostatné kapitole o bindování. 10.3. Kontajnery (Containers) V předchozí kapitole jsme si popsali jednotlivé ovládací prvky. Ty nám zajišťují funci a interaktivitu s uživatelem. Ovládací prvky je ale potřeba rozmístit na obrazovku, pozicovat. A to ne pouze absolutně, ale také relativně, s podporou rozvržení fixního nebo flow layoutu. Kontajner je logická skupina několika dalších prvků. Jsou řazeny hierarchicky do tzv. display listu, tj. kontajnery mohou obsahovat buď další kontajnery nebo vizuální prvky. Následující obrázek naznačuje strukturu display listu. Hlavní třídou je Stage, ve které jsou pak obsaženy v hierarchii kontajnery (Container), což může být třeba komponenta Panel, Group a jednotlivé vizuální nekontajnerové elementy (DisplayObject), např. Button. 17 V příkladu jsou použita stejná data jako u DataGridu ▪ 28 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 4: Ukázka řazení elementů v display listu zdroj http://workflowflash.com/1554/using-spark-containers-in-mx-navigators.php Flex obsahuje Spark kontajnery rozdělené na dvě hlavní skupiny. První skupina jsou kontajnery, které není možno skinovat, druhá skupina jsou kontajnery skinovatelné. Tabulka 4: Kontajnery a skiny Skiny Kontajnery bez skinů Group (HGroup, VGroup a TileGroup) a DataGroup se skiny SkinnableContainer, SkinnableDataContainer, Panel, TitleWindow, NavigatorContent, BorderContainer a Application Většina Sparkových kontajnerů podporuje zaměnitelné layouty, což znamená, že je možné nastavit kontajnerům buď layouty přímo podporované Flexem, kterými jsou horizontal, vertical, basic a tiled, nebo je možné vytvářet i layouty vlastní. Více o layoutech je popsáno v samostatné kapitole. U kontajnerů VGroup, HGroup, TileGroup naopak není možné nastavovat layout, protože je pevně definovaný. ▪ 29 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Kontajnery Group a DataGroup, které patří do skupiny “bez skinů”, je vhodné používat pro vyšší výkonnost, pokud není nutné pro daný kontajner použít skiny. Group a SkinnableContaner může obsahovat jako své prvky vizuální komponenty. Všechny vizuální komponenty implementují IVisualElement interface a jsou zděděny buď od UIComponent nebo od GraphicElement. UIComponent třída je supertřída pro všechny Flex komponenty. Což znamená, že je možné do těchto kontajnerů umístit všechny Flex komponenty. GraphicElement je supertřída pro 2D prvky typu čára, elipsa, atd. I tyto prvky mohou být obsaženy uvnitř kontajnerů. Výše uvedené kontajnery slouží pro zobrazení grafických elementů, nejsou určeny pro zobrazování datových položek. Pokud chceme pracovat s datovými položkami a ty zobrazovat, existují speciální kontanery, které s nimi umí pracovat. Datovými položkami mohou být jak primitivní typy, tak objekty nebo XMLNode objekty. Pro tyto učely slouží DataGroup a SkinnableDataContainer. Rozdíl od Group a SkinnableContainer je také v prvcích, které můžou obsahovat. U předchozích dvou stačilo, aby elementy implementovaly IVisualElement interface, ale u datových kontajnerů je třeba, aby také dědily z DisplayObject třídy. Tabulka se seznamem kontajnerů je v příloze Seznam kontajnerů. Ukázka práce s kontajnery Container1.mxml <s:SkinnableContainer> <s:layout> <s:HorizontalLayout/> </s:layout> <s:Button label="Button 1"/> <s:Button label="Button 2"/> <s:Button label="Button 3"/> <s:Button label="Button 4"/> </s:SkinnableContainer> ▪ 30 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 <s:SkinnableDataContainer itemRenderer="spark.skins.spark.DefaultItemRenderer"> <mx:ArrayList> <fx:String>Dave Jones</fx:String> <fx:String>Mary Davis</fx:String> <fx:String>Debbie Cooper</fx:String> </mx:ArrayList> </s:SkinnableDataContainer> výstup: Dave Jones Mary Davis Debbie Cooper 10.4. Spark Layouty U všech Sparkových kontajnerů je nastaven nějaký výchozí layout. U některých je neměnný (VGroup, HGroup, TileGroup), u některých je možné layout přenastavit přiřazením třídy layoutu k property layout na kontajneru (Group, Panel). Flex nabízí několik layout tříd, které je možné používat pro Spark kontajnery, krom toho je možné vytvořit si vlastní layout třídy. Layouty, které Flex obsahuje jsou definovány v balíku spark.layouts. Tabulka 5: Základní layouty Layout třída Popis BasicLayout Používá absolutní pozicování prvků (children) nebo používá omezení (constraints) HorizontalLayout Řadí prvky horizontálně vedle sebe do jednoho řádku, výška řádku je určena podle výšky nejvyššího prvku. Šírka pro každý prvek je defaultně variabilní, ale může být nastavena fixně pro všechny prvky. VerticalLayout Řadí prvky vertikálně do jednoho sloupce, šírka sloupce je určena podle šířky nejširšího prvku. Výška pro každý prvek je defaultně variabilní, ale může být nastavena fixně pro všechny prvky. TileLayout Řadí prvky do jednoho nebo více horizontálních řádků nebo vertikálních sloupců, přičemž každý nový řádek nebo sloupec je vytvořen dle potřeby. Směr layoutu určuje property “orientation” a všechny buňky mají fixní velikost. ▪ 31 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ekvivalentní ukázka <s:Group> <s:layout> <s:HorizontalLayout/> </s:layout> <s:Button label="Button 1"/> <s:Button label="Button 2"/> <s:Button label="Button 3"/> <s:Button label="Button 4"/> </s:Group> <s:HGroup> <s:Button <s:Button <s:Button <s:Button </s:HGroup> label="Button label="Button label="Button label="Button 1"/> 2"/> 3"/> 4"/> Na některých layoutech je možné definovat Boolean property variableRowHeight (resp. variableColumnWidth), která zapíná/vypíná variabilní výšku řádku (resp. šířku sloupce). Dále je možno definovat přesnou výšku a šířku pomocí rowHeight a columnWidth nebo pomocí property typicalLayoutElement, které předáme konkrétní element. 10.5. Navigátory (Navigators) Popsali jsme si jednotlivé ovládací prvky, jak je řadit na obrazovku pomocí kontajnerů a layoutů. Tím máme zajištěno rozvržení dané stránky nebo-li view. Ale to k plnohodnotné aplikaci nestačí, ještě chybí způsob navigace, tj. jak přepnout stránku nebo její obsah na stránku následující? K tomu slouží ve flexu tzv. navigátory (navigators). Základním prvkem pro navigaci je MX kontajner ViewStack, který obsahuje kolekci dalších kontajnerů, které jsou poskládány přes sebe s tím, že pouze jeden kontajner z kolekce je v danou chvíli zobrazen. K přepínání aktivního kontajneru je třeba nějaké navigační komponenty, která je k přepínání určena a reprezentuje tím v podstatě menu. Jedná se např. o LinkBar, TabBar, ButtonBar a ToggleButtonBar. zdroj: http://help.adobe.com/ ▪ 32 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 5: ViewStack ukázka přepínání aktivních kontajnerů Ve Flexu je více druhů komponent pro navigaci, popíši jen ty nejpoužívanější – ButtonBar, TabBar a MenuBar. ButtonBar ButtonBar je navigátor, který reprezentuje horizontální 18 seznam toggle19 tlačítek, které přepínají nabindovaný ViewStack. <s:ButtonBar dataProvider="{vs}"/> <mx:ViewStack id="vs" width="200" height="50"> <s:NavigatorContent width="100%" height="100%" label="První stránka"> <s:Label text="Toto je stránka první"/> </s:NavigatorContent> <s:NavigatorContent width="100%" height="100%" label="Druhá stránka"> <s:Label text="Toto je stránka druhá"/> </s:NavigatorContent> <s:NavigatorContent width="100%" height="100%" label="Třetí stránka"> <s:Label text="Toto je stránka třetí"/> </s:NavigatorContent> </mx:ViewStack> TabBar Použití i učel je stejný jako ButtonBar, jen vzhledově tlačítka vypadají jako záložky, proto příklad neuvádím. 18 ButtonBar je Spark komponenta, u které je vzhled a rozložení definováno skinem. Tudíž je možné úpravou skinu definovat ButtonBar vertikální 19 Tzv. toggle tlačítko je takové, které drží a také vizualizuje svou pozici aktivní/neaktivní nebo zmáčknuté/nezmáčknuté ▪ 33 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MenuBar MenuBar je MX navigační komponenta, která reprezentuje klasické horní menu, které může být víceúrovňové. <fx:Script> <![CDATA[ import mx.collections.XMLListCollection; import mx.controls.Alert; import mx.events.MenuEvent; [Bindable] public var menuBarCollection:XMLListCollection; private var menubarXML:XMLList = <> <menuitem label="Menu1" data="top"> <menuitem label="MenuItem 1-A" data="1A"/> <menuitem label="MenuItem 1-B" data="1B"/> </menuitem> <menuitem label="Menu2" data="top"> <menuitem label="MenuItem 2-A" type="check" data="2A"/> <menuitem type="separator"/> <menuitem label="MenuItem 2-B" > <menuitem label="SubMenuItem 3-A" type="radio" groupName="one" data="3A"/> <menuitem label="SubMenuItem 3-B" type="radio" groupName="one" data="3B"/> </menuitem> </menuitem> </>; private function initCollections():void { menuBarCollection = new XMLListCollection(menubarXML); } private function menuHandler(evt:MenuEvent):void { if (evt.item.@data != "top") { Alert.show("Label: " + evt.item.@label + "\n" + "Data: " + evt.item.@data, "Clicked menu item"); } } ]]> </fx:Script> <s:Panel title="MenuBar" width="200" height="200" horizontalCenter="0" verticalCenter="0"> <s:VGroup left="10" right="10" top="10" bottom="10"> <s:Label width="100%" color="blue" text="Select a menu item."/> <mx:MenuBar labelField="@label" itemClick="menuHandler(event);" dataProvider="{menuBarCollection}" /> </s:VGroup> </s:Panel> zdroj: http://help.adobe.com/ ▪ 34 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Pokud se tedy rozhodneme do aplikace implementovat navigaci pomocí navigátorů je potřeba mít vytvořen hlavní ViewStack, který bude obsahovat seznam všech kontajnerů 20 reprezentující daný obsah, což je ve většině případů konkrétní stránka s libovolným obsahem a použijeme přímého bindingu navigační komponenty (např. TabBar) na ViewStack. Pokud chceme využívat klasického hierarchického menu a pro každou položku menu mít možnost spuštění konkrétní akce, pak je vhodné použít MX komponentu MenuBar, které musíme jako data providera nastavit XML obsah s definicí menu. Na závěr bych chtěl ještě uvést že ViewStack je možné ovládat také napřímo, bez pomocí standardních navigačních komponent, přes property selectedIndex. 10.6. Grafy Flex krom předchozích komponent obsahuje také knihovnu s grafy. Nebudu zde popisovat možnosti jednotlivých grafů. Pouze zmíním, že všechny grafy jsou MX komponenty a pochází z balíku mx.charts. Jsou k dispozici sloupcové, koláčové, čárové a další. Grafy podporují standardní funkce jako popisky hodnot na osách, zobrazení legendy, rozsah jednotlivých os. Vstupními daty mohou být libovolné kolekce dat nebo XML s ohledem na charakteristiku konkrétního typu grafu. 20 Kontajnery uvnitř ViewStacku musí být buďto typu MX, a nebo pokud chceme používat Sparkové, pak musí být uvnitř kontajneru NavigatorContent. ▪ 35 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 11.PRÁCE S FLEXEM 11.1. Data Binding Data binding je obecná funkcionalita poskytující propojení datové vrstvy s view. Jinými slovy propojení nějaké vlastnosti na objektu nebo celého objektu s konkrétním controlem nebo komponentou na obrazovce. Jednoduchým příkladem může být svázání proměnné typu String s Labelem. Binding může být ale i na složitější objekty, jako například svázání kolekce s Listem. Svázání se projevuje dvěma způsoby. První, tzv. one-way binding zajišťuje jednosměrnou propagaci změn ze zdrojových dat do cílových (např. z modelu na view). Two-way binding, tedy obousměrný binding, zajišťuje krom propagace změn ze zdrojových dat do cílových také propagaci opačnou. <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" > <fx:Script> <![CDATA[ [Bindable] private var myString:String = "Výchozí hodnota"; protected function clickHandler(event:MouseEvent):void { myString = "Nová hodnota"; } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:Label text="{myString}"/> <s:TextInput text="@{myString}"/> <s:Button label="Změň hodnotu" click="clickHandler(event)"/> </s:Application> Z ukázky kódu je vidět, že proměnná myString má anotaci [Bindable] a samotný one-way binding na komponentě Label je reprezentovaný složenými závorkami. To je vše. Překladač sám zajistí doplnění potřebných AS3 kódů, které vygenerují dispatchování CHANGE událostí a jejich handlerů. V našem příkladu s Labelem by jednoduše došlo ke změně textu v Labelu při každé změně v proměnné myString. ▪ 36 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 V ukázce kódu pro two-way binding přibyl navíc jediný znak, a to zavináč v definici TextInputu. Pokud se změní proměnná myString, která je nabindovaná na TextInput, obsah proměnné je zobrazen v TextInputu. Ale funguje také směr opačný, jakmile uživatel zadá do TextInput nějakou hodnotu je hodnota automaticky propagována zpět do proměnné myString. Z ukázek je patrné, jak jednoduché je ve Flexu navázat model a view dohoromady pomocí bindingů, a že se jedná o velice silnou vlastnost Flexu. 11.2. Validátory Komponenty máme popsány, a nyní víme, jak na ně bindovat data. Je zřejmé, že komponenty se mohou dělit na vstupní a výstupní, podle toho, zda obsah pouze zobrazují (používá se one-way binding), nebo jejich obsah modifikujeme a chceme jej propagovat do modelu (víme, že se používá two-way binding). Vyvstává asi otázka, zda do komponent nemůže uživatel zadat nesmyslná data, se kterými logika aplikace, databáze nebo následně volané služby nemusí počítat. Proto je nutné vstupní data od uživatele vždy validovat. A k tomu ve Fexu slouží validátory. Validátorů ve Flexu máme celou řadu, a také můžeme vytvářet vlastní. Těmi standardními jsou MX validační komponenty, všechny založené na třídě mx.validators.Validator. Validační logika je implementována přetížením metody doValidate(). Tímto způsobem je možné vytvořit si libovolný validátor, který pouze dědí z mx.validators.Validator a implementuje onu logiku. Na níže uvedeném obrázku je zobrazen class diagram validátorů jak jej popisuje dokumentace 21. 21 http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/validators/Validator.html ▪ 37 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 6: Class diagram validátorů V následující ukázce je formulář, který ukazuje dva druhy dat – datum a text – v souladu s tím jsou použity různé validátory. ▪ 38 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Validators.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:local="*"> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.ValidationResultEvent; import mx.validators.Validator; protected function validate_clickHandler(event:MouseEvent):void { var validators:Array = new Array(nameVal, birtdayVal); if (areValid(validators)) Alert.show('Data jsou validní'); } private function isValid(validator:Validator):Boolean { return validator.validate().type == ValidationResultEvent.VALID; } private function areValid(validators:Array):Boolean { for each (var validator:Validator in validators) { if (!isValid(validator)) return false; } return true; } ]]> </fx:Script> <fx:Declarations> <mx:StringValidator id="nameVal" source="{nameTI}" property="text" maxLength="50" minLength="3"/> <mx:DateValidator id="birtdayVal" source="{birtdayTI}" property="text" inputFormat="DD.MM.YYYY"/> </fx:Declarations> <s:layout> <s:VerticalLayout/> </s:layout> <s:Form> <s:FormItem label="Jméno a příjmení"> <s:TextInput id="nameTI" text="Michal Kolesár"/> </s:FormItem> <s:FormItem label="Datum narození"> <s:TextInput id="birtdayTI" text="26.5.1978"/> </s:FormItem> </s:Form> <s:HGroup> <s:Button label="validuj" click="validate_clickHandler(event)"/> </s:HGroup> </s:Application> ▪ 39 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 7: Validace dat Všiměte si, že validátory jsou definovány v sekci Declarations, protože se nejedná o vizuální elementy. U validátorů je vidět, že jsou bindované prostřednictvím property source na příslušnou instanci TextInput komponenty, kterou budou validovat. Validuje se konkrétní property na dané komponentě, která se zadává ve formátu String do property s názevm property na validátoru. V našem případě se všude validuje property text na TextInputu. Parametry validace jsou nastaveny v maxLength a minLength u StringValidatoru a inputFormat u DateValidatoru. Jednotlivé TextInputy jsou umístěny v kontajneru Form, který usnadňuje zarovnávání labelů a komponent uvnitř formuláře. Ve Flexu jsou ještě další zajímavé validátory, kromě uvedených v příkladu je ještě možné validovat čísla, měnu, kreditní karty, email, telefonní čísla, regulární výrazy. Podrobný popis validátorů včetně ukázky tvorby vlastního validátoru je v příloze Validátory. 11.3. Formátery Pokud jsou data správně nabindovaná a zobrazená ve view, prochází validacemi, může být ještě požadováno, aby podoba zobrazení dat byla pozměněna. Proto je ve Flexu možnost data na výstupu formátovat pomocí formáterů. Podobně jako u validátorů jsou formátery předdefinovány a všechny dědí z třídy mx.formatters.Formatter. Jedná se tedy o MX22 komponenty, které nejsou vizuální, tudíž se umísťují opět do sekce Declarationas. 22 Ve Flexu 4.5 jsou také nově některé formattery Sparkové, ale ty nebudu popisovat. ▪ 40 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 8: Class diagram formáterů Na následujícím příkladu si ukážeme, jak fungují formátery CurrencyFormatter a PhoneFormatter . Všimněte si, že jsou u obou přidány další parametry např. pro definici měny (currencySymbol thousandsSeparator*) a alighSymbol), a formátování validPatternChars). ▪ 41 ▪ separátory telefonního čísla (decimalSeparator*, (formatString a Bakalářská práce Adobe Flex 4 Adobe Flex 4 Formatters.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:local="*"> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.formatters.Formatter; private var errorsA:Array; private var currencyVal:String = "36845,5"; private var phoneVal:String = "777997619"; private var formatujLabel:String = "formátuj"; private var resetLabel:String = "reset"; protected function format_clickHandler(event:MouseEvent):void { if (btn.label == formatujLabel) { errorsA = []; format(currencyFmt, currencyTI); format(phoneFmt, phoneTI); printErrors(); btn.label = resetLabel; } else { resetTI(); btn.label = formatujLabel; } } private function format(formatter:Formatter, textInput:TextInput):void { if (formatter.format(textInput.text) == "") { errorsA.push(textInput.id.toString() + ": " + formatter.error); return; } textInput.text = formatter.format(textInput.text); } private function printErrors():void { if (errorsA == null || this.errorsA.length <= 0) return; var errors:String = ""; for each (var error:String in errorsA) { errors += error + "\n"; } Alert.show(errors); } private function resetTI():void { currencyTI.text = currencyVal; phoneTI.text = phoneVal; } ]]> </fx:Script> ▪ 42 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Formatters.mxml - pokračování <fx:Declarations> <mx:CurrencyFormatter id="currencyFmt" currencySymbol="Kč" alignSymbol="right" decimalSeparatorFrom="," decimalSeparatorTo="," thousandsSeparatorFrom="." thousandsSeparatorTo="."/> <mx:PhoneFormatter id="phoneFmt" formatString="###-###-###" validPatternChars="#-" /> </fx:Declarations> <s:layout> <s:VerticalLayout/> </s:layout> <s:Form> <s:FormItem label="Měsíční příjem"> <s:TextInput id="currencyTI" text="{currencyVal}"/> </s:FormItem> <s:FormItem label="Mobil:"> <s:TextInput id="phoneTI" text="{phoneVal}"/> </s:FormItem> </s:Form> <s:HGroup> <s:Button id="btn" label="{formatujLabel}" click="format_clickHandler(event)"/> </s:HGroup> </s:Application> Obrázek 9: Výchozí hodnoty dat před formátováním Obrázek 10: Zformátované hodnonty U validátorů byly přímé bindingy mezi validátorem a zdrojovou komponentou, která se měla validovat pomocí property source. U formáterů je to trochu jinak, není možné je bindovat přímo na ▪ 43 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 komponenty. Všechny formátery mají metodu format(), kterou dědí z mx.formatters.Formatter. Tuto metodu overridují jednotlivé formátery a definují v ní logiku formátování. Samotné formátování probíhá buď na nějakou konkrétní akci, např. stisknutí tlačítka nebo např. na focusOut23. Funkce format() má parametr objekt, v našem případě se jedná o String reprezentující např. telefonní číslo a vrací zformátovaný text. Ten je nutné přiřadit zpět do property text dané TextInput komponentě nebo přiřadit na proměnnou, kterou má TextInput nabidovanou. Pokud se z nějakého důvodu nepodaří formát provést, metoda vrací prázdný String a v property error je chybová hláška. V reálné aplikaci je nejlepší vytvořit si vlastní komponenty, např. pro měnu, které uvnitř už přímo implementují jak logiku validací, tak formátování. O custom komponentách si ale budeme povídat v samostatné kapitole. Nebudu popisovat tvorbu vlastního formáteru, postup je velice podobný, jako u validátorů, jen s tím rozdílem, že je overridnutá metoda format(). 11.4. Label Function Komponenty ovládacích prvků (controly), které jsme si výše popsali, je možné rozdělit do několika skupin. Jedna z těchto skupin jsou komponenty, které obsahují nějaký seznam záznamů (typicky kolekce), který zobrazují. Jako příklad můžeme uvést DataGrid, List, ComboBox. Všechny tyto komponenty mají na vstupu nějaký seznam objektů, které v dané formě zobrazují. Většinou ve formě textových záznamů. V případě, že chceme pracovat s jednoduchým textovým záznamem, který je obsažen v atributu objektu, pak je situace velice jednoduchá. Komponentě předáme kolekci (ArrayCollection) jako dataProvider a nastavíme konkrétní labelField. A více není potřeba. O něco složitější je situace, kdy zobrazený text neodpovídá obsahu atributu na objektu, ale je např. kombinaci několika atributů. Pak přichází na řadu labelFunction místo labelFieldu. Label Function je funkce, která na vstupu má celý objekt a její implementací jsme schopni vrátit libovolný String s využitím vstupního objektu. 23 focusOut je událost, která se dispatchuje ve chvíli, kdy aktuální komponenta ztratí focus, tj. např. kurzor se přemístí z TextInput komponenty na jiný nebo uživatel klikne na button. ▪ 44 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 LabelFunctionApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <fx:Declarations> <s:ArrayCollection id="ac"> <fx:Object firstname="Michal" surname="Kolesár" /> <fx:Object firstname="Tomáš" surname="Procházka"/> <fx:Object firstname="Zdeněk" surname="Košárek"/> </s:ArrayCollection> </fx:Declarations> <fx:Script> <![CDATA[ private function fullname(value:Object):String { return value.firstname + " " + value.surname; } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:Label text="List1: labelField=firstname"/> <s:List id="list1" dataProvider="{ac}" labelField="firstname"/> <s:Label text="List2: labelFunction=fullname()"/> <s:List id="list2" dataProvider="{ac}" labelFunction="fullname"/> </s:Application> ▪ 45 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 11: ukázka labelField a labelFunction V ukázce je jedna kolekce s daty, která obsahují seznam objektů osob s atributy jméno a příjmení. V prvním seznamu (list1) je použit labelField na křestní jméno. V druhém Listu (list2) se vypisuje celé jméno i s příjmením za použití labelFunction, která oba atributy spojuje do jednoho Stringu odděleného mezerou. 11.5. Item Renderer V předchozí kapitole jsme rendrovali do komponenty List pouze textový obsah pomocí labelField a labelFunction. Co ale v případě, že chceme obsah jedné položky listu obohatit např. o nějaký obrázek nebo text zobrazovat v nějakém formuláři? Pak nám nestačí pouhá práce se Stringy, ale je třeba obsah nějak renderovat. K tomu se ve Flexu používá spark.components.supportClasses.ItemRenderer. ItemRenderer nám umožňuje sestavit si vlastní obraz daného záznamu a využít k tomu dalších komponent. Vstupem do ItemRendereru je tedy opět náš objekt, ale výstupem může být libovolná kombinace komponent zapouzdřená do ItemRendereru. Pro každý záznam v Listu pak existuje jedna instance ItemRendereru. ▪ 46 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ItemRendererApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" layout="{new VerticalLayout()}"> <fx:Script> <![CDATA[ import spark.layouts.VerticalLayout; ]]> </fx:Script> <fx:Declarations> <s:ArrayCollection id="ac"> <fx:Object firstname="Michal" surname="Kolesár" /> <fx:Object firstname="Tomáš" surname="Procházka"/> <fx:Object firstname="Zdeněk" surname="Košárek"/> </s:ArrayCollection> <fx:Component id="inlineRenderer" className="MyInlineRenderer"> <s:ItemRenderer> <s:VGroup> <s:Label text="{data.firstname}"/> <s:Label text="{data.surname}"/> </s:VGroup> </s:ItemRenderer> </fx:Component> </fx:Declarations> <s:Label text="inline ItemRenderer"/> <s:List dataProvider="{ac}" itemRenderer="MyInlineRenderer"/> <s:Label text="ItemRenderer definovaný v samostatné třídě MyRenderer1"/> <s:List id="list2" dataProvider="{ac}" itemRenderer="MyRenderer1"/> </s:Application> MyRenderer1.mxml <?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" autoDrawBackground="true"> <s:VGroup> <s:Label text="{data.firstname}"/> <s:Label text="{data.surname}"/> </s:VGroup> </s:ItemRenderer> ▪ 47 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 12: Item Renderer V příkladu jsou uvedeny dva různé způsoby zápisu práce s renderery. První je tzv. „inline“, který umožňuje uvnitř nějaké MXML aplikace nebo komponenty definovat svou vlastní komponentu v sekci Declarations pomocí tagu <fx:Component></fx:Component>. Druhý způsob je definice rendereru v samostatné třídě a souboru s názvem MyRenderer1.mxml. Výsledky jsou zcela totožné. Je ale vhodnější definovat renderery v samostatných souborech, zpřehledňuje se tím čitelnost kódu. Renderery dělají jednoduchou úlohu, a to zobrazení dvou labelů řazených pod sebou, v jednom je křestní jméno a v druhém příjmení. Data jsou do rendereru předávána prostřednictvím property data, která je definovaná na každé komponentě, jež implementuje interface mx.core.IDataRenderer. ItemRenderer dědí z spark.components.DataRenderer, která implmentuje zmiňovaný interface. ▪ 48 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 13: ItemRenderer class diagram Všiměte si, že v příkladu jsem použil jiný způsob definice layoutu. Doposud byl layout definován v MXML samostatným element tagem <s:layout></s:layout>. Nyní jsem property layout nastavil přes atribut na element tagu Application, a to vytvořením nové instance trřídy VerticalLayout. Zápis je naprosto totožný. 11.6. Filter Function Představme si situaci, kdy máme k dispozici nějaký seznam hodnot zobrazený např. v komponentě DataGrid a podle daného parametru chceme zobrazit pouze podmnožinu prvků. Konkrétněji si představme, že máme seznam osob, každá osoba má svůj věk, a my je chceme filtrovat podle věku, který nastavíme třeba komponentou Slider. ▪ 49 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 FilterFunctionApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protected function ageSliderChange(event:Event):void { // refresh kolekce provede filter function na vsechny // polozky people.refresh(); } protected function creationCompleteHandler(event:FlexEvent):void { people.filterFunction = filter; } private function filter(item:Object):Boolean { if (ageMaxSlider.value >= item.age && ageMinSlider.value <= item.age) return true; else return false; } ]]> </fx:Script> <fx:Declarations> <s:ArrayCollection id="people"> <fx:Object name="Franta" age="14"/> <fx:Object name="Tonda" age="18"/> <fx:Object name="Lojza" age="22"/> <fx:Object name="Katka" age="10"/> <fx:Object name="Pepička" age="28"/> <fx:Object name="Martina" age="25"/> <fx:Object name="Tomáš" age="30"/> <fx:Object name="Honza" age="24"/> </s:ArrayCollection> </fx:Declarations> <s:layout> <s:VerticalLayout/> </s:layout> <s:Form> <s:FormItem label="max věk"> <s:HSlider id="ageMaxSlider" change="ageSliderChange(event)" minimum="10" maximum="30" value="30"/> </s:FormItem> <s:FormItem label="min věk"> <s:HSlider id="ageMinSlider" change="ageSliderChange(event)" minimum="10" maximum="30" value="10"/> </s:FormItem> </s:Form> <s:DataGrid dataProvider="{people}"/> </s:Application> ▪ 50 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 14: Filter function Ihned po vytvoření komponenty se dispatchuje creationComplete, na který nastavíme na kolekci people filterFunction s názvem filter. Samotná akce filtrování nastává spuštěním refresh() na kolekci. Ta se pouští vždy po změně na HSlideru. A protože je kolekce bindovaná na DataGrid, položky se dynamicky mění podle aktuálních hodnot na sliderech. 11.7. Lokalizace a multijazyčnost U moderních programovacích jazyků, které mají uspět a rozšířit se do celého světa je dnes multijazyková podpora naprostou samozřejmostí. Nejedná se však pouze o podporu více jazyků a fontů. Jedná se o celou řadu dalších lokalizačních vlastností a možnost externí konfigurace těchto vlastností. Namátkou uvedu například různé tvary desetinných čárek (někde se používá tečka, jinde čárka), měrné jednotky, týden začínající nedělí nebo pondělím, atd. Flex je plně lokalizovaný, nabízí nástroje, kterými je možné lokalizace vytvářet a ručně upravovat. Lokalizace je možné přepínat v runtime, veškeré texty je možné externalizovat do resource bundlů a tím lépe spravovat. Základní informace o locales jsme si ukázali už v kapitole Flash Builder, tudíž se zde zaměřím hlavně na použití v kódu. Pro správnou funkčnost bude třeba vytvořit resource bundly, které je třeba umístit do adresářů locales/en_US a locales/cs_CZ. Dále je potřeba přidat parametr -source- path+=locales/{locale} pro překladač, aby o těchto adresářích s resource bundly věděl a ▪ 51 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 také přidat překladovému parametru -locale všechny potřebné lokalizace, se kterými má aplikace pracovat -locale=cs_CZ,en_US. locales/cs_CZ/Bundle.properties firstname=Jméno surname=Příjmení age=Věk locales/en_US/Bundle.properties firstname=Firstname surname=Surname age=Age Obrázek 15: Locales Obrázek 16: Nastavení parametrů překladače pro locales ve Flash Builderu ▪ 52 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ResourceBundleApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" layout="{new HorizontalLayout()}"> <fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.collections.ArrayList; import spark.layouts.HorizontalLayout; private const BUNDLE:String = "BundleName"; [Bindable] private var locales:ArrayList = new ArrayList([ "cs_CZ","en_US" ]); ]]> </fx:Script> <fx:Metadata> [ResourceBundle("BundleName")] </fx:Metadata> <s:VGroup> <s:ComboBox id="bundleCB" dataProvider="{locales}" change="{resourceManager.localeChain = [bundleCB.selectedItem]}"/> <s:Form> <s:FormItem label="{resourceManager.getString(BUNDLE, 'firstname')}"> <s:TextInput/> </s:FormItem> <s:FormItem label="{resourceManager.getString(BUNDLE, 'surname')}"> <s:TextInput/> </s:FormItem> <s:FormItem label="{resourceManager.getString(BUNDLE, 'age')}"> <s:NumericStepper/> </s:FormItem> </s:Form> </s:VGroup> <mx:DateChooser/> </s:Application> ▪ 53 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 17: Ukázka lokalizace Všiměte si, že při přepnutí locales v runtime se změní jak resource bundly, tak celá komponenta DateChooseru. Ta si bere nastavení locales v SDK, konkrétně z framework_rb.swc, kde jsou upraveny properties soubory controls.properties, formatters.properties, SharedResources.properties pro českou lokalizaci. 11.8. Moduly Další pojem, se kterým se ve Flexu setkáte je tzv. modul. Protože považuji oblast modulů za důležitou, pokusím se ji probrat trochu podrobněji. Modul je již binární soubor SWF, který je možné připojit k aplikaci a využívat jeho funkčnosti. Moduly se používají hlavně při větších projektech, kde není vhodné, aby aplikace běžela v jednom samostatném SWF souboru, ale aby byla rozdělena na více samostatných částí a tyto se nahrávaly dle potřeby v runtime. To šetří jak paměť na straně klienta, tak dává možnost stahovat ze serveru moduly až v případě potřeby, čímž se při startu aplikace ušetří čas nahrávání jednoho velkého SWF. Pomocí manažerů modulů je možné ručně zajišťovat jak nahrávání, tak odehrávání jednotlivých modulů. Moduly nemohou být spouštěny samostatně, ale více aplikací může naopak jeden modul sdílet. Typicky je hlavní aplikace pouze tzv. shell, který se stará o náhrávání a odehrávání modulů dle potřeby v runtime. Výhody modulární aplikace shrnu na • Rychlejší nahrávání aplikace při startu, hlavní SWF soubor je malý • Méně paměti pro aplikaci, jsou využívány jen moduly, které jsou potřeba a ostatní jsou odehrány z paměti • Modularizace aplikace, která rozděluje aplikaci do samostatných funkčních celků ▪ 54 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Existují dva způsoby pro práci s moduly ve Flexu, a to buď prostřednictvím ModuleManageru nebo ModuleLoaderu. ModuleManager poskytuje low-level API pro práci s moduly. Stará se o nahrávání modulů, které se chovají jako seznam singletonů a jsou indexovány podle URL modulu. Při nahrávání modulu se spouští několik událostí, kterými klient sleduje stav modulu. READY událost oznamuje, že modul byl nahrán a je připraven k použití. ModuleLoader poskytuje high-level API pro práci s moduly. Je to třída, která využívá ModuleManageru, a byla vytvořena pro jednodušší práci s moduly. Nenabízí ale takovou kontrolu nad moduly jako ModuleManager. Výhoda ModuleLoaderu je v tom, že implementuje rozhraní INavigatorContent a tím je možné jej použít přímo v MX navigátorech, jako např. TabNavigator. ModuleLoaderApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <mx:TabNavigator width="200" height="200"> <s:ModuleLoader label="Modul 1" url="module/Module1.swf"/> <s:ModuleLoader label="Modul 2" url="module/Module2.swf"/> </mx:TabNavigator> </s:Application> module/Module1.mxml <?xml version="1.0" encoding="utf-8"?> <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"> <s:Label text="Toto je modul 1"/> </s:Module> module/Module2.mxml <?xml version="1.0" encoding="utf-8"?> <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"> <s:Label text="Toto je modul 2"/> </s:Module> ▪ 55 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Příklad se skládá z hlavní aplikace a dvou modulů. Moduly jsou nahrávány ModuleLoaderem uvnitř TabNavigatoru do aplikace až ve chvíli, kdy jsou použity, tj. při přepnutí tabu. Toto chování je možné změnit vlastností creationPolicy na TabNavigatoru. Moduly je možné také manuálně odehrát nebo nahrát spouštěním metod unloadModule() a loadModule() na ModuleLoaderu. Práce s moduly v AS3 je velice podobná, pro vytvoření modulu je potřeba extendovat třídu spark.modules.Module. Je tu ale ještě možnost úspory velikosti modulu tím, že pokud nebudeme chtít využívat žádné funkce z frameworku, můžeme extedovat třídu mx.modules.ModuleBase. SimpleModule.as package { import mx.modules.ModuleBase; public class SimpleModule extends ModuleBase { public function SimpleModule() { trace("SimpleModul byl vytvořen"); } public function secti(numberA:Number, numberB:Number) { return numberA + numberB; } } } V prvním příkladu jsme si ukázali použití ModuleLoaderu, teď si ukážeme jak použít ModuleManager. Jeho použití je o něco složitější, nabízí ale větší kontrolu nad práci s moduly. Nejprve manageru nastavíme přes metodu getModule() příslušný SWF soubor. Tato metoda vrací rozhraní IModuleInfo, jehož metodou load je možné modul nahrát. Jako čtvrtý parametr je možné předat moduleFactory, které předá modulu informace o embednutých fontech a style manageru. Pro vytvoření instance modulu je možné zavolat metodu create na factory property IModuleInfo. Takto vytvořenou instanci je pak možné přidat jako DisplayObject do display listu. ▪ 56 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ModuleManagerApp.mxml <?xml version="1.0"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="initApp()" layout="{new VerticalLayout()}"> <fx:Script> <![CDATA[ import mx.core.IVisualElement; import mx.events.ModuleEvent; import mx.modules.IModuleInfo; import mx.modules.ModuleManager; import spark.layouts.VerticalLayout; public var info:IModuleInfo; private function initApp():void { info = ModuleManager.getModule("ColumnChartModule.swf"); info.addEventListener(ModuleEvent.READY, modEventHandler); info.load(null, null, null, moduleFactory); } private function modEventHandler(e:ModuleEvent):void { vb1.addChild(info.factory.create() as DisplayObject); vg1.addElement(info.factory.create() as IVisualElement); } ]]> </fx:Script> <!-- MX container --> <mx:VBox id="vb1"> <s:Label text="Module loaded in MX VBox container:"/> </mx:VBox> <!-- Spark container --> <s:VGroup id="vg1"> <s:Label text="Module loaded in Spark VGroup container:"/> </s:VGroup> </s:Application> zdroj: http://help.adobe.com/ IModuleInfo má kromě parametru moduleFactory ještě parametry pro definování aplikační domény (application domain) a bezpečnostní domény (security domain). Pokud, jako v našem příkladu, nejsou parametry specifikovány, pak je modul nahrán do poděděné domény (child domain). Pro vytvoření samotného modulu, tedy SWF souboru je nutné modul přeložit. Překlad modulu je stejný, jako by se pracovalo s aplikací. Není třeba dalších parametrů. Pouze pokud chceme ▪ 57 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 provést optimalizaci velikosti modulu, je možné tak dosáhnout definováním, pro kterou aplikaci je modul určen. Pokud by měl být modul využíván více aplikacemi, optimalizace v tomto směru není možná. Ve Flash Builderu 4.5 je možné přímo při vytváření nového modulu specifikovat, kterou aplikací bude modul využíván a tím optimalizován. Obrázek 18: Ukázka voleb pro optimalizaci modulu ve Flash Builderu Z příkazové řádky je třeba nejprve vytvořit link report a poté s ním přeložit modul mxmlc -link-report=report.xml ModuleLoaderApp.mxml mxmlc -load-externs=report.xml Module1.mxml mxmlc -load-externs=report.xml Module2.mxml Ještě na závěr bych rád řekl, že moduly je možné nahrávat i z modulů, takže je možné z aplikace nahrát modul, z modulu další modul a z něj opět modul, atd. Dále je potřeba si dávat pozor, aby nebyla definována instance modulu v lokálním scope, tudíž např. uvnitř funkce, ale na globální úrovni. Po spuštění funkce jsou lokální proměnné uvolňovány z paměti, protože už na ně neexistují reference. Mohlo by se stát, že by objekt modulu mohl být ▪ 58 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 uvolněn z paměti garbage collectorem (GC) a případné handler funkce by nebyly nikdy spuštěny, protože k uvolnění by došlo ještě před jejich spuštěním. Pokud se totiž uvolní všechny reference na modul, je automaticky uvolněn GC z paměti. Takže pokud chceme odehrát modul z paměti, stačí nastavit IModuleInfo na null. Pokud nahráváme aplikaci a moduly z různých serverů, je potřeba nastavit mezi bezpečnostními doménami důvěryhodnost. 1. V aplikaci je nutné volat funkci allowDomain() a jako parametr jí nastavit doménu, ze které bude modul stahován 2. Na straně serveru, kde jsou umístěny moduly, je třeba umístit crossdomain.xml soubor, ve kterém bude informace o serveru, na kterém je umístěna aplikace 3. Nahrát crossdomain.xml soubor ze serveru kde jsou umístěny moduly do aplikace, a to ve fázi preinitialize 4. V modulu volat allowDomain() pro doménu aplikace, aby měl povoleno s aplikací komunikovat Nastavení v aplikaci, je třeba spustit na preinicialize public function setup():void { Security.allowDomain("remoteservername"); Security.loadPolicyFile("http://remoteservername/crossdomain.xml"); var request:URLRequest = new URLRequest("http://remoteservername/crossdomain.xml"); var loader:URLLoader = new URLLoader(); loader.load(request); } Nastavení v modulu public function initMod():void { Security.allowDomain("loaderservername"); } <!-- crossdomain.xml na vzdáleném serveru s modulem --> <cross-domain-policy> <site-control permitted-cross-domain-policies="all"/> <allow-access-from domain="loaderservername" to-ports="*"/> </cross-domain-policy> Moduly jsou standardně nahrávány buď manuálně nebo, v případě ModuleLoaderu, mohou být nahrávány až když jsou v aplikaci aktivovány resp. využívány. ▪ 59 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Pokud bychom toto chování chtěli změnit, museli bychom nastavit vlastnost creationPolicy24 na all, na kontajneru, ve kterém jsou ModuleLoadery umístěny. Tím se moduly z daného kontajneru nahrajou automatomaticky ještě před tím, než jsou v aplikaci využity (modules preloading). Preloading je možné zajistit i manuálním nahráním modulů v inicializační fázi aplikace, např. na creationComplete. Modul je ze serveru fyzicky stažen pouze jednou a následně uložen do cache browseru. Jakmile je pak manuálně odehrán a opětovně nahrán, nenahrává se ze vzdáleného serveru, ale z cache browseru. Tabulka 6: Události modulu Událost Popis error Nastane, když v modulu nastane chyba loading Nastane, když ModuleLoadere začne nahrávat URL progress Nastane v průběhu nahrávání modulu ready Nastane, když je dokončeno nahrávání modulu setup Nastane, když jsou dostupné informace o modulu, ale modul ještě není připraven unload Nastane, když je modul odehrán urlChanged Nastane, když ModulLoader dostane nové URL Jak komunikovat s moduly Nyní jsme se seznámili, jak moduly nahrávat a odehrávat. To nám ale pro práci s moduly nebude stačit, protože moduly a aplikace by spolu nijak nekomunikovaly a tudíž by byly zcela oddělené. Komunikace mezi moduly a aplikací může záviset na tom, jakým směrem je komunikováno, tj. aplikace → modul, modul → aplikace, modul → modul. Použití rozhraní První způsob, jak komunikovat mezi aplikací a modulem, je vytvoření rozhraní metod a vlastností, které moduly a aplikace mohou používat, což zajišťuje nepřímou vazbu a zajišťuje kontrolu nad interakcí. Jediné co je potřeba je sdílet mezi modulem a aplikací dané rozhraní. V následujícím příkladu si ukážeme, jak může aplikace komunikovat s modulem prostřednictvím rozhraní a two-way bindingu na obou stranách (tj. jak v aplikaci, tak v modulu) propagovat automaticky změny. 24 vlastnost creationPolicy je v případě Spark komponent na SkinnableContaineru a má hodnoty „auto“, „all“ a „none“. Výchozí hodnota je „auto“, která vytváří komponenty až ve chvíli, kdy jsou potřeba. Oproti tomu „none“ nevytváří vůbec a je třeba manuálně vyvolat „createDefferredContent()“ ▪ 60 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyModuleApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="init()"> <fx:Script> <![CDATA[ import mx.events.ModuleEvent; import spark.modules.ModuleLoader; [Bindable] private var myModule:IMyModule; private var ml:ModuleLoader; private function init():void { ml = new ModuleLoader(); ml.url = "MyModule.swf"; ml.addEventListener(ModuleEvent.READY, onModuleLoaded); ml.loadModule(); addElement(ml); } private function onModuleLoaded(e:ModuleEvent):void { myModule = ml.child as IMyModule; } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:HGroup> <s:Label text="App TextInput"/> <s:TextInput text="@{myModule.moduleName}"/> </s:HGroup> <s:Button label="Unload" click="{ml.unloadModule()}"/> <s:Button label="Load" click="{ml.loadModule()}"/> </s:Application> ▪ 61 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyModule.mxml <?xml version="1.0" encoding="utf-8"?> <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" implements="IMyModule"> <fx:Script> <![CDATA[ private var _moduleName:String = "myModule"; public function set moduleName(value:String):void { _moduleName = value; } [Bindable] public function get moduleName():String { return _moduleName; } ]]> </fx:Script> <s:layout> <s:HorizontalLayout/> </s:layout> <s:Label text="Module TextInput"/> <s:TextInput text="@{moduleName}"/> </s:Module> IMyModule.as package { [Bindable] public interface IMyModule { function set moduleName(value:String):void; function get moduleName():String; } } Obrázek 19: Ukázka ModuleLoaderu Zde stojí za povšimnutí, že MyModule.mxml implementuje interface IMyModule, tj. settery a gettery moduleName. Bindingy zajišťují propagaci změn z TextInputu aplikace do TextInputu modulu a naopak. Výhodou tohoto řešení je, že není třeba tvrdě svazovat aplikaci s modulem, vše je zajištěno prostřednictvím rozhraní. ▪ 62 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Předávání dat pomocí query stringu Existuje také jiný způsob, jak předávat modulu parametry, a to přímo přes URL, předáním parametrům hodnoty, např. url=“myModule.swf?par1=value1&par2=value2”. Tato varianta umožňuje předávat pouze jednoduché hodnoty, nikoliv komplexní objekty. V modulu samotném je pak URL dostupné přes vlastnost loaderInfo. Je dostupné pouze jako string celého URL a jednotlivé parametry je nutné rozparsovat. MyModule2App.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="creationComplete()"> <fx:Script> <![CDATA[ import mx.events.ModuleEvent; import spark.modules.ModuleLoader; private const PARAM:String = "MyModule2.swf? param1=value1¶m2=value2"; private function loadModule():void { // zmena URL zpusobi nahrani modulu ml.url = ""; ml.url = ti.text; } private function creationComplete():void { ml.addEventListener(ModuleEvent.ERROR, onEvent); ml.addEventListener(ModuleEvent.PROGRESS, onEvent); ml.addEventListener(ModuleEvent.READY, onEvent); ml.addEventListener(ModuleEvent.SETUP, onEvent); ml.addEventListener(ModuleEvent.UNLOAD, onEvent); ml.addEventListener("urlChanged", onEvent); ml.addEventListener("loading", onEvent); } private function onEvent(e:Event):void { // trace("type: " + e.type); } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:Form> <s:FormItem label="modul a parametry"> <s:TextInput id="ti" text="{PARAM}" width="300"/> </s:FormItem> </s:Form> <s:Button label="init URL" click="{loadModule()}"/> <s:ModuleLoader id="ml"/> </s:Application> ▪ 63 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyModule2.mxml <?xml version="1.0" encoding="utf-8"?> <s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="creationComplete()"> <fx:Script> <![CDATA[ import mx.utils.StringUtil; [Bindable] private var param1:String; private function creationComplete():void { var parametersString:String = loaderInfo.url.split("?")[1]; if (parametersString == null || parametersString == "") return; var parameters:Array = parametersString.split("&"); for each (var item:String in parameters) { var parValArr:Array = item.split("="); var outString:String = "klic: " + parValArr[0] + ", hodnota: " + parValArr[1]; trace(outString); ta.text += outString + "\n"; } } ]]> </fx:Script> <s:layout> <s:HorizontalLayout/> </s:layout> <s:TextArea id="ta" width="200"/> </s:Module> Obrázek 20: Ukázka query string Další způsoby komunikace mezi moduly a aplikací jsou již přímou vazbou, a proto se příliš nedoporučují. Nebudu zde uvádět příklady na toto téma, pouze stručně nastíním problematiku. Z modulu je možné se odkazovat na aplikaci přímo přes parentApplication. Z aplikace na modul pak přes ml.child, kde ml je příslušný ModuleLoader. A z modulu na jiný nahraný modul v aplikaci přes parentApplication.ml.child, kde ml je daný ModuleLoader. ▪ 64 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 12. 12.1. KOMPONENTY Event-Driven architektura Je třeba si říct, že ve Flexu komunikují jednotlivé komponenty pomocí událostí a bindingu. Všechny vizuální komponenty dědí od EventDispatcheru, proto je možné přímo z nich události iniciovat a stejně tak na ně poslouchat. Abychom porozuměli lépe této architektuře, ukážeme si, jak vypadá propagace událostí. Každá událost prochází 3 fázemi – capturing, targeting a bubbling. První fáze capturing vyvolává události na display listu od Application až po nadřazený kontajner komponenty, ze které byla událost vyvolána. Na tuto událost je možné poslouchat 25 na libovolném kontajneru pomocí addEventListener. V praxi se v této fázi poslouchá jen zřídka. Druhá fáze targeting vyvolává událost na konkrétní komponentě, ze které byla událost vyvolána. Třetí fáze bubbling jde zpět po display listu z nadřazeného kontajneru až po aplikaci a vyvolává na všech kontajnerech stejnou událost. Této vlastnosti se ve Flexu využívá nejčastěji, a to z důvodu odchycení události, která nastala uvnitř komponenty a „bublá 26“ z komponenty ven. Tuto událost je pak možné zachytit. Bubbling je možné v libovolném kontajneru zastavit pomocí metod stopPropagation() nebo stopImmediatePropagation() na události. Rozdíl mezi nimi je pouze v tom, že první pozastaví bubbling až ve chvíli, kdy dojde spuštění všech handlerů na daném kontajneru. V druhém případě dojde k propagaci okamžitě po zavolání metody. Obrázek 21: Propagační fáze událostí 25 Pro zachycení capturing fáze listenerem je třeba mít nastaven useCapture na true 26 Aby bubbling fungoval, je třeba na dané události mít nastaveno bubble na true ▪ 65 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Na obrázku27 je představen model propagace událostí. Jednoduchá aplikace, která se skládá z Application, VBox a Buttton. Po vyvolání události click na Button dochází nejprve k Capturing fázi ve směru od Application k Button, pak targeting fáze je na Button a následuje bubbling fáze zpět k Application. 12.2. MXML komponenta MXML komponenta je třída, jejímž hlavním úkolem je zajistit přepoužitelnost sama sebe. Měla by proto definovat jasné rozhraní a sadu událostí, které spouští. V příkladu si ukážeme MXML komponentu, která obsahuje pouze panel a tlačítko a po stisku tlačítka vyvolává událost. Nápis tlačítka je možné měnit parametrem komponenty a na danou událost je možné poslouchat a spustit handler. MyPanel.mxml <?xml version="1.0" encoding="utf-8"?> <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" > <fx:Metadata> [Event(name="buttonClicked", type="flash.events.Event")] </fx:Metadata> <fx:Script> <![CDATA[ [Bindable] public var buttonLabel:String; protected function myButton_clickHandler(event:MouseEvent):void { dispatchEvent(new Event("buttonClicked")); } ]]> </fx:Script> <s:Button id="myButton" label="{buttonLabel}" click="myButton_clickHandler(event)"/> </s:Panel> Komponenta, má vnější tagy s názvem třídy, ze které dědí. Podobně jako aplikace dědí z třídy Application, naše komponenta MyPanel dědí z třídy Panel. V sekci Metadata je definován název události, který umí číst Flash Builder a nabídnout při autocompletion. V našem případě definujeme buttonClicked a v následujícím příkladu MyPanelApp.mxml, kde je komponenta 27 http://learn.adobe.com/wiki/display/Flex/Event+Propagation ▪ 66 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyPanel použita je patrné, že handlery jsou navázány právě na buttonClicked, který je díky metadatům pro MXML již znám. V AS3 je public property buttonLabel, přes který je bindován label tlačítka. Pro binding mezi MXML a AS3 property je třeba mít pouze u property anotaci [Bindable] a složenými závorkami pak definujeme kam bindovat. Více o bindingu je v samostatné kapitole Data Binding. MyPanelApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:ns="bp.ch8_5.*"> <fx:Script> <![CDATA[ import mx.controls.Alert; protected function panel1_buttonClickedHandler(event:Event):void{ Alert.show("You clicked on button in component panel1") } protected function panel2_buttonClickedHandler(event:Event):void{ Alert.show("You clicked on button in component panel2") } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <ns:MyPanel id="panel1" buttonLabel="Button 1" title="Panel1" buttonClicked="panel1_buttonClickedHandler(event)"/> <ns:MyPanel id="panel2" buttonLabel="Button 2" title="Panel2" buttonClicked="panel2_buttonClickedHandler(event)"/> </s:Application> Obrázek 22: Ukázka MXML komponenta ▪ 67 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 V příkladu je dvakrát použita komponenta MyPanel. V sekci Script jsou definovány jednotlivé handlery a v definici view jsou pak dva panely, každý má definován vlastní popisek tlačítka a handler stisku tlačítka. 12.3. ActionScript3.0 komponenta V předchozím příkladu jsme si ukázali jednoduchou komponentu napsanou v MXML, nyní si ukážeme, jak bude vypadat zcela stejná komponenta napsaná v AS3. MyPanel.as package bp.ch8_5 { import flash.events.Event; import flash.events.MouseEvent; import mx.binding.utils.BindingUtils; import spark.components.Button; import spark.components.Panel; [Event(name="buttonClicked", type="flash.events.Event")] public class MyPanel extends Panel { [Bindable] public var buttonLabel:String; public var button:Button; public function MyPanel() { createButton(); } protected function clickHandler(event:MouseEvent):void { dispatchEvent(new Event("buttonClicked")); } private function createButton():void { button = new Button(); button.addEventListener(MouseEvent.CLICK, clickHandler); addElement(button); BindingUtils.bindSetter(updateLabel, this, "buttonLabel"); } public function updateLabel(value:String):void { button.label = value; } } } Komponenta dědí opět z Panel a obsahuje vlastnost buttonLabel s anotací Bindable. V konstruktoru se vytváří uvnitř panelu tlačítko (metoda createButton()). addElement přidává tlačítko do panelu a pomocí BindingUtils sledujeme vlastnost buttonLabel. Pokud dochází ▪ 68 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ke změně, spouští se metoda updateLabel(). Na tlačítku je také listener na CLICK, který způsobí vyvolání události buttonClicked. 12.4. Stavy a Přechody (States and Transitions) Představme si situaci, že naší komponentu budeme chtít mít ve dvou různých stavech. V prvním stavu bude vypadat zcela stejně, jako v předchozím příkladu. Ale po kliknutí budeme chtít, aby se uvnitř komponenty objevil status, že už bylo tlačítko stisknuto a možnost vyvolaní resetu komponenty do původního stavu novým tlačítkem. Pro zjednodušení práce s různými stavy komponent je ve Flexu nástroj, který práci zjednodušuje. Dané komponentě definuje, jaké stavy má, a pak u každého elementu komponenty je možné definovat, v jakém stavu je obsažen. V našem přípdě by tedy byly definovány dva stavy zakladni a kliknuto. V základním bude naše původní tlačítko a ve stavu kliknuto bude navíc Label a nový reset Button. Přechodům mezi jednotlivými stavy se říká transitions. Každý přechod definuje, z jakého stavu se přechází do jakého. Na každý takto definovaný přechod je možné aplikovat nějaký efekt nebo více efektů řazených do série či paralelně. V našem příkladu si ukážeme jednoduché přechody, kdy při přechodu stavu se nový obsah komponenty objeví pozvolna změnou alfy. V níže uvedeném příkladu jsou v sekci Declarations definovány efekty Fade. Sekce states definují dva stavy zakladni a kliknuto a sekce transitions definující přechody z obou směrů. V samotném view pak je navíc Button pro reset a Label. Ty jsou pomocí includeIn vlastnosti nastaveny pouze na stav kliknuto. Samotné přepínání stavů nastává změnou vlastnosti currentState. Po spuštění aplikace se komponenty nachází ve stavu zakladni28. Kliknutím na tlačítko nastane přechod ze stavu zakladni na kliknuto, a pozvolna se pomocí změny alfy zobrazí Button reset a Label. Stejně tak při stisku tlačítka reset pozvolně změnou alfy Button reset a Label zmizí, protože dojde k přechodu ze stavu kliknuto do stavu zakladni. 28 Výchozí stav je vždy ten, který je uveden jako první v pořadí v definici, tj. v sekci „states“ ▪ 69 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyPanel.mxml <?xml version="1.0" encoding="utf-8"?> <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" > <fx:Declarations> <s:Fade id="faderHide" alphaFrom="1" alphaTo="0" targets="{[resetButton, clickLabel]}"/> <s:Fade id="faderShow" alphaFrom="0" alphaTo="1" targets="{[resetButton, clickLabel]}"/> </fx:Declarations> <fx:Metadata> [Event(name="buttonClicked", type="flash.events.Event")] </fx:Metadata> <s:states> <s:State name="zakladni"/> <s:State name="kliknuto"/> </s:states> <s:transitions> <s:Transition fromState="kliknuto" toState="zakladni" effect="{faderHide}" /> <s:Transition fromState="zakladni" toState="kliknuto" effect="{faderShow}" /> </s:transitions> <fx:Script> <![CDATA[ [Bindable] public var buttonLabel:String; protected function myButton_clickHandler(event:MouseEvent):void{ dispatchEvent(new Event("buttonClicked")); currentState = "kliknuto"; } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:Button id="myButton" label="{buttonLabel}" click="myButton_clickHandler(event)"/> <s:Label id="clickLabel" text="Jsem ve stavu kliknuto" includeIn="kliknuto"/> <s:Button id="resetButton" label="Reset Button" includeIn="kliknuto" click="{currentState = 'zakladni'}"/> </s:Panel> ▪ 70 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 13. CSS, SKINY Ve Flexu je možné měnit vzhled aplikace dvěma různými způsoby, a to kombinací kaskádových stylů známých z HTML nebo změnou skinů. V této kapitole si popíšeme, jak je možné oba způsoby aplikovat. 13.1. Kaskádové styly Jistě znáte kaskádové styly (CSS), které se používají ve spojitosti s HTML stránkami. CSS slouží k oddělení stylů, tj. vzhledu, stránky od její struktury. Jedná se o W3C standard, který je obecně využívaný a velice rozšířený. Flex podporuje tento způsob pro stylovaní. Styly je možné definovat buď přímo v aplikaci a nebo je mít v externím souboru, který lze aplikací používat. Styly se umísťují mezi tagy <fx:Style></fx:Style>. StyleApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx"; s|Button { color: #FF0000; } .myLabelStyle { fontSize: 16; color: #8844FF; } #mxButton1, #label2 { color: #00FF00; } </fx:Style> <!-- pro vlozeni externich stylu ze souboru styly.css --> <!-- <fx:Style source="styly.css"/> --> <s:layout> <s:VerticalLayout/> </s:layout> <s:Button id="button1" label="Button1"/> <s:Button id="button2" label="Button2"/> <mx:Button id="mxButton1" label="mxButton1"/> <mx:Button id="mxButton2" label="mxButton2"/> <s:Label id="label1" text="Label1" styleName="myLabelStyle" /> <s:Label id="label2" text="Label2"/> </s:Application> ▪ 71 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 V příkladu je ukázka použití stylů definovaných přímo v aplikaci mezi zmíněnými tagy <fx:Style></fx:Style>. Níže v komentáři je popsán způsob, jak vložit styly z externího souboru. Způsob použití je ekvivalentní. Na prvních řádcích je definice namespace pro Spark a MX komponenty. Ty jsou pak použity jako součást selektoru, pokud se odkazujeme na konkrétní třídu, v našem případě globální nastavení stylů pro Spark Button je namespace oddělen od třídy pomocí znaku pipeline „|”. Pokud se chceme odkázat pomocí názvu stylu, je možné definovat vlastní s tečkou na začátku a u každé komponenty je pak možné se na tento styl odkázat pomocí vlastnosti styleName. Další možností je odkazovat se přímo na id komponenty a to pomocí znaku #. Pro zápis více selektorů je možné selektory oddělovat čárkou. Selektory je možné různě kombinovat podle hierarchie display listu. Např. pokud se chceme odkázat pouze na tlačítko, které je vnořené v HGroup a ta v VGroup, použijeme následující selektor. Style2App.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx"; s|VGroup s|HGroup s|Button { color: #FF00FF; } </fx:Style> <s:layout> <s:VerticalLayout/> </s:layout> <s:Button id="button1" label="Button1"/> <s:VGroup> <s:HGroup> <s:Button id="button2" label="Button2"/> </s:HGroup> </s:VGroup> </s:Application> ▪ 72 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Na závěr ještě zmíním, že styly je možné přiřazovat i k jednotlivým stavům. Například pokud bychom chtěli nastavovat styly jednotlivým stavům komponenty Button (up, over, down), použili bychom pro definici stavu separátor „:“ StyleState.mxml <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; @namespace mx "library://ns.adobe.com/flex/mx"; s|Button:up { color: #00FFFF; } s|Button:over { color: #FF0000; } s|Button:down { color: #FFFF00; fontWeight: "bold"; } </fx:Style> 13.2. Spark skiny Co ale Flexové komponenty činí zajímavějším jsou Spark skiny 29. Jedná se o externalizaci vzhledu od logiky komponenty. Obecně se dá říci, že logika komponenty by si měla udržovat její datový stav, držet si informace ve svém vnitřním modelu, definovat události, ale zobrazení komponenty může vypadat velice různě. Může mít jiný layout, může mít jiné barevné provedení, ale může také obsahovat chování v podobě přechodů (transitions) mezi stavy dané komponenty. Proto jsou Spark komponenty, které podporují skinování, rozděleny do dvou fyzických souborů, přičemž jeden reprezentuje logickou strukturu komponenty a druhý její konkrétní vzhled a stavy. Každá vizuální Spark komponenta, kterou je možné skinovat, dědí z spark.components.supportClasses.SkinnableComponent nebo některé podtřídy. Každý Spark skin dědí z spark.components.supportClasses.Skin nebo opět z podtřídy. 29 Ve Flexu jsou také skiny pro komponenty MX, ty jsou ale značně omezené a proto je zde nebudu nijak popisovat. ▪ 73 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Každý Spark skin by se měl skládat z několika částí. Jednotlivé části jsou k nahlédnutí v ukázce v následující kapitole. • root tag Skin nebo některou podtřídu • Metadata v podobě Host componenty, na kterou bude skin aplikován • deklarace stavů • definice skin parts, což jsou komponenty definované ve skinu, které většinou slouží k posílání dat z host komponenty směrem do skinu • grafické elementy a definující vzhled komponenty Pokud máme vytvořen skin, který obsahuje všechny náležitosti, je třeba jej také přiřadit dané komponentě. To je možné několika způsoby. Buď přímo pomocí vlastnosti skinClass nebo pomocí kaskádových stylů. Konkrétní příklad je uveden v následující kapitole. 13.3. Vytvoření vlastního skinu V ukázkovém příkladu si vytvoříme vlastní skin na komponentu Button. Standardně Button používá skin spark.skins.spark.ButtonSkin. Ten je možné si vzít také jako inspiraci k vytvoření skinu vlastního. Host komponentou bude tedy spark.components.Button třída, ve skinu budou definovány stavy up, over, down, disabled, které Button podporuje30. Skin tlačítka obsahuje tzv. SkinPart labelDisplay31. Rect je FXG komponenta definující obdélník s daným ohraničením nebo výplní. V našem příkladu bude použit na vykreslení ohraničení tlačítka kolem textu Label a po kliknutí se vyplní obsah tlačítka. 30 Protože je Flex open source, je možné do třídy Button nahlédnout a jednotlivé stavy jsou definovány pomocí anotací SkinState 31 Jednotlivé skin party je možné zjistit buď nahlédnutím do zdrojových kódů k třídě Button, kde jsou uvedeny vlastnosti s anotací SkinPart nebo vytvořením nového skinu ve Flash Builderu, který do šablony nového skinu uvede seznam skin partů v komentáři. ▪ 74 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyButtonSkin.mxml <?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Metadata> [HostComponent("spark.components.Button")] </fx:Metadata> <s:states> <s:State name="disabled" /> <s:State name="down" /> <s:State name="over" /> <s:State name="up" /> </s:states> <s:Rect left="0" right="0" top="0" bottom="0" width="70" height="20" radiusX="2" radiusY="2"> <s:stroke> <s:SolidColorStroke color="0x000000" weight="1"/> </s:stroke> </s:Rect> <s:Label id="labelDisplay" horizontalCenter="0" verticalCenter="1" left="10" right="10" top="2" bottom="2"> </s:Label> <s:Rect left="0" right="0" top="0" bottom="0" width="70" height="20" includeIn="down"> <s:fill> <s:SolidColor color="0x000000" alpha="0.25"/> </s:fill> </s:Rect> </s:Skin> SparkSkinApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"> <s:Button label="Button" skinClass="skin.MyButtonSkin"/> </s:Application> Z příkladu je patrné, že vytvoření vlastního skinu je poměrně jednoduché. K tvorbě skinů bych chtěl poznamenat, že je možné je buď vytvářet ručně, což zajistí lepší kontrolu nad kódem nebo je možné využít nástoje Adobe Catalyst, který nabízí možnost tvorby, importu a exportu Sparkových skinů. ▪ 75 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 14. DATOVÉ SLUŽBY V předchozích kapitolách jsme si představili Flex a měli bychom být schopni připravit bez problémů klientskou aplikaci. Tato aplikace by ale byla datově izolovaná, protože jsme si zatím nepopsali další důležitou funkčnost a tou je připojení aplikace na vzdálené služby. Flex nabízí tři způsoby volání služeb – webových služeb (SOAP), HTTP/S volání a remoting (RPC). V této kapitole si ukážeme jakým způsobem volat jednotlivé druhy služeb z Flexu. Až v následujících kapitolách si popíšeme, jak nastavit server k poskytování služeb klientovi. 14.1. Web Service Web Service nabízí přístup k SOAP webovým službám, které poskytují operace prostřednictvím rozhraní WSDL32. Jedná se o univerzální formát 33 pro výměnu dat mezi různými systémy. Komponenta, která slouží k volání webových služeb se jmenuje WebService. WebServiceApp.mxml – ukázka části kódu <fx:Script> import mx.collections.ArrayCollection; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; [Bindable] private var employees:ArrayCollection = new ArrayCollection(); protected function resultHandler(event:ResultEvent):void { employees = event.result as ArrayCollection; } </fx:Script> <fx:Declarations> <s:WebService id="es" result="resultHandler(event)" wsdl="http://www.adobetes.com/f45iaw100/remoteData/EmployeeData.cfc? wsdl"/> </fx:Declarations> <s:Button label="zavolej službu" click="{es.getEmployees()}"/> <s:DataGrid dataProvider="{employees}"> <s:columns> <s:ArrayList> <s:GridColumn dataField="CITY"/> <s:GridColumn dataField="FIRSTNAME"/> <s:GridColumn dataField="LASTNAME"/> </s:ArrayList> </s:columns> </s:DataGrid> 32Web Services Description Language 33 http://www.w3.org/2002/ws/ ▪ 76 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Na službě es je volána metoda getEmployees() prostřednictvím WebService komponenty. Protože se jedná o komponentu, která není vizuální a nebude umístěna na display list, je třeba ji umístit do sekce Declarations. Po úspěšném volání služby se přiřadí result na globální proměnnou employees, která je nabindovaná na DataGrid. Předávání parametrů službě je možné přes parametry metody operace. V příkladu voláme službu veřejně dostupnou pro účely testování na webu společnosti Adobe. 14.2. HTTP Service HTTP služby jsou využívány v případě, že vzdálená strana nepodporuje ani webové služby a ani remoting. Pak je možné poskytovat např. pomocí JSP, Servletu, PHP, ASP nějaký interface klientovi prostřednictvím obecného HTTP protokolu. Komponenta, která nabízí zpracování HTTP požadavků se nazývá HTTPService a ve Flexu nabízí GET a POST, v AIRu také PUT a DELETE. S využitím LCDS nebo BlazeDS je možné používat také HTTPProxyService, který navíc nabízí HEAD, OPTIONS a TRACE. Jak je vidět, HTTPService je možné využívat pro komunikaci s REST34 službami. 34 Representational State Transfer ▪ 77 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 HTTPServiceApp.mxml – ukázka části kódu <fx:Script> import mx.collections.ArrayCollection; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; [Bindable] private var employees:ArrayCollection = new ArrayCollection(); protected function resultHandler(event:ResultEvent):void { employees = event.result.employees.employee; } </fx:Script> <fx:Declarations> <s:HTTPService id="es" result="resultHandler(event)" url="http://www.adobetes.com/f45iaw100/remoteData/employees.xml"/> </fx:Declarations> <s:Button label="zavolej službu" click="{es.send()}"/> <s:DataGrid dataProvider="{employees}"> <s:columns> <s:ArrayList> <s:GridColumn dataField="city"/> <s:GridColumn dataField="firstName"/> <s:GridColumn dataField="lastName"/> </s:ArrayList> </s:columns> </s:DataGrid> Výstup je shodný jako u předchozího příkladu. Pokud metodě method na HTTPService není zadána žádná hodnota, je výchozí volání typu GET. Nastavením metody můžeme změnit typ volání např. na POST. Pak budeme potřebovat také předávat parametry dotazu, což je možné předat jako parametr metodě send(). V příkladu voláme službu veřejně dostupnou pro účely testování na webu společnosti Adobe. 14.3. Remote Object Remote Object, nebo-li remoting, nabízí přímé připojení na obchodní logiku, oproti HTTPService nebo WebService, které pracují s XML respt REST. Tento způsob komunikace je velice efektivní, protože odpadá mezistupeň konvertování do XML formátu. Toto se projevuje také na rychlosti komunikace, protože data jsou serializována a zasílána v binární podobě, což má za následek nižší objem dat. Remounting využívá pro komunikaci buď HTTP nebo HTTPS protokol. Další výhodou tohoto způsobu komunikace je automatická konverze typů objektů. Takže na straně serveru, jehož business logika je implementována např. v Javě a posílá do strany Flexu objekt typu String je po unmarshallingu vytvořen objekt stejného typu v AS3. Konverze typů je obousměrná. ▪ 78 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 RemoteObjectApp.mxml <fx:Script> import mx.collections.ArrayCollection; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import vo.Employee; [Bindable] private var employees:ArrayCollection = new ArrayCollection(); protected function resultHandler(event:ResultEvent):void { employees = event.result as ArrayCollection; } </fx:Script> <fx:Declarations> <s:RemoteObject id="es" destination="ColdFusion" source="f45iaw100.remoteData.employeeData" endpoint="http://adobetes.com/flex2gateway/" result="resultHandler(event)"/> </fx:Declarations> <s:Button label="zavolej službu" click="{es.getEmployees()}"/> <s:DataGrid dataProvider="{employees}"> <s:columns> <s:ArrayList> <s:GridColumn dataField="city"/> <s:GridColumn dataField="firstName"/> <s:GridColumn dataField="lastName"/> </s:ArrayList> </s:columns> </s:DataGrid> Employee.as package vo { [RemoteClass(alias="f45iaw100.remoteData.Employee")] public class Employee { public var firstName:String; public var lastName:String; public var id:String; public var title:String; public var email:String; public var managerID:String; public var department:String; public var location:String; public var phone:String; public var directDial:String; public var deskLocation:String; public var city:String; public var state:String; public var countryCode:String; public var hireDate:String; public var evaluation:String; public var postalCode:String; }} ▪ 79 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 V tomto příkladu je oproti předchozím použit i VO 35 Employee. V jeho definici je anotace RemoteClass, která určuje, na jaký vzdálený typ/třídu se má VO mapovat. Objekt je pak v AS3 silně typovaný. U RemoteObject komponenty je potřeba vyplnit destination, což je string definující danou službu na straně serveru36. Dále endpoint s URL služby a source, který v některých případech blíže specifikuje danou službu. V příkladu voláme službu veřejně dostupnou pro účely testování na webu společnosti Adobe. 35 Value Object je objekt, který nese informaci. Používá se také označení DTO Data Transfer Object 36 Na straně serveru je tato destination definována v souboru services-config.xml ▪ 80 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 15. CAIRNGORM U rozsáhlejších aplikací je nějaký MVC framework vhodné použít. Cairngorm je MVC framework, který zjednodušuje vývoj. MVC frameworků je více (např. PureMVC, Parsley, Robotlegs, Mate), budu zde popisovat pouze tento, protože je již poměrně odladěný a je vydáván přímo od společnosti Adobe. Jedná se o poměrně robustní řešení použitelné pro větší projekty. 15.1. Vývoj rozsáhlých aplikací Při vývoji větších aplikací se dostáváme do situace, kdy různé týmy programátorů je vhodné specializovat na konkrétní činnost. Například někteří se budou specializovat na tvorbu samostatných obrazovek, jiní na logiku komponent, další na tvorbu modelu a jiná skupina na volání servisní vrstvy. Z rozdělení do jednotlivých oblastí plyne, že je důležité využívat nějaké implementace MVC patternu při vývoji. Cairngorm MVC pattern přímo implementuje. Při standardním modelu vývoje, kdy view je definováno pomocí MXML, controller je implementován v AS3 a model na úrovni proměnných v daném view, zjistíme, že se stává aplikace čím dál více „prodrátována“, a to pro implementaci změn není dobré. Lepší je striktně oddělit Model View a Controller do samostatných částí. 15.2. Popis MVC frameworku Cairngorm Cairngorm37 je MVC framework, který striktně odděluje Model View a Controller. Model s View propojuje pomocí bindingů a controller je implementován za použítí commandů, které jsou spouštěny přes front-controler pomocí událostí. Aplikace využívá jednu instanci modelu. Jedna z výhod tohoto principu je jednoduché ladění aplikace (debugování). Cairngorm se skládá z: • ModelLocator – globální model aplikace • Event – události spouštěné z view • Command – spouští daný kód jako reakci na událost a handluje odpovědi služeb • FrontController – zjišťuje vazbu mezi událostí a commandem • ServiceLocator – seznam volaných služeb obchodní logiky 37 Popisuji zde verzi 2.2.1, v současnosti je také novější verze 3 http://opensource.adobe.com/wiki/display/cairngorm/Downloads ▪ 81 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 23: Cairngorm architektura zdroj: http://www.cairngormdocs.org/cairngormDiagram/index.html 15.3. ModelLocator Jedná se o implementaci singletonu modelu v AS3. Smyslem modelu je zajistit přístup z jakékoliv třídy k jednomu modelu a umožnit jej bindovat na view nebo měnit. Vzhledem k tomu, že AS3 nepodporuje privátní konstruktory, implementace vypadá následovně ▪ 82 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 package cg { import com.adobe.cairngorm.model.ModelLocator; import mx.collections.ICollectionView; [Bindable] public class Model implements ModelLocator { private static var modelLocator : Model; public static function getInstance() : Model { if ( modelLocator == null ) modelLocator = new Model(); return modelLocator; } public var products : ICollectionView; } } Přístup k modelu je pak možný takto: var products : ICollectionView = Model.getInstance().products; 15.4. Event Událost, která akci vyvolá, je zajištěna dispatchnutím nějakého Eventu. Event je v tomto případě třída, která extenduje CairngormEvent. Jako dispatcher je možné použít jak klasický dispatcher na UIComponent, tak přímo určený CairngormEventDispatcher, který spouští událost přímo bez bublání na display listu. Při tvorbě nové události ve Flexu je nutné vždy přidat override metody clone(). Pokud bychom toto neudělali, měli bychom problém s castingem při dispatchování Eventu v handleru události. ▪ 83 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 ProductEvent.as package cg { import com.adobe.cairngorm.control.CairngormEvent; import flash.events.Event; public class ProductEvent extends CairngormEvent { public static var ADD_PRODUCT:String = "addProduct"; public static var DEL_PRODUCT:String = "delProduct"; public static var GET_PRODUCTS:String = "getProducts"; public var name:String; public function ProductEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) { super( type ); } override public function clone() : Event { return new ProductEvent(this.type, this.bubbles, this.cancelable); } } } Použítí je následující CairngormEventDispatcher.getInstance().dispatchEvent(new ProductEvent(ProductEvent.ADD_PRODUCT, newProduct)); 15.5. Command Command slouží ke spuštění konkrétní akce. Je volán front controllerem a typicky zabezpečuje volání konktérní služby a handlování odpovědi. Při spuštění volání služby jsou commandu předány příslušné parametry prostřednictvím události, která command spustila. Tyto parametry pak mohou být předány volané službě. Odpověď na servisní volání může být dvojího typu. Bezchybné, pak posílá zpravidla nějaká data nebo nastala chyba, a přichází chybový kód. Command implementuje obsahuje metodu interface com.adobe.cairngorm.commands.ICommand, execute(event:CairngormEvent) pro spuštění kódu. Dále který může implementovat také mx.rpc.IResponder, který obsahuje metody fault(info:Object) a result(data:Object) pro implementaci handlerů odpovědi služby. ▪ 84 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 AddProductCommand.as – část třídy public class AddProductCommand implements ICommand, IResponder { public function execute(event:CairngormEvent):void { var service:RemoteObject = MyServiceLocator.getInstance() .getService(MyServiceLocator.PRODUCT_SERVICE); var call:AsyncToken = service.addProduct(ProductEvent(event).name); call.addResponder(this); } public function result(data:Object):void {}//nic nevrací public function fault(info:Object):void { var faultEvent:FaultEvent = info as FaultEvent; Alert.show('Chyba: ' + faultEvent.fault.message); } } GetProductsCommand.as – část třídy public class GetProductsCommand implements ICommand, IResponder { public function execute(event:CairngormEvent):void { var service:RemoteObject = MyServiceLocator.getInstance() .getService(MyServiceLocator.PRODUCT_SERVICE); var call:AsyncToken = service.getProducts(); call.addResponder(this); } public function result(data:Object):void { var resultEvent:ResultEvent = data as ResultEvent; Model.getInstance().products = resultEvent.result as ArrayCollection; } public function fault(info:Object):void { var faultEvent:FaultEvent = info as FaultEvent; Alert.show('Chyba: ' + faultEvent.fault.message); } } } 15.6. FrontController FrontController slouží ke zpracování událostí dispatchnutých CairngormEventDispatcherem a svázáním s příslušným commandem. V předchozí kapitole jsou definovány dva typy událostí a pro každou z nich chceme přiřadit jeden command. Kód by vypadal následovně. ▪ 85 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 package cg { import cg.command.AddProductCommand; import cg.command.DelProductCommand; import cg.command.GetProductsCommand; import com.adobe.cairngorm.control.FrontController; public class MyController extends FrontController { public function MyController() { initialiseCommands(); } public function initialiseCommands() : void { addCommand(ProductEvent.ADD_PRODUCT, AddProductCommand); addCommand(ProductEvent.GET_PRODUCTS, GetProductsCommand); } } } Pokud tedy dojde k dispatchnutí události typu ProductEvent.ADD_PRODUCT, je spuštěn command AddProductCommand, konkrétně jeho metoda execute() a jí je jako parametr předán ProductEvent. 15.7. ServiceLocator Jedná se o jednoduchou factory, která vrací podle String parametru konkrétní služby, v našem případě RemoteObject objekt. Může být ale definována obecně na jakoukoliv službu. ServiceLocator je volaný buď prostřednictvím delegáta38, a nebo jako v našem případě je volán přímo z Commandu. V praxi je vhodné volat službu prostřednictvím delegáta. V našem příkladu se volá služba productService. 38 Delegát slouží jako mezistupeň mezi způsobem volání nějaké služby a commandem ▪ 86 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyServiceLocator.mxml package cg { import mx.rpc.remoting.RemoteObject; public class MyServiceLocator { private static var serviceLocator : MyServiceLocator; public static const PRODUCT_SERVICE:String = "product_service"; public static const ANOTHER_SERVICE:String = "another_service"; public static function getInstance() : MyServiceLocator { if ( serviceLocator == null ) serviceLocator = new MyServiceLocator(); } return serviceLocator; } public function getService(value:String):RemoteObject { var ro:RemoteObject; switch (value) { case PRODUCT_SERVICE: ro = new RemoteObject(); ro.destination = "productService"; // pripadne dalsi parametry jako // endpoint, pokud je treba break; case ANOTHER_SERVICE: // vytvoreni dalsi sluzby break; } return ro; } } ▪ 87 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 16. TESTOVÁNÍ 16.1. FlexUnit – Unit Testy Testování software je součástí vývojového procesu a pro větší projekty naprostou nezbytností. Flex nabízí testovací nástroj FlexUnit, který je podobný testovacímu nástroji JUnit. Ve Flash Builderu je přímo FlexUnit podporován a skeletony testů je možné jednoduše vygenerovat pro konkrétní třídu, na základě vybraných metod pomocí průvodce (New → Test Case Class). V Test Case je možné používat několik anotací a assertů. Tabulka 7: Anotace TestCase Anotace Popisek Before Je uvedena před metodou, která se spouští před každým spuštěním konkrétního testu, tj. metod anotovaných Test. After Je uvedena před metodou, která se spouští po každém spuštění konkrétního testu. BeforeClass Je před statickou metodou, která se spustí při inicializaci testovací třídy, ještě před spuštěním jednotlivých testů. Typicky pro inicializaci globalních parametrů. AfterClass Je před statickou metodou, která se spustí po spuštění všech testů. Typicky pro uklizení použitých zdrojů. Test Je před metodou konkrétního testu Tabulka 8: Asserty Assert Popisek assertEquals projde, když jsou hodnoty parametrů shodné assertStrictlyEquals projde, pokud se jedná o tentýž objekt assertFalse projde, když je parametr false assertTrue projde, když je parametr true assertNull projde, když je parametr null assertNotNull projde, když parametr není null V následujícím příkladu je jednoduchá třída MyMath.as, která má metody pro sčítání a odčítání. Následuje ukázka Test Case MyMathTest.as. ▪ 88 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 MyMath.as package test { public class MyMath { public function plus(a:Number, b:Number):Number { return a + b; } public function minus(a:Number, b:Number):Number { return a - b; } } } MyMathTest.as package flexUnitTests { import flexunit.framework.Assert; import org.flexunit.asserts.assertEquals; import test.MyMath; public class MyMathTest { private static var myMath:MyMath; private var a:Number; private var b:Number; [Before]public function setUp():void { a = 5; b = 4; } [After]public function tearDown():void { } [BeforeClass]public static function setUpBeforeClass():void{ myMath = new MyMath(); } [AfterClass]public static function tearDownAfterClass():void{ myMath = null; } [Test]public function testMinus():void { assertEquals(myMath.minus(a,b), 1); } [Test]public function testPlus():void { assertEquals(myMath.plus(a,b), 9); } } } Pro spuštění testů je třeba zvolit v menu na daném projektu „Execute FlexUnit Tests“. Tato volba při prvním spuštění automaticky vygeneruje další potřebné soubory v „default package“, které slouží pro další spouštění testů. Tyto soubory pouze předávají seznam spouštěných testů komponentě FlexUnitTestRunnerUI. Po spuštění testů se zobrazí stránka s výsledky testů. Detaily je možné sledovat v „FlexUnit Results“ záložce přímo ve Flash Builderu. ▪ 89 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 16.2. FlexMonkey – Funkční testy Pro funkční automatizované testování Flexové aplikace slouží nástroj FlexMonkey. Je třeba poznamenat, že na rozdíl od FlexUnit, který je přímo od společnosti Adobe, je FlexMonkey od společnosti GorillaLogic pod licencí GNU GPL. FlexMonkey se skládá ze dvou základních částí, a to AIR konzole, která umožňuje interaktivně zaznamenávat, přehrávat a upravovat testovací skripty. A dále SWC knihovnu, která je součástí testované aplikace, pro možnost komunikace s AIR konzolí. Dále je nutné mít ve Flex frameworku SWC knihovnu automation. Ta je součástí 39 SDK, jen je potřeba upravit parametry překladače ve Flash Builderu. -include-libraries "../libs/automation_monkey4.x.swc" "${flexlib}/libs/automation/automation_spark.swc" "${flexlib}/libs/automation/automation.swc" "${flexlib}/libs/automation/automation_agent.swc" "${flexlib}/libs/automation/automation_dmv.swc" Po instalaci40 konzole a vytvoření projektu je třeba otestovat, zda je konzole správně propojená s testovanou aplikací, na což nás upozorní „Connection Indicator“. Pokud je konzole připojená, můžeme začít se záznamem událostí v aplikaci pomocí tlačítka „Record Button“. V „Recording Window“ je vidět seznam akcí, které s aplikací provádíme. Z těchto akcí je možné vytvořit nový test doplněním verifikací. Pro verifikace nebo spouštění dalších příkazů (command) slouží „Tool Palette“. „Test Suite Editor“ je seznam samotných testovacích scriptů řazených do standardní struktury „Test Suite/Test Case/Test“. Verifikace jsou k dispozici ve třech variantách. Pro základní verifikaci (Verify) je možné využít libovolnou vlastnost na komponentě a porovnat ji s hodnotou. FlexMonkey dá na výběr jak komponentu na obrazovce, tak seznam vlastností, což práci při vytváření testů značně zjednoduší. Dále je možné verifikovat výraz (VerifyExpression), pokud není možné použít verifikace jednoduché vlastnosti, ale složené. Pro verifikaci hodnot uvnitř DataGridu slouží VerifyGrid, který umožňuje jednoduše identifikovat hodnotu pomocí čísla řádku a sloupce. Součástí verifikací je také možnost verifikovat snapshop obrazovky, zda daná komponenta vypadá stejně. Podmínkou v tomto případě je, že testy musí být spouštěny na počítači se stejným rozlišením, jako na počítači, na kterém byly testy vytvářeny. Ideálně, pokud se jedná o stejný stroj. 39 Knihovny jsou umístěny v podadresáři „automation“ balíku SDK 40 FlexyMonkey konzole vyžaduje mít nainstalovaný Adobe AIR. Samotnou aplikaci je možné stáhnout na http://www.gorillalogic.com/flexmonkey ▪ 90 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Pokud jsou jednotlivé testy ve FlexMonkey vytvořeny a funkční, je možné z nich vygenerovat přes „File → Generate FlexUnit Tests” AS3 testy. Na obrázku41 je zobrazena konzole s popisy jednotlivých částí. Obrázek 24: FlexMonkey konzole 41 zdroj: http://www.gorillalogic.com/flexmonkey ▪ 91 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 17. BEZPEČNOST Bezpečnost je důležitým faktorem při vyvoji aplikace. Je třeba si již od počátku uvědomit komu bude aplikace zpřístupněna a tomu bezpečnost přizpůsobit. Něco jiného je, pokud je aplikace využívána omezeným množstvím uživatelů v nějaké společnosti nebo je dostupná komukoliv na internetu. Na bezpečnost je možné nahlížet z několika možných úhlů. Jedná se o bezpečnost samotné aplikace, jak ji psát, čemu se vyvarovat. Dále se jendá o bezpečnost přenosu dat mezi klientem (Flash Playerem) a serverem. A pak je to také bezpečnost samotného Flash Playeru, který je v počítači instalován a vnitřní chybou může narušit bezpečnost celého operačního systému. 17.1. Flash Player Velkou výhodou Flash Playeru je, že je instalován na velkém množství desktopových počítačích v internetu. Aplikace v něm spuštěné vypadají ve všech prohlížečích stejně. To je výhoda oproti JavaScriptu, který může být v některých případech interpretován různými prohlížeči různě. Verze Flash Playeru jsou dostupné nejen pro různé prohlížeče a jejich verze, ale také pro různé operační systémy, takže je možné pokrýt opravdu velké procento počítačů po celém internetu. Tato výhoda se ale může z hlediska bezpečnosti jevit jako nevýhoda. Protože pro útočníka je výhodné zaměřit se na velké množství počítačů, na kterých může být instalován nějaký software, který obsahuje chybu. Úspěch nabourání se do chybné aplikace je pak mnohem pravděpodobnější. Nejinak je tomu i u Flash Playeru, který není bezchybný. Flash Player implementuje celou řadu bezpečnostních prvků. Hlavní omezení je v přístupu k systémovým zdrojům, takže není možné např. ukládat data aplikace na disk standardním způsobem, ale pouze omezené množství dat do vyhrazeného uložiště (Local Storage). Flash Player také kontroluje přístupy k multimediálním zařízením jako je mikrofon, kamera, reproduktory. Aplikace může být překládána42 v režimu komunikace přes síť, pak nemůže přistupovat napřímo k disku, ale vše tahá přes síť ze zdrojového serveru, nebo v řežimu lokálním, pak naopak nemůže využívat síťové komunikace. Tato možnost zcela odděluje lokální data a síťový provoz. Nyní se podíváme na Flash Player z hlediska bezpečnostních záplat. Flash Player je současně v major verzi 10, která byla vydána září 2008. Od 43 té doby bylo vydáno 23 bezpečnostních záplat, přičemž 22 záplat bylo kritických (critical) a jedna důležitá (important). Z toho lze usoudit, že Flash 42 zda je aplikace v režimu komunikace přes síť či lokálně ovlivňuje parametr překladače -use-network s boolean hodnotou true nebo false 43 Situaci jsem zjišťoval v 07/2011 ▪ 92 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Player není zcela bezpečný. U některých 44 chyb lze například získat administrátorská oprávnění daného počítače, pokud máme přístup jako obyčejný uživatel. U jiných zase spouštět nechtěný kód způsobený chybou přetečením zásobníku. Tabulka 9: Severita chyb Rating Definition Critical A vulnerability, which, if exploited would allow malicious native-code to execute, potentially without a user being aware. Important A vulnerability, which, if exploited would compromise data security, potentially allowing access to confidential data, or could compromise processing resources in a user's computer. Moderate A vulnerability that is limited to a significant degree by factors such as default configuration, auditing, or is difficult to exploit. Low A vulnerability that has minimal impact and is extremely difficult to exploit. zdroj: http://www.adobe.com/devnet/security/severity_ratings.html Jak tedy zajistit bezpečnost Flash Playeru? Jako zatím zdařilé řešení se zdá být způsob, který zvolila společnost Google ve svém prohlížeči Chrome. Ta nabízí předinstalovaný Flash Player plugin ve verzi, která by měla být relativně bezpečná. A pokud se objeví novější bezpečnější verze, plugin automaticky zablokuje a nabídne možnost stažení nové verze. Tato varianta ale vyžaduje používat konkrétní prohlížeč a také mít přístup na internet, aby se Chrome o nové verzi mohl dozvědět. Jen okrajově zmíním také Adobe AIR, který nabízí oproti Flash Playeru rozšířené možnosti přístupu k systémovým zdrojům, jako např. plnohodnotný přístup k souborovému systému a databázi. Dalším bezpečnostním prvkem Flash Playeru jsou security sandboxy. Flash player si veškeré nahrávané zdroje (assets), jako jsou SWF z lokálního filesystému, vzdáleného serveru, obrázky, videa, sdílené objekty, přiděluje do jednotlivých security sandboxů, právě podle jejich původu. Základní rozdělení je na remote a local sandboxy. Remote sandboxy jsou využity k oddělení zdrojů stahovaných z internetu podle různých domén. Ve výchozím stavu je povoleno, aby daný zdroj – především SWF - komunikoval pouze se zdroji ze stejného sandboxu a stejné domény. Pokud mají zdroje komunikovat s jinou doménou, je třeba to povolit jak na straně aplikace pomocí Security.allowDomain(), tak na straně serveru pomocí cross-comain policy. Příklad byl na toto téma popsán v kapitole Moduly. Lokální sandboxy jsou třech druhů. První local-with-filesystem sandbox je výchozím sandboxem pro lokální zdroje a z tohoto sandboxu je možné číst lokální soubory, ale je zakázáno komunikovat po síti. 44 konkrétně chyba APSB09-10 ▪ 93 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Druhý lokální sandbox je local-with-networking. Aby bylo SWF v tomto sandboxu je třeba nastavit parametr překladače -use-network na true, což umožní, že SWF soubor má možnost komunikovat po síti, ale ztrácí možnost čtení lokálních souborů. Třetí lokální sandbox local-trusted jsou SWF soubory, které jsou uživatelem, administrátorem nebo instalačním programem označeny45 jako důvěryhodné. SWF soubory v tomto sandboxu mají přístup k libovolným dalším SWF souborům a také k internetu. Základem celé myšlenky security sandboxů je, že je přísně zakázána komunikace mezi localwith-networking a local-with-filesystem, a stejně tak mezi local-with-filesystem a remote sandboxy. Tato komunikace nemůže být povolena ani uvnitř Flash aplikace, ani uživatelem či administrátorem. Ještě zde zmíním způsob, jakým se dá zjistit, ve kterém security sandboxu se dané SWF nachází. Přístup k je možný přes statickou read-only vlastnost Security.sandboxType, která může nabývat hodnot Security.REMOTE, Security.LOCAL_WITH_FILE, Security.LOCAL_WITH_NETWORK nebo Security.LOCAL_TRUSTED. 17.2. Vnitřní bezpečnost aplikace Podívejme se nyní na bezpečnost z pohledu samotných SWF souborů. Jedná se o binární soubory, které vzniknou překladem AS3, popř. MXML. Tyto SWF soubory jsou většinou 46 staženy browserem přes HTTP protokol a následně spuštěny ve Flash Playeru. Oproti interpretovaným jazykům běžících na serveru (např. PHP) je Flexová aplikace spouštěna přímo na klientovi. Tudíž je zde potenciální riziko v možnosti nahlížet do binárního kódu a reverzním inženýringem zjišťovat zdrojový kód. V dnešní době existuje celá řada software produktů47, které umožňují dekompilovat SWF soubory a tím získat plnohodnotné zdrojové kódy aplikace. Není proto nic složitého ani pro laika zjistit obsah zdrojových kódů. Na tuto skutečnost je třeba si dávat pozor již při návrhu aplikace a nezadávat do zdrojových kódů žádné choulostivé informace jako např. hesla v plain text podobě. Pokud je to možné, pak nechat heslo zadávát přímo uživatele. Pro části aplikace, u nichž není vhodné dávat k dispozici SWF soubor ve standardním formátu, bych doporučil SWF soubor obfuskovat. Jedná se o nevratný proces, který zajistí přejmenování 45 Více o způsobu nastavení je možné nalézt na http://livedocs.adobe.com/flex/3/html/help.html? content=05B_Security_03.html#122778 46 Pokud se bavíme o aplikaci přeložené s parametrem -use-network=true 47 Osobně mám dobré zkušenosti s AS3 Sorcerer – www.as3sorcerer.com ▪ 94 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 metod, proměnných, balíků, atd., napříč aplikací. Tím je zajištěna funkčnost aplikace i po přejmenování. Pokud na takto vytvořený SWF soubor použijeme dekompilátor, zobrazí se velice nečitelný zdrojový kód, tudíž v podstatě nepoužitelný pro běžnou práci. Hlavní nevýhodou, která může nastat je to, že při použití reflexe, na které jsou založeny některé frameworky, je jakákoliv obfuskace téměř nerealizovatelná, protože se aplikace rozpadne. Proto je třeba pečlivě zvážit, zda a co obfuskovat. Při práci s moduly je poměrně důležité správně pracovat s aplikačními doménami (applicationDomain). Obrázek 25: Aplikační domény zdroj: http://livedocs.adobe.com/flex/3/html/help.html?content=18_Client_System_Environment_5.html Jak již bylo nastíněno v kapitole Moduly, aplikaci, která se skládá z několika SWF modulů je možné dělit do aplikačních domén. Hlavní aplikační doménou je systémová doména. Aplikační doména č. 1 má rodičovskou (parent) doménu systémovou. Obecně aplikační domény mohou být použity třemi možnými způsoby. ▪ 95 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 První varianta je module1.swf, který je součástí hlavní aplikace a je ve stejné aplikační doméně č. 1. Tudíž je možné používat všechny třídy z modulu i aplikace uvnitř domény 1. Jedná se o jakési rozšíření hlavní aplikace. Varianta druhá je zcela oddělená aplikační doména č. 2 od aplikační domény č. 1. Aplikační doména č. 2 má rodičovskou doménu systémovou. Použití této varianty je možné například v případě, že původní stará verze aplikace dynamicky nahrává novou verzi té samé aplikace tak, aby nenastal konflikt tříd. Varianta třetí je Aplikační doména č. 3, jejíž rodičovská doména je aplikační doména č. 1., čímž zajistíme, aby potomek používal všechny třídy pouze z verze rodičovské domény. Tím máme jistotu, že zajistíme všem potomkům jednotnou verzi tříd z rodičovské domény a zároveň znemožníme vzájemným konfliktům mezi potomky. 17.3. Síťová bezpečnost Pokud se v této kapitole bavíme o síťové bezpečnosti přenosu dat, myslím tím dva typy. V první řadě se jedná o komunikaci HTTP, kde probíhá komunikace mezi browserem a webovým serverem, který předává browseru fyzicky SWF soubory při startu aplikace a zpřístupňuje zdroje na straně serveru. V druhém případě tím myslím komunikaci mezi samotnou spuštěnou Flash aplikací ve Flash Playeru a mezi serverem, jeho vzdálenými službami. Tato komunikace bývá na bázi samostatného protokolu48 a většinou49 zabalena do HTTP. První případ, který zmiňuje bezpečnost je především o nastavení webového serveru, tj. Ověření přístupu přes HTTP autorizaci, pokud je ke zdrojům třeba autorizovat přístup. Dále je zde možnost komunikaci šifrovat, a to prostřednictvím SSL (HTTPS), aby data nebyla po cestě monitorována a aby nebylo možné útočníkem podhodit falešné SWF. Obrázek 26: Komunikace klient – web server 48 může být např. XML based SOAP nebo binární AMF 49 Aplikace může komunikovat také pomocí protokolu RTMP. Ten je ale možné použít jen v uzavřené síti, kde je povolen na firewallech. V internetu se nepoužívá. ▪ 96 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Případ druhý, tj. komunikace mezi Flash aplikací a vzdálenými službami, je o komunikaci mezi aplikačním serverem a Flash Playerem. Zde je možnost ověření uživatelského přístupu k jednotlivým servisním voláním přes zabezpečení aplikačního serveru, například přes Spring Security50. Obrázek 27: Komunikace mezi Flash Playerem a aplikačním serverem Zde je opět na místě třeba zmínit bezpečnost na úrovni komunikace mezi více servery, kterou je možné nastavit pomocí Security.allowDomain() a cross-domain policy, jak je popsáno v kapitole Moduly. 50 http://static.springsource.org/spring-security/site/ ▪ 97 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 18. VRSTVA OBCHODNÍ LOGIKY V následujících kapitolách se pokusím velmi stručně nastínit, jak je možné Flex propojit s vrstvou obchodní logiky a datovou vrstvou. Cílem kapitol není detailně popisovat Spring a Hibernate, ani detailně popisovat propojení Flexu s těmito technologiemi. Cílem je nastínit, jaké jsou možnosti pro integraci Flexu jako prezentační vrstvy s dalšími vrstvami. V předchozích kapitolách jsme si popsali prezentační vrstvu, která reprezentovala grafické rozhraní dostupné pro uživatele a řeší převážně úlohu zobrazení výstupních dat, čtení a validaci dat vstupních. Tato data jsou pak předána na stranu aplikačního serveru, kde je umístěna vrstva obchodní logiky. Tato vrstva je přístupná Flexové aplikaci, popřípadě i jiným aplikacím pomocí rozhraní. Vrstva obchodní logiky zajišťuje hlavní business funkcionalitu. Dostává od prezentační vrstvy (naší Flex aplikace) vstupy, volá nad nimi příslušnou logiku a vrací prezentační vrstvě výstupy. V Javě je možné vrstvu obchodní logiky reprezentovat několika způsoby. Nejznámějšími jsou pomocí EJB nebo Springu. My se zaměříme na druhý zmiňovaný, protože nabízí jednoduchou integraci s frameworkem BlazeDS, který používáme pro datové služby. Abychom lépe porozuměli ukázkám konfigurací, je třeba seznámit se s pojmy Inversion of Control (IoC) a Dependency Injection (DI). 18.1. Spring, IoC a DI Spring obsahuje tzv. IoC (Inversion of Control) kontajner a jeho úkolem je zajistit propojení komponent/tříd nezávisle na jejich implementaci. Lepší bude představit si tuto situaci na obrázku: Obrázek 28: Závislosti tříd přes IoC Jak je vidět z prvního obrázku, není zcela přehledné a flexibilní mít v kódu přímé provázání mezi jednotlivými třídami/komponentami. A to z několika důvodů. První důvod je právě přehlednost, kdy ▪ 98 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 není jasné, jak jsou vazby uspořádány. Druhý důvod je, že pokud bychom chtěli provádět nějaké změny, je třeba zasahovat do kódu, což znamená minimálně opětovný překlad. Oproti tomu varianta druhá zajistí, aby se jednotlivé třídy vytvořily pomocí IoC kontajneru a následně nastavily závislosti pomocí Dependency Injection (DI). To nám umožní konfiguraci závislostí definovat externě nikoliv provazovat přímo. Tím dosáhneme větší nezávislosti a přehlednosti, což je patrné z druhého obrázku. Spring framework využívá DI pro provázání Spring Bean 51 pomocí getter a setter metod nebo konstruktorů místo aby byly reference uvedeny přímo v třídách. Závislosti jsou definovány Springem buď v XML souboru nebo pomocí anotací. Nejprve jsou jednotlivé beany instancovány a následně jsou provázány podle definovaných závislostí. V definici závislosti je nutné mít danou vlastnost třídy dostupnou přes setter / getter metodu pro vložení (injection) reference na konkrétní beanu. Tuto beanu je také nutné mít instancovanou pomocí Springu. Spring při načítání XML/anotací vytvoří beany obou tříd a pak vloží (inject) pomocí setteru referenci na druhou beanu. Reference je možné předávat i do konstruktorů. Proto rozlišujeme tzv. „setter injection“ a „constructor injection“. 51 Spring Bean třída, kterou Spring (resp. IoC) instancuje a konfiguruje. Je proto nutné, aby měla přístupné potřebné settery/gettery a konstruktory. ▪ 99 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Person.java package bp.spring.example; public class Person { private String firstname; private String surname; private String partner; public Person() {} public Person(String firstname, String surname) { this.firstname = firstname; this.surname = surname; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public String getPartner() { return partner; } public void setPartner(String partner) { this.partner = partner; } } di.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="me" class="bp.spring.example.Person"> <property name="firstname" value="Michal"/> <property name="surname" value="Kolesar"/> <property name="partner" ref="myWife"/> </bean> <bean id="myWife" class="bp.spring.example.Person"> <constructor-arg value="Helena"/> <constructor-arg value="Kolesarova"/> </bean> </beans> V příkladu je použita konfigurace pomocí XML (je možné také pomocí anotací). Nejprve jsou vytvořeny dvě beany s názvy me a myWife obě typu Person a následně jsou jim vloženy ▪ 100 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 závislosti. Konkrétně u beany me je pomocí setterů nastaveno firstname, surname na danou string hodnotu a partner je reference na druhou beanu myWife. U beany myWife je použit constructor injection pro nastavení jména a příjmení oproti první beaně me, kde je použit setter injection. 18.2. LCDS, BlazeDS Jak již jsme si popsali v kapitole Datové služby, existuje několik přístupů k serverovým službám. Pro zopakování se jedná o HTTPService (protokol HTTP/S), WebService (protokol SOAP), RemoteObject (protokoly RTMP/S a AMF). V našich příkladech se zaměříme na poslední z uvedených. První dva je možné také použít, ale nenabízejí takové možnosti jako RPC RemoteObject. Na straně serveru je potřeba poskytovat datové služby (Data Services). K těmto účelům je možné využít několik frameworků. Zmíním zde pouze dva LifeCycle Data Services (LCDS 52) a BlazeDS53. Oba frameworky jsou od společnosti Adobe a oba jsou napsány v Javě, podporují tudíž tuto platformu. LCDS je komerční produkt, který nabízí vše co BlazeDS, a navíc vyšší výkonnost a Data Managemet služby. Více popíši ve srovnávací tabulce. LCDS se zde nebudu blíže zabývat, v popisu se zaměřím na služby, které nabízí BlazeDS, které je zdarma. Jedná se o open source projekt k dispozici pod GNU LGPL licencí. Více o rozdílech mezi oběma produkty viz. obrázek 54. 52 http://www.adobe.com/products/livecycle/dataservices/ 53 http://opensource.adobe.com/wiki/display/blazeds/Overview 54 zdroj: http://www.adobe.com/products/livecycle/dataservices/compare.html ▪ 101 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 29: Vlastnosti BlazeDS vs. LCDS Co vše BlazeDS nabízí? – možnost spouštět vzdálené metody z Flex aplikací (remoting) – překlad Java objektů, které přichází jako odpověď na volání Java metody do AS3 obdoby – překlad AS3 objektů, které jsou předávány jako parametry Java metodán do Java obdoby – komunikace mezi Flash Playerem a Java serverem přes binární TCP/IP protokol – zasílání zpráv iniciovaných z Java serveru na Flex klienta (push) – formu zasílání zpráv mezi Flex a Java pomocí publish/subscribe (messaging) – nastavení několika komunikačních kanálů mezi Flexem a Javou (polling, stream) – adaptéry pro JMS, JPA, Hibernate ▪ 102 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 BlazeDS je sada JARů distribuovaná jako WAR, která může běžet v libovolném Java Servlet kontajneru, jako např. Apache Tomcat, JBoss, IBM WebSphere nebo Oracle Weblogic. Instalace je velice jednoduchá, stačí nasadit (deploy) WAR aplikaci55 do Java Servlet kontajneru. Všechny dotazy, které BlazeDS zpracovává jsou směrovány na MessageBrokerServlet. Message Broker používá kanály, endpointy a adaptéry pro poskytování služeb remotingu, messagingu a proxy. Základní konfigurační XML soubory Servletu jsou umístěny v adresáři WEB-INF/flex. Kanál je způsob komunikace, kterou používá Flexový klient se serverm. Endpoint je Servlet na straně BlazeDS pro obsloužení klienta. Na straně serveru jsou kanály a endpointy spárovány. Adaptéry jsou specifické pro daný server, pro který jsou určeny, např. JavaAdapter pro remoting. Ukázka konfigurace kanálu <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/ {contex.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition> Ukázka konfigurace adaptéru <adapters> <adapter-definition id="java-object“ class="flex.messaging.services.remoting.adapters.JavaAdapter“ default="true" /> </adapters> 55 Pro začátečníky je k dispozici také tzv. turkey distribution, která obsahuje předkonfigurovaný Tomcat s nasazeným a nakonfigurovaným BlazeDS ▪ 103 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 30: Vrstvy mezi Flex a BlazeDS Pro messaging (real-time komunikaci mezi serverem a Flexem) je určen ActionScriptAdapter. Existuje několik způsobů konfigurace kanálů s endpointy pro messaging. První způsob je kombinace AMFChannel a Polling Endpointu, který funguje na principu zasílání dotazů na server v pravidelných předdefinovaných intervalech. Tím je zajištěno, že server může klientovi zaslat zprávu. Tento způsob však klade nároky na síť a závisí také na interfalu pollingu. Druhý způsob je kombinace AMFChannel a Long-polling Endpointu. Ten se ze strany klienta chová totožně, tj. zasílá v pravidelných intervalech dotazy na server, zda pro něj nemá nějakou zprávu. Server v případě, že žádnou zprávu nemá nevrací ihned odpověď s touto informací, ale čeká definovanou dobu, zda pro klienta zpráva nepříjde. A pokud v definované době příjde, vrací zprávu jako odpověď na dotaz. Tento způsob se blíží více real-time komunikaci a nezatěžuje tolik síť. Na druhou stranu klade větší paměťové nároky na server, protože každý požadavek na server je nějakou dobu v paměťi než dojde k odpovědi. To je ovšem možné minimalizovat pomocí Java NIO (non-blocking IO), které není přímo obsaženo v BlazeDS (je součástí LCDS), ale existuje projekt dsadapters56, který si klade za cíl implementovat NIO podporu do BlazeDS. Poslední způsob je použití Streaming AMFChannel s klasickým Endpointem. Komunikace je založena na otevření spojení mezi serverem a klientem, přes které je zasílán obsah, který není ukončený. Typicky pro streaming nějakých dat. Pochopitelně jsou zde kladeny nároky na síť i paměť serveru. 56 http://code.google.com/p/dsadapters/ ▪ 104 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 BlazeDS nabízí ještě další možnosti, jako podporu clusteringu, kešování, komprimace přenášených dat. BlazeDS je možné propojit s frameworkem Spring a tím i dalšími frameworky, jako např. Hibernate pro perzistenci. O obou variantách si povíme něco v následujících kapitolách. 18.3. Konfigurace Spring a BlazeDS Nyní bychom měli mít představu o tom, že existují datové služby (Data Services), co poskytují a co konkrétně poskytuje za služby framework BlazeDS. Jelikož BlazeDS nenabízí například přímou podoru perzistence oproti LCDS, je možné použít pro perzistenci Spring frameworku, který perzistenci dokáže poskytnout. Pro integraci Springu a BlazeDS existuje projekt Spring BlazeDS integration 57. Pro zprovoznění budeme potřebovat stáhnout několik knihoven a závislostí. – BlazeDS - http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/ – Spring Framework - http://www.springsource.org/download – Spring BlazeDS Integration - http://www.springsource.org/spring-flex – AOP Alliance - http://sourceforge.net/projects/aopalliance/files/ – backport-util-concurrent - http://sourceforge.net/projects/backport-jsr166/files/backportjsr166/ – cglib - http://sourceforge.net/projects/cglib/files/ – asm - http://forge.ow2.org/projects/asm/ Nejdříve bude potřeba si nastavit webový projekt. Po nasazení WAR souboru z BlazeDS bude potřeba nastavit správně hlavní Servlet tak, aby primární zpracování požadavků přicházelo na Spring. BlazeDS používá MessageBrokerServlet jako hlavní Servlet oproti tomu Spring používá DispatcherServlet. Pro správné nastavení je třeba upravit web.xml následovně: 57 http://www.springsource.org/spring-flex ▪ 105 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <listener> <listener-class> flex.messaging.HttpFlexSession </listener-class> </listener> <servlet> <servlet-name>flexspring</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>flexspring</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> </web-app> Poté je třeba všechny výše uvedené knihovny (.jar) překopírovat do adresáře WEB-INF/lib. Tím bychom měli mít minimální základ. Dále si ukážeme, jak by měly vypadat konfigurační soubory pro zprovoznění remotingu. Nejdřív si ukážeme, jak vypadá konfigurace kanálů s endpointy v souboru services-config.xml, kde jsou k nastaveny klasický endpoint, polling a streaming. ▪ 106 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 services-config.xml <?xml version="1.0" encoding="UTF-8"?> <services-config> <channels> <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint" /> </channel-definition> <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel"> <endpoint url="http://{server.name}:{server.port}/ {context.root}/messagebroker/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint" /> </channel-definition> <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/ {context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint" /> </channel-definition> </channels> </services-config> A nakonec si ukážeme samotnou konfiguraci Springu. Na Root úrovni webového projektu (na stejné kde je web.xml) vytvoříme soubor applicationContext.xml s následujícím obsahem. applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:flex="http://www.springframework.org/schema/flex" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <flex:message-broker> <flex:remoting-service default-channels="my-amf"/> </flex:message-broker> <context:component-scan base-package="flex" /> </beans> ▪ 107 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Toto by mělo být dostačující z hlediska konfigurace frameworků. Nyní je potřeba připravit službu, která bude obsahovat metody volatelné z Flex klienta. V této kapitole se nebudu věnovat messagingu ani streamingu dat. Ukázku je možné nalézt v dokumentaci 58. Takovou službu musíme podle konfigurace v applicationContext.xml vytvořit v balíčku flex s příslušnými anotacemi. Více o tvorbě služby v následující kapitole. 18.4. Ukázka jednoduché Java služby pomocí BlazeDS Ještě než začnu hovořit o konkrétní implementaci služby jako takové, rád bych zmínil, že je důležité se před návrhem služeb dohodnout na rozhraní, které bude služba implementovat. Toto rozhraní je pak jasný kontrakt mezi stranou Flexového klienta a serveru. V praxi může službu implementovat někdo jiný než klientskou aplikaci a proto je vhodné, aby se dohodnulo včas jasné rozhraní, a to se v průběhu implementace pokud možno neměnilo. Když je jasné rozhraní služby je možno začít se samotnou implementací. Služba je jednoduchá třída, která nabízí metody/operace se vstupními parametry a návratovou hodnotou. Parametry jsou předávány Flexem a do Javy a návratové hodnoty Javy jsou předávány Flexu. Z předchozích kapitol víme, že automatickou konverzi typů zajišťují příslušné adaptéry. Aby daná služba byla správně vystavená, je třeba přidat několik anotací. Na třídu to jsou @Service, která řekne Springu, že daná třída je služba a @RemotingDestination, která zpřístupní třídu jako remoting endpoint pro Flex. Dále u konkrétní metody, která má být zpřístupněna je třeba59 dát anotaci @RemotingInclude. 58 http://learn.adobe.com/wiki/display/Flex/Creating+a+BlazeDS+messaging+application+in+Flex+Builder 59 Ve výchozím nastavení jsou všechny metody vystavené, ale pro přehlednost je dobré anotaci uvést. Pokud naopak nechceme některou metodu vystavit, je možné přidat anotaci @RemotingExclude ▪ 108 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 HelloWorldService.java package bp.spring.example; import org.springframework.flex.remoting.RemotingDestination; import org.springframework.flex.remoting.RemotingInclude; import org.springframework.stereotype.Service; @Service @RemotingDestination public class HelloWorldService { @RemotingInclude public String sayHello(String name) { return "Ahoj, " + name; } } V tuto chvíli máme na straně serveru vše přípraveno pro Flex klienta. Zbývá ukázka Flex aplikace, která službu HelloWorldService zavolá. HelloWorldServiceApp.mxml <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Declarations> <s:RemoteObject id="ro" destination="helloWorldService" endpoint="http://localhost:8080/flexspring/messagebroker/amf"/> </fx:Declarations> <s:layout><s:VerticalLayout/></s:layout> <s:TextInput id="t"/> <s:Button label="sayHello" click="ro.sayHello(t.text)"/> <s:Label text="{ro.sayHello.lastResult}"/> </s:Application> Protože bylo použito anotace @RemotingDestination, je služba dostupná pro RemoteObject volání pod destination helloWorldService. Tento název je automaticky vytvořen z názvu třídy služby HelloWorldService . Vlastnost endpoint odkazuje na standardní AMF endpoint. V případě, že bychom použili službu, která bude jako vstupní parametry nebo návratovou hodnotu používat jiné než primitivní typy, je třeba na straně Flexu i v Javě připravit value objekty (VO). VO jsou jednoduché třídy, které neobsahují žádnou logiku, pouze vlastnosti a případně settery/gettery. Aby byla funkční automatická konverze typů, je třeba aby třídy na obou stranách byly totožné. Dále musí existovat v Javě bezparametrický konstruktor60. A na straně AS3 musí být na třídě anotace RemoteClass61 60 Nemusí být ve třídě přímo uveden, pokud třída nemá žádný další konstruktor, protože je použit automaticky. Pokud ale má třída další konstruktory s parametry, pak je nutné uvést i bezparametrický. 61 použití: [RemoteClass(alias=”bp.spring.example.Person”)], kde daná třída v uvozovkách reprezentuje ▪ 109 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Answer.as package bp.model.vo { [Bindable] [RemoteClass(alias='flex.drivingschool.vo.Answer')] public class Answer { public var id:String; public var text:String; public var correct:Boolean; public var selected:Boolean; public var question:Question; } } Protějšek anotované třídy na straně Javy: Answer.java package flex.drivingschool.vo; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; public class Answer { public Answer() {} public public public public String id; String text; Boolean correct; Boolean selected; } ▪ 110 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 19. HIBERNATE PRO DATOVOU VRSTVU První dvě vrstvy, tj. prezentační a vrstvu obchodní logiky, jsme si už popsali. Zbývá vrstva poslední a tou je perzistence. Předchozí dvě nám zajišťují samotnou funkčnost a interakci s uživatelem. Jedná se vždy o nějakou práci s daty a zobrazování dat v určitém formátu, určité podobě a získávání dat od uživatele. Data jsou základem celé aplikace, a proto je nutné je nějakým způsobem ukládat. Na aplikačním serveru a na klientu se s daty pracuje pouze v operační paměti, proto nejsou nikde uchována při restartu PC nebo serveru. O tuto důležitou činnost se stará právě vrstva perzistenční. Ta zajišťuje uložení dat tak, aby je bylo možné používat v momentě, kdy jsou potřebná. Perzistence může probíhat mnoha způsoby, od uložení do flat file až po ukládání do databáze. Pokud se zamyslíme, je pochopitelně důležitější mít data uložena v takové podobě, aby bylo možné s nimi jednoduše pracovat, jednoduše vyhledávat ta data, která potřebujeme, možnost data jednoduše modifikovat, mazat, přidávat. Nad daty tedy provádět základní CRUD operace. K tomu pochopitelně není vhodná metoda ukládání do flat file, ale ukládání do databáze. Databází můžeme použít několik druhů. Máme databáze objektové, relační, kombinované. Všechny varianty mají své klady i zápory. Objektové databáze umí jednoduše perzistovat celé objektové grafy, ale stále nejsou dostatečně rozšířené. Relační databáze jsou sice starší a nejsou zcela vhodné pro ukládáni objektových struktur, nicméně existují způsoby, jak mapovat objekty do relační struktury, tzv. ORM. V práci se omezím pouze na popis ukládání do relační databáze H2 62 prostřednictvím frameworku Hibernate63. 19.1. Modelování datových entit Pokud vytváříme strukturu tabulek v relační databázi je nutné si v prvním kroku rozmyslet, jaké datové entity (tabulky) budeme chtít vytvořit a popsat je. Popisem rozumějme seznam atributů tabulky (sloupečků). Mapování objektů je pak možné podle pravidla, že co tabulka, to třída. Co sloupec v tabulce, to atribut v třídě. A co řádek v tabulce to konkrétní perzistovaný objekt/instance dané třídy. Mapování je možné nastavovat ručně konfigurací Hibernate nebo nechat možnost vytvoření db schematu na frameworku. V příkladech představuji druhou variantu, protože je jednodušší. 62 http://www.h2database.com 63 http://www.hibernate.org/ ▪ 111 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Protože necháme mapování na frameworku můžeme entity modelovat jako klasické třídy, např. pomocí nástroje Enterprise Architect od Sparx. Entity nejsou v tomto případě nic jiného než value objekty o kterých jsme hovořili v kapitole Ukázka jednoduché Java služby pomocí BlazeDS. Pro oddělení způsobu připojení k datové vrstvě a zprostředkování základních CRUD operací nad entitou je možné použít DAO objekty. Ten zajiš'tuje abstraktní mezivrstvu a tím i vyšší přepoužití aplikace bez závislosti nad konkrétní implementací datové vrstvy. V našem příkladu ale s DAO objekty nepracujeme. 19.2. Spring a Hibernate Zaměříme se nyní na popis konfigurace propojení Springu s Hibernate. Pokud navážeme na předchozí ukázku applicationContext.xml, je potřeba přidat do tohoto souboru definici – – – dataSource – vytváří databázové připojení sessionFactory – řídí Hibernate Session transactionManager – prostřednictvím sessionFactory řídí transakce applicationContext.xml – nové sekce pro perzistenci <tx:annotation-driven /> <bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource"> <property name="driverClassName"><value>org.h2.Driver</value> </property> <property name="url"><value>jdbc:h2:~/bp</value></property> <property name="username"><value>sa</value></property> <property name="password"><value></value></property> <property name="autoCommit"><value>true</value> </property> <property name="suppressClose"><value>true</value></property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFac toryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="flex" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect </prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> ▪ 112 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Zde lehce nastíním, co je v souboru zajímavé. V dataSource je bp název databáze, která bude vytvořena v domovském adresáři uživatele, pod kterým běží Servlet Container. V sessionFactory je definováno, že budou hledány anotované entity v balíku flex. Dále, že se schéma bude vytvářet automaticky a také automaticky aktualizovat (hbm2dll.auto) a zobrazovat v logu SQL dotazy. 19.3. Entity Teď si ukážeme, jak bude vypadat třída Answer, kterou jsme si již ukazovali, pokud ji budeme chtít perzistovat. Answer.java – persistent entity package flex.drivingschool.vo; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Answer { public Answer() {} @Id @GeneratedValue public String id; public String text; public Boolean correct; public Boolean selected; } Oproti původní třídě jsou zde navíc anotace. @Entity zajistí, že je viditelná pro Hibernate, @Id musí být uvedena u vlastnosti, která udává databázové id záznamu a @GeneratedValue zajistí generování id automaticky. Takto anotovaná entita je v databázi automaticky vytvořena po startu Servlet Containeru. 19.4. Perzistentní služby A nakonec si ukážeme jak bude vypadat služba, která bude naší entitu Answer perzistovat. Protože se jedná o perzistentní službu, je místo @Service anotace @Repository, která povoluje připojení se k dataSource. @Autowired u sessionFactory zajistí Springem automatickou setter injection. A konečně anotace @Transactional u metody saveAnswer() zajistí zabalení dotazu do transakce. ▪ 113 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 package flex.drivingschool.service; import java.util.ArrayList; import java.util.List; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.flex.remoting.RemotingDestination; import org.springframework.flex.remoting.RemotingInclude; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import flex.drivingschool.vo.Answer; import flex.drivingschool.vo.DrivingTest; import flex.drivingschool.vo.Evaluation; import flex.drivingschool.vo.Question; @Repository @RemotingDestination public class DrivingSchoolService { private SessionFactory sessionFactory; @Autowired public void setSessionFactory(SessionFactory factory) { sessionFactory = factory; } @RemotingInclude @Transactional public void saveAnswer(Answer answer) { sessionFactory.getCurrentSession().save(answer); } } 19.5. Administrace H2 databáze Ještě je důležité popsat jednu věc a to jak se připojit do H2 databáze bp. H2 databáze má integrovánu webovou konzoli64 na správu prostřednictvím Servletu. Pro zapnutí konzole je potřeba do web.xml přidat následující: 64 http://www.h2database.com/html/quickstart.html ▪ 114 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 web.xml – H2 web console <servlet> <servlet-name>H2Console</servlet-name> <servlet-class>org.h2.server.web.WebServlet</servlet-class> <init-param> <param-name>webAllowOthers</param-name> <param-value></param-value> </init-param> <init-param> <param-name>trace</param-name> <param-value></param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>H2Console</servlet-name> <url-pattern>/console/*</url-pattern> </servlet-mapping> Konzole pak bude přístupná na adrese65, která odpovídá kontextu na aplikačním serveru. Obrázek 31: Konzole H2 databáze 65 V mém případě se jedná o http://localhost:8080/flexspring/console/ ▪ 115 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 32: Konzole H2 databáze po příhlášení ▪ 116 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 20. BUILD POMOCÍ MAVENU V této kapitole bych se rád stručně zmínil o možnosti využití externího nástroje Maven pro building. Nebudu zde popisovat Maven jako takový, jen bych rád nastínil, k čemu je takový nástroj dobrý a odkázal na vhodné zdroje. 20.1. V čem je dobrý nástroj typu Maven U větších projektů, které se skládají z většího množství podprojektů (v našem případě Java a Flex projektů) a dohromady tvoří jeden SW celek, je vhodné mít k dispozici nástroj pro automatický building, verzování, testování a nasazení (deployment). Existuje více takových nástrojů, např. z Unixů je známý Make, dále např. Ant a dnes častěji používaný Maven. Maven nabízí všechny výše zmíněné vlastnosti, a tím umožňuje vlastně řídit projekt jako takový. Umí projekt buildovat, definovat verze, spouštět automatizované testy, vytvářet balíky vhodné pro nasazení. Navíc je modulární, proto podporuje funkce externích dodavatelů. Maven také umožňuje velice šikovnou vlastnost, a tou je spolupráce s externími repositáři, tzv. Artifactory. Pomocí konfiguračních souborů je možné nastavit, kde jsou repozitáře umístěny a jaké jsou závislosti mezi projekty a knihovnami. Maven si pak umí závislosti sám seřadit a z Artifactory si stáhnout potřebné knihovny pro překlad. Tyto knihovny Maven ukládá do lokálního repository. 20.2. Jak Maven použít Abychom mohli Maven využívat, je třeba jej nainstalovat 66 a nakonfigurovat. Instalace je velice jednoduchá. Protože se jedná se o Java aplikaci, je nutné mít nejprve nainstalovaný JRE. Pak již stačí extrahovat ZIP soubor se staženým Mavenem do vhodného adresáře a nastavit několik systémových proměnných67. Maven se konfiguruje prostřednictvím souboru settings.xml (repo, proxy, artifactory) a jednotlivé projekty, které má mít Maven řídit, pak pomocí pom.xml souborů, které jsou umístěny přímo v rootu projektu. V POM68 (Project Object Model) souborech jsou definovány potřebné informace o projektu, tj. název projektu, závislosti mezi projekty, verze, přídavné pluginy apod. Ve 66 http://maven.apache.org/download.html 67 M2_HOME, M2, MAVEN_OPTS – více o parametrech na stránkách Apache. 68 Project Object Model ▪ 117 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Flash Builder/Eclipse editoru není přímá podpora pro Maven, ale je možné stáhnout a nainstalovat plugin m2eclipse69 Do souboru settings.xml není třeba zasahovat, pokud máme přímý přístup do internetu a nechceme lokální Artifactory. V opačném případě je možné využít pro nastavení proxy a přístupů na Artifactory. Soubor je dobře komentovaný, proto není nutné jej blíže popisovat. Maven ve své standardní instalované podobě nemá podporu pro Flex, ale existuje samostatný projekt FlexMojos, který podporu přidává. Pro více informací o FlexMojos odkazuji přímo na dokumentaci70. Pro nastavení projektů a závislostí slouží POM soubory, jak jsme si již naznačili. Tyto soubory jsou ve formátu XML a na ukázku uvedu jednoduchý příklad. pom.xml <project> <modelVersion>4.0.0</modelVersion> <groupId>bp.example</groupId> <artifactId>my-app</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>bp.example</groupId> <artifactId>my-dep-app</artifactId> <version>1.1.0</version> </dependency> </dependencies> </project> POM soubor popisuje projekt s názvem my-app, který je ve verzi 1.0.0 a patří do skupiny bp.example. Tento projekt závisí na projektu s názvem my-dep-app ve verzi 1.1.0. Maven ovládáme příkazem mvn. Pokud bychom např. chtěli projekt přeložit a výsledné binárky uložit do lokálního repository, použijeme mvn clean install. 69 http://m2eclipse.sonatype.org/ 70 http://flexmojos.sonatype.org/getting-started. ▪ 118 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 21. POSTUP PŘI NÁVRHU APLIKACE 21.1. Zadání aplikace „Autoškola“ Jako součást práce jsem vytvořil aplikaci jež má demonstrovat funkce, které jsem v práci popsal. Od vytvoření obrazovek, modelu, přes propojení s frameworkem Cairngorm, po vytvoření služeb na straně Javy, zpřístupnění prostřednictvím BlazeDS a Springu a napojení na H2 databázi. Aplikace Autoškola je založena na testovacích otázkách z dopravních předpisů. Cílem aplikace je umožnit uživateli poskytnout zkušební testy v podobě, v jaké jsou k dispozici při skládání zkoušky na řidičský průkaz. Aplikace pracuje ve dvou režimech – výukový a testovací. Ve výukovém režimu je možné procházet náhodné otázky a pokusně volit odpověďi. Aplikace uživatele ihned informuje o tom, zda odpověděl na otázku správně nebo chybně. V testovacím režimu již má seznam 25 otázek celkově za 50 bodů a časové omezení 30 minut. Po vyplnění testu nebo vypršení časového limitu jsou výsledky vyhodnoceny. Aplikace také nabízí možnost jednoduché administrace, přes kterou jsem otázky a testy vytvářel. Při administraci jsou otázky a testy zasílány na server, kde jsou prostřednictvím perzistentních služeb ukládány do databáze. V režimu výuky a testování jsou naopak z databáze nahrávány. 21.2. Analýza V této fázi je důležité ujasnit si základní případy užití. V našem případě to je administrace otázek a testů, zkušební testy a výuka. Uživatelé systému • Student – Má možnost spouštět výuku a zkušební testy. Typicky se jedná o žáka autoškoly, který se připravuje na zkoušku. • Administrátor – Má stejná práva jako Student a navíc možnost vytvářet otázky a zkušební testy. ▪ 119 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 33: Případy užití aplikace Autoškola Případ užití 1: Tvorba otázek a testů Stručný popis Uživatel má možnost administrace, tj. přidávat nové otázky do databáze a vytvářet zkušební testy Podmínky spuštění Případ užití může spouštět uživatel s rolí Administrátor Výstupní podmínky Vytvoření nové otázky nebo testu Základní tok 1. Uživatel vyplní data otázky (otázka, odpovědi, bodového ohodnocení a obrázku) nebo zkušebního testu (vybere otázky pro vytvoření testu a zadá název testu) a potvrdí akci uložit. 2. Systém data uloží do databáze. 3. Uživatel pokračuje v kroku 1 nebo končí. ▪ 120 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Případ užití 2: Výuka Stručný popis Uživatel má možnost procházet náhodné otázky a zjišťovat správnou odpověď. Podmínky spuštění V systému již musí být založeny nějaké otázky Výstupní podmínky Žádné Základní tok 1. 2. 3. 4. Systém zobrazí po spuštění výuky uživateli náhodnou otázku. Uživatel vybere jednu z odpovědí dle své volby. Systém uživateli zobrazí informaci o správnosti odpověďi. Uživatel má možnost svou odpověď změnit (následuje krok 3) nebo pokračovat na další otázku (následuje krok 1). Případ užití 3: Zkušební test Stručný popis Uživatel má seznam otázek, kterými může listovat a libovolně odpovídat. Po časové lhůtě nebo po uživatelské akci jsou otázky vyhodnoceny a uživatel se dozví výsledek testu. Podmínky spuštění V systému již musí být založeny nějaké testy Výstupní podmínky Hodnocení testu Základní tok 1. Systém zobrazí 25 otázek celkem za 50 bodů. 2. Uživatel postupně listuje otázkami a vybírá odpovědi dle uvážení. Po odpovězení otázek odešle otázky na vyhodnocení. 3. Systém zobrazí uživateli vyhodnocení testu a pokračuje bodem 1. Alternativní tok 1. Systém zobrazí 25 otázek celkem za 50 bodů. 2. Uživateli se nepodaří odeslat otázky k vyhodnocení do 30 minut. 3. Systém automaticky provede vyhodnocení odpovědí. ▪ 121 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 21.3. Architektura Architektura aplikace se skládá ze třech základních vrstev. Klientskou vrstvru tvoří klientská část aplikace, která je implementována ve Flexu. Společně s Flex frameworkem je použit ještě Cairngorm pro MVC. Runtime prostředí je Flash Player, alternativně by mohl být také AIR. Klientská vrstva komunikuje s vrstvou obchodní logiky přes AMF protokol, který je zapouzdřený v HTTP protokolu. Vrstva obchodní logiky je již na Tomcat serveru, což je Java Servlet container. Pro komunikaci mezi Flexem a Javou je na serveru framework BlazeDS. Spring je použit pro obecně lepší integraci s obchodní logikou. Dále je prostřednictvím O/R mapování propojena vrstva obchodní logiky a databázová vrstva, k tomu zde slouží framework Hibernate, který je konfigurovaný pomocí Springu. Data jsou perzistována do databáze H2. Obrázek 34: Architektura aplikace ▪ 122 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 21.4. Návrh a implementace Flexových komponent Aplikace jsem rozdělil na několik částí. Hlavní aplikace MainApp se skládá z loga, hlavního menu a ComboBoxu pro výběr jazyku. Aby byla aplikace použitelné také na menším rozlišení, přidal jsem vertikální scrollbar. V aplikaci jsem se rozhodl vytvořit přepoužitelnou komponentu QuestionComponent s rozhraním Question. která řeší zobrazení otázky se seznamem odpovědí. Důvodem je použití komponenty v obrazovce pro výuku, ale také v obrazovce testu. Obrazovka pro výuku má krom této komponenty ještě tlačítko následující otázky a zobrazení stavu, jak student na otázku odpověděl. V obrazovce testu je krom komponenty také progress bar, určující délku trvání testu, dále název testu společně s číslem aktuální otázky a také jejího bodového ohodnocení. Pod komponentou jsou tlačítka pro start nového testu, přechody mezi otázkami a tlačítko pro vyhodnocení testu. Následují obrazovky pro administraci. První je obrazovka nové otázky, kde je formulář s otázkou, odpověďmi, bodovým ohodnocením a číslem obrázku, pokud jej otázka obsahuje 71. Obrázky jsou součástí Flexového projektu v adresáři assets, jejich názvy jsou číselné. V administraci není řešeno nahrávání obrázků. Druhá obrazovka řeší tvorbu nového testu, kde z jedné tabulky je možné označit otázky a přesouvat je do tabulky druhé a test pojmenovat. Poslední obrazovka je pouze pro zobrazení otázek z vybraného testu. Při návrhu větší aplikace bych doporučil věnovat fázi analýzy a designu dostatečný čas a rozdělit jednotlivé obrazovky na přepoužitelné části. Z nich pak vytvořit samostatné komponenty s jasně definovaných rozhraním. Pro návrh obrazovek je vhodné použít nějaký nástroj. Mě se osvědčil Balsamiq 72, ve kterém jsem obrazovky tvořil. V základní verzi je k dispozici zdarma, je naprogramovaný v Adobe AIR a je určen přímo na vývoj Flex projektů, takže jsou k dispozici všechny standardní Flexové komponenty. Pokud se rozhodneme navrhnout nějakou komponentu tak, aby byla použitá ve více variantách, je dle mého názoru třeba zvážit, zda nevyužít možnosti definování stavů a přechodů, které Flex nabízí. Je třeba si ale dávat pozor, aby nebyly stavy zneužity za účelem úpravy komponenty pro použití komponenty z různých míst aplikace vždy s jistou modifikací. Tím se stává komponenta nepřehledná a složitá, údržba takové komponenty je pak nepraktická. Lepší je komponentu rozdělit na menší samostatné části. 71 Pokud neobsahuje, vyplňí se hodnota 0. 72 http://balsamiq.com ▪ 123 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 36: Návrh komponenty Otázka Obrázek 35: Návrh hlavní aplikace Obrázek 37: Návrh obrazovky Výuka Obrázek 38: Návrh obrazovky Test Obrázek 39: Návrh obrazovky Vytvořit otázku Obrázek 40: Návrh obrazovky Vytvořit test Obrázek 41: Návrh obrazovky Zobrazit testy ▪ 124 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 21.5. Návrh a implementace modelu V našem příkladu je použit princip ModelLocatoru, tj. singleton modelu, který je využit pro binding na view a přístupný z commandů pro úpravy modelu. Model aplikace Autoškola obsahuje atributy pro celkový čas testu, aktualní otázku, aktuální test, seznam všech otázek, seznam všech odpovědí a timer. Při návrhu je třeba vycházet z doménového modelu, potažmo class diagramu, tj. v tomto případě value objekty, které mají vzájemné vztahy. V souvislosti s view je třeba se zamyslet, jak by měl vypadat binding, co za objekty budeme potřebovat, abychom byli schopni předat data pomocí bindingu na komponenty a obrazovky a zároveň tato data budeme potřebovat mít dostupná také z commandů, např. pro účely plnění návratové hodnoty z volání serverové služby. Z toho nám postupně vznikne samotný model (myšleno ModelLocator, nikoliv seznam všech tříd). Protože value objekty je potřeba tvořit jak na straně Flexu tak na straně Javy, je vhodné použít nějaký UML nástroj na generování kódu z class diagramu. Enterprise Architect podporuje UML class diagram společně s možností generovat zdrojový kód jak do AS3, tak do Javy. Pochopitelně je pak nutné přidat potřebné anotace. Další možností je upravit v EA generovací šablony pro konkrétní potřeby projektu. Obrázek 42: Class diagram programu Autoškola 21.6. Návrh a implementace vzdálených služeb U služeb je třeba si stanovit nejdříve, jaké služby budeme chtít klientovi poskytovat a následně jaké budou mít rozhraní. Až budeme mít v tomto ohledu jasno, je možné se pustit do implementace. Služby je možné dělit dle účelu, a to na perzistentní, služby obchodní logiky, atd. V aplikaci ▪ 125 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Autoškola jsou všechny metody perzistentní služby v třídě DrivingSchoolService a obchodní logika v službě EvaluationService. Obě služby implementují příslušné rozhraní. Obrázek 43: Rozhraní služeb IDrivingSchoolService obsahuje metody pro vytvoření testu, otázky, načtení všech testů, všech otázek, náhodného testu a náhodné otázky. Dále setter pro nastavení sessionFactory ze Springu. Obchodní logiku reprezentuje rozhraní IEvaluationService se svou metodou pro vyhodnocení testu. 21.7. Návrh a implementace datové vrstvy Pro datovou vrstvu byla zvolena kombinace Spring, Hibernate, H2. Protože je použita konfigurace automatického generovaní schema databáze, je třeba pouze specifikovat, jaké perzistentní služby budou vystaveny příslušnými anotacemi a mít anotované value objekty jako entity, v našem případě to jsou Answer, DrivingTest a Question. Jak již jsem zmínil v předhozím bodu, perzistetní služba v aplikaci Autoškola je v třídě DrivingSchoolServis a uvnitř se nachází metody pro perzistenci příslušných value objektů (nebo-li datových entit). 21.8. Finální aplikace Aplikace je k dispozici v přiloženém CD. Aplikace se skládá ze dvou projektů. První projekt bpautoskola obsahuje Flexovou aplikaci. Druhý projekt flexspring obsahuje vrstvu obchodní logiky a napojení na perzistenci. Celý kód je kompletně okomentovaný, tudíž by mělo být zřejmé, co která část vykonává. Třídy jsou přehledně rozděleny do příslušných balíků (commandy, události, value objekty, item renderery, skiny, vizuální komponenty a pomocné utility). ▪ 126 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 22. POROVNÁNÍ FLEXU S DALŠÍMI TECHNOLOGIEMI Flex není jediná technologie pro psaní RIA, a proto několik podobných technologií v této kapitole popíši. Nutno podotknout, že technologie Flex má před konkurenty několikaletý náskok. Konkurencí Adobe jsou ale poměrně silní hráči, kteří se s největší pravděpodobností chtějí dostat do vedení v dohledné době, protože současné možnosti vývoje webových aplikací jsou stále trochu omezené a společnosti i vývojáři vítají technologie a frameworky, které zjednoduší vývoj RIA. Přímými konkurenty Flexu jsou společnosti Sun, dnes již Oracle, Microsoft, ale také specifikace jazyka HTML ve verzi 5, který je navrhován organizací W3C. Společnost Oracle, která je vlastníkem programovacího jazyka Java, přichází s technologií JavaFX. Microsoft nabízí technologii Silverlight. Blíže rozdíly popíšu v následujících kapitolách. 22.1. Flex a Silverlight První vydání Flexu bylo v roce 2004 od společnosti Macromedia. Od té doby Flex urazil poměrně dlouhou cestu. První vydání Silverlight bylo v roce 2007 pod označením Windows Presentation Foundation/Everywhere (WPF/E). To je zřejmě hlavní důvod, proč má Flex jistý náskok. Společnosti Microsoft se ale snaží tento náskok srazit a navíc nabízí některé funkce, které Flex nemá a asi ani nikdy mít nebude. Nyní je Silverlight ve verzi 4 a tento rok se očekává verze 5, která bude nabízet např. podporu 64-bitových systémů, vylepšenou podporu DRM a zlepšení rychlosti startu aplikace. Výhodou Silverlightu je to, že z Flexu si bere to dobré a k tomu přidává zajímavé vlastnosti a provázání s .NET. Tak například Flex využívá k psaní aplikací AS3 a MXML. Podobně Silverlight nabízí C# a deklarativní programovací jazyk XAML pro definici uživatelského rozhraní. Další zajímavostí Silverlightu je, že aplikace může být psaná jak na straně klienta tak na serveru a to ve stejném jazyce. Flex je pouze client-based a na straně serveru není možné psát v AS3, ale využít jiných technologií určených pro server-side, např. zmiňovaná Java. Silverlight má oproti Flexu nativní podporu multi-threading na klientovi, Flash Player nativní multithreading zatím nepodporuje, ale již je v plánu. Výhodna na straně Flexu je rozšířenost Flash Playeru, která je vyšší než u Silverlightu. Flex má také podporu na více backend technologiích, např. Java, PHP, ColdFusion a pro komunikaci nabízí binární protokol AMF, který přenáší celé objekty v komprimované formě. Flex je také spojen s desktopovou technologií AIR (vyžaduje ovšem samostatně instalovaný ▪ 127 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 runtime), oproti tomu Silverlight je svázán s prohlížečem a všemi bezpečnostními omezeními s ním spojeným. Osobně jsem psát v Silverlightu žádné větší aplikace nezkoušel. S technologií Silverlight jsem se před cca 3 lety seznamoval a v té době byla pro produkční použití oproti Flexu nepoužitelná. Ale situace se od té doby velice změnila, vyšlo několik nových major verzí. Na internetovém serveru StackOwerflow jsem nalezl příspěvek, kde je nezávislé srovnání pracnosti vývoje a porovnání obou technologií. “I can tell you from direct experience that Flex is a more productive platform. I work for a large RIA consultancy that builds a large number of apps with both Flex and Silverlight and we see that equivalent functionality in SL takes about 10-20% longer to develop than in Flex. Data binding support in Flex is significantly easier to use than in SL. I can also tell you that a suitablyexperienced Flex developer could easily build a MDI toolkit in Flex with a couple of weeks of development time. So I would advise you to consider hiring experienced Flex developers rather than shelling out money for SL components. SL does have a big advantage in that C# can be used on both the client and server and business logic can be reused in both tiers. This is significant and should not be discounted. ActionScript doesn't have a server-side counterpart and lacks this ability, although Flex does play nicely with a number of different backend technologies, especially Java using BlazeDS. Silverlight services integration has a variety of options on the .NET side (see Bart's comment below) while Flex can use very performant AMF in both RPC and data push (messaging). BlazeDS is free and open source.” (Cliff Meyers) zdroj http://stackoverflow.com/questions/992437/adobe-flex-vs-silverlight Cliff zde zmiňuje, že např. data binding je ve Flexu jednodušší a vývoj stejné aplikace v Silverlight odhaduje o cca 10-20% déle. Flex <mx:Button id="jméno" click="kliknuto(event)" /> private function kliknuto(event: MouseEvent):void { // do your stuff } Silverlight <Button x:Name="jméno" Click="kliknuto" /> private void kliknuto(object sender, RoutedEventArgs e) { // do your stuff } zdroj http://myego.cz/item/adobe-flex-air-versus-microsoft-silverlight ▪ 128 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 22.2. Flex a JavaFX JavaFX je technologie pro vývoj a běh RIA aplikací, podobně jako Silverlight a Flex. Je od společnosti Oracle (dříve Sun) a ke svému běhu potřebuje vlastní JavaFX Runtime. První verze technologie JavaFX byla uvolněna v prosinci roku 2008. Je tedy vidět, že je mladší než Silverlight. Oproti Flexu nabízí možnost aplikaci přesunout z browseru na plochu a spouštět ji jako klasický desktopový program, a to i v módu offline. Stejně jako Flex nabízí např. databinding. • • • • • Květen 2007 – poprvé představen projekt JavaFX veřejnosti na konferenci vývojářů JavaOne Květen 2008 – Sun Microsystems oznámil plán, že do konce roku 2008 uvolní JavaFX pro prohlížeče a desktopy, pro mobilní zařízení *pak na jaře 2009 Od konce července 2008 – možnost náhledu do JavaFX SDK pro Windows a Macintosh, také uvolněn plugin pro IDE Netbeans 6.1 Prosinec 2008 – Sun uvolnil první verzi platformy - JavaFX 1.0 Únor 2009 – JavaFX dostupná také pro mobilní zařízení ve verzi JavaFX 1.1 zdroj http://cs.wikipedia.org/wiki/JavaFX#Historie Protože bohužel s touto technologií nemám žádné praktické zkušenosti, budu citovat Wikipedii, jaké jsou výhody JavaFX. “Platforma byla navržena tak, aby se ti, jež ji používají, mohli soustředit na kreativní část práce namísto kódování. Konkurenční výhodu přináší také přenositelnost mezi platformami - JavaFX koresponduje s heslem „Write once, run anywhere“. To znamená, že aplikace naprogramované na platformě JavaFX můžete spouštět na kterémkoliv prostředí, kde běží JRE (Java Runtime Environment). V současnosti je JavaFX oficiálně plně podporována Windows XP /Vista a MacOS, nicméně brzy se očekává podpora i pro Linux. U mobilních zařízení lze spouštět aplikace na Androidu, systému Windows Mobile a dalších příslušných OS. Další neméně zajímavou vlastností je, že programátoři mohou v rámci JavaFX využívat jakoukoliv třídu napsanou v Javě. Vývoj aplikací je poměrně rychlý a snadný a to díky jazyku JavaFX Script. Mimo jiné nabízí také velmi dobrou podporu pro používání multimediálních prvků, ať už jde o video, audio, animace, atd. Výhodou oproti mnohým podobně cíleným platformám je ochrana zdrojového kódu proti prohlížení ze sítě Internet, která se nevyskytuje např. u AJAXu.” zdroj http://cs.wikipedia.org/wiki/JavaFX JavaFX aplikace se nepíší klasickou Javou ale JavaFX Scriptem. JavaFX Script je staticky typovaný deklarativní skriptovací jazyk, který vnitřně je postaven na Javě. Jeho výhodou je úspora množství psaného kódu, která je prý až pětinásobná. Syntaxe je ▪ 129 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 podobná JavaScriptu a soubory jsou uloženy ve formátu .fx. Pro vývoj aplikací je třeba mít JavaFX SDK a případně Plugin do vývojového nástroje NetBeans Syntaxe je podobná jako v JavaScriptu var myVar:String = „value“; Binding var text1 = „text1“; let text2 = bind text1; System.out.println(text2); text1 = „novy text“; System.out.println(text2); // vypíše „text1“ // vypíše „novy text ukázka úspory kódu Alternativa 1 import javafx.ext.swing.*; SwingFrame { title: "Hello world“; width: 100; height: 50; content: Label { text: " Hello world "; } visible: true; } Alternativa 2: import javafx.ext.swing.*; var myFrame:SwingFrame = new SwingFrame(); var myLabel:Label = new Label(); myLabel.text = "Hello World!"; myFrame.width = 200; myFrame.height = 50; myFrame.visible = true; myFrame.content = myLabel; příklady zdroj http://cs.wikipedia.org/wiki/JavaFX ▪ 130 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 22.3. Flex a HTML5 HTML5 jako jediné není komerčním produktem, ale je tvořeno organizací W3C. V současné době HTML5 ještě není kompletně specifikováno. Přesto části, které již jsou specifikovány, mají podporu v řadě prohlížečích jako Firefox, Internet Explorer a Safari. Multimediální obsah na webu je dnes doménou především Adobe Flash Playeru. HTML5 bude mít podporu audio a video elementů, což bude znamenat, že bude možné přímo vkládat mediální obsah pomocí HTML bez potřeby pluginů. <video src=""></video> <audio src=""></audio> <video> <source src="video.3gp" type="video/3gpp" media="handheld"> <source src="video.mp4" type="video/mp4"> </video> <audio> <source src="music.oga" type="audio/ogg"> <source src="music.mp3" type="audio/mpeg"> </audio> Dále je možné využít Canvas pro přímé renderování obrázků a vektorové grafiky a vytváření jednoduchých animací. HTML5 nově nabízí práci offline, tzv. offline data storage. Využitelná bude databáze, ve které může uživatel manipulovat s daty, i když není online a jakmile dojde k připojení, data jsou synchronizována se serverem. Zlepšila se také práce s formuláři. V předchozích verzí vstupní pole Input nemělo možnost definovat typ. Nově je přidán tento atribut a tím i celá řada vstupních polí. ▪ 131 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 <form action=""> <input type="datetime" name="" value=""> <input type="date" name="" value=""> <input type="month" name="" value=""> <input type="week" name="" value=""> <input type="time" name="" value=""> <input type="number" name="" value=""> <input type="range" name="" value=""> <input type="email" name="" value=""> <input type="url" name="" value=""> <input type="search" name="" value=""> <input type="color" name="" value=""> </form> • • • • • • • • • • • datetime – reprezentuje datum a čas date – datum month – měsíc week – týden time – čas number - číslo range – rozsah číselných hodnot, které se nastaví parametry min a max email – pole pro zadání e-mailové adresy včetně ověření, zda je formát správný url – URL adresa search – vyhledávací políčko color – pole s výběrem barvy a převedením do jejího textového formátu Struktura se oproti HTML4 změnila ve zjednodušení definice DOCTYPE a v kódování dokumentu. <!DOCTYPE html> <html lang="cs-cz" dir="ltr"> <head> <meta charset="UTF-8"> <title>Titulek stránky</title> </head> <body> </body> </html> zdroje: http://bexhuff.com/2009/06/html-5-versus-flash-flex http://cs.wikipedia.org/wiki/HTML5 ▪ 132 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Celkově velkou výhodou HTML5 je otevřený standard nezávislý na konkrétní společnosti a navazující na předchozí verzi HTML4. Má velkou šanci se prosadit ve velkém měřítku a předčit komerční technologie. Nevýhodou je zatím nedokončená specifikace a možnost implementace v různých prohlížečích různým způsobem. ▪ 133 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 23. ZÁVĚR V práci jsem si kladl za cíl představit Flex především na praktických příkladech a ukázat jej v kontextu s jinými technologiemi a frameworky. Na názorných příkladech jsem ukázal důležité vlastnosti a způsoby použití, tak aby byla pro čtenáře pochopitelná finální aplikace Autoškola. Ta demonstruje použití Flexu v kontextu jeho možného využití. Dále jsem chtěl představit i jiné technologie pro tvorbu RIA a jejich rozdíly oproti Flexu, zmínit výhody a nevýhody. Z přehledu technologií je patrné, že všechny se snaží jít směrem zjednodušit vývojářům práci a zefektivnit způsob vytváření RIA. Každá firma využívá své přednosti a stávající technologie k prosazení té své. U Silverlight je to integrace s .NET a sázka na jazyk C#. JavaFX je postavená na Javě a nabízí skriptovací jazyk pro jednodušší zápis. Všechny technologie jdou mnohem více směrem k multimédiím a komponentnímu vývoji s využitím data bindingů. Z vlastní zkušenosti bych chtěl říct, že jsem se při práci s Flexem setkal s celou řadou problémů. Pro úplnost zmíním alespoň některé. Jeden z problémů Flexu, nebo spíš AS3 je, že nepodporuje datový typ Enum. Pro integraci s existující obchodní logikou postavenou na Javě to může být poměrně velká komplikace. Tento problém se mi podařilo řešit vytvořením vlastních enum implementací na straně Flexu a registrace použitých enumů pomocí EnumProxy obsaženého v BlazeDS na straně serveru. Dále jsem narazil na potíže s přenosem hodnot NaN a null u číselných typů mezi Javou a Flexem. BlazeDS tyto hodnoty konvertuje na hodnotu 0. Situaci jsem vyřešil vytvořením vlastního marshalleru73. Potíže jsem zaznamenal i se samotným Flash Builderem. Při práci s menším množstvím projektů se chová poměrně stabilně, ale při práci na větší aplikaci není příliš stabilní vizuální editor. Buď je práce s ním velice pomalá nebo zapříčiní pád celého editoru. U projektů, které vyžadují používat pluginy m2eclipse, FlexMojos a WTP jsem zaznamenal problémy s memmory-leak při častých překladech, což pramení v opakované každodenní pády Flash Builderu / Eclipse. Za slabou stránku Flexu také považuju fakt, že bezpečnost Flash Playeru není na takové úrovni, jaké bych očekával. Zde vycházím především z analýzy frekvence vydávaných záplat na kritické chyby. Nemohu jednoznačně říci, která z popsaných technologií je nejlepší, protože každá má své výhody i nevýhody. Z mého pohledu i přes všechny výhody ostatních technologií a nevýhody Flexu, které jsem zmínil ve své práci, je zatím na trhu nejdále Flex, a to především kvůli brzskému nástupu v roce 2004 a rozšířenosti Flash Playeru. Ostatní technologie jej však rychle dohánějí. 73 http://flexblog.faratasystems.com/category/blazeds ▪ 134 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Myslím, že bude velice zajímavé sledovat, jakým směrem se RIA aplikace budou v následujících letech vyvíjet. Věřím, že trend bude patřit W3C specifikaci HTML5, pokud si vezme příklad ze současných možností komerčních technologií, a pokud se ji podaří interpretovat ve všech prohlížečích ve „stejném duchu“. ▪ 135 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 24. CONCLUSION It has been my intention to present the Flex technology in my work using practical examples and show it in the context with other technologies and frameworks. In illustrative examples, I turned the attention to its important properties and modes of application, where the Driving School Programme has been given for better understanding of the readers. This programme demonstrates the Flex use in the context of its potential applications. Furthermore, it was my intention to present other technologies used for the RIA creation and explain how they differ from Flex together with their advantages and shortcomings. It is evident, from the technology survey that all of them try to follow the trend of making the developers ' tasks easier and RIA creation process more effective. Each company uses its own assets and existing technologies with the aim of asserting their respective ones. In the case of Silverligth, it is the integration with .NET and relying on the C# language. JavaFX is based on Java and it offers a script language easier for the scripting. In general, all technologies tend, in a greater extent, to multimedia and component development using the data of bindings. From my own experience, I would like to stress many problems I have encountered in my work with Flex. For the sake of completeness, let me mention some at least. One of the problems of Flex – or better say AS3 – is the fact that it does not support the Enum data type. For the integration with the existing commercial logic based on Java, it might pose a rather significant difficulty. I solved this problem successfully by creations of my own Enums by the implementation on the Flex side and registration of the Enums used through EnumProxy contained in BlazeDS on the server side. Furthermore, I encountered difficulties with the transfer of NaN and null at numeric formats between Java and Flex. BlazeDS converts these values to zero (0). I had to solve this situation by creating my own marshaller74. Some problems have been also encountered with Flash Builder itself. In my work with a smaller number of projects, it behaved relatively stably, however the visual editor was stable sufficiently while working with more applications. Either the work was too slow or it caused a collapse of the whole editor. In projects requiring the use of plug-ins, such as m2eclipse, flexmojos and WTP, I noted some problems connected with memory leaks at frequent compilations, which resulted in repeated everyday collapses of Flash Builder / Eclipse. Another weakness of Flex can be seen in the fact that the Flash Player security is not at a level that could be expected. This opinion is supported by the analysis of frequency of issuing of patches for critical errors. 74 http://flexblog.faratasystems.com/category/blazeds ▪ 136 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 In spite of the Flex shortcomings, and advantages of other technologies herein mentioned, the most advanced technology on the market is Flex for the reasons of its early launching in 2004 and Flash Player wide-scale use. Nevertheless, the other technologies are successfully narrowing the gap. In my opinion, it will be very interesting to observe, in which direction the RIA applications will expand during next few years. I believe that the trend will be occupied by W3C, HMTL5 specification, if it takes an example by the current commercial technology possibilities and if it is possible to interpret it in all browsers in the same vein. ▪ 137 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 25. SEZNAM POUŽITÉ LITERATURY 1. Joshua Noble, Todd Anderson, Garth Braithwaite, Marco Casario, Rich Tretola (2010), Flex 4 Cookbook. O'Reilly 2. Filippo di Pisa (2009), Beginning Java and Flex. APress. 3. Chris Giametta (2009), Pro Flex on Spring. APress 4. Eric Pugh, Joseph D. Gradecki (2004), Professional Hibernate. Wrox 5. Flex in Week video training www.adobe.com/devnet/flex/videotraining.html 6. ActionScript3.0 Reference http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/index.html 7. Adobe Flash Builder http://www.adobe.com/products/flash-builder.html 8. Flex SDK Licencing http://opensource.adobe.com/wiki/display/flexsdk/Legal+Stuff 9. Cairngorm http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm 10. FlexMonkey http://www.gorillalogic.com/flexmonkey 11. RefCardz http://refcardz.dzone.com/ 12. LCDS http://www.adobe.com/products/livecycle/dataservices/ 13. Spring BlazeDS integration http://www.springsource.org/spring-flex 14. H2 database http://www.h2database.com 15. Hibernate http://www.hibernate.org/ 16. Maven http://maven.apache.org 17. FlexMojos http://flexmojos.sonatype.org/getting-started 18. JavaFX http://cs.wikipedia.org/wiki/JavaFX 19. Flex vs Silverlight http://myego.cz/item/adobe-flex-air-versus-microsoft-silverlight 20. Flex vs Silverlight http://stackoverflow.com/questions/992437/adobe-flex-vs-silverlight 21. Flex vs HTML5 http://bexhuff.com/2009/06/html-5-versus-flash-flex 22. HTML5 http://cs.wikipedia.org/wiki/HTML5 23. Custom Validators http://flexscript.wordpress.com/2008/09/22/flex-creating-customvalidators/ ▪ 138 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 26. SEZNAM POUŽITÝCH SYMBOLŮ A ZKRATEK Zkratka Popisek RIA Rich Internet Application FTP File Transfer Protocol DNS Domain Name Service HTML HyperText Markup Language PHP HTML-embedded scripting language JSP JavaServer Pages GUI Graphical User Interface SDK Software Development Kit AS3 ActionScript3.0 MXML XML-based user interface markup langage by Micromedia XML eXtensible Markup Language OOP Object-Oriented Programming ECMAScript Scringping Language standardized by Ecma Int. UTF USC Transformation Format FLV Flash Video AIR Adobe AIR runtime MPL Mozilla Public License SWF multimedia file format by Micromedia SWC library package file format by Micromedia FB Flash Builder LCDS LifeCycle Data Services CSS Cascade Style Sheet MVC Model View Controller RGB Red Green Blue TLF Text Layout Framework API Application Programming Interface URL Uniform Resource Locator GC Garbage Collection W3C World Wide Web Consortium FXG Flash XML Graphics SOAP Simple Object Access Protocol HTTP HyperText Transfer Protocol SSL Secure Socket Layer RPC Remote Procedure Call WSDL Web Service Definition Language ▪ 139 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 REST Representational State Transfer VO Value Object DTO Data Transfer Object GNU GNU is Not Unix GPL GNU Public License AMF Action Message Format RTMP Real Time Messaging Protocol EJB Enterprise Java Bean IoC Inversion of Control DI Dependency Injection JMS Java Message Service JPA Java Persistence API WAR Web Archive NIO Non-blocking Input Output CRUD Create Remove Update Delete ORM Object-Relation Mapping H2 H2 database SW Software JRE Java Runtime Environment POM Project Object Model UML Unified Modeling Language EA Sparx Enterprise Architect DRM Digital Rights Management XAML eXtensible Application Markup Language SVN Apache Subversion IDE Integrated Development Environment ▪ 140 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 27. SEZNAM OBRÁZKŮ Seznam ilustrací Obrázek 1: Ukázka spuštěné MXML aplikace (po kliknutí na button)................................18 Obrázek 2: Flash Builder 4.5................................................................................................21 Obrázek 3: Seznam locales v SDK po instalaci Flash Builderu...........................................23 Obrázek 4: Ukázka řazení elementů v display listu.............................................................29 Obrázek 5: ViewStack ukázka přepínání aktivních kontajnerů............................................33 Obrázek 6: Class diagram validátorů...................................................................................38 Obrázek 7: Validace dat........................................................................................................40 Obrázek 8: Class diagram formáterů....................................................................................41 Obrázek 9: Výchozí hodnoty dat před formátováním..........................................................43 Obrázek 10: Zformátované hodnonty...................................................................................43 Obrázek 11: ukázka labelField a labelFunction...................................................................46 Obrázek 12: Item Renderer..................................................................................................48 Obrázek 13: ItemRenderer class diagram............................................................................49 Obrázek 14: Filter function..................................................................................................51 Obrázek 15: Locales.............................................................................................................52 Obrázek 16: Nastavení parametrů překladače pro locales ve Flash Builderu......................52 Obrázek 17: Ukázka lokalizace............................................................................................54 Obrázek 18: Ukázka voleb pro optimalizaci modulu ve Flash Builderu.............................58 Obrázek 19: Ukázka ModuleLoaderu..................................................................................62 Obrázek 20: Ukázka query string.........................................................................................64 Obrázek 21: Propagační fáze událostí..................................................................................65 Obrázek 22: Ukázka MXML komponenta...........................................................................67 Obrázek 23: Cairngorm architektura....................................................................................82 Obrázek 24: FlexMonkey konzole.......................................................................................91 Obrázek 25: Aplikační domény............................................................................................95 Obrázek 26: Komunikace klient – web server.....................................................................96 Obrázek 27: Komunikace mezi Flash Playerem a aplikačním serverem.............................97 Obrázek 28: Závislosti tříd přes IoC....................................................................................98 Obrázek 29: Vlastnosti BlazeDS vs. LCDS.......................................................................102 Obrázek 30: Vrstvy mezi Flex a BlazeDS..........................................................................104 Obrázek 31: Konzole H2 databáze.....................................................................................115 Obrázek 32: Konzole H2 databáze po příhlášení...............................................................116 Obrázek 33: Případy užití aplikace Autoškola...................................................................120 Obrázek 34: Architektura aplikace.....................................................................................122 Obrázek 35: Návrh hlavní aplikace....................................................................................124 Obrázek 36: Návrh komponenty Otázka............................................................................124 Obrázek 37: Návrh obrazovky Výuka................................................................................124 Obrázek 38: Návrh obrazovky Test....................................................................................124 Obrázek 39: Návrh obrazovky Vytvořit otázku..................................................................124 Obrázek 40: Návrh obrazovky Vytvořit test.......................................................................124 ▪ 141 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 41: Návrh obrazovky Zobrazit testy....................................................................124 Obrázek 42: Class diagram programu Autoškola...............................................................125 Obrázek 43: Rozhraní služeb.............................................................................................126 Obrázek 44: Class diagram kontajnerů..............................................................................146 ▪ 142 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 28. SEZNAM TABULEK Seznam tabulek Tabulka 1: AS3 - primitivní datové typy..............................................................................15 Tabulka 2: AS3 - komplexní datové typy.............................................................................15 Tabulka 3: Licence Flex SDK..............................................................................................19 Tabulka 4: Kontajnery a skiny..............................................................................................29 Tabulka 5: Základní layouty.................................................................................................31 Tabulka 6: Události modulu.................................................................................................60 Tabulka 7: Anotace TestCase................................................................................................88 Tabulka 8: Asserty................................................................................................................88 Tabulka 9: Severita chyb......................................................................................................93 Tabulka 10: Seznam kontajnerů.........................................................................................145 Tabulka 11: Validátory........................................................................................................147 Tabulka 12: Formátery.......................................................................................................149 ▪ 143 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 29. SEZNAM PŘÍLOH Příloha 1 – Seznam kontajnerů Obsahuje seznam kontajnerových typů a jejich doplňujících informací Příloha 2 – Validátory Obsahuje seznam všech validátorů Příloha 3 – Formátery Obsahuje seznam všech formáterů Příloha 4 – Ovládací prvky Obsahuje rozšířený seznam ovládacích prvků Příloha 5 – CD Přiložené CD obsahuje • návrhy obrazovek aplikace Autoškola (balsamiq) • diagramy použité v práci (diagramy) • zdrojové kódy aplikace Autoškola (bp-autoskola, flexspring) • zdrojové kódy ukázek (bp) ▪ 144 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 PŘÍLOHA 1 – SEZNAM KONTAJNERŮ Tabulka 10: Seznam kontajnerů Creation policy Container Children Skinnable Scrollable Primary use Group (including HGroup, VGroup, and TileGroup) IVisualElement No As a child of All Scroller Lay out visual children. DataGroup Data Item IVisualElement and DisplayObject No As a child of All Scroller Render and lay out data items. SkinnableContainer IVisualElement Yes By skinning Selectable Lay out visual children in a skinnable container. SkinnablePopUpContainer IVisualElement Yes By skinning Selectable Lay out visual children in a skinnable container opened as a pop up window. SkinnableDataContainer Data item IVisualElement and DisplayObject Yes By skinning Selectable Render and lay out data items in a skinnable container. BorderContainer IVisualElement Yes No Selectable Lay out visual children in a basic container that includes a border. Form IVisualElement Yes Yes Selectable Lay out FormItem and FormHeading children similar to an HTML form. Yes Inherited from By skinning parent container Subclass of SkinnableContainer that can be used as the child of an MX navigator container. By skinning Selectable Subclass of SkinnableContainer that adds a title bar and other visual elements to the container. By skinning Selectable Subclass of Panel that is optimized for use as a pop-up window. NavigatorContent Panel TitleWindow IVisualElement IVisualElement IVisualElement Yes Yes zdroj http://help.adobe.com/ ▪ 145 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 Obrázek 44: Class diagram kontajnerů ▪ 146 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 PŘÍLOHA 2 - VALIDÁTORY Název třídy Popis CreditCardValidator Používá se na ověření čísla kreditních karet, např. o jaký typ karty se jedná (Visa, MC, atd.) CurrencyValidator Validuje částku a to jak zformátovanou, takže např. 1.123,50Kč je validní stejně jako 1123,5 DateValidator Validuje zadaný string na datum, vstupní formát je možné nastavit pomocí inputFormat s použitím znaků „DD“, „MM“ a „YYYY“ EmailValidator EmailValidator validuje, zda je string platná emailová adresa a to ne pouze s doménou za zavináčem, ale také ve formátu myname@[206.132.22.11]. Neumí validovat, zda email existuje. NumberValidator Validuje, zda se string dá převést na číslo daného typu (real, int), zda může být např. záporné, rozmezí, a může být formátované podobně jako CurrencyValidator PhoneNumberValidator Validuje ve výchozím nastavení délku tel. čísla na min. 10 čísel. Tato hodnota se dá nastavit (minDigits), dále jsou platné také formátovací znaky. Neumí validovat, zda číslo aktuálně existuje. RegExpValidator Tento validátor pracuje s regulárním výrazem, který je definován v property „expression“. SocialSecurityValidator Validátor je platný pouze pro US Social Security number. Testuje, zda je formát čísla validní, nedokáže validovat, že je existující. StringValidator Validuje délku stringu, zda je v určitém rozmezí. Pro neomezenou délku je hodnota „NaN“ ZipCodeValidator Validuje poštovní směrovací číslo včetně formátovacích znaků. Je možné explicitně zdat validace pouze pro US, Canadu nebo kombinovat (domain) Tabulka 11: Validátory ▪ 147 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 CustomPersonalNumberValidator.mxml <?xml version="1.0" encoding="utf-8"?> <mx:StringValidator xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Script> <![CDATA[ import mx.validators.ValidationResult; override protected function doValidation(value:Object):Array { var results:Array = super.doValidation(value); var val:String = value ? String(value) : ""; if (results.length > 0 || ((val.length == 0) && !required)) return results; else return personalNumberValidation(val); } // toto je primitivni implementace validace rodneho cisla // skutecna validace je o mnoho slozitejsi private function personalNumberValidation(value:String):Array { var results:Array = []; var re:RegExp = /^[0-9]{6}\/[0-9]{3,4}$/; if (!re.exec(value)) { results.push(new ValidationResult(true, value, "noValidPI", "Personal number is not valid, it has to be in format NNNNNN/NNNN")); } return results; } ]]> </fx:Script> </mx:StringValidator> zdroj: http://flexscript.wordpress.com/2008/09/22/flex-creating-custom-validators/ ▪ 148 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 PŘÍLOHA 3 – FORMÁTERY Tabulka 12: Formátery Název třídy Popis CurrencyFormatter Používá se na formátování částky v dané měně. Je možné používat separátory desetinné čárky, tisíců, přidávat symbol měny před nebo za číslo. DateFormatter Formátuje datum na definovaný formát, za použití vyhrazených znaků. Defaultně je použit formát "MM/DD/YYYY" . Podrobně jsou všechny paterny uvedené v dokumentaci75. NumberFormatter Tento formáter je stejný jako CurrencyFormatter, ale neumožňuje definovat symbol měny PhoneFormatter Formátuje telefonní číslo, přidává např. znaky +, závorky, pomlčky, mezery. ZipCodeFormatter Formátuje PSČ, ale je připraven pouze na US a Kanadskou variantu. Pro formátování českého PSČ je nepoužitelný. 75 http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/formatters/DateFormatter.html ▪ 149 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 PŘÍLOHA 4 - OVLÁDACÍ PRVKY Control Stručný popis MXML a ukázka Button Button, nebo-li tlačítko, je jednoduchý ovládací <s:Button prvek, který umožňuje vyvolat akci stlačením label="Button" „klinkutím“ nebo také stisknutím mezerníku, click="button_clickH pokud je na tlačítku focus. Po stisku tlačítka je andler(event)"/> spuštěna událost (event), která může být zachycena listenerem a zavolána konkrétní akce. Tlačítko je možné skinovat a stylovat. Typicky obsahuje text a případně také obrázek. Checkbox Checkbox je prvek, který graficky zobrazuje <s:CheckBox label="CheckBox" binární hodnotu (vybráno, nevybráno) selected="true"/> ColorPicker ColorPicker je MX komponenta, která umožňuje <mx:ColorPicker selectedColor="0x000 užvateli vybrat si barvu z RGB palety 000"/> ComboBox Jedná se o druh seznamu (listu), který po <s:ComboBox prompt="Vyberte rozkliknutí zobrazí seznam hodnot. Je možná hodnotu"/> definovat také hodnotu vlastní. Zobrazované hodnoty mohou být labely, ale také upravená itemRendererem DataGrid DataGrid je tabulka s daným počtem řádků a sloupců. Typicky je každý řádek objekt a sloupce jeho atributy. Řádky je možné třídit dle sloupců, zarovnávat. Hodnoty mohou být jak textové, tak upravené itemRendererem <fx:Declarations> <s:ArrayList id="dataColl"> <fx:Object field1="aaa" <fx:Object field1="ddd" <fx:Object field1="ggg" <fx:Object field1="jjj" </s:ArrayList> </fx:Declarations> field2="bbb" field2="eee" field2="hhh" field2="kkk" ▪ 150 ▪ field3="ccc"></fx:Object> field3="fff"></fx:Object> field3="iii"></fx:Object> field3="lll"></fx:Object> Bakalářská práce Adobe Flex 4 Adobe Flex 4 <s:DataGrid dataProvider="{dataColl}" width="200"/> DateChooser DateChooser je MX komponenta kalendáře, ukazuje vybrané datum, je možné si konkrétní datum vybrat, listovat mezi měsíci a roky. V příkladu je vybraný datum nabindovaný na proměnnou „dateVariable“, která musí být definovaná jako [Bindable]76 <mx:DateChooser selectedDate="{dateVariable}"/> HSlider Hslider je horizontální77 slider komponenta pro manipulaci s číselným prosotorem v daném rozmezí a daným krokem. <s:HSlider minimum="0" maximum="100" value="100" snapInterval="1" liveDragging="true"/> Image Image je jednoduchá komponenta, která zobrazí obrázek78. Podporuje JPG, PNG, GIF formáty souborů. Pomocí autoLoad <s:Image source="@Embed('assets/mojefoto.jpg')"/> Label Label je jednořádkový výstupní text Label <s:Label text="Label"/> List List je seznam hodnot, typicky zobrazení nějaké kolekce objektů79 a to formou textových záznamů reprezentující konkrétní atribut objektu, uživatelsky popř. definovaný Kombinaci výstup nebo pomocí itemRendereru. 76 Pokud je proměnná definována v AS3 (v sekci fx:Script), je nutné přidat anotaci [Bindable]. Více o bindingu bude v samostatné kapitole 77 Podobně jako HSlider je horizontální, existuje také VSlider vertikální. 78 Obrázky mohou být buď přímo kompilované v SWF, což je použito v ukázce přes anotaci @Embed nebo je možné uvést jen cestu a pak jsou samostatně dotaženy po spuštění SWF. První varianta je rychlá, ale výsledkem je větší SWF soubor. V druhé je to naopak. 79 V příkladu jsou použita stejná data jako u DataGridu ▪ 151 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 <s:List dataProvider="{dataColl}" labelField="field1"/> NumericStepper NumericStepper je komponenta, která pracuje s číselnou hodnotou. Jedná se o jakousi kombinaci TextInputu a Slideru. <s:NumericStepper maxChars="2" value="10" minimum="0" maximum="99"/> TextArea TextArea je editovatelná komponenta pro vstup/zobrazení víceřádkového textu. Umožňuje text upravovat pomocí TLF tagů. 80 <s:TextArea height="60">Hello <s:span fontWeight="bold">World! </s:span><s:br/>Text může být víceřádkový s automatickým zalamováním</s:TextArea> TextInput TextInput je vstupní komponenta pro načtení jednoho řádku řetězce. <s:TextInput text="Vstupní text"/> Tree Tree je MX komponenta pro zobrazení adresářové struktury, která zobrazuje hierarchicky složky a soubory. Vstupem jsou většinou XML data, ale může být např. i ArrayCollection <fx:Declarations> <fx:XMLList id="treeData"> <node label="Mail Box"> <node label="Inbox"> <node label="Marketing"/> <node label="Product Management"/> <node label="Personal"/> </node> <node label="Outbox"> 80 Text Layout Framework knihovna - http://labs.adobe.com/technologies/textlayout/ . Pro pouhé zobrazení textu je lepší použít komponentu RichText ▪ 152 ▪ Bakalářská práce Adobe Flex 4 Adobe Flex 4 <node label="Professional"/> <node label="Personal"/> </node> <node label="Spam"/> <node label="Sent"/> </node> </fx:XMLList> </fx:Declarations> <mx:Tree dataProvider="{treeData}" labelField="@label" showRoot="false" width="200"/> HScrollBar HScrollBar je komponenta horizontálního81 scrollbaru. Je možno jej nabindovat na viewport82 komponentu. <s:VGroup id="vgroup" height="50" width="100"> <s:Label text="Lorem ipsum dolor sit amet"/> <s:Label text="Lorem ipsum dolor sit amet"/> <s:Label text="Lorem ipsum dolor sit amet"/> </s:VGroup> <s:HScrollBar viewport="{vgroup}" width="100%"/> ProgressBar ProgressBar je MX komponenta, která zobrazuje průběh nějaké činnosti. Pracuje ve 3 módech. Manuální (manual) řídí progress ručně pomocí aktuální a maximální hodnoty volané metodou „setProgress“. Řízený událostí (event), kdy do „source“ property přiřadíme control, který dispatchuje ProgressEvent nebo CompletedEvent. Třetí mód dle velikosti loadovaného objektu (polled), kdy objekt v property „source“ musí mít nastaveny property „bytesLoaded“ a „bytesTotal“. <fx:Script> <![CDATA[ protected function ns_changeHandler(event:Event):void { pb.setProgress(NumericStepper(event.target).value, pb.maximum); } ]]> </fx:Script> <s:NumericStepper id="ns" maxChars="2" value="10" minimum="0" maximum="99" change="ns_changeHandler(event)"/> <mx:ProgressBar id="pb" mode="manual" minimum="0" maximum="99"/> 81 Stejně jako je HScrollBar komponenta horizontální scrollbar, existuje také VScrollBar vertikální 82 viewPort komponenta implementuje interface IViewPort. Jsou to např. komponenty postavené na kontajneru Group. Je třeba si uvědomit, že scrollbar je samostatná komponenta, která může být zobrazena libovoně na obrazovce (ne pouze na pravé straně vedle komponenty) a bindingem na view port komponentu zajišťuje scroll jejího obsahu. ▪ 153 ▪
Podobné dokumenty
Řešené příklady v C# aneb C# skutečně prakticky
8.10.1 Přidání položek do ListView .............................................................. 71
8.10.2 Přidání položek do ListView a označení druhé z nich ........................ 71
8.10.3 D...
TS-480HX TX-480SAT
rušení rozhlasového nebo televizního vysílání, které
může být zjištěno pomocí vypnutí a zapnutí
zařízení, uživatel by měl zkusit odstranit rušení
jedním z následujících způsobů:
• přeorientovat neb...
Ceník - ADJ.cz
S novým vozem získáváte bezplatně asistenční službu Mazda Europe Service. Asistenční služba je vám k dispozici 24
hodin denně v celé ČR a dalších více než 40 zemích Evropy. Služba se bezplatně prod...
NOVÝ KATALOG PEUGEOT PROFESSIONAL
vozy a servisní střediska otevřená i během víkendu. V každém
centru PEUGEOT PROFESSIONAL vám vyškolený obchodní
poradce pomůže vybrat vůz, který bude nejlépe vyhovovat
vašim potřebám. Poradí vám ta...
C2_Novak_Kadlec_Smidochova
• 72% firem inzeruje pracovní místa přes sociální sítě
• 59% firem tvrdí, že získává více kandidátů na doporučení a 50% získává více reakcí
vužíváním social recruitmentu
• V roce 2013 3 x více spol...
Software, který je součástí Služeb
Pokud s námi máte uzavřenou jinou smlouvu týkající se konkrétního Softwaru, mají její podmínky přednost,
pokud se dostanou do konfliktu s těmito podmínkami.
1. Používání Softwaru.
1.1 Licence na So...