České vysoké učení technické v Praze Fakulta elektrotechnická
Diplomová práce
Elektronická podpora výuky předmětu Komprese dat Vojtěch Ouška
Vedoucí práce: Ing. Miroslav Balík, Ph.D.
Studijní program: Informatika a výpočetní technika květen 2006
Volný list iii
iv
Poděkování Rád bych poděkoval všem lidem, kteří mi byli nápomocni při sestavování a vytváření této diplomové práce. Zde bych rád vyzdvihl pana Ing. Miroslava Balíka, Ph.D. za jeho vedení a věcné připomínky. Dále pak mé ženě, Bc. Janě Ouškové, Dis., za pomoc při korektuře a za trpělivost při probděných nocích. Velký dík patří také celé mé rodině za podporu v dobách studia.
v
Prohlášení Prohlašuji, že jsem svou diplomovou práci vypracoval samostatně a použil jsem pouze podklady uvedené v přiloženém seznamu. Nemám závažný důvod proti užití tohoto školního díla ve smyslu §60 Zákona č. 121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů (autorský zákon).
V Praze dne 20.5. 2006
.............................................................
vii
Abstract The main aim of this work is to design and implement software system for students testing via dynamically generated tests concerning the data compression problems. The system tries to help lectors to provide e-learning form of studying. However it provides a possibility for student self-testing using trial test as well.
Abstrakt Cílem této diplomové práce je navrhnout a realizovat systém pro automatické testování studentů pomocí dynamicky generovaných testů zabývajících se problematikou komprese dat. Systém slouží jako pomůcka pro hodnocení studentů e-learningovou formou, ale zároveň i jako vhodný materiál pro samotné studenty, kteří si pomocí zkušebních testů mohou ověřovat hloubku svých znalostí problematiky komprese dat.
ix
Obsah Seznam obrázků
xv
1 Úvod
1
2 Cíl práce
5
3 Definice a specifikace požadavků
7
3.1
Definice pojmů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
3.2
Uživatelské role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.2.1
Administrátor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.2.2
Student . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.2.3
Neregistrovaný uživatel . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.3
Typy otázkových šablon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
3.4
Druhy testů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
3.5
Hodnocení studentů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
3.6
Jazykové mutace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
3.7
Bezpečnost systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
3.8
Správa systémových zdrojů . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
4 Tvorba analytického modelu 4.1
15
Relační model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
4.1.1
Závislost mezi otázkou a její šablonou . . . . . . . . . . . . . . . . . . .
18
4.1.2
Jazykové mutace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
4.2
Funkční model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
4.3
Životní cyklus testu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
5 Návrh systému 5.1 5.2
25
Modul pro prezentaci kompresních algoritmů . . . . . . . . . . . . . . . . . . .
25
5.1.1
Struktura modulu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
Modul pro testování studentů . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
5.2.1
Typ aplikace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
5.2.2
Návrh struktury aplikace . . . . . . . . . . . . . . . . . . . . . . . . . .
27
6 Realizace 6.1
31
Modul pro prezentaci kompresních algoritmů . . . . . . . . . . . . . . . . . . .
31
6.1.1
Použité technologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
6.1.2
Grafický vzhled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
xi
6.1.3 6.2
Podepisování JAR archivů . . . . . . . . . . . . . . . . . . . . . . . . . .
32
Modul pro testování studentů . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
6.2.1
Použité technologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
6.2.1.1
Aplikační server . . . . . . . . . . . . . . . . . . . . . . . . . .
32
6.2.1.2
Databázový server . . . . . . . . . . . . . . . . . . . . . . . . .
33
6.2.1.3
Prezentační vrstva . . . . . . . . . . . . . . . . . . . . . . . . .
34
6.2.1.4
Rámce pro vývoj aplikace . . . . . . . . . . . . . . . . . . . . .
35
6.2.2
Struktura tříd systému . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
6.2.3
Zabezpečení systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
6.2.3.1
Autentizace a autorizace . . . . . . . . . . . . . . . . . . . . .
38
6.2.3.2
Prolomení autorizace . . . . . . . . . . . . . . . . . . . . . . .
38
6.2.3.3
Vkládání XHTML entit do uživatelského vstupu . . . . . . . .
40
6.2.3.4
Vkládání SQL příkazů do uživatelského vstupu . . . . . . . . .
40
Implementace grafického rozhraní testových otázek . . . . . . . . . . . .
41
6.2.4.1
Testová otázka typu AnswerOne . . . . . . . . . . . . . . . . .
42
6.2.4.2
Testová otázka typu AnswerMany . . . . . . . . . . . . . . . . .
42
6.2.4.3
Testová otázka typu AnswerText . . . . . . . . . . . . . . . . .
43
6.2.5
Dynamické otázky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
6.2.6
Správa obrázků . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
6.2.6.1
Statické obrázky . . . . . . . . . . . . . . . . . . . . . . . . . .
45
6.2.6.2
Dynamické obrázky . . . . . . . . . . . . . . . . . . . . . . . .
47
6.2.7
Tisk testů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
6.2.8
Správa uživatelů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49
6.2.8.1
Postupné vkládání . . . . . . . . . . . . . . . . . . . . . . . . .
49
6.2.8.2
Hromadný import . . . . . . . . . . . . . . . . . . . . . . . . .
49
Databázový pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
6.2.10 Doba trvání testu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
6.2.11 Generování pouze jednoho ostrého testu . . . . . . . . . . . . . . . . . .
54
6.2.12 Podpora vícejazyčných verzí . . . . . . . . . . . . . . . . . . . . . . . . .
55
6.2.13 Logování událostí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
6.2.14 Akceptační testy aplikace . . . . . . . . . . . . . . . . . . . . . . . . . .
58
6.2.4
6.2.9
7 Rozhraní pro vytváření dynamických otázek 7.1
Popis rozhraní
59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
7.1.1
Rozhraní DynamicQuestion . . . . . . . . . . . . . . . . . . . . . . . . .
60
7.1.2
Rozhraní DynamicQuestionText . . . . . . . . . . . . . . . . . . . . . .
61
7.1.3
Rozhraní DynamicQuestionOption . . . . . . . . . . . . . . . . . . . . .
61
xii
7.1.4
Rozhraní DynamicQuestionOne . . . . . . . . . . . . . . . . . . . . . . .
62
7.1.5
Rozhraní DynamicQuestionMany . . . . . . . . . . . . . . . . . . . . . .
62
7.2
Pořadí volaných metod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
7.3
Serializace objektů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63
7.4
Generování dynamického obrázku . . . . . . . . . . . . . . . . . . . . . . . . . .
64
7.5
Příklady implementace zásuvných modulů . . . . . . . . . . . . . . . . . . . . .
64
7.5.1
Příklad 1 - Hledání podřetězců . . . . . . . . . . . . . . . . . . . . . . .
64
7.5.2
Příklad 2 - Huffmanovo kódování
. . . . . . . . . . . . . . . . . . . . .
67
Testování zásuvných modulů . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
7.6.1
74
7.6
Popis aplikace Plugin Tester . . . . . . . . . . . . . . . . . . . . . . . . .
8 Závěr
77
9 Literatura
79
A Seznam použitých zkratek
81
B Instalační příručka
83
B.1 Instalace PostgreSQL
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
B.1.1 Operační systém Windows XP . . . . . . . . . . . . . . . . . . . . . . .
83
B.1.2 Operační systém Linux . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
B.2 Instalace aplikačního serveru Apache Tomcat . . . . . . . . . . . . . . . . . . .
85
B.2.1 Operační systém Windows XP . . . . . . . . . . . . . . . . . . . . . . .
85
B.2.2 Operační systém Linux . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
B.2.3 Potřebná rozšíření . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
B.3 Instalace systému SyVyKoD . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
B.3.1 META-INF/context.xml . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
B.3.2 WEB-INF/web.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
C Administrátorský manuál
93
C.1 Přihlášení do systému . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
C.2 Vytváření skupin uživatelů . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
C.3 Vytváření uživatelů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
C.4 Vytváření kategorií . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
C.5 Vytváření otázkových šablon . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
C.6 Vytváření šablon testů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
C.7 Přidávání zásuvných modulů . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
C.8 Průběh testu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
C.9 Údržba aplikace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
xiii
C.9.1 Základní funkce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
C.9.2 Logování událostí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
100
C.9.3 Správa obrázků . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
100
D Obsah přiloženého CD
101
D.1 Obsah . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
D.2 Text diplomové práce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
D.3 Systém Syvykod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
D.4 Potřebný software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
101
xiv
Seznam obrázků 3.1
Schéma pro vytváření testových šablon . . . . . . . . . . . . . . . . . . . . . . .
11
4.1
E-R model systému SyVyKoD . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
4.2
Model případu použití (Use Case diagram) systému SyVyKoD . . . . . . . . .
20
4.3
Diagram datových toků - Neregistrovaný uživatel . . . . . . . . . . . . . . . . .
21
4.4
Diagram datových toků - Student . . . . . . . . . . . . . . . . . . . . . . . . . .
21
4.5
Diagram datových toků - Administrátor . . . . . . . . . . . . . . . . . . . . . .
22
4.6
Dynamický model životního cyklu testu . . . . . . . . . . . . . . . . . . . . . .
24
5.1
Použití návrhového vzoru MVC v základní struktuře aplikace . . . . . . . . . .
28
6.1
Ukázka grafického rozhraní otázky typu AnswerOne . . . . . . . . . . . . . . . .
42
6.2
Ukázka grafického rozhraní otázky typu AnswerMany . . . . . . . . . . . . . . .
43
6.3
Ukázka grafického rozhraní otázky typu AnswerText . . . . . . . . . . . . . . .
44
6.4
Zobrazování dynamických obrázků . . . . . . . . . . . . . . . . . . . . . . . . .
47
7.1
Struktura rozhraní pro dynamické otázky . . . . . . . . . . . . . . . . . . . . .
59
7.2
Pořadí volání metod zásuvných modulů . . . . . . . . . . . . . . . . . . . . . .
63
7.3
Generovaný obrázek k příkladu Huffmanovo kódování . . . . . . . . . . . . . .
67
7.4
Aplikace Plugin Tester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
xv
Kapitola 1 Úvod Mezi známá didaktická pravidla patří tvrzení, které přisuzuje důkladnému ověřování pochopení učiva stejnou váhu jako jeho výkladu. V dnešní době, kdy se oblibě začínají těšit různé formy „dálkovéhoÿ studia, vzniká celá řada systémů pro podporu e-learningových kurzů. E-Learning je poměrně nový, velice široký pojem, pod kterým si lze představit celou řadu věcí týkajících se problematiky výuky podporované informačními technologiemi. Za nejzákladnější formu e-learningu lze považovat převádění existujících studijních materiálů do elektronické podoby - tzv. e-dokumentů. Další stupeň zahrnuje různé formy testování a metody komunikace mezi studenty pomocí audiovizuálních prostředků. Nejpokročilejší formy e-learningu nabízejí dokonce počítačové simulace laboratorních pokusů atd. Proces zavádění e-learningu je poměrně zdlouhavý. Důkazem je zatím nízké zastoupení vzdělávacích institucí, které by na tuto formu studia byly plně odkázány. Ovšem existují výjimky, které na e-learningu úspěšně postavili převážnou část výuky. Příkladem může být společnost Cisco a její vzdělávací program Cisco Networking Academy (CNA). Pro podporu e-learningového způsobu výuky existuje celá řada profesionálních produktů nazývaných course management systems (CMS) nebo také learning management systems (LMS). Ty mají velice propracovanou výukovou část. Většina z nich obsahuje propracovanou podporu komunikace uživatelů, podporu diskusních skupin, nástěnek, sdílení aplikací, video konferencí, virtuálních tříd atd. Vedle komerčních produktů (WebCT, Authorware, produkty firmy Macromedia atd.) existují i open-source systémy, které narozdíl od předchozích nevyžadují znalosti speciálních softwarových technologií. Mezi asi nejrychleji se rozšiřující patří produkt Moodle (Modular Object-Oriented Dynamic Learning Environment). Jedná se o modulové objektově orientované dynamické vzdělávací prostředí určené pro podporu prezenční i distanční výuky prostřednictvím online kurzů dostupných na WWW. Nevýhoda všech zmíněných systémů spočívá v poměrně obtížném nasazování do procesu výuky. Kvůli jejich flexibilitě nastavení a širokým možnostem může být těžké se v takovýchto e-learningových systémech rychle zorientovat. Cílem této práce je vytvoření systému, který tento problém odstraňuje. Zároveň více než na prezentování učiva se zaměřuje na testování studentů. Tímto se nejvíce odlišuje od existujících produktů. Jeho přehledné webové rozhraní umožňuje rychlé a snadné vytváření testovacích materiálů. Vedle snadné instalace se také vyznačuje možností vytváření dynamických otázek, které jsou generovány pomocí Java tříd snadno integrovatelných do systému. Automatické testování osvojených znalostí (u e-learningových kurzů preferované) musí zaručit podobné podmínky, kterým jsou studenti vystaveni u zkoušení klasického, v nejčastěj-
1
2
KAPITOLA 1. ÚVOD
ším případě zkoušení písemným testem či ústní formou. Toho se dá celkem snadno dosáhnout v případě, kdy jsou studentům předkládány testy připravené přímo lektorem. Ovšem v situacích, kdy systém vytváří jednotlivé testy dynamicky, musí být kladen velký důraz na to, aby testy byly srozumitelné, jednotlivé otázky podobně složité a v neposlední řadě, aby vyhodnocené testy tvořily přehledný podkladový materiál pro ohodnocení studenta. Navržení systému, který má splňovat výše uvedené podmínky a přitom nabízí lektorům příjemný způsob, jak flexibilně, rychle a hlavně snadno připravovat testovací materiály, není vůbec triviální. Cílem této diplomové práce je navržení a implementování právě takovéhoto systému. Práce je rozčleněna do následujících kapitol:
Kapitola 1 představuje obecný úvod do problematiky e-learningových kurzů.
Kapitola 2 specifikuje cíle, kterých by tato diplomová práce měla dosáhnout a popisuje v jakém směru navazuje na práce předchozí.
Kapitola 3 seznamuje se specifikací systému. Zároveň zavádí pojmy, které pomáhají popisovat jeho jednotlivé části. V této kapitole se z původních slovních požadavků vyčleňují podstatná fakta a hlavní komponenty systému. Obsah kapitoly určuje jakým směrem se bude vývoj projektu ubírat. Mimo jiné rozděluje uživatelské role a druhy podporovaných otázek.
Kapitola 4 popisuje analytickou část projektu. Pomocí modelů představuje jednotlivé komponenty systému a jejich vzájemnou interakci. V kapitole jsou uvedeny různé možnosti návrhů vztahů těchto komponent. U jednotlivých možností jsou zmíněné výhody a nevýhody toho či onoho přístupu. Diagramy dynamického modelu pomáhají pochopit funkce, které systém nabízí a zároveň definuje ty uživatele, kteří jsou oprávněni nabízené funkce provádět. V závěru kapitoly je popsán životní cyklus testu, jehož pochopení je pro další orientaci v textu nezbytně nutné.
Kapitola 5 popisuje návrh systému. Ve svém popisu opouští abstraktní úroveň vývoje a začíná pracovat s konkrétními technologiemi. Ještě se však nepouští do vysvětlování technických detailů implementace. Představuje střední vrstvu popisu struktury aplikace. Čtenář by měl po přečtení nabýt dojmu o tom, jak systém funguje. Popis je prováděn pomocí návrhových vzorů a blokových schémat.
Kapitola 6 je popisem samotné realizace. Objevuje se zde popis problémů, které v rámci vývoje nastaly, a jejich konkrétní řešení. Pro větší přiblížení problematiky obsahuje kapitola příklady a klíčové úseky kódu, které řeší nastíněné problémy. Konkrétně se kapitola zabývá bezpečností systému, správou uživatelů, zaručením regulérních podmínek při ověřování znalostí studentů, správou demonstračních obrázků atd.
KAPITOLA 1. ÚVOD
3
Kapitola 7 je velice důležitá pro tvůrce rozšíření testovacích materiálů. Obsahuje detailní popis návrhu Java tříd (tzv. zásuvných modulů otázek) reprezentujících dynamické otázky. Popis programových rozhraní je doplněn kódem ukázkových modulů. Konec kapitoly představuje nástroj pro ověřování správnosti návrhu takovýchto modulů. Kapitola 8 shrnuje výsledky a uzavírá tuto práci. Přílohy obsahují především materiály nutné k instalaci potřebných softwarových komponent a systému samotného. Administrátorský manuál obsahuje informace vhodné pro snazší orientaci v systému, popisuje základní administrátorské akce a upozorňuje na věci, kterým je třeba při správě systému věnovat zvýšenou pozornost.
Kapitola 2 Cíl práce Cílem této práce je navržení a implementace systému pro podporu výuky předmětu Komprese dat, vyučovaném na Fakultě elektrotechnické Českého vysokého učení technického. Realizace systému si klade za cíl nabídnout dva moduly: • modul prezentující informace o vyučovaných algoritmech, • modul pro automatické a dynamické testování studentů. První modul navazuje na předchozí diplomové práce vytvářené pro Stringologickou skupinu Elektrotechnické fakulty, zejména pak na práci Ondřeje Hanouska [1] a na semestrální práce studentů předmětu 36KOD. Tyto práce se zabývají tvorbou vizualizačních Java appletů. Modul nabízí rozhraní pro tyto applety a prezentuje je formou webových stránek. Cílem druhé části je vytvoření vícejazyčné webové aplikace, nabízející možnost snadného vytváření testových materiálů, ze kterých je možné generovat testy. Ačkoli je aplikace vytvářena pro potřeby vyučujících předmětu 36KOD, její obecný návrh umožňuje nasazení ve všech oblastech, kde je zapotřebí ověřovat znalosti studentů pomocí e-learningových testů.
5
Kapitola 3 Definice a specifikace požadavků Systém pro podporu výuky se odlišuje od běžných webových aplikací několika vlastnostmi. Navrhovaný systém umožňuje generování testů dynamicky pomocí algoritmů integrovaných do systému. Systém se zaměřuje na řešení těchto problémů: • realizace rozhraní pro snadné vytváření testových šablon a otázek, • možnost vytváření dynamických otázek pomocí algoritmů řešících libovolný výpočetní problém (tzv. zásuvných modulů1 otázek), • ošetření regulérního průběhu vyplňování testu, • striktní zabezpečení proti neoprávněným změnám dat a neoprávněným akcím, • variabilní metody hodnocení studentů. Výše zmíněné problémy budou podrobně rozebrány dále v textu. Nejprve však následuje seznam zavedených pojmů.
3.1
Definice pojmů
Systém SyVyKoD Pojem systém SyVyKoD je používán jako zkrácené označení názvu Systém pro podporu výuky předmětu Komprese dat. Pokud nehrozí záměna pojmů, je používán pouze termín systém. Testová otázka Testová otázka (zkráceně otázka) reprezentuje konkrétní podobu příkladu, který mají studenti za úkol vyřešit. Šablona otázky Pojem šablona otázky (nebo také otázková šablona) představuje objekt, který souhrnně popisuje vlastnosti generovaných otázek jednoho typu. Jedná se především o částečné znění zadání, čas stanovený na vypracování otázky, počet bodů za správnou a špatnou odpověď atd. V případech, kdy nehrozí záměna pojmů, je používán pouze termín šablona. Nejsnáze si lze šablonu představit jako záznam popisující vzor, podle kterého se konkrétní testové otázky generují. Tento záznam může obsahovat například tyto informace: „Určete součet čísel a a b. Za správnou odpověď obdržíte 10 bodů, za špatnou 0 bodů.ÿ Pro otázku generovanou z této šablony systém náhodně 1
Termín zásuvný modul je používaný jako český ekvivalent k anglickému termínu plugin.
7
8
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ
zvolí konstanty a a b a dosadí je do sčítanců v textu. Tím vzniká konkrétní otázka, u které už je možné kontrolovat správnost odpovědi.
Test Termínem test je označována množina testových otázek. Na vypracování každého testu existuje časový limit, po jehož překročení není dále možné na otázky odpovídat.
Kategorie Pojmem kategorie je označována množina otázkových šablon zabývajících se podobnou problematikou.
Šablona testu Ze šablon testů (v případě, že nehrozí záměna s pojmem šablona otázky, je používán termín šablona) jsou generovány konkrétní testy. Šablony testů obsahují informace o tom, které kategorie se při vytváření testu použijí.
Skupina Termínem skupina je označována množina sdružující studenty společných vlastností.
Zásuvný modul otázky Pojmem zásuvný modul otázky (zkrácené modul ) se označuje Java program, který umožňuje generovat znění otázek. Moduly lze do systému jednoduše přidávat a přiřazovat je jednotlivým otázkovým šablonám. Právě modul by byl ve výše uvedeném příkladu zodpovědný za generování hodnot čísel a a b.
Jazyková mutace Pod pojmem jazyková mutace se obecně myslí texty přeložené do cizího jazyka. Konkrétně se pak jedná o jazykové mutace aplikace, šablon otázek, šablon testů a zásuvných modulů.
Dynamický obrázek Dynamický obrázek je zde chápán jako obrázek vygenerovaný programově zásuvným modulem na základě zvolených hodnot parametrů. Neznamená to, že by se obrázek v průběhu času měnil.
Statický obrázek Tento pojem představuje obyčejný obrázek uložený v souboru souborového systému. Jeho obsah je v rámci systému neměnný.
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ
3.2
9
Uživatelské role
Systém umožňuje prezentaci podpůrných materiálů k výuce předmětu Komprese dat a po autorizovaném vstupu testování znalostí studentů. Systém je založen na modelu klient-server. Spojení klientské části se serverovou je zajištěno pomocí webového prohlížeče, přes který uživatelé žádají o informace. Ty jsou aplikačním serverem zasílány zpět klientské straně. Aplikační server úzce spolupracuje s databázovým serverem, kde jsou uložena data využívaná systémem. Po přihlášení uživatele do systému se jeho vlastnosti liší podle následujících uživatelských rolí. 3.2.1
Uživatelská role Administrátor
Administrátor má privilegia ke spravování systému, nastavování vlastností a pozorování probíhajících událostí. Předpokládá se, že administrátor má zároveň oprávnění ke konfiguraci aplikačního a databázového serveru. Základním úkolem administrátora je sestavování šablon testů a otázek, ze kterých si uživatelé generují konkrétní testy. Typickou osobou, která v systému vystupuje v roli administrátora, je vyučující předmětu. Kromě přípravy testů má administrátor za úkol také správu studentů. Ty může přidávat do systému postupně nebo může využít funkci hromadného importu uživatelů. Poslední funkcí administrátora je dohlížení na bezproblémový chod systému. K tomu může použít nástroj pro logování událostí, který zaznamenává veškeré události, které se v systému odehrály. 3.2.2
Uživatelská role Student
Pod touto rolí vystupují v systému uživatelé, kteří mají možnost se do systému přihlašovat a pomocí něho skládat testy. Student může také upravovat své osobní údaje, které slouží administrátorovi v případě nutnosti kontaktování studenta. Kvůli zvyklostem v názvosloví je někdy role student označována jako role Uživatel. V případech, kdy se například mluví o údajích studentů, je běžnější používat pojem uživatelské heslo než heslo studenta. V žádném případě však nesmí docházet k záměně role Student s rolí Neregistrovaný uživatel. 3.2.3
Uživatelská role Neregistrovaný uživatel
Za neregistrovaného uživatele se považuje každý návštěvník systému, který nemá oprávnění k přihlášení. První modul systému, zabývající se prezentací vizualizačních appletů, je plně k dispozici i neregistrovaným uživatelům.
3.3
Typy otázkových šablon
Otázkové šablony mohou mít různé vlastnosti. Kombinací těchto vlastností vznikají různé typy šablon. Systém podporuje celkem 5 takových typů. Při vytváření nové šablony musí adminis-
10
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ
trátor šabloně jeden z těchto typů přiřadit. Následující text uvádí seznam vlastností, kterými se může šablona vyznačovat.
Static Šablony s touto vlastností vytvářejí otázky, které mají vždy stejné zadání. Toto zadání je v plném znění uvedeno přímo v šabloně.
Dynamic Šablonám s vlastností Dynamic je přiřazen zásuvný modul, který při vytváření otázky ovlivňuje její zadání. Může například náhodně generovat sčítance v otázce zaměřené na znalost operace sčítání.
AnswerMany Šablony s vlastností AnswerMany generují otázky, u kterých student vybírá z nabízených možností ty, které považuje za správné. U typu AnswerMany se počet správných odpovědí pohybuje v rozmezí 0. .n, kde n je celkový počet odpovědí.
AnswerOne Šablony s vlastností AnswerOne se oproti AnswerMany liší pouze v tom, že generují právě jednu správnou odpověď.
Option Vlastnost Option představuje souhrnné označení šablon s vlastností AnswerOne a AnswerMany.
AnswerText Na otázky generované tímto typem šablon odpovídá student pomocí textového řetězce vloženého do vstupního textového pole. Ten je porovnáván se správnou odpovědí. Příkladem může být otázka, kdy student musí zadat výstupní řetězec procesu kódování ze znalosti vstupního řetězce.
ImageGenerator Šablony s vlastností ImageGenerator generující dynamický obrázek.
Na základě kombinací uvedených vlastností systém rozlišuje 5 konkrétních typů šablon. Tabulka 3.1 v levém sloupci uvádí seznam těchto typů a v pravých sloupcích definuje, jaké vlastnosti tyto šablony mají. Jestliže se šablona některou z vlastností vyznačuje, pak je u této vlastnosti uveden symbol +. Tři poslední šablony mohou mít také vlastnost ImageGenerator, v závislosti na tom, zda generují či negenerují dynamický obrázek.
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ Typ šablony StaticOne StaticMany DynamicOne DynamicMany DynamicText
Static + +
Dynamic
+ + +
Vlastnosti šablon AnswerOne AnswerMany + + + +
11
AnswerText
Option + + + +
+
Tabulka 3.1: Přehled podporovaných typů šablon otázek a jejich vlastností
Každá šablona otázky spadá do právě jedné kategorie. Výhoda zavedení kategorií spočívá v přehledném uspořádání šablon do logických celků. Administrátor má možnost tyto kategorie vytvářet a upravovat. Skládáním kategorií dohromady pak vytváří šablony testů. K šablonám přiřazuje jednotlivé kategorie a zároveň určuje, kolik otázek se z jednotlivých kategorií použije při vytváření testu. Šablony testů mají příznak nastaveny buď na aktivní nebo neaktivní. Studenti pak v závislosti na tomto příznaku mohou nebo nemohou testy generovat. Celý proces sestavování šablon je vidět na obrázku 3.1, kde jsou vytvořené 2 šablony testů, z nichž je možné generovat testy. Šablona Testu 1 generuje 2 otázky z Kategorie A a 1 otázku z Kategorie B. Šablona testu 2 generuje test se 3 otázkami pouze z Kategorie B.
Obrázek 3.1: Schéma pro vytváření testových šablon
12
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ
3.4
Druhy testů
Systém umožňuje studentům generovat dva druhy testů. Ostrý test je takový, který se započítává do celkového hodnocení studenta. Takovýto test může být jedním studentem generován podle konkrétní šablony pouze jedenkrát. Zkušební test může student generovat tolikrát, kolikrát uzná za vhodné, a proto se výsledky těchto testů do výsledného hodnocení nezapočítávají. Zkušební testy slouží pro procvičení vyučované látky. Konfigurací systému lze generování zkušebních testů povolit nebo zakázat.
3.5
Hodnocení studentů
Důležitou vlastností systému je zpracování výsledků testů a promítnutí těchto výsledků do studentova hodnocení. V tomto směru nabízí systém řadu možností jak hodnocení určovat. Zadání diplomové práce klade požadavek na velkou flexibilitu v nastavování parametrů otázek. Počítá s tím, že existují otázky různých obtížností. Tuto obtížnost lze ohodnotit různým počtem bodů získaných v případě správné odpovědi. V případě špatné odpovědi student body nezískává. Ovšem neznalost základů problematiky by měla být penalizována důsledněji než pouhým ziskem 0 bodů. Zde by měla být administrátorovi ponechána možnost odečítat od bodů získaných v jiných otázkách. Z tohoto důvodu jsou u každé otázky uváděny dva parametry definující její bodové hodnocení. První specifikuje získané body v případě správné odpovědi, druhý body v případě odpovědi špatné. Z logiky věci vyplývá, že první parametr může nabývat kladných hodnot, kdežto druhý hodnot záporných nebo hodnoty 0. Celková úspěšnost testu je vypočítávána vždy pouze z ostrých testů. Pro způsob výpočtu se nabízí dva přístupy. První přístup bere v úvahu fakt, že studentovo celkové hodnocení testu může nabývat záporných hodnot. Tyto záporné hodnoty jsou přičítány k ostatním testům. Celkový počet získaných bodů se počítá z konečného součtu. Druhý přístup bere v úvahu fakt, že nejhorší hodnocení z jednoho testu je 0 bodů. Pokažený test tak neovlivňuje výsledky z jiných testů. Oba dva přístupy mohou být aplikovány na tři různé skupiny ostrých testů: • První skupina obsahuje pouze ty testy, které pochází ze šablon, jež jsou právě aktivní. • Druhá skupina zahrnuje testy generované ze šablon, které v systému v daný okamžik existují - v aktivním i neaktivním stavu. • Poslední skupina obsahuje všechny ostré testy, dokonce i ty, jejichž šablony byly již ze systému odstraněny. Aplikováním dvou zmíněných přístupů na tyto tři skupiny testů vzniká celkem šest možných hodnocení každého studenta. Z těchto hodnocení může být zvoleno to, které nejlépe vyhovuje konkrétním podmínkám. Možnosti jsou zrekapitulovány následujícím příkladem.
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ Číslo testu 1 2 3 4
Maximálně dosažitelný počet bodů 10 10 10 10
13 Získaný počet bodů 10 5 -2 10
Tabulka 3.2: Ukázka bodového ohodnocení z příkladu 3.1 Započítávané testy 1. skupina 2. skupina 3. skupina
Hodnocení - 1. přístup maximum získáno úspěšnost 20 3 15 % 30 13 43 % 40 23 58 %
Hodnocení - 2. přístup maximum získáno úspěšnost 20 5 25 % 30 15 50 % 40 25 63 %
Tabulka 3.3: Ukázka výpočtu hodnocení studenta z příkladu 3.1
Příklad 3.1: V uvažované situaci administrátor vytvořil celkem 4 šablony testů. Všechny nastavil jako aktivní, a proto si student mohl ze všech šablon vygenerovat ostrý test. Po složení všech testů dosáhl student hodnocení uváděného v tabulce 3.2. Za nějaký čas administrátor přišel na chybu v šabloně, která generovala test číslo 4 a šablonu odstranil. Zároveň kvůli podezření na generování špatného obrázku deaktivoval šablonu číslo 1, aby tím zamezil dalšímu generování chybných testů. Po těchto akcích systém vypočítává celkové studentovo hodnocení tak, jak je uvedeno v tabulce 3.3.
3.6
Jazykové mutace
Důležitou podmínkou je možnost provozovat systém v různých jazykových mutacích. To ovšem neznamená pouze přeložení systémových textů do jiných jazyků. Systém nabízí možnost, jak vytvářet univerzální šablony, ze kterých si studenti mohou generovat testy v různých jazycích. Tyto mutace musí být tedy možné vytvářet pro znění zadání otázek i znění odpovědí.
3.7
Bezpečnost systému
Systém musí zaručit takové podmínky, aby studenti nemohli zneužívat operací, které systém nabízí, a zlepšovat tak své celkové hodnocení. Zvláště důležitá je kontrola operací, které generují testy. Zde je třeba zaručit, aby student mohl generovat skutečně jen jeden ostrý test. Neméně důležitá pozornost musí být věnována také těm akcím, které jakýmkoli způsobem ovlivňují podobu testu po vypršení časového limitu k těmto změnám určenému. V neposlední řadě je třeba zabezpečit detaily uživatelů, které mají zůstat skryty jiným uživatelům.
14
3.8
KAPITOLA 3. DEFINICE A SPECIFIKACE POŽADAVKŮ
Správa systémových zdrojů
Šablony otázek mají možnost používat systémové zdroje v podobě obrázků a zásuvných modulů otázek. Aby bylo možné zamezit existenci neplatných odkazů na tyto zdroje, nabízí systém nástroje, kterými je možné tyto odkazy kontrolovat.
Kapitola 4 Tvorba analytického modelu V této kapitole jsou představeny nejdůležitější analytické modely, které slouží ke snadnějšímu pochopení a návrhu systému. Při návrhu těchto modelů je třeba pečlivě zvažovat veškeré požadavky, které od systému očekáváme, jelikož pozdější změna a zapracování těchto, byť sebemenších detailů, může mít značný vliv na celkovou délku vývoje aplikace.
4.1
Relační model
Systém ke svému běhu potřebuje úložiště dat, které nabízí rychlé vyhledávání, snadnou modifikaci a vytváření nových záznamů. Všechny tyto aspekty splňují systémy, které jsou navrženy pro spolupráci s datovými strukturami definovanými pomocí relačního modelu dat. Relační model přináší celou řadu výhod, zejména mnohdy přirozenou reprezentaci zpracovávaných dat, možnost snadného definování a zpracování vazeb apod. Relační model klade velký důraz na zachování integrity dat. Zavádí pojmy jako referenční integrita, cizí klíč, primární klíč apod. Relační model systému SyVyKoD je složen z několika entit, které jsou zobrazeny na obrázku 4.1. Pro definování vztahů je zvolena binární notace zápisu. Vztahy mezi entitami jsou značené čarami. Plné čáry jsou použity tam, kde primární klíč otcovské entity přechází do části primárního klíče entity závislé. Čárkované čáry jsou použity v opačném případě. Povinné členství ve vztahu je značeno krátkou čárkou, nepovinné členství prázdným kolečkem. Rozvětvení čáry představuje vícenásobnou účast ve vztahu. V následujícím textu jsou použité entity stručně popsány a zároveň budou představeny i jiné způsoby, jakými je možné strukturu entit a jejich vztahů navrhnout. User Entita User shromažďuje informace o uživatelích systému. Každý uživatel vlastní své přihlašovací jméno. K ověření pravosti uživatele slouží heslo. Dále může mít uživatel nastaveno jméno, příjmení, email a členství k nějaké skupině uživatelů. Group Entita Group udržuje informace o existujících skupinách uživatelů v systému. Question template V entitě Question template jsou uchovávány otázkové šablony. Question template text Tato entita shromažďuje jazykové mutace zadání otázek. 15
16
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
Obrázek 4.1: E-R model systému SyVyKoD
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
17
Log K uchovávání záznamů o událostech systému slouží entita Log. Answer template U všech šablon typu Static musí administrátor do systému vkládat odpovědi, ze kterých je při generování testových otázek část vybrána a v testu použita. Entita Answer template udržuje seznam všech odpovědí. Answer template text Pro uložení jazykových mutací odpovědí je využita entita Answer template text. Category Entita Category udržuje informace o existujících kategoriích. Tato entita nemá ekvivalent k Question template text. Je to z toho důvodu, že kategorie nejsou pro uživatele viditelné. Proto není třeba jejich názvy překládat. Test template Entita Test template udržuje informace o testových šablonách. Test category Entita Test category pouze umožňuje existenci vícenásobných vztahů entit Test template a Category. Test template text Entita Test template text udržuje jazykové překlady názvů testových šablon. Test Entita Test shromažďuje všechny testy, které v systému existují. Testy mají vazbu na testové šablony, ze kterých vznikly. Informace obsažené v této entitě představují obecné údaje o testu. Mezi důležité patří příslušnost ke studentovi, který test vygeneroval a začátek a doba trvání testu, z nichž se odvozuje časový limit na vypracování testu. Test question Tato entita shromažďuje testové otázky, ze kterých je test složen. Podle typu jsou pak studentovy odpovědi uloženy v entitě Answer 1 nebo v entitě Answer 2. Answer 1 Entita Answer 1 uchovává studentovy odpovědi na otázky generované šablonou s vlastností Option.
18
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
Answer 2 Entita Answer 2 uchovává studentovy odpovědi na otázky generované šablonou s vlastností AnswerText. Popsaná podoba modelu není jediná možná. Cest, jak model navrhnout, je v případě systému SyVyKoD více. V následujícím textu jsou naznačeny některé další varianty, které by bylo možné při návrhu použít. U každé varianty jsou uvedeny její výhody a nevýhody.
4.1.1
Závislost mezi otázkou a její šablonou
Z modelu 4.1 je patrné, že při generování testových otázek dochází ke kopírování některých atributů ze šablon do testových otázek. Tím dochází k vytváření jisté redundance dat. Tato akce má ovšem za následek odstranění závislosti mezi otázkou a její šablonou. Pokud by při generování měla tato závislost zůstat zachována, musel by se model změnit tak, že by byl do otázky přidán odkaz na příslušnou šablonu. To by se projevilo přidáním cizího klíče. Toto řešení by odstranilo část redundance. Použitý model však oproti této variantě nabízí několik výhod. Předně to jsou regulérní podmínky skládání testů. Jaké následky by mělo použití zmíněného řešení ukazuje příklad 4.1.
Příklad 4.1: Administrátor vytvoří šablonu otázky, která testuje studenty ze znalosti operace součtu v závislosti na dvou sčítancích. Student, který si vygeneruje test obsahující tuto otázku, odpoví správným výsledkem. Tato otázka by tudíž měla být vyhodnocena jako správně zodpovězena. Ovšem administrátor může zadání v šabloně (a tudíž v uvažovaném případě i v otázce) změnit (například z důvodu nalezení chyby v textu) a s ním i hodnotu některého ze sčítanců. Od této chvíle se studentova odpověď vyhodnotí jako chybná. Podobný příklad lze použít i pro atributy udávající počty bodů za správnou a špatnou odpověď. Jestliže test uvádí nějaké podmínky, které prezentuje studentovi, měly by tyto podmínky zůstat zachovány i nadále. Z tohoto důvodu není nastíněné řešení použito. Místo toho systém odděluje šablony od otázek. Tento fakt zajišťuje, že vyhodnocovány budou odpovědi přesně na ty otázky, které byly součástí testu v době jeho vypracování. To ovšem neznamená, že by administrátorovi nebyla ponechána možnost úpravy zadání otázek v budoucnu generovaných. Administrátor může v šablonách otázek upravovat nejen zadání, ale i ostatní atributy. Změny se však promítnou až do nově vygenerovaných testů. Staré zůstanou nezměněny. Ve prospěch použité varianty přispívá i fakt, že systém je navrhován řádově pro desítky až stovky studentů. V takovémto počtu není redundance způsobená kopírováním studentů nijak závažná.
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU 4.1.2
19
Jazykové mutace
Systém umožňuje vytváření šablon v různých jazykových mutacích. Nejsnazší cesta k poskytování těchto mutací by spočívala ve vytvoření několika tematicky shodných šablon v různých jazycích. Zároveň by v systému existovalo několik kategorií, které by se týkaly stejného tématu, avšak sdružovaly by pouze šablony jedné jazykové mutace. Tyto kategorie by se dále sdružovaly do jednojazyčných šablon testů atd. Popsané řešení je značně neefektivní a má hned několik nevýhod. Administrátor by musel vícekrát zadávat stejné hodnoty atributů pro několik tematicky shodných šablon. Tyto informace by se v databázi zbytečně duplikovaly. Dále by nastával problém s automatickým hodnocením, kde by bylo obtížné rozlišit, které kategorie testů již student vypracoval a které ne. Z tohoto důvodu systém využívá jiné řešení. Atributy každé šablony se do systému zadávají pouze jednou. Jestliže je nutná existence otázky i v jiných jazycích, administrátor může šabloně přidat jazykový překlad. Ten se ovšem ukládá v jiné entitě než hodnoty zbylých atributů. Proto nedochází ke zbytečné redundanci. Toto řešení operuje s tzv. implicitním zněním otázky. Jelikož je rozumné předpokládat, že každá otázka bude mít zadání alespoň v jednom jazyce1 , je entita otázek navržena tak, že sama obsahuje toto implicitní znění. Pokud je aplikace provozována v jednojazyčném prostředí, je šablona kompletní a není zapotřebí nic přidávat. Pokud je prostředí vícejazyčné, doplní administrátor příslušnou jazykovou mutaci. Jestliže se při generování testu vyskytne požadavek na generování otázky v jazyce, který šablona podporuje, bude otázka do testu začleněna v tomto jazyce. Pokud šablona požadovanou jazykovou mutaci nepodporuje, vytvoří se otázka v jazyce implicitním. Analogický postup je aplikován i při vytváření odpovědí u šablon s vlastností Static. Tento přístup má ještě jednu výhodu oproti prvně zmíněnému návrhu. Často se stává, zvláště pak u otázek s vlastností Option, že obsah odpovědí není závislý na jazykové mutaci - je ve všech jazykových mutacích totožný. Může se jednat například o binární výstup algoritmu. V takovýchto případech není nutné, aby administrátor zadával odpovědi ve všech jazykových mutacích, ale stačí uvést odpověď pouze jednou, v implicitní jazykové mutaci. Popsaný mechanizmus pak zajistí, že se při absenci požadované mutace použije mutace implicitní, tudíž ta s textem nezávislým na zvoleném jazyce.
4.2
Funkční model
Modelování případů užití je jednou z forem, jak získávat přehled o požadavcích, které jsou na systém kladeny. Jedná se o doplňkový způsob vzhledem k specifikaci požadavků, jež byla popsána v předchozí kapitole. Modelování případu užití používá objekty známé pod těmito názvy: • Účastníci. To jsou role přidělené osobám nebo předmětům využívající systém. 1
Většinou v jazyce prostředí, ve kterém je aplikace provozována
20
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU • Případy užití(use cases). Činnosti, které systém umožňuje provádět. • Relace. Vztahy mezi účastníky a případy užití. • Hranice systému. Hranice, jež vymezuje funkčnost systému.
Na obrázku 4.2 je znázorněn model případu užití pro systém SyVyKoD. Představuje 3 aktéry - Student, Neregistrovaný uživatel a Administrátor. Každý z nich je spojen s konkrétním případem užití. Diagram přehledně zobrazuje základní funkce systému.
Obrázek 4.2: Model případu použití (Use Case diagram) systému SyVyKoD
Další částí analýzy jsou funkční datové toky. Na obrázcích 4.3, 4.4 a 4.5 jsou postupně znázorněny datové toky v závislosti na aktivitách pro neregistrovaného uživatele, studenta a administrátora. Neregistrovaný uživatel má právo pouze na prohlížení vizualizačních appletů znázorňující činnost kompresních algoritmů. Student může v systému vystupovat pod uživatelským jménem, může procházet svá osobní nastavení a hlavně může skládat administrátorem připravené testy. Po dokončení má možnost nechat testy automaticky vyhodnotit a zobrazit si své hodnocení. Osobní údaje ani hodnocení jiných uživatelů mu nejsou přístupné. Administrátor má právo vidět údaje ostatních uživatelů. Jeho hlavním úkolem je vytváření šablon, ze kterých si uživatelé generují vlastní testy. Administrátor má také možnost
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
21
testy upravovat, mazat z nich jednotlivé testové otázky a nastavovat časový měřič limitu na vypracování testu.
Obrázek 4.3: Diagram datových toků - Neregistrovaný uživatel
Obrázek 4.4: Diagram datových toků - Student
4.3
Dynamický model - životní cyklus testu
Reakce systému v závislosti na akcích uživatelů jsou velice podobné běžným aplikacím stejného typu. Proto není zapotřebí tyto triviální reakce systému rozvádět. Výjimku tvoří životní cyklus testu, který ovlivňuje značnou část uživatelských akcí. Jak bylo již dříve zmíněno, testy se generují z předpřipravených testových šablon. Od vygenerování až po ohodnocení prochází test několika fázemi, které se od sebe navzájem liší tím, jak je možné v těchto fázích s testem pracovat.
22
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
Obrázek 4.5: Diagram datových toků - Administrátor
1. fáze - Aktivní šablona Tato fáze reprezentuje období testu před jeho vznikem. Jakmile administrátor sestaví testovou šablonu a označí ji jako aktivní, může student použít tuto šablonu pro vygenerování testu. Šablony, které nejsou aktivní, jsou pro studenta skryté, a proto z nich testy generovat nemůže.
2. fáze - Aktivní test V době generování nového testu se z parametrů testových otázek vypočítá časový interval potřebný na vypracování testu. Po tento interval bude test aktivní a bude patřit do 2. fáze životního cyklu. Po celou dobu této fáze je student oprávněn odpovídat na testové otázky a to dokonce i po odhlášení a opětovném přihlášení do systému. Po uplynutí času stanoveného na vypracování přechází test automaticky do 3. fáze. Pokud student dokončí test dříve než vyprší limit, může si nechat test vyhodnotit a tím přeskočit 3. fázi cyklu a přemístit ho přímo do 4. fáze.
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
23
3. fáze - Test čekající na vyhodnocení Po skončení časového limitu již není možné dále test upravovat ani prohlížet2 . Test se nachází ve stavu, kdy čeká na vyhodnocení testových otázek. Tuto akci může provést student kdykoli. Pokud test není ohodnocen, nezapočítávají se výsledky do celkového hodnocení studenta. Administrátor má možnost obnovit časový měřič testu. Tato volba může být užitečná v případě, kdy student neměl možnost regulérně test dokončit. Příkladem mohou být technické problémy připojení k systému apod. Po obnovení měřiče přechází test do 2. fáze Aktivní test a student může dokončit skládání testu. Zároveň platí, že administrátor má možnost test kdykoli ze systému odstranit a tím dát opět studentovi možnost ostrý test z této šablony generovat. 4. fáze - Kompletní Test Po vyhodnocení testu už samozřejmě nelze test dále upravovat. Je možné ho pouze prohlížet. U vyhodnocených otázek je zvýrazněno, zda student odpověděl na otázku správně či špatně. Zároveň má student k dispozici i správné řešení. Všechny ostré testy, které se nacházejí v této fázi, jsou započítávány do výsledného hodnocení. Celý životní cyklus testu je zobrazen pomocí dynamického modelu na obrázku 4.6. Výrazně jsou značeny ty stavy, které představují jednotlivé fáze životního cyklu. Pro přesnost je třeba dodat, že v diagramu není značena možnost odstranění testu. Tato akce může být provedena pouze administrátorem a to v každém ze stavů, v kterých se může test nacházet. Akce není do diagramu zanesena z důvodu zvýšení jeho přehlednosti.
2
Toto pravidlo se nevztahuje na administrátora
24
KAPITOLA 4. TVORBA ANALYTICKÉHO MODELU
Obrázek 4.6: Dynamický model životního cyklu testu
Kapitola 5 Návrh systému Tato kapitola popisuje hlavní body návrhu systému SyVyKoD. Je rozdělena do dvou hlavních částí. První popisuje návrh modulu pro vizualizaci kompresních algoritmů. Druhá část se zabývá návrhem modulu pro testování studentů.
5.1
Modul pro prezentaci kompresních algoritmů
Hlavním cílem této části je vytvoření šablony XHTML dokumentu, který bude studentům předmětu Komprese dat sloužit k vytváření prezentací kompresních algoritmů. U každé ukázky algoritmu je uveden jeho krátký popis vlastností, činnosti a především applet, který vizualizuje proces komprese a dekomprese zadaného vstupního textu. Tyto applety jsou vytvářeny v rámci semestrálních prací a navazují na diplomovou práci [1]. Dalším úkolem je návrh struktury webových stránek, které semestrální práce prezentují. Při návrhu přichází v úvahu dvě možnosti řešení. První z nich, která by seskupovala modul pro prezentaci algoritmů a modul pro testování studentů v jeden celek, může využívat výhod dynamického webu, což by pomohlo obzvláště při realizaci navigace mezi jednotlivými ukázkami algoritmů. Jako lepší se však ukázala možnost druhá, která rozděluje oba moduly na dva na sobě zcela nezávislé celky. Modul pro prezentaci algoritmů tak může být realizován formou statických webových stránek, což ho činí nezávislým na aplikačních serverech a webových službách a může být tudíž provozován i lokálně na offline PC stanici. Web existuje ve dvou jazykových variantách - české a anglické. Navržení kostry modulu umožňuje přepnutí jazyka v libovolné době při zachování zobrazovaného tématu. 5.1.1
Struktura modulu
V následujícím textu je popsána struktura modulu. img ALG1 index_cs.html index_en.html ALG1.jar ALG2 ... styl.css compression.jar epsgraphics.jar
-
adresář s obrázky adresář algoritmu ALG1 český popis algoritmu anglický popis algoritmu vizualizační applet algoritmu ALG1 adresář algoritmu ALG2
- specifikace grafického vzhledu - základní balíček pro vizualizační applety - balíček pro výstup obrázků v postskriptovém formátu 25
26
KAPITOLA 5. NÁVRH SYSTÉMU streams.jar index.html index_en.html obsah.html content.html
-
balíček pro podporu kompresních proudů úvodní strana v češtině úvodní strana v angličtině přehled všech dostupných algoritmů v češtině přehled všech dostupných algoritmů v angličtině
Soubory compression.jar a streams.jar jsou archivy podporující vývoj aplikací zabývajících se kompresí dat. Konkrétně se jedná o základní třídy pro vytváření vizualizačních appletů. Jednotlivé vizualizační applety jsou uloženy v adresářích pojmenovaných podle názvu algoritmu. V adresářovém výpisu slouží jako ukázka algoritmu adresář ALG1, který obsahuje XHTML dokumenty pro popis algoritmu a JAR archiv s vizualizačním appletem.
5.2
Modul pro testování studentů
Dobrý návrh struktury, objektů a vztahů mezi nimi je velice důležitý pro celkový vývoj modulu. Pokud k odhalení nedostatků systému dojde už ve fázi návrhu, je jeho změna méně bolestivá než v následujících fázích vývoje. Až doposud nebylo zapotřebí specifikovat na jakých konkrétních technologiích bude systém postaven. V tomto stupni vývoje je však třeba učinit rozhodnutí, které ovlivní jeho další směr. Odborná literatura uvádí, že i fáze návrhu má být pokud možno nezávislá na prostředcích konečné implementace. V tomto případě je návrh specifický natolik, že další abstraktní pohled na věc by byl nepřínosný. V následujícím textu bude nastíněna podoba aplikace do té míry, aby bylo možné provádět její další návrh. 5.2.1
Typ aplikace
Modul pro testování studentů je realizován jako webová aplikace založená na Java 2 Platform Enterprise Edition (J2EE). J2EE je standardní součástí Javy. Platforma Java byla vybrána kvůli výhodám, které nabízí. Jedná se o perspektivní objektový programovací jazyk. Je vyvíjen společností SUN Microsystems a je zdarma dostupný pro různé operační systémy (Windows, Linux, Solaris atd.) Nezávislost na operačním systému a na hardwaru počítače zajišťuje způsob kompilace. Zdrojové kódy programu nejsou překládány do strojového kódu procesoru, ale pouze předzpracovávány do tzv. byte-kódu. Ten ještě není závislý na konkrétním procesoru, ale časově náročné fáze kompilace jsou v něm již provedeny. Při spuštění Java programu je byte-kód interpretován virtuálním strojem Java Virtual Machine (JVM). Java tedy patří do skupiny interpretovaných jazyků. J2EE je množina specifikací a praktik, které dohromady poskytují řešení pro vývoj, rozmístění a řízení vícevrstvých serverových aplikací. J2EE vychází z Java 2 Standard Edition (J2SE), k níž přidává vlastnosti potřebné pro poskytnutí stabilní, bezpečné a rychlé Java platformy na úrovni podnikových aplikací. Mezi tyto vlastnosti patří například zpracování událostí na straně serveru, řízení transakcí, databázové služby a další. Platforma J2EE zpřístupňuje podnikové aplikace širokému spektru klientů včetně internetových prohlížečů. Spojuje celou řadu
KAPITOLA 5. NÁVRH SYSTÉMU
27
technologií do jediné architektury s komplexním modelem programování aplikací. Platforma J2EE podstatně zjednodušuje vývoj síťových aplikací a snižuje jeho náklady. Modul pro testování (dále označován jako webová aplikace) nevyužívá všech dostupných součástí J2EE, ale zaměřuje se na použití servletů a JSP stránek. Servlet je obdoba CGI skriptu napsaná v Javě. Je to třída odvozená z třídy javax.servlet.http.HTTPServlet. Oproti CGI skriptům má několik výhod. Servlet je jednou zkompilován a načten do paměti. Potom už jenom odpovídá na požadavky klientů (takže je rychlejší než PHP, CGI nebo ASP). Jelikož je servlet program psaný v Javě, má přístup k většině Javovských knihoven. Servlet běží v servlet kontejneru aplikačního serveru. JSP je technologie založená na servletech, která jejich použití velice zjednodušuje a tím zrychluje vývoj webových aplikací. Další výhoda, kterou JSP mají, je oddělení obsahu od zpracování. Pro tyto účely používají JSP tzv. javabeans a uživatelské tagy. JSP technologie umožňuje směšovat statické HTML stránky s dynamicky generovaným obsahem. JSP stránky je možno používat i samostatně, ale podstatně lepší využití se nabízí ve spolupráci se servlety. Použití servletu je totiž poměrně obtížné pro vytváření statického HTML kódu. JSP se proto používá ke směšování statických částí HTML stránek, které jsou napsány v klasickém HTML kódu, s dynamickými částmi, které jsou vytvářeny pomocí servletu. 5.2.2
Návrh struktury aplikace
Při návrhu systémů je výhodné používat osvědčené postupy, kterým se říká návrhové vzory. Tyto postupy jsou dostatečně propracované a pomáhají k modularizaci systému a tím i k jeho lepšímu pochopení. Systém SyVyKoD ve svém návrhu používá několik takovýchto vzorů. Celý systém je navržen podle modelu MVC - Model-View-Controller. MVC (někdy také označován jako Model-2) je softwarová architektura, která rozděluje datový model aplikace, uživatelské rozhraní a řídicí logiku do tří nezávislých komponent tak, že modifikace některé z nich má minimální vliv na ostatní. Komponenty MVC mají následující funkce: • Komponenta Model představuje specifickou reprezentaci informací, s nimiž aplikace pracuje. • Komponenta View převádí data reprezentovaná modelem do podoby vhodné k interaktivní prezentaci uživateli. • Komponenta Controller reaguje na události (typicky pocházející od uživatele) a zajišťuje změny v komponentě model nebo v komponentě view. Použití tohoto návrhového vzoru v systému SyVyKoD je znázorněno na obrázku 5.1. Obrázek představuje obecný model, podle kterého je postavena celá aplikace. Aplikace je řízena požadavky uživatelů. Na každý HTTP požadavek je vygenerována HTTP odpověď, která je zaslána zpět uživateli. Požadavky přijímá controller, který je v aplikaci reprezentován servlety zvanými dispatchery. Dispatcher má za úkol rozhodnout, zda je přijímaný požadavek platný či nikoli. Jestliže ano, servlet extrahuje parametry předávané v HTTP požadavku. Podle těchto
28
KAPITOLA 5. NÁVRH SYSTÉMU
parametrů zavolá příslušnou akci objektu BackingBean a předá mu extrahované parametry. BackingBean má za úkol připravit data pro komponentu view. Pokud má prováděná akce změnit datový model, BackingBean vytvoří objekt JavaBean, který slouží pouze jako kontejner pro přenášená data. Tento kontejner je zaslán komponentě model, která podle předávané JavaBeany provede příslušné změny v datovém modelu.
Obrázek 5.1: Použití návrhového vzoru MVC v základní struktuře aplikace
Komponenta model se skládá z několika vrstev. Nejspodnější vrstvu tvoří datový zdroj1 , který uchovává data systému. S datovým zdrojem komunikují tzv. DAO (data access object) objekty, které slouží jako rozhraní mezi datovým zdrojem a zbytkem aplikace. Použitím DAO objektů je docíleno odstínění aplikační logiky od perzistentní vrstvy, což mimojiné umožňuje i snadnou výměnu datového zdroje bez zásahu do jiných komponent než DAO objektů. Každý DAO objekt je spjatý s jednou z databázových entit popsaných v relačním modelu dat. Jelikož jedna akce může ovlivňovat více entit najednou, je na rozhraní mezi komponentou controller a komponentou view zařazen ještě jeden typ objektů, který se nazývá DatabaseBean. Ten má za úkol reagovat na požadavky od BackingBean a provádět změny v modelu s využitím přesně těch DAO objektů, které jsou k provedení akce potřeba. Z komponenty model proudí data opět zapouzdřená v JavaBeanech zpět do komponenty controller. Podle výsledku prováděné akce objekt BackingBean určí, jak se komponenta view změní. Jinými slovy řečeno, BackingBean vybere JSP stránku, která bude uživateli ve formě HTTP odpovědi odeslána. Pak předá řízení opět servletu. Ten už jen zařídí přesměrování HTTP 1
Datový zdroj je v nejčastějších případech reprezentován databázovým serverem
KAPITOLA 5. NÁVRH SYSTÉMU
29
požadavku na příslušnou JSP stránku. JSP stránky představují komponentu view. Při generování XHTML kódu si JSP stránky od objektu BackingBean vyžádají připravená data. Ta jsou jím uchovávána po zbytek doby trvání HTTP požadavku. Odesláním HTTP odpovědi ve formě vygenerované XHTML stránky životnost požadavku končí. Komponenta view neslouží v systému pouze jako interpret dat, ale zároveň jako rozhraní pro zadávání uživatelských požadavků. Toto rozdělení aplikace zajišťuje přehlednost a jasné přiřazení úloh jednotlivým komponentám. Pro zpřehlednění textu byly některé klíčové úlohy jednotlivých komponent vynechány. Následující text ve stručnosti zrekapituluje všechny podstatné komponenty a vyjmenuje jejich hlavní úkoly. Servlet přijímá požadavky od uživatelů. Pokud je požadovaný zdroj dostupný pouze přihlášeným uživatelům, kontroluje zda uživatel přihlášený je či není. Z přijatých parametrů určí požadovanou akci a zavolá ji. Objekt BackingBean, který akci provádí, zkontroluje, zda má přihlášený uživatel oprávnění k vykonávání této akce. Pokud ano, tuto akci provede. Pokud ne, pak se jako cílová označí JSP stránka, která informuje o neprivilegovaném přístupu. Většina prováděných akcí spolupracuje s komponentou model. Z této komponenty přicházejí data ve formě JavaBeanů. Ty jsou uchovány v objektu BackingBean pro JSP stránku. Po vykonání akce přesměruje servlet požadavek na příslušnou JSP stránku. Ta vygeneruje XHTML stránku podle dat z JavaBeanů. Z takto navržené struktury vyplývá, že všechny akce, které lze v systému provádět, jsou prováděny v objektech BackingBean. Z tohoto důvodu jsou tyto objekty vhodné pro zaznamenávání událostí systému - tzv. logování.
Kapitola 6 Realizace Tato kapitola popisuje řešení a prostředky zvolené při implementaci systému. Je rozdělena do dvou hlavních částí. První část popisuje modul pro prezentaci kompresních algoritmů. Druhá, rozsáhlejší, je věnována modulu pro testování studentů. Na úvod každé části jsou vyjmenovány potřebné softwarové produkty, bez kterých není možné systém provozovat. Dále následuje popis použitých technologií a v závěru jsou popsány ty části, které jsou z implementačního hlediska zajímavé a netriviální.
6.1
Modul pro prezentaci kompresních algoritmů
Šablony ukázek algoritmů a struktura webových stránek jsou popsány v předchozí kapitole. Následující text představuje technologie použité při vytváření tohoto modulu.
6.1.1
Použité technologie
Prezentace je realizována pomocí XHTML stránek, které jsou psány tak, aby vyhovovaly standardu XHTML 1.0 ve variantě Transitional. Přestože „čistšíÿ přístup by spočíval v použití varianty Strict, v případech, kdy je do stránky vkládán applet, je nutné použít variantu Transitional. Varianta Strict totiž ve svém DTD použití tagu
... nepovoluje. Tento tag by měl být nahrazován obecným tagem
... , avšak doposud je jeho podpora v různých prohlížečích odlišná, a proto jeho použití přináší celou řadu problémů1 . Podoba XHTML dokumentu představující šablonu pro prezentaci algoritmů je k dispozici na CD přikládaném k diplomové práci.
6.1.2
Grafický vzhled
Jednotný grafický vzhled stránek je zajištěn pomocí kaskádových stylů uložených v externím souboru. To přináší výhodu snadné a hromadné modifikace. Pomocí kaskádových stylů lze také snadno ovlivnit odlišný vzhled pro různé jazykové mutace. To je vhodné například k zobrazování odstavců podle národních zvyklostí. Dokument XHTML umožňuje svým atributem xml:lang specifikovat jazyk, který je v dokumentu použit. V kaskádových stylech je možné s touto informací pracovat pomocí pseudo-třídy :lang. Zkombinováním těchto prostředků lze specifikovat vzhled dokumentu odvislý od jazykové mutace bez potřeby změny základní struktury XHTML stránek. 1 Řešení by spočívalo v detekci prohlížeče skriptovacím jazykem a přizpůsobením tagu
podmínkám konkrétního prohlížeče.
31
32
KAPITOLA 6. REALIZACE
6.1.3
Podepisování JAR archivů
Jelikož vizualizační applety umožňují uložení obrázku na disk, musejí být podepsány. Standardní bezpečnostní mechanismy Javy neumožní uložení obrázku na disk bez přijetí podpisu2 . Proto je zapotřebí vytvořit certifikát, kterým lze JAR archivy podepisovat. Pro bezpečnostně méně citlivé aplikace postačuje tzv. self-signed certifikát, což je certifikát, který nevydala žádná certifikační autorita. Všechny nástroje potřebné k podepsání JAR archivu jsou standardní součástí JDK. Nejdříve je zapotřebí vytvořit úložiště, do kterého se certifikáty ukládají. K tomuto účelu lze použít nástroj keytool. keytool -genkey -keystore mykeys -alias myself Keytool se nejdříve zeptá na základní informace a posléze i na heslo. V dalším kroku je vytvořen samotný self-signed certifikát. keytool -selfcert -alias myself -keystore myKeystore V posledním kroku se podepíší všechny JAR archivy. jarsigner -keystore myKeystore ALG1.jar myself Podrobnější detaily ohledně vizualizačních appletů jsou k dispozici v [1].
6.2
Modul pro testování studentů
Tento stěžejní modul je realizován jako webová aplikace postavená na několika vzájemně se doplňujících technologiích. Je navržen jako třívrstvá aplikace typu klient-server, která se skládá z aplikační, datové a prezentační vrstvy. 6.2.1
Použité technologie
V návrhu systému bylo zmíněno, že aplikace je postavena na platformě J2EE vycházející z J2SE. Pro implementaci aplikace byly zvoleny verze 5.0 pro J2SE a verze 1.4 pro J2EE. 6.2.1.1
Aplikační server
Aplikační server je srdcem celého informačního systému. Řadí se mezi střední vrstvu v takzvané vícevrstvé architektuře. Současným trendem ve vývoji aplikací je odlehčování koncovým zařízením (PC, PDA, mobilní telefony atd.) od aplikační logiky a plné využívání komfortu vícevrstvé architektury. Výhody, které tento model nabízí, jsou zřejmé. Ve starších přístupech část aplikační logiky spočívala na klientské části. V praxi to představovalo použití aplikace 2
V některých prohlížečích existuje možnost obejití této ochrany nastavením důvěryhodných zdrojů dat
KAPITOLA 6. REALIZACE
33
desktopového typu, která komunikovala se serverem a vykonávala část aplikační logiky. Ovšem tyto aplikace vyžadovaly složitější údržbu než klienti ve třívrstvé architektuře. Ty jsou dnes většinou zastoupeny webovými prohlížeči a je na nich ponechána pouze prezentační část. Aplikační server kromě výkonných funkcí aplikační logiky zároveň provádí komunikaci s databázovými servery, na kterých jsou uložena data. Ve většině případů bývá aplikační server spojen i s webovým serverem, který je zodpovědný za přijímání uživatelských požadavků, komunikaci s aplikačním serverem a odesílání odpovědí zpět k uživateli.
Apache Tomcat Jakarta, nebo také Apache Jakarta, je projektem organizace Apache Software Foundation3 . Cílem projektu Jakarta je vytvářet kvalitní open-source řešení serverových aplikací pro Java platformu. V současné době se jedná o nejkomplexnější volně šiřitelné řešení pro serverové aplikace. Jedním ze stěžejních podprojektů je projekt Jakarta Tomcat, nazývaný také jako Apache Tomcat. Tomcat je aplikační server, který je považován ze referenční implementaci servlet kontejneru, což zajišťuje, že obsahuje vždy ty nejnovější specifikace. Tomcat 5.5 nabízí podporu servletů ve verzi 2.4 a JSP ve verzi 2.0. Tyto verze jsou také použity pro implementaci modulu testování. Tomcat může pracovat v samostatném módu, kdy není zapotřebí žádný další webový server, nebo ve spolupráci s jiným webovým serverem jako je například Apache, IIS a jiné. Tomcat je rychlejší pokud běží samostatně, ale pokud je provozovaný web spíše statického rázu, pak je lepší použít druhý způsob. Díky tomu, že je Tomcat psaný v Javě, je platformově nezávislý a může být provozován na všech systémech, pro něž existuje JVM. Server je snadno konfigurovatelný buďto pomocí konfiguračních nástrojů nebo pomocí přímé editace XML konfiguračních souborů. Pro uvedené vlastnosti byl Apache Tomcat vybrán jako aplikační server systému SyVyKoD. Popis instalace a správy serveru je uveden v příloze B.2.
6.2.1.2
Databázový server
Databázový server je softwarový produkt, který ostatním systémům poskytuje služby pro uchovávání dat a manipulaci s nimi . Tímto termínem bývá také označován počítač, na kterém server běží. Při výběru vhodného databázového serveru je třeba zvážit, co přesně od konkrétního serveru požadujeme. U menších systémů, jako je i SyVyKoD, hraje důležitou roli cena produktu a vlastnosti podporované serverem. S přihlédnutím k těmto faktům byl zvolen databázový server PostgreSQL. 3
Hlavní portál projektu se nachází na adrese http://jakarta.apache.org
34
KAPITOLA 6. REALIZACE
PostgreSQL PostgreSQL je relační databáze vyvíjená jako open-source. Je to jeden z nejvyspělejších databázových systémů v této skupině. PostgreSQL je postaven na systému klient - server, který podporuje transakční zpracování. V jazyku SQL podporuje cizí klíče, spojování tabulek, pohledy, vnořené příkazy SELECT, příkazy CASE, COALESCE a NULLIF. Tyto všechny vlastnosti jsou implementací aplikace hojně využívány. Důležitý je fakt, že pro PostgreSQL existuje JDBC driver, který umožňuje snadné spojení z aplikací napsaných v Javě. Tento driver není jediný, který PostgreSQL podporuje. Možnosti připojení jsou podporovány například i pro programovací jazyky PHP, Perl, Pascal, Python, C/C++ a další. Velkou předností PostgreSQL je podpora všech moderních operačních systémů včetně OS/2 a Novell. Je součástí většiny distribucí Linuxu. Je šířen pod BSD licencí umožňující vlastní úpravy a šíření binárního kódu. Mezi další přednosti patří vysoká rychlost a stabilita.
6.2.1.3
Prezentační vrstva
Prezentační vrstva zaujímá ve třívrstvém modelu nejméně komplikovanou část. Má na starosti zobrazování informací zasílaných aplikačním serverem. K tomuto účelu prezentace byly zvoleny webové stránky. Ty mohou uživatelé prohlížet pomocí webových prohlížečů, které jsou běžnou součástí operačních systémů. Na straně klienta tudíž není nutná instalace nových programů. Webové stránky jsou vytvářeny podle standardu XHTML 1.0 Strict, který je doporučován konsorciem W3C. O grafickou podobu stránek se starají kaskádové styly, které předepisují vzhled celé aplikace centralizovaně v externím souboru. Změna v tomto souboru se projeví v grafickém vzhledu všech stránek. Pro zobrazování obsahu webových stránek používají různí uživatelé různé prohlížeče. Prohlížeče jsou vyvíjeny různými tvůrci. Je spíše výjimkou, že by některý výrobce v implementaci prohlížeče striktně dodržoval webové standardy. Z tohoto důvodu se chování a interpretace obsahu stránek často značně odlišuje a to nejen v závislosti na typu prohlížeče, ale dokonce i v závislosti na jeho verzi. Aplikace pomocí skriptovacího jazyka Java Script zavádí do obsahu stránek dynamické prvky, které zpříjemňují uživatelům provádění některých akcí či zpřehledňují obsah stránek. Podpora JavaScriptu se v různých prohlížečích také velice odlišuje. Z předchozího je zřejmé, že vytváření webových stránek tak, aby jejich vzhled a funkčnost byly totožné ve všech majoritních prohlížečích, není jednoduché. V případě, kdy autoři nechtějí pro každý typ prohlížeče vytvářet samostatný web, musí hledat takové konstrukce, které jsou všemi prohlížeči interpretovány stejně. Systém SyVyKoD je realizován takovým způsobem, aby splňoval podmínky pro správnou funkčnost ve všech standardních prohlížečích. Zároveň počítá i s možností, kdy někteří uživatelé záměrně upravují chování svých prohlížečů, aby co nejvíce vyhovovalo jejich požadavkům. To se může projevit i v zákazu spouštění kódu JavaScriptu. Proto je systém navržen tak, aby využíval výhod JavaScriptu tam, kde je povolen, ale zároveň umožňoval provádění všech akcí
KAPITOLA 6. REALIZACE
35
i bez jeho použití. To samé platí i pro grafický vzhled aplikace. Je navržen tak, aby webové stránky byly čitelné ve všech standardních rozlišeních. 6.2.1.4
Rámce pro vývoj aplikace
Pro urychlení vývoje webových aplikací existuje množství podpůrných nástrojů - tzv. rámců4 . Tyto rámce představují soubor tříd a rozhraní, které v programu společně řeší určitý typ problému. Řada takovýchto rámců je volně k dispozici ke stažení z Internetu a je určena k bezplatnému používání. Mezi nejrozšířenější patří Jakarta Struts, Freemarker, Maverick a další. Asi nejrychleji se rozšiřující rámec založený na platformě Java se jmenuje JavaServer Faces (JSF), který je vytvářený organizací Java Community Process. Je to systém pro tvorbu uživatelského rozhraní aplikací běžící na straně serveru. Základní myšlenka návrhu používá model MVC. Aplikace založená na JSF je realizována jako samostatný servlet. Servlet přijímá veškeré požadavky a zpracovává je podle pravidel JSF životního cyklu. Vstupem servletu jsou HTTP požadavky. Hlavním bodem, který si JSF klade za cíl, je přiblížení vývoje webových aplikací co nejblíže k postupům použitých u vývoje desktopových aplikací využívajících grafické komponenty. Mechanismy JSF například zajišťují snadnou validaci webových formulářů. Zároveň pokud formulář validací neprojde, jsou obsahy grafických komponent formuláře automaticky obnoveny, aniž by se o to musel sám programátor starat. Díky těmto vlastnostem byla původně technologie JSF použita při vývoji aplikace. Při implementaci se však ukázalo, že tento nástroj není vhodný pro vývoj systému jako je SyVyKoD. Velkou překážkou se ukázala nutnost podpory JavaScriptu ve webových prohlížečích a to i pro akce tak triviální, jako je přechod na jinou stránku pomocí hypertextového odkazu. Základní mechanismy JSF jsou nastaveny tak, že umožňují práci převážně na vyšších vrstvách této technologie, a proto není možné dostatečně flexibilně ovlivňovat celý proces zpracování požadavků. V praxi to znamená složité zabezpečování nadbytečných dotazů zasílaných na databázový server. Z těchto důvodů nebyla technologie JSF použita. Naprosto mylný názor by si čtenář z těchto odstavců vyvodil, kdyby se domníval, že autor považuje technologii JSF za špatnou, pro tvorbu webových aplikací nepoužitelnou. To jistě není pravda. Technologie má svou cílovou skupinu aplikací, kde její nasazení pomáhá k urychlení vývoje a k omezení chybovosti systému. Zvláště u případů, kdy je aplikace psána pro konkrétní cílovou skupinu uživatelů, kteří při práci s aplikací používají stejné nástroje, čímž lze zajistit podmínky pro funkčnost celé aplikace. Pro realizaci systému byl vyvinut jednodušší rámec, který zdaleka nenabízí všechny možnosti JSF, ale na druhou stranu je „ušitý na míruÿ podobným aplikacím jako je SyVyKoD a uspokojuje většinu požadavků vyvstávajících při jejich implementaci. Obsahuje mnoho dobrých myšlenek přejatých z technologie JSF. Rámec se nesestává pouze z tříd, ale předepisuje i strukturu jednotlivých komponent aplikace a jejich vzájemnou interakci. Dodržování těchto pravidel zajišťuje neustálý přehled nad kódem jednotlivých komponent. Proto přidávání nových 4
Rámec je běžně používaný český překlad pro anglický termín framework.
36
KAPITOLA 6. REALIZACE
komponent nečiní žádné problémy, pravidla přesně určují, kam která komponenta patří. Tato pravidla de facto ovlivňují i strukturu aplikace popsanou v kapitole 5.2.2, kde přesně stanovují jaké objekty se nacházejí v jednotlivých komponentách MVC modelu. Rámec se dále vyznačuje těmito vlastnostmi: • podporuje snadné ovládání navigace mezi JSP stránkami a servlety, • nabízí propracovaný systém pro předávání chybových a informativních zpráv, • umožňuje snadnou manipulaci s parametry základních typů v HTTP dotazech, • zavádí základní třídy zodpovědné za vyřizování HTTP požadavků, • součástí rámce je celá řada validátorů pro ověřování správnosti parametrů předávaných v HTTP dotazech, • nabízí nástroje pro běžné postupy používané při vývoji webových aplikací jako je spojení s databázovým serverem, řazení a filtrování záznamů založené na SQL dotazech, • implementuje sadu uživatelských JSP tagů, které zpřehledňují kód JSP dokumentů. Vytváření takového rámce bylo sice časově náročné, ale tato investice se v pozdějším vývoji samotné aplikace mnohonásobně vrátila. Implementace rámce je obsažena v balíčku net.ouska.webtool a je poskytována v odděleném JAR archivu webtool.jar společně s aplikací. Aby mohla aplikace s rámcem plně spolupracovat, je nutné do aplikace přiřadit soubor net.ouska.tag.tld, který popisuje strukturu balíčku. Tento soubor je společně s celým balíčkem k dispozici na CD přiloženém k diplomové práci v adresáři software/net.ouska.webtool. Instalace systému SyVyKoD má v sobě tento balíček zakomponovaný, čili už ho není nutné do aplikace nahrávat. Podrobnosti o instalaci jsou popsány v příloze B. Rámec se skládá ze čtyř hlavních částí. Balíček net.ouska.webtool.database obsahuje třídy pro práci z databází. Jedná se o rozhraní databázového připojení, které umožňuje implementaci jak poolovaného tak nepoolovaného způsobu spojení s databází. Dále balíček obsahuje třídy Sorter a Filter, které slouží pro snadné použití třídění a filtrování databázových záznamů prezentovaných pomocí XHTML stránek. Druhý balíček net.ouska.webtool.tag definuje sadu uživatelských JSP tagů, které zpřehledňují strukturu JSP dokumentu. Jedná se především o definici komponent, které na základě předávaného parametru umožňují prezentovaná data buď pouze prohlížet nebo i editovat. V balíčku net.ouska.webtool.validator jsou implementovány validátory HTTP parametrů. Třídě ParamExtractor, která má za úkol extrahování parametrů z HTTP požadavků, může být předán příslušný validátor kontrolující podmínky, které musí hodnota atributu splňovat. Příkladem mohou být validátory kontrolující minimální a maximální hodnoty číselných atributů, prázdné hodnoty textových řetězců atd. Pokud hodnoty parametrů nevyhovují nastaveným podmínkám, validátor předá objektu ParamExtractor zprávu, která pak může být zobrazena například u formulářové vstupní komponenty.
KAPITOLA 6. REALIZACE
37
Poslední skupinou jsou třídy přímo v balíčku net.ouska.webtool. Jsou to třídy zastřešující použití nástrojů z prvních tří balíčků. 6.2.2
Struktura tříd systému
Modul pro testování studentů je koncipován jako webová aplikace vycházející z J2EE. J2EE jasně definuje strukturu takovýchto aplikací. JSP stránky, představující prezentační komponenty, se obecně umisťují do kořenového adresáře aplikace. Implementace aplikační logiky ve formě Java tříd má své definované místo v podadresáři WEB-INF/classes. Odtud se Tomcat snaží používané třídy nahrávat do JVM. Třídy aplikace jsou strukturovány do několika balíčků. Balíček elearning.servlet obsahuje implementaci všech servletů. Tyto servlety jsou považovány za vstupní bránu aplikace přijímající HTTP požadavky. Balíček elearning.database obsahuje implementace DAO objektů - pro každou databázovou tabulku jeden. Dále jsou zde implementovány jednotlivé Sortery a Filtery. Nejvíce tříd obsahuje balíček elearning.bean. Zde jsou implementovány JavaBean třídy sloužící pro transport dat. Jména tříd kopírují označení databázových entit. Nejdůležitější postavení zde zaujímají hierarchické struktury tříd QuestionTemplate a TestQuestion. QuestionTemplate je předkem tříd reprezentujících různé typy šablon otázek. TestQuestion je předkem tříd reprezentujících testové otázky generované ze šablon. Objektový přístup umožňuje takovou implementaci, kde každá šablona generuje svou příslušnou testovou otázku. Balíček elearning.bean.backing obsahuje třídy typu BackingBean popsané v kapitole 5.2.2. Též popsané třídy typu DatabaseBean obsahuje balíček elearning.bean.database. Veškeré lokalizované texty aplikace jsou zařazeny do elearning.messages, kde mohou být podle potřeb upravovány. Programové rozhraní pro vytváření nových zásuvných modulů otázek je k dispozici v balíčku elearning.question. Detailní přehled použití těchto rozhraní je popsán v kapitole 7. Ukázky takovýchto modulů, zaměřených na výuku komprese dat, jsou dodávané se systémem SyVyKoD v balíčku kod.question. Posledním z balíčků elearning.exception obsahuje množinu definovaných výjimek použitých v aplikaci. 6.2.3
Zabezpečení systému
Webové aplikace jsou kvůli své dostupnosti často vyhledávaným cílem nejrůznějších bezpečnostních útoků. Útočníci se snaží nacházet slabá místa v zabezpečení a využitím těchto slabin systém upravit či vyřadit z provozu nebo dokonce převzít nad systémem úplnou kontrolu. Proto je pro vývojáře systémů důležité tato slabá místa objevovat a případným útočníkům jejich postupy co nejvíce znesnadňovat. Otázka zabezpečení webových aplikací není vůbec triviální. Často se můžeme setkat se systémy, které jsou sice na jednu stranu postaveny na nejmodernějších zabezpečovacích systémech, ovšem na druhou stranu opomíjejí například základní bezpečnostní pravidla týkajících se správy hesel apod. U zabezpečování aplikací stále platí pravidlo:
38
KAPITOLA 6. REALIZACE
„Celkové zabezpečení systému je tak kvalitní, jak kvalitní je zabezpečení jeho nejslabší části.ÿ
6.2.3.1
Autentizace a autorizace
Autentizace, neboli ověření identity uživatele, je v systému řešena pomocí uživatelských jmen a hesel. Ta jsou uložena v databázi systému. Pokud se uživatel chce do systému přihlásit, musí se systému identifikovat uživatelským jménem. Aby potvrdil svou identitu, musí prokázat znalost uživatelského hesla. Porovnáním údajů od uživatele a údajů z databáze systém zjistí, zda je uživatel oprávněn vstoupit do systému a využívat tak funkcí přihlášeného uživatele. Pro zvýšení bezpečnosti nejsou v databázi ukládaná přímo hesla, ale pouze jejich MD5 kódy. Stejně tak i z hesla, kterým se uživatel prokazuje, je pořízen MD5 kód a ten je porovnán s kódem v databázi. Porovnáním těchto kódů systém prověří, zda uživatel zadává správné či špatné heslo. Proto ani uživatel, který má přístup k databázovému serveru, nemá možnost cizí uživatelská hesla zjistit. Tato metoda ovšem neodstraňuje nevýhody plynoucí z požívání HTTP protokolu při ověřování uživatele. HTTP je protokol založený na přenosu informací v textové formě. Proto může dojít k odposlechu HTTP požadavku, a tak k získání jména a hesla jiného uživatele. Částečné řešení by nabízelo použití JavaScriptu. V tomto řešení by server nejdříve poslal klientovi náhodně vygenerované znaky. Po té, co by uživatel zadal své heslo a odeslal formulář, JavaScript by spojil toto heslo a přijaté znaky a ze vzniklého řetězce vytvořil MD5 kód, který by putoval přes síť. Server by ze znalosti správného hesla (v textové podobě) a znaků zaslaných klientovi vytvořil MD5 kód stejným způsobem. Pokud by se oba kódy shodovaly, by byl uživatel do systému přihlášen. Výhoda tohoto přístupu by spočívala v omezení přenosu čitelného hesla přes počítačovou síť. Vedle ukládání hesla v textové podobě však existuje ještě jedna nevýhoda tohoto řešení. Tou je nezbytná podpora JavaScriptu v prohlížeči. Kvůli tomuto omezení není v systému metoda použita. Nejlepším řešením problému přenosu hesla po síti je vytvoření zabezpečeného kanálu. Ten lze realizovat například pomocí protokolu HTTPS. Veškerá data, která si server a klient vyměňují, cestují po síti v šifrované podobě. Autorizace je proces zpřístupňování částí systému podle oprávnění, která přihlášený uživatel získal autentizací. Uživatel může v systému provádět pouze některé akce nad některými daty. Autorizace se neřídí pouze uživatelskými rolemi, ale i vlastnictvím zdrojů. Student smí například prohlížet pouze ty testy, jejichž je vlastníkem, smí odpovídat pouze na otázky svého testu atd.
6.2.3.2
Prolomení autorizace
Existuje celá řada postupů, kterými se lze pokusit o prolomení procesu autorizace. Mezi nejrozšířenější patří podvrhování HTTP požadavku. Jedná se o jednoduchou metodu, kdy se útočník snaží dostat systém do takového stavu, do kterého by se normální cestou nedostal. U webových aplikací jsou akce zpřístupněny pomocí URL odkazů. Po kliknutí na takovýto odkaz vytvoří prohlížeč HTTP požadavek a odešle ho na server. Systém na webových stránkách nabízí uži-
KAPITOLA 6. REALIZACE
39
vatelům pouze ty URL odkazy, které reprezentují akce, jež mohou být uživatelem prováděny. Pokud uživatel zfalšuje URL odkaz, a odešle takto připravený HTTP požadavek na server, může se při špatné bezpečnostní ochraně stát to, že systém požadovanou akci provede, aniž by ověřil, zda má k provádění akce uživatel oprávnění. Počítá totiž s tím, že uživatel provádí pouze ty akce, které mu byly v předchozím stavu systémem nabídnuty. Lepší pochopení nabízí následující příklad.
Příklad 6.1: Student se pokusí zhoršit studijní výsledky svému kolegovi tím, že bude chtít odpovídat na otázky jeho testu. Nejdříve si zjistí identifikační čísla otázek kolegova testu. Pak se přihlásí do systému a sám začne vyplňovat libovolný test. Po zobrazení otázky si nechá zobrazit HTML kód stránky a modifikuje jej tak, že místo identifikačních čísel svých otázek doplní čísla otázek kolegy. Systém je ve stavu, kdy čeká, že student bude odpovídat na své otázky. Proto při obdržení požadavku na uložení odpovědi zjistí, na kterou otázku chce student odpovědět a odpověď příslušné otázky zmodifikuje. Ovšem identifikační čísla v příchozím HTTP požadavku byla zfalšována, a tak systém změní odpověď, která se vztahuje k testové otázce kolegy, a ne přihlášeného studenta. Systém SyVyKoD používá několik přístupů, kterými čelí prolomení autorizace. Metoda ochrany založená na utajení (označována jako security through obscurity) je velice prostá. Spoléhá na to, že útočník nemůže způsobit žádnou škodu tam, kde neví co má hledat. Webová aplikace přechází z jednoho stavu do druhého na základě HTTP požadavků. Tyto požadavky obsahují parametry, podle kterých aplikace řídí své akce. Příkladem takového předávání parametrů může být odeslání webového formuláře. Formuláře se dají odesílat pomocí dvou metod - GET a POST. Tyto metody se odlišují podle toho, v jaké části HTTP požadavku přenášejí parametry. U GET metody je to v hlavičce požadavku, kdežto u metody POST je to v těle požadavku. Příkladem aplikace bezpečnostní metody založené na utajení je použití metody POST. Je to z toho důvodu, že webové prohlížeče zobrazují hlavičku vysílaného HTTP požadavku. Pokud bude použita metoda GET, uživatel přímo v prohlížeči uvidí jména a hodnoty parametrů určené ke zpracování. Při použití metody POST se informace z hlavičky v prohlížeči nezobrazí. Dalším příkladem může být grafické rozhraní aplikace, které nenabízí uživatelům akce, na jejichž provádění nemají oprávnění. Utajení není špatná taktika. Zabezpečení však nesmí být založeno pouze na ní. Systém ve svém návrhu navíc nepoužívá tak naivní způsob zpracování požadavku, jaký byl uveden v příkladu 6.1. Zajišťuje kontrolu autentizace na několika úrovních. V první řadě kontroluje přístup na JSP stránky. Jak je patrné z obrázku 5.1, HTTP požadavek prochází v systému několika fázemi, ve kterých se připravují data pro prezentaci na JSP stránkách. Pokud uživatel požaduje obsah přímo od JSP stránky, je upozorněn, že adresuje špatnou komponentu systému. Další kontrola probíhá na úrovni servletů - dispatcherů. V systému existují dva druhy servletů - ty, jež je možné kontaktovat i bez přihlášení, a servlety označované jako secure, které přihlášení vyžadují. Pokud servlet dostupný pouze pro přihlášené uživatele obdrží požadavek od uživatele nepřihlášeného, je jeho požadavek odmítnut už na úrovni servletu. Pokud je uživatel
40
KAPITOLA 6. REALIZACE
přihlášený, servlet zavolá akci objektu BackingBean. Ten zkontroluje, zda má uživatel právo akci provádět a zároveň, jestli je uživatel vlastníkem všech prostředků, kterých se akce týká. Tato ochrana je nastavena u každé akce, kterou systém podporuje. Proto ani podvržením HTTP požadavku není možné neautorizované akce provádět.
6.2.3.3
Vkládání XHTML entit do uživatelského vstupu
Zvýšenou pozornost je třeba věnovat u akcí, které ukládají uživatelská data do databáze. Zde se vyplatí řídit se pravidlem, které radí, aby se s daty získanými z uživatelského vstupu nakládalo vždy jako s nedůvěryhodnými. A to proto, že speciálně upravená data mohou být zdrojem pro neplánované ovlivňování systému. V systému SyVyKoD přicházejí do úvahy dva možné důsledky špatné kontroly vstupních dat. Prvním z nich je ovlivňování prezentovaného obsahu stránek pomocí vkládání XHTML entit do textových vstupů. V případech, kdy je uživateli povoleno ukládat do databáze řetězce textu později prezentované na stránkách, může uživatel vložením XHTML tagů do řetězce vzhled těchto stránek ovlivnit. Pokud navíc prohlížeč podporuje JavaScript, je možné HTTP požadavek pomocí správně vložených skriptovacích instrukcí zcela přesměrovat na jiný server a prezentovat tak úplně odlišná data, než bylo původně zamýšleno. Pro vyřešení tohoto problému není potřeba vkládání řetězců obsahujících XHTML entity do databáze zakazovat. Stačí zajistit to, aby kritické znaky5 byly vhodně nahrazeny pomocí bezpečných znakových sekvencí. To zakáže interpretování těchto znaků jako speciálních symbolů a namísto toho budou tyto znaky normálně zobrazeny na stránce. JSP technologie pro takovýto převod nabízí tag . Systém SyVyKoD používá nahrazování speciálních XHTML znaků ve všech případech kromě jednoho. Dovoluje administrátorovi používání XHTML formátování v zadání otázek. Předpokládá se, že administrátor systému je natolik zodpovědný a schopný, aby dokázal formátovací XHTML entity správně využívat a neporušoval tak formátování vzhledu zbytku stránky. Více informací o možnostech formátování je uvedeno v příloze C.5.
6.2.3.4
Vkládání SQL příkazů do uživatelského vstupu
Druhý důsledek špatné kontroly vkládaných dat představuje ještě závažnější problém. Jedná se o vkládání SQL příkazů do uživatelského vstupu (SQL Injection). Přímé zařazení neošetřeného uživatelského vstupu do SQL příkazu může mít za následek nejen jeho chybnou syntaxi, ale dokonce naprostou změnu jeho logiky.
Příklad 6.2: Uvažujme, že student chce získat oprávnění pro vstup do systému pod kolegovým uživatelským jménem. K tomu potřebuje znát příslušné heslo. Heslo může získat následujícím způsobem. Student se přihlásí do systému pod svým uživatelským jménem a heslem. Přepne se na stránku s formulářem pro změnu hesla. Z formuláře se pomocí hidden tagu odesílá 5 V HTML a XHTML se musí znaky &, <, >, ’, ” nahradit pomocí sekvencí &, <, >, ', ".
KAPITOLA 6. REALIZACE
41
parametr ID UZIVATELE a pomocí secret tagu parametr NOVE HESLO. Student vyplní nové heslo a formulář odešle. Data z formuláře jsou použita v následujícím SQL příkazu: update user set password=NOVE_HESLO where id = ID_UZIVATELE. Jestliže student nezmění identifikační číslo v hidden tagu, pak má provedení SQL příkazu kýžený dopad. Ovšem jestliže student změní parametr ID UZIVATELE například na hodnotu ’1’ OR ’1’=’1’, pak sestavený SQL příkaz vypadá následovně. update user set password=NOVE_HESLO where id = ’1’ OR ’1’=’1’ Tento příkaz bude mít za následek změnu hesla všech studentů na hodnotu NOVE HESLO. Přijímaná uživatelská data nesmí být do SQL dotazů vkládaná přímo. Systém SyVyKoD tento problém řeší převáděním hodnot textových parametrů z HTTP požadavků na hodnoty proměnných příslušných datových typů. K tomu slouží třídy z balíčku net.ouska.webtool. To odstraňuje problém s parametry číselného a logickými typu. Ne však s parametry, které reprezentují textové řetězce. Pro bezpečné sestavování SQL příkazů jsou proto využívány třídy z balíčku java.sql. Jedná se o především o třídu java.sql.PreparedStatement, pomocí níž lze SQL předpřipravit a odeslat na databázový server. Tam je příkaz předkompilován pro rychlejší provádění příkazů. V dalším kroku jsou pak na server posílány pouze konkrétní hodnoty atributů, které jsou zařazeny do SQL dotazu. Sám server se postará o správné předřazení „nebezpečných znakůÿ tzv. escape sekvencemi. Použití vypadá následovně. prepStmt=con.prepareStatement(update user set password=‘‘?’’ where id=‘‘?’’); prepStmt.setString(1, NOVE_HESLO); prepStmt.setInt(2, ID_UZIVATELE); prepStmt.executeUpdate();
6.2.4
Implementace grafického rozhraní testových otázek
Každý test se skládá ze sady otázek. Existují tři typy otázek, které systém podporuje. Typy otázek se od sebe liší formou, jakou jsou uživateli předkládány a zároveň způsobem, kterým na ně může odpovídat. Každý typ otázky stanovuje pravidla, podle kterých se vypočítávají body získané za odpověď. Otázky jsou realizovány jako webové formuláře, které jsou sestaveny z různých grafických komponent. Tyto komponenty nabízejí různé formy uživatelského vstupu. Jelikož jsou tyto grafické komponenty vykreslovány prohlížečem, je tudíž jejich vzhled a chování závislé na typu prohlížeče. V aplikaci jsou používány standardní komponenty, které jsou všemi běžnými prohlížeči zobrazovány velice podobně.
42 6.2.4.1
KAPITOLA 6. REALIZACE Testová otázka typu AnswerOne
Tento typ otázky nabízí množinu odpovědí, ze kterých může uživatel volit. Typ otázky definuje, že z celé sady odpovědí je správná právě jedna. Proto je logické, aby se tento fakt v použitém grafickém rozhraní projevil. A to tak, že povolí studentovi označit pouze jednu odpověď. Pro tento účel je v XHTML používána komponenta radio. Několik takovýchto komponent stejného jména se pak chová jako skupina, kde může být označen maximálně jeden prvek. Následující ukázka demonstruje příklad použití a obrázek 6.1 zobrazuje, jak se tyto komponenty vykreslují v prohlížečích. Každá otázka nese informaci o tom, jaké bodové ohodnocení student získá pokud odpoví na otázku správně a bodové ohodnocení pokud odpoví špatně. Otázka tohoto typu se považuje za správně zodpovězenou, pokud student označil správnou odpověď. V ostatních případech je otázka považována za špatně zodpovězenou.
Obrázek 6.1: Ukázka grafického rozhraní otázky typu AnswerOne
6.2.4.2
Testová otázka typu AnswerMany
Tento typ otázky opět nabízí množinu odpovědí, z kterých může student volit. Typ otázky definuje, že správných odpovědí může být jakýkoli počet z celkového počtu odpovědí. Z toho plyne, že správná odpověď nemusí být ani jedna. Pro tento model se k použití v XHTML formulářích nabízí grafická komponenta checkbox. Ta umožňuje studentovi vybrat libovolný
KAPITOLA 6. REALIZACE
43
počet položek. Následující ukázka XHTML demonstruje příklad použití této komponenty a obrázek 6.2 znázorňuje obvyklý vzhled používaný prohlížeči pro její vykreslení. U tohoto typu otázky je otázka považována za správně zodpovězenou pouze v případě, jestliže student označí všechny správné odpovědi a zároveň ani jednu špatnou.
Obrázek 6.2: Ukázka grafického rozhraní otázky typu AnswerMany
6.2.4.3
Testová otázka typu AnswerText
Poslední typ otázky se odlišuje od předchozích dvou tím, že nenabízí seznam možných odpovědí. Student musí sám odpověď vyplnit. Pro tyto účely je použita formulářová komponenta textarea, která umožňuje vstup víceřádkového textu. Tento text je systémem zkontrolován a odpověď je označena jako správná či špatná. Při kontrole správnosti odpovědi se vyskytuje celá řada problémů, o jejichž řešení pojednává kapitola 7.1.2. Použití této komponenty v XHTML kódu představuje následující ukázka. Obrázek 6.3 demonstruje vzhled otázky zobrazené v prohlížeči.
44
KAPITOLA 6. REALIZACE
Obrázek 6.3: Ukázka grafického rozhraní otázky typu AnswerText
6.2.5
Dynamické otázky
Mocnou vlastností systému je možnost vytváření šablon, které reprezentují dynamické otázky. Tyto šablony se souhrnně nazývají Dynamic. Liší se od statických šablon tím, že otázky, které generují, mají proměnlivé znění. Zadání otázek je v době jejich generování vytvořeno algoritmem, tzv. zásuvným modulem otázek. Moduly jsou třídy napsané v programovacím jazyce Java. Ty musí splňovat určitá kritéria. Jedná se především o implementaci předepsaných rozhraní. Tyto třídy pak mohou být začleněny do systému, kde jsou využívány ke generování otázek. Aby systém mohl zásuvné moduly využívat, je nutné je umístit do adresáře, který je pro tuto funkci v konfiguračním souboru nastaven. V tomto adresáři lze vytvářet libovolnou podadresářovou strukturu. Ke svázání šablony se zásuvným modulem dochází ve fázi jejího vytváření. Do šablony se uvede název třídy reprezentující modul. Název je buďto možné uvést ručně, nebo lze využít přehledný vkládací dialog. V dialogu může administrátor procházet strukturu modulů a výběrem určit ten modul, který se pro šablonu použije. Pokud navíc prohlížeč administrátora podporuje JavaScript, je kontrolován typ modulu s uvedenými hodnotami v šabloně. Ke klíčové fázi dochází při generování otázky. Systém vytvoří instanci příslušného modulu a voláním metod předepsaných rozhraním je tomuto modulu dána možnost vytvořit podmínky pro vznik nové otázky. V této fázi se mohou generovat hodnoty parametrů, které ovlivňují znění otázky a podobu případných dynamických obrázků. Nakonec modul vrátí požadované texty a systém je přiřadí k vygenerované otázce. V prvních návrzích systému zde životnost instance třídy modulu končila. Vedle znění otázky generoval modul rovnou i správné odpovědi, které sloužily ke kontrole správnosti při vyhodnocování testu. Ty byly uloženy do databáze v textové podobě. Tento mechanizmus však při kontrole neposkytoval dostatečnou flexibilitu. Jelikož každá z otázek může klást na formu odpovědi jiné požadavky, nebylo možné jednoznačně určit správnost odpovědi prostým porovnáním znakových řetězců. Některé odpovědi mohou obsahovat například formátovací mezery, které neovlivňují správnost odpovědi. Další problém nastával v kontrole zápisu čísel apod. Proto byla tato koncepce nahrazena novou, která nastavuje takové podmínky, kde je za kontrolu správnosti odpovědi zodpovědný sám modul, který otázku generuje. Jelikož každá otázka je spjata s jinou
KAPITOLA 6. REALIZACE
45
instancí třídy modulu, musí existovat mechanizmus, který zaručí stejnou životnost instance, jako má sama otázka. Kontrolu otázek lze navíc provádět i po odhlášení a opětovném přihlášení do systému. V tomto případě už nestačí instance ukládat do session 6 aplikace, jelikož ta existuje pouze po dobu jednoho přihlášení. Vhodnou formou řešení je využití databáze ve spolupráci s Java technologií nazývanou serializace. Ta představuje způsob, jak trvale uchovávat objekty ve formě binárních dat. Takováto data lze ukládat do souborů, databáze nebo posílat po síti. U serializovaných objektů lze označit ty položky, jejichž hodnoty mají být do procesu serializace zahrnuty a při deserializaci tudíž obnoveny. Takto jsou u modulů označeny ty položky, jejichž hodnota je potřebná při kontrole správnosti odpovědi a při generování dynamických obrázků. Při generování otázky je příslušná instance třídy modulu serializována do pole bytů, které je uloženo spolu s obsahem otázky do databáze7 . Při obdržení požadavku na zobrazení obsahu otázky, která generuje dynamický obrázek, je instance vyzvednuta z databáze a deserializována. Metoda getGeneratedImage() vygeneruje obrázek a ten je začleněn do obsahu otázky. Při obdržení požadavku na kontrolu odpovědi je instance opět deserializována. Z databáze je vyzvednuta studentova odpověď a ta je deserializované instanci předána metodou isAnswerCorrect(String answer), která zkontroluje správnost odpovědi. Popsané řešení problému pevně svazuje jednotlivé otázky a instance tříd zásuvných modulů. Díky serializaci mohou být instance ukládány do jedné a té samé databázové tabulky, jako jsou ukládány zbylé informace o otázkách. To zaručuje stejnou dobu existence obou spjatých částí. Provádění kontroly správnosti odpovědí zajišťuje přímo modul a ten tak sám nejlépe určí, zda je odpověď správně formulována či nikoli. Tato kapitola popisovala pouze tu část problematiky, která zajišťuje mechanismy pro integraci dynamických otázek do systému. Konkrétní detaily implementace zásuvných modulů, podporovaná rozhraní a příklady uvádí kapitola 7. 6.2.6
Správa obrázků
K objasnění problému je někdy výhodné použít názornou obrázkovou ilustraci. Proto systém SyVyKoD nabízí podporu pro začleňování obrázků do zadání otázek. Podporuje dva druhy obrázků - statické a dynamické. 6.2.6.1
Statické obrázky
Statické obrázky jsou ty, které jsou uloženy ve formě souborů v souborovém systému. Otázkové šablony se na tyto soubory odkazují pomocí XHTML tagů. Statické obrázky mohou být použity ve všech typech šablon a to v libovolném množství. Administrátor nahrává obrázky na server běžným způsobem, stejně tak jako JSP stránky. Většinou se tak děje ze vzdáleného počítače 6
Session je objekt reprezentující oblast, do které se ukládají data, jež mají životnost po dobu přihlášení uživatele. 7 Databáze PostgreSQL poskytuje dvě možnosti, jak ukládat binární data - jako pole bytů bytea nebo jako tzv. BLOB objekty. Pro ukládání instancí třídy modulů je výhodnější zvolit první možnost.
46
KAPITOLA 6. REALIZACE
pomocí přenosových protokolů jako je například FTP, SFTP atd. Pro tyto obrázky je určen speciální adresář, který je nastaven v konfiguračním souboru aplikace. Administrátor může v tomto adresáři vytvářet libovolnou strukturu dalších podadresářů a souborů. Formát obrázků je závislý pouze na podpoře webových prohlížečů. Běžně podporované formáty jsou PNG, JPG a GIF. Administrátor má při vytváření šablon otázek možnost vkládat do zadání a do případných odpovědí formátovací XHTML entity. To mu do jisté míry umožňuje formátovat podobu textu v otázce. Pomocí této cesty je také zajištěna možnost vkládání tagu , který zajišťuje vykreslení obrázku. Administrátor může použít dialog pro vkládání obrázků, který usnadňuje průchod adresářovou strukturou a vkládá img tag i se jménem obrázku, na který tag ukazuje. Systém zajišťuje kontrolu existence obrázků, na které se šablona odkazuje. Při zobrazení detailu šablony, systém automaticky prochází znění otázek a vyhledává jednotlivé výskyty img tagů. Pomocí regulárních výrazů zjistí adresu obrázku a ověří, zda v souborovém systému takový obrázek skutečně existuje. Pokud ne, zobrazí výstražné znamení, které upozorňuje administrátora na vyskytující se problém. Regulární výrazy jsou navrženy tak, aby kontrolovaly zápis img tagu podle normy XHTML8 . Ačkoli je možné používat XHTML tagy i v textech šablon odpovědí, nepředpokládá se, že by do nich bylo zapotřebí vkládat obrázky. Proto systém provádí kontrolu existence obrázků pouze ve všech jazykových mutacích znění otázek. Texty odpovědí kontrolovány nejsou. Aby bylo možné provádět správu obrázků, je zapotřebí i kontrola opačná. Systém umí zjistit, kolik otázkových šablon a kolik testových otázek se na konkrétní obrázek odkazuje. To administrátorovi umožňuje odstranění těch obrázků, které nejsou dále potřeba. Grafické rozhraní této části systému je realizováno seznamem obrázků existujících v jednotlivých adresářích. U každého obrázku je zobrazen jeden čítač pro počet šablon a druhý čítač pro počet testových otázek odkazujících se na obrázek. U každého obrázku lze také vyvolat seznam všech odkazujících se otázkových šablon.
Upozornění: Je důležité si uvědomit, že hodnoty čítačů uvádí počet odkazujících se šablon a otázek, a ne počet všech odkazů. Například pokud šablona používá obrázek v každé své jazykové mutaci, je hodnota čítače zvýšena pouze o jedna. Zároveň jako v předchozí kontrole existence obrázku tak i zde, při počítání img tagů, je kontrolován pouze text zadání. V textech odpovědí se tagy nekontrolují. Výhoda zvoleného mechanizmu spočívá v odstranění redundance statických obrázků na souborovém systému. Všechny otázky generované z jedné šablony ukazují na jeden a ten samý obrázek. Při vytváření šablon typu Dynamic je možné část zadání otázky generovat přímo v kódu zásuvného modulu. I v tomto textu je možné využít formátovacích XHTML entit. Avšak ani v 8 Jelikož jsou všechny webové stránky systému generovány ve standardu XHTML, doporučuje se, aby administrátor při používání XHTML entit v šablonách tento standard dodržoval.
KAPITOLA 6. REALIZACE
47
tomto textu se neprovádí kontrola počtu img tagů.
6.2.6.2
Dynamické obrázky
Vedle statických obrázků podporuje systém i práci s obrázky dynamickými. Tyto obrázky nejsou uloženy v souborovém systému serveru, ale generují se podle kódu modulu až v době požadavku na zobrazení otázky společně s generováním XHTML stránky. Každý modul může generovat maximálně jeden obrázek. Tento obrázek vzniká podle Java instrukcí, které mohou být ovlivněny náhodně zvolenými hodnotami parametrů. To v praxi znamená, že obrázky v otázkách, které byly vygenerované ze stejné šablony, se mohou navzájem odlišovat. Tato vlastnost je pro testování studentů velice užitečná. S generováním obrázků až v době HTTP požadavku odpadá problém s uskladňováním obrázku v souborovém systému, ale naopak vyvstává problém s jeho začleněním do stránek a s jeho samotným zobrazením. Řešení tohoto problému spočívá ve využití vlastností webových stránek a protokolu HTTP. Při zobrazení webové stránky v prohlížeči nedochází k zasílání pouze jednoho HTTP požadavku. Ten je závislý na množství zdrojů, na které se webová stránka odkazuje. HTTP protokol přenáší vždy pouze jeden samostatný soubor. Proto při načtení stránky odkazující se například na externí kaskádový styl, prohlížeč automaticky pro tento soubor vygeneruje nový HTTP požadavek. Až teprve po stažení všech potřebných souborů je obsah zobrazované stránky kompletní. Stejný mechanizmus se používá i pro práci s obrázky. Tohoto faktu lze využít pro zobrazení dynamického obrázku. Postup je ukázán na obrázku 6.4. Když uživatel vyšle požadavek na zobrazení testové otázky, příslušný servlet přijme požada-
Obrázek 6.4: Zobrazování dynamických obrázků
vek a vyvolá akci potřebnou k získání obsahu otázky. V ní dojde i k vytvoření objektu třídy TestQuestionDynamic, který reprezentuje testovou otázku. Mimo jiné se také stará o přípravu dynamického obrázku. Objekt vygeneruje data potřebná pro zobrazení otázky a zkontroluje, zda má být dynamický obrázek u této otázky generován. Dále je kontrola předána JSP stránce, která vygeneruje XHTML kód zaslaný zpět uživateli. V závislosti na existenci dynamického obrázku může být součástí tohoto kódu i tag , kde id představuje identifikační číslo testové otázky. Díky tomuto tagu prohlížeč vygeneruje nový HTTP požadavek, tentokráte na zaslání souboru dynamicimage/img-id . V servletovém
48
KAPITOLA 6. REALIZACE
kontejneru jsou všechny názvy začínající na dynamicimage/ namapovány na speciální servlet ImageHandler.ser, který nevrací XHTML kód, ale který se postará o zjištění id požadovaného zdroje, nechá si od příslušného objektu TestQuestionDynamic reprezentujícího testovou otázku s identifikačním číslem id obrázek vygenerovat a odešle ho klientovi. Prohlížeč tento obrázek automaticky na stránce vykreslí. Při odesílání obrázku musí být správně nastavena hlavička HTTP odpovědi. Následující ukázka demonstruje kód servletu odesílající obrázek. 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12:
response.setContentType(‘‘image/png’’); OutputStream outs = response.getOutputStream(); try { BufferedImage image = null; String uri = request.getRequestURI(); int id = Integer.valueOf(uri.substring(uri.lastIndexOf(‘‘-’’)+1)); image = bbQuestion.getGeneratedImage(id); if (image==null) throw new Exception(); ImageIO.write(image, ‘‘png’’, outs); } catch (Exception exc) { /* neni co posilat */ }
Pvní řádek nastavuje správný content-type, což je parametr říkající prohlížeči, jaký typ dat má očekávat. V tomto případě se jedná o obrázek ve formátu PNG. Na druhém řádku získá servlet výstupní proud, který je napojen na generovanou HTTP odpověď a do kterého bude obrázková data zapisovat. Na pátém řádku se do proměnné uri uloží podoba URI řetězce, který požaduje dynamicimage/img-id . Na dalším řádku je extrahované id otázky uložené do proměnné id. Sedmý řádek předává řízení objektu bbQuestion, který zajišťuje vytvoření objektu TestQuestionDynamic v závislosti na předávaném id parametru. TestQuestionDynamic je požádán o vygenerování obrázku. Objekt bbQuestion vrátí tento obrázek. Ten je uložen do proměnné image. Osmý řádek kontroluje, zda je potřeba nějaký obrázek generovat. Výsledné zapsání obrázkových dat do výstupního proudu probíhá na devátém řádku. Zvolený přístup má své výhody i nevýhody. Za kladnou vlastnost lze považovat úsporu paměti. Jelikož se dynamické obrázky generují na požádání, není je nutné nikde uchovávat. Nevýhoda plynoucí z použitého mechanizmu je zřejmá. Stejný obrázek se generuje tolikrát, kolikrát je obdržen požadavek na jeho zobrazení. Doba celého procesu vytváření kompletní stránky s obsahem otázky (v případě, že otázka obsahuje dynamický obrázek) je delší, než kdyby server skládal stránku již z připravených elementů. 6.2.7
Tisk testů
Aby měl administrátor možnost používat generované testy také pro písemné zkoušení studentů, může využít funkci systému, která z připravených testových šablon generuje testy vhodné pro
KAPITOLA 6. REALIZACE
49
tisk. Takto generované testy se neukládají do databáze, nejsou přiřazeny žádnému uživateli a nezapočítávají se do žádného hodnocení. Toto je jediný způsob, jak může administrátor generovat testy. Vygenerované testy jsou k dispozici ve dvou variantách - s řešením a bez řešení. První varianta je určena pro testované studenty, druhá pro administrátora a kontrolu odpovědí. 6.2.8
Správa uživatelů
Provozování systému bez existence uživatelů by nemělo velký smysl. Existující uživatelé se do systému přihlašují pomocí uživatelského jména a hesla. Jestliže heslo nebylo doposud nastaveno, může se uživatel přihlásit i bez jeho uvedení. Po přihlášení je uživatel informován o tom, že by heslo mělo být neprodleně nastaveno. Více informací o heslech je uvedeno v kapitole 6.2.3. Existují dva způsoby, jak uživatele do systému vložit. 6.2.8.1
Postupné vkládání
Toto je jednodušší cesta, která administrátorovi nabízí možnost zadávat uživatele do systému postupně pomocí webového formuláře. Administrátor ve formuláři vyplní údaje o uživateli a odešle formulář na server. Pokud uživatel se stejným uživatelským jménem v systému již existuje, skončí akce chybou. 6.2.8.2
Hromadný import
Tato varianta je složitější, ale nabízí možnost jak do systému vložit větší počet uživatelů najednou. V tomto případě jsou informace o uživatelích uvedeny v XML souboru, který administrátor odešle prostřednictvím webového rozhraní na server. Tam je dokument zpracován a údaje o nových uživatelích jsou vloženy do systému. Ke zpracování XML dokumentu je využita JAXP technologie. Aktuální verze JAXP 1.3 je součástí Java SE 5.0. JAXP nabízí API nezávislé na implementaci, které umožňuje aplikacím parsovat a transformovat XML dokumenty. Pro zpracování XML dokumentu obsahující údaje o importovaných uživatelích je použit standard SAX. Při využití tohoto standardu se položky dokumentu zpracovávají postupně při jeho čtení. Není proto nutné vytvářet v paměti datové struktury, které mohou být při větších velikostech XML dokumentu značně rozsáhlé. Pro popis struktury XML dokumentu importovaných uživatelů byl zvolen standard XML Schema. Ten pochází z dílny konsorcia W3C a stal se standardem podporovaným předními IT firmami. Mezi jeho vlastnosti patří podpora datových typů, podpora jmenných prostorů a syntaxe založená na XML. XML Schema je umístěno v souboru students.xsd, který je součástí webové aplikace (další informací o tomto souboru se nachází v příloze C.3). V následující ukázce je výpis tohoto souboru. <xs:schema xmlns:xs=’http://www.w3.org/2001/XMLSchema’>
50
KAPITOLA 6. REALIZACE
<xs:element name=’students’> <xs:complexType> <xs:sequence> <xs:element ref=’student’ minOccurs=’0’ maxOccurs=’unbounded’/> <xs:unique name=’uniqueLogin’> <xs:selector xpath=’student’/> <xs:field xpath=’login’/> <xs:element name=’student’> <xs:complexType> <xs:sequence> <xs:element name=’login’ type=’xs:token’ minOccurs=’1’ maxOccurs=’1’/> <xs:element name=’name’ minOccurs=’0’ maxOccurs=’1’> <xs:complexType><xs:sequence> <xs:element name=’firstname’ type=’xs:token’ minOccurs=’1’ maxOccurs=’1’/> <xs:element name=’surname’ type=’xs:token’ minOccurs=’1’ maxOccurs=’3’/> <xs:element name=’email’ type=’xs:token’ minOccurs=’0’ maxOccurs=’1’/> XML Schema definuje strukturu XML dokumentu, která umožňuje vkládání studentů do systému. Každý student je specifikován následujícími atributy. • Atribut login představuje uživatelské jméno. Tento atribut je povinný. • Atribut name představuje celé jméno uživatele. Tento atribut není povinný. Pokud je ale uveden, musí obsahovat dva vnořené atributy firstname a surname reprezentující jméno a příjmení. • Poslední atribut email představuje emailovou adresu uživatele. Tento atribut není povinný. Všechny atributy jsou typu xs:token, který představuje řetězec u něhož jsou konce řádků, opakující se mezery a tabelátory nahrazeny jednou mezerou a mezery na začátku a na konci
KAPITOLA 6. REALIZACE
51
jsou odstraněny. Některé atributy nemusí být vyplněny. Uživatel je po přihlášení o těchto chybějících údajích informován a může je sám doplnit. Z bezpečnostních důvodů není součástí údajů uživatelské heslo. Integritní omezení uniqueLogin zaručuje, že každý vkládaný uživatel má unikátní uživatelské jméno. Pokud tato podmínka není splněna, dokument není parserem označen jako validní a parsování dokumentu skončí chybou. Pro lepší představu o tom, jak může XML dokument importovaných uživatelů vypadat, slouží následující ukázka. Ta demonstruje, že jediným povinným atributem je atribut login. Ostatní jsou pouze volitelné. <students xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’> <student> novotnyj <student> dvorakp Pavel <surname>Dvořák <student> boudam Miroslav <surname>Bouda <email>[email protected] 6.2.9
Databázový pooling
Komunikace mezi aplikací a databázovým serverem je realizována pomocí databázového spojení. Bez něho není uskutečnění jakéhokoli přenosu dat vůbec možné. Vytváření takovéhoto spojení je časově náročná operace. Proto kdyby aplikace měla navazovat databázové spojení při každém HTTP požadavku, spotřebovala by většinu času trvání požadavku právě na navazování spojení. Z tohoto důvodu je výhodné udržovat existenci spojení i v době mezi požadavky. Systém SyVyKoD ve svých prvních verzích přistupoval k tomuto problému tak, že pro každého nově přihlášeného uživatele vytvořil jedno databázové spojení, které bylo uloženo do session. To zrychlilo běh systému, jelikož navazování spojení probíhalo pro každého uživatele právě jednou. Nevýhoda tohoto řešení ovšem spočívá ve faktu, že počet vytvořených spojení je roven počtu
52
KAPITOLA 6. REALIZACE
právě přihlášených uživatelů. Spojení jsou jako i jiné systémové zdroje věcí cennou, se kterou se musí šetřit. Databázové systémy mají běžně určené limity pro počet navázaných spojení. Z tohoto důvodu se při překročení určitého počtu přihlášených uživatelů může stát, že další spojení už nepůjde navázat. To se projeví tím, že se uživatel nebude moci do systému přihlásit. Z důvodu existence konečného množství aktivních databázových spojení je do systému zaveden tzv. databázový pooling. Pooling je mechanizmus, který zavádí centralizovanou správu nad zdroji. V případě systému SyVyKoD je databázové spojení zajišťováno pomocí JDBC driveru, konkrétně objektu Connetion. Connetion nabízí prostředky pro manipulaci s daty uloženými v databázi. Pooling odstraňuje hlavní nedostatek předchozího přístupu. V tom bylo aktivní spojení rezervováno exkluzivně pro jednoho uživatele i v době, kdy ho vůbec nepotřeboval. Hlavní myšlenka poolingu spočívá ve vyhrazení maximálního počtu aktivních spojení přidělených jedné aplikaci. Aplikace vytvoří objekty Connection a ty uloží do databázového poolu. Kdykoli uživatel zašle aplikaci požadavek, aplikace vyzvedne z poolu volné spojení a využije ho k provedení uživatelova požadavku. Po provedení akce spojení do poolu opět vrátí. Tak je zaručeno, že uživatelé databázová připojení neblokují. Pokud se stane, že více uživatelů požaduje provádění akcí ve stejný okamžik, všechna spojení jsou právě používána a pool je tudíž prázdný, musí aplikace s vykonáváním dalšího požadavku počkat až do té doby, než provádění jedné z akci skončí a spojení se uvolní. Tento přístup umožňuje přihlášení více uživatelů než je počet aktivních databázových spojení. Uživatelé si mezi sebou spojení „půjčujíÿ podle potřeby. Pokud je limit maximálního počtu aktivních spojení správně nastaven, není se třeba obávat zahlcení databázového serveru uživatelskými požadavky. V systému SyVyKoD je vyzvedávání objektů Connection z databázového poolu implementováno ve třídách typu DatabaseBean. Uživatelé tak okupují spojení jenom po dobu opravdu nezbytně nutnou pro provedení databázové akce. Po vyzvednutí dat z databáze ve formě JavaBeanů je objekt Connection opět vrácen do poolu, kde čeká na další použití. Volně dostupných implementací databázových poolů je k dispozici hned několik. Systém používá implementaci DBCP (Databse Connection Pooling) z projektu Apache Jakarta, konkrétně komponentu common-dbcp. Aplikace může spolupracovat buď přímo s touto komponentou nebo využívat podporu správy datových zdrojů servletového kontejneru. V případě produktu Apache Tomcat je výhodnější zvolit druhou možnost. Tomcat totiž nabízí použití komponenty common-dbcp ve formě JNDI datového zdroje. Nastavování vlastností datového zdroje se provádí přímo při konfiguraci aplikace. Aplikace při obdržení požadavku jen žádá Tomcat o přidělení datového zdroje ve formě databázového spojení. Tomcat tedy sám navazuje a ukončuje spojení s databází, spravuje databázový pool a na požádání přiděluje aplikacím databázová spojení. Popis konfigurace je uveden v příloze B.2.
6.2.10
Doba trvání testu
U každého vygenerovaného testu je stanovena doba na jeho vypracování. Po tuto dobu je student oprávněn měnit odpovědi testu. Aby bylo zabráněno studentovi tento čas podvrhovat, je časový odpočet implementován na straně serveru. U každého testu se uloží doba začátku. Při
KAPITOLA 6. REALIZACE
53
požadavcích na změnu odpovědí je nejdříve porovnáván aktuální čas s časem začátku testu. Jestliže je tento časový rozdíl menší než doba stanovená na vykonávání testu, je uložení odpovědí povoleno. V opačném případě je student informován o vypršení časového limitu a požádán o aktivaci vyhodnocení testu. Veškeré časové informace jsou vztažené k serveru, proto nemůže docházet k nesrovnalostem vzniklým rozdílným nastavením klientských a serverových hodin. Student by ovšem měl mít informace o tom, kolik času mu do konce testu zbývá. To stěžuje fakt, že mezi jednotlivými HTTP požadavky nemá webový prohlížeč se serverem možnost komunikace. Proto nemůže docházet k synchronizaci časových údajů. Ta může proběhnout pouze s dalším HTTP požadavkem. Jednou z možností řešení problému by bylo použití technologie známé jako Asynchronous JavaScript And XML (AJAX). Ta umožňuje asynchronní komunikaci mezi prohlížečem a serverem bez změny načtené stránky. Zasíláním informací ve formátu XML v pravidelných intervalech a za použití JavaScriptu by bylo možné testový měřič synchronizovat a zobrazovat na stránkách vždy aktuální hodnotu. Ovšem jelikož je technologie AJAX poměrně nová, je její podpora v různých prohlížečích odlišná. Zároveň vyžaduje častou datovou výměnu. Kvůli těmto skutečnostem bylo zvoleno jiné řešení, které tuto asynchronní komunikaci nepotřebuje. Použité řešení je založené pouze na JavaScriptu. Při každém HTTP požadavku týkajícího se obsahu testu, server vypočte z času aktuálního a počátečního zbývající časový interval a ten odešle společně s informacemi o testu klientovi běžným způsobem. Tento údaj se zobrazí na webové stránce. Pokud uživatelův prohlížeč navíc podporuje JavaScript, je spuštěn JavaScriptový měřič času, který se nastaví na příchozí hodnotu a od té začne odpočítávat. Tak student může vidět aktuální čas, který mu zbývá do konce, aniž by musel znovu kontaktovat server. Jelikož výpočet času na serveru a na klientovi je v tu chvíli oddělený, může se stát, že nebude plně synchronizovaný. Proto by uživatel při hlídání času neměl spoléhat pouze na JavaScriptový měřič. Příkladem, kdy měřič neukazuje správné hodnoty může být situace, kdy uživatel ve svém prohlížeči použije tlačítko Zpět. Při této akci prohlížeč nekontaktuje server, ale předkládá uživateli stránku v té podobě, v jaké byla obdržena v době požadavku - to znamená s původní hodnotou vypočteného času na dokončení testu. JavaScriptový měřič použije pro odpočet tento údaj a začne odpočítávat. Ovšem tento údaj už jistě není aktuální. K další synchronizaci dojde opět při odeslání HTTP požadavku na server. Jakmile JavaScriptový časový měřič dosáhne konce odpočítávání, upozorní uživatele, že časový limit vypršel. Výhoda tohoto přístupu spočívá v nezávislosti na podpoře JavaScriptu. Jestliže JavaScript není podporován, pak uživatel na stránce uvidí po celou dobu údaj aktuální v době požadavku. Jelikož kontrola konce časového intervalu probíhá na serveru a ne na klientovi, je uživateli znemožněno u testu podvádět ve smyslu prodlužování si doby na vypracování testu. Tento způsob je také nezávislý na nepřetržitém přihlášení uživatele v systému. Tím je vyřešen i problém zaručení regulérnosti testovacích podmínek v případě výpadku spojení. Ať už úmyslné nebo neúmyslné přerušení konektivity neovlivní časový odpočet na serveru. Ba dokonce i úplný restart serveru tento odpočet nepřeruší. Pokud dojde k nějakému výpadku a uživatel se po obnovení spojení opět přihlásí, najde test v tom samém stavu, v jakém ho zanechal až na časový interval, který bude samozřejmě kratší. Neznamená to ale, že by uživatel, v pří-
54
KAPITOLA 6. REALIZACE
padě dlouhodobého výpadku, nebyl poškozen. Pokud výpadek bude trvalý, nebude mít uživatel dostatek času na zodpovězení všech otázek. Na tento problém systém také myslí a umožňuje administrátorovi obnovit časový odpočet. Pokud si uživatel myslí, že byl při vypracovávání testu znevýhodněn, může kontaktovat administrátora a ten po prověření okolností může provádění testu opět zpřístupnit. K tomuto účelu může sloužit logování událostí, které je popsáno v části 6.2.13. JavaScriptový měřič je implementován tak, že může zobrazovat více instancí na jedné stránce. Každý takový měřič může ukazovat jiný čas. Pro základní časové vlastnosti je použit globální objekt timerManager. U něj se nastavuje časový interval, po kterém se budou obnovovat hodnoty jednotlivých čítačů, reprezentovanými objekty třídy Timer. Každý Timer má přiřazenou délku odpočtu, HTML entitu, ve které se zobrazuje, a text, který se ve formě upozorňující zprávy objeví při konci odpočtu. Použití na stránce může vypadat následovně. 01: 02: 03: 04: 05: 06: 07: 08: 09:
10
20
<script src=’js/clock.js’> <script type=’text/javascript’> timerManager.setTickInterval(1000*5); timerManager.addTimer(new Timer(1000*10, ’txt1’, ’Tak to je konec’)); timerManager.addTimer(new Timer(1000*20, ’txt2’, null)); timerManager.run();
První dva řádky vyčleňují místo pro dva měřiče. Na řádku 3 je vložena knihovna implementující měřiče. Pátý řádek nastavuje objekt timerManager tak, aby obnovoval měřiče po 5 vteřinách. Řádek 6 vytváří nový objekt třídy Timer a nastavuje mu délku odpočtu na 10 vteřin. Druhý argument specifikuje grafickou komponentu, ve které se měřič bude zobrazovat. Poslední argument určuje obsah zprávy zobrazené po dokončení odpočtu. Vytvořený měřič je předán objektu timerManager. Řádek číslo 7 vytváří další měřič. Ten je nastaven na hodnotu 20 vteřin. Narozdíl od prvního měřiče, nebude informovat uživatele o vypršení časového limitu. Na dalším řádku je timerManager instruován k zahájení odpočtu. Od této chvíle bude každých 5 vteřin odečítat čas od obou měřičů, zobrazovat aktuální hodnotu a kontrolovat, zda některý z měřičů nedoběhl. Implementace JavaScriptových měřičů je v aplikaci umístěna v souboru js/clock.js. 6.2.11
Generování pouze jednoho ostrého testu
Důležitou podmínkou dodržení regulérních podmínek pro testování studentů je striktní dodržení pravidla umožňující studentovi z každé testové šablony generování pouze jednoho ostrého testu. Při implementaci těchto omezení musí být kladen důraz i na zabezpečení v prostředí systému, který umožňuje zpracování více požadavků najednou. Pokud by se kontrola sestávala pouze z obyčejného databázového dotazu na existenci ostrého testu a následovalo by generování testu,
KAPITOLA 6. REALIZACE
55
mohl by student pomocí dvou po sobě rychle vyslaných požadavků docílit vygenerování dvou ostrých testů z jedné a té samé šablony, což není přípustné. Tvrzení umocňuje fakt, že generování testů může být časově náročná operace řešící náročné výpočetní problémy. Relační databáze pomáhají podobné problémy řešit pomocí tzv. integritních omezení. V případě, kdy jsou data ukládána do databázových tabulek, spočívá jedno z řešení problému ve vhodném definování primárních klíčů tabulky. Každý řádek je pak jasně definován hodnotami sloupců: • Sloupec user id specifikuje vlastníka testu. • Sloupec template id specifikuje šablonu, ze které test vznikl. • Sloupec live určuje, zda se jedná o ostrý či zkušební test. Při takto nastavených podmínkách by sama databáze kontrolovala, zda je možné vložení dalšího ostrého testu. V případě existence ostrého testu by databázový stroj zareagoval hláškou oznamující chybu při pokusu o vložení záznamu s již existujícím primárním klíčem. Toto řešení však není vyhovující, jelikož zároveň umožňuje vložení pouze jednoho zkušebního testu. Při druhém pokusu by databáze reagovala stejně jako při pokusu o vložení dalšího ostrého testu. Systém však studentovi musí umožňovat vypracování i více než jednoho zkušebního testu. V tomto případě se tato podmínka nedá implementovat pouze pomocí integritních omezení, ale musí být realizována programově. Systém k řešení problému využívá tzv. zamykání tabulek. Jedná se o službu databáze, která uzamčením tabulky nabízí výlučný přístup k databázovým zdrojům pouze jednomu subjektu. Používání tabulkových zámků je třeba provádět velice obezřetně, jelikož špatné použití může zapříčinit vznik uváznutí. Programové vlákno v době generování testu na krátkou dobu uzamkne databázovou tabulku tbl test, a tím zamezí ostatním vláknům tuto tabulku ovlivňovat. Následný SQL dotaz zkontroluje existenci ostrého testu. V případě, že přihlášený student z příslušné šablony ostrý test ještě negeneroval, je nově vygenerovaný test vložen do databáze. S ukončením databázové transakce je tabulka automaticky opět odemknuta. Použitý mechanizmus elegantně zamezuje výskytu dvou ostrých testů vytvořených z téže šablony. Webové stránky zobrazující průběh generování testu jsou navíc navrženy tak, aby se obsah načteného dokumentu po aktivaci odkazu pro vytvoření testu změnil. Touto změnou, která proběhne ještě dříve, než prohlížeč obdrží HTTP odpověď s výsledkem akce, JavaScript zajistí to, že opětovná aktivace odkazu již není možná. 6.2.12
Podpora vícejazyčných verzí
Pokud má být aplikace vícejazyčným systémem, pak musí podporovat lokalizaci v následujících třech úrovních: • Prostředí aplikace skládajících se z popisků, zpráv a ovládacích prvků se musí přizpůsobovat zvolenému jazyku.
56
KAPITOLA 6. REALIZACE • Stejně tak testy skládající se z generovaných otázek musí vznikat v právě zvoleném jazyce. • Podobná funkčnost musí být zaručena i u zásuvných modulů.
Řešení prvního bodu spočívá v používání externích lokalizačních souborů a speciálních Java tříd, o kterých bude řeč v této kapitole. Řešení druhého bodu je popsáno v analýze problému v kapitole 4.1.2. Třetí bod je svým řešením úzce spjat s bodem prvním. Většina informací uváděných v této části bude pro oba dva body totožná. Případné rozdíly jsou zmíněny v kapitole 7. Java nabízí mechanizmus pro lokalizace aplikací pomocí .properties textových souborů. Properties soubory se skládají z dvojic klíč - lokalizovaný řetězec. Podpora práce s těmito soubory je zajištěna ve třídách z balíčku java.util. Objekty třídy Locale v sobě uchovávají informace o jazyku a o oblasti. Jsou používány v mnoha metodách různých tříd, které mají něco společného s jazykovými mutacemi. V instalaci JVM je nastaven implicitní Locale, který může být získán příkazem Locale.getDefault(). Objekty třídy ResourceBundle slouží k uchovávání lokalizačně závislých zdrojů - v našem případě řetězců. Na příkladu bude vysvětleno, jak celý mechanismus funguje. Příklad 6.3: Aplikaci je potřeba provozovat dvojjazyčně - česky a anglicky. Nejdříve je zapotřebí vytvořit lokalizační soubory, které mohou vypadat následovné: btnSave=Save btnRemove=Delete txtGreeting=Hello World!
btnSave=Uložit btnRemove=Odstranit txtGreeting=Ahoj Světe!
Vlevo je obsah souboru text.properties en s anglickými texty a vpravo obsah souboru text.properties cs s českými texty. Když je v programu potřeba použít nějaký lokalizační text, pak stačí ResourceBundle požádat o lokalizovanou verzi a pomocí metody getString(klíč ) získat potřebný text. Kód může vypadat následovně. ... ResourceBundle bundle = ResourceBundle.getBundle(‘‘text’’, locale); label = new JLabel(myResources.getString(‘‘txtGreeting’’)); button1 = new Button(myResources.getString(‘‘btnSave’’)); button2 = new Button(myResources.getString(‘‘btnRemove’’)); ... O tom, který z uvedených souborů se pro ResourceBundle použije, rozhoduje předávaný parametr locale. Takto může být aplikace přizpůsobena konkrétnímu jazyku bez nutnosti změny zdrojového kódu. Názvy lokalizačních souborů mají přesně definovaný formát, který je popsán v dokumentaci tříd Locale a ResourceBundle. Popis těchto tříd je k dispozici v API pro J2SE [9] nebo také v [1]. Lokalizační soubory mohou obsahovat pouze znaky bez diakritiky. Diakritické znaky musí být nahrazeny Unicode sekvencí znaků. Ruční převádění by bylo zajisté neefektivní, a proto může být použit nástroj native2ascii dodávaný v rámci J2SE 5.0 JDK.
KAPITOLA 6. REALIZACE
57
Ve všech lokalizačních souborech systému SyVyKoD je použito kódování UTF8. Proto musí být při použití programu native2ascii použit přepínač pro nastavení správného kódování. Použití pak vypadá následovně (při zpětné transformaci obsahu souborů je třeba navíc použít přepínač -reverse). native2ascii -encoding utf8 zdroj.properties cil.properties Lokalizační texty systému SyVyKoD jsou rozděleny podle tematických okruhů a jsou umístěny v balíčku elearning.messages. Rozšíření prostředí aplikace o další jazykovou mutaci spočívá pouze v přidání nové sady lokalizačních souborů a přidáním informace o novém jazyku do konfiguračního souboru aplikace. Vše ostatní, dokonce i odkazy přepínající jazyky v JSP stránkách, je přizpůsobeno automaticky. Technologie JSP navazuje na lokalizační třídy Javy a zavádí tagy pro spolupráci nejen s lokalizovanými texty, ale zároveň i s jinými objekty. Pomocí těchto tagů se datumy nebo čísla mohou prezentovat podle národních zvyklostí a norem. Použití je jednoduché. Na začátku JSP stránky se musí určit Locale, podle kterého má být obsah zobrazován. K tomu slouží tag . V atributu value se uvádí kód jazyka, tedy například cs, en atd. Dále je zapotřebí určit, ze kterého ResourceBundle se bude čerpat. To zajišťuje tag . Pak už mohou být použity klíče k získávání lokalizovaných textů. Tag vygeneruje do výsledného XHTML kódu text, který se v příslušném souboru nachází pod klíčem klic. Implicitní jazyk použitý pro zobrazování stránek je možné zvolit v konfiguračním souboru aplikace. Aby uživatel nemusel u každé stránky vybírat požadovaný jazyk znovu a znovu, je objekt Locale, který reprezentuje zvolený jazyk, ukládán do session, kde je uschován po dobu celého přihlášení. Ten samý objekt je použit při výběru správné jazykové mutace otázky z databáze. 6.2.13
Logování událostí
Logování událostí je mocný nástroj pro odhalování příčin nežádoucích jevů odehrávajících se v systému. Podle těchto záznamů může být zrekonstruován průběh událostí, a tak mohou být odhaleny chyby, neoprávněné požadavky uživatelů, snaha o získání nadvlády nad systémem, snaha o podvádění při provádění testů a další. Pokud je logování v konfiguračním souboru povoleno, zaznamenává systém SyVyKoD události do databáze - konkrétně do tabulky tbl log. Do logů se ukládá jméno uživatele, který událost vytvořil, čas vzniku a výsledek události. Pokud prováděná akce skončila neúspěchem, je také přidána chybová zpráva objasňující neúspěch akce. Stránka pro přehled logů, která je přístupná pouze administrátorovi, pak umožňuje tyto záznamy přehledně zobrazovat. Kvůli složité orientaci ve velkém množství záznamů je v aplikaci implementován filtr, který umožňuje podrobně specifikovat záznamy, které administrátora zajímají. Pro nastavení filtrování událostí vzhledem k časovému období, používá aplikace JavaScriptový kalendář, jehož autorem je Mihai
58
KAPITOLA 6. REALIZACE
Bazon. Kalendář je šířen pod licencí GNU, podporuje všechny majoritní prohlížeče, existuje pro něj řada jazykových mutací (české nevyjímaje) a jeho vzhled je plně nastavitelný pomocí kaskádových stylů. Kromě toho existuje několik variant, jak jej lze do stránky vložit. Tento produkt je k dispozici ke stažení na adrese http://www.dynarch.com/projects/calendar/. Text záznamů o událostech je nezávislý na zvolené jazykové mutaci. Existuje pro něj pouze jeden .properties soubor. Nepředpokládá se potřeba logování ve více jazycích. Ta by podle autora byla naopak nepřehledná až matoucí. S aplikací je dodáván soubor s logovacími zprávami psanými v češtině. Nahrazením souboru logMessage.properties, lze změnit jak jazyk, tak i obsah zpráv použitý při zaznamenávání událostí. Následující ukázka zobrazuje strukturu záznamu.
uživatel:
ouskav1
datum a čas: akce: výsledek: chybová zpráva:
2006-04-13 23:35:26 prohlédnutí testové otázky číslo 556 false test už není aktivní, ale ještě není vyhodnocen
6.2.14
Akceptační testy aplikace
Celá webová aplikace (klientská i serverová strana) prošla testováním na různých operačních systémech. Aplikace byla naplněna zkušebními šablonami otázek a testů. Obzvláště pečlivě bylo ověřováno generování testů a spolupráce aplikace se zásuvnými moduly. V žádné z prováděných akcí nebylo zjištěno chybné chování aplikace. Serverová část modulu pro testování studentů byla testována na operačních systémech Windows XP a Gentoo Linux. Zobrazování webových stránek bylo kontrolováno v prohlížečích Internet Explorer 6.0, Mozilla Firefox 1.5 a Opera 8.5. Testováním bylo ověřeno, že stránky jsou dobře zobrazitelné ve všech těchto prohlížečích. Zároveň bylo také ověřeno, že použité JavaScriptové konstrukce jsou navrženy tak, aby byly všemi prohlížeči interpretovány stejně.
Kapitola 7 Rozhraní pro vytváření dynamických otázek Tato kapitola podrobně popisuje mechanizmus, kterým systém SyVyKoD umožňuje vytváření dynamických otázkových šablon. Je v ní popsána struktura programátorských rozhraní jednotlivých typů šablon spolu s příklady použití. Kapitola také uvádí, co je třeba udělat proto, aby otázky generovaly obrázky. Pro vývoj nových zásuvných modulů otázek je zapotřebí do proměnné CLASSPATH přidat JAR archiv s rozhraními dynamických otázek, aby se nově vytvářené třídy mohly na implementovaná rozhraní odkazovat. JAR archiv, který obsahuje definice rozhraní a jiné pomocné třídy se nachází na přiloženém CD v adresáři syvykod/plugin_tester a je součástí aplikace Plugin Tester, která pomáhá ověřovat správnost navržení modulů dynamických otázek. Aplikace je popsána na konci kapitoly. V předcházející kapitole bylo vysvětleno, co jsou to zásuvné moduly otázky, a jak jsou integrovány do systému. Stručně řečeno: jsou to Java třídy, které jsou svázané se šablonami a které společně s nimi generují otázky. Systém podporuje tři typy šablon dynamických otázek. Jsou to DynamicOne, DynamicMany a DynamicText. Jelikož každý typ šablony je svázán právě s jedním typem modulu, budou typy modulů označovány v následujícím textu stejně jako typy otázkových šablon. Takže například místo označení modul pro šablonu typu DynamicOne je použito označení modul typu DynamicOne. Při vytváření modulů různých typů je zapotřebí, aby třídy implementovaly předepsaná rozhraní. Všechna potřebná rozhraní jsou umístěna v balíčku elearning.question.
Obrázek 7.1: Struktura rozhraní pro dynamické otázky
Obrázek 7.1 znázorňuje hierarchickou strukturu rozhraní. Pro zobrazení závislostí je 59
60
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK typ modulu DynamicOne DynamicMany DynamicText
rozhraní DynamicQuestionOne DynamicQuestionMany DynamicQuestionText
Tabulka 7.1: Vztah mezi jednotlivými rozhraními a typy zásuvných modulů použita notace UML. Kurzíva použitá ve jménech říká, že se jedná o rozhraní. Rozhraní neposkytuje vlastní implementaci metod, pouze stanovuje, že třída implementující rozhraní musí tuto metodu definovat. Šipky ve vztazích představují rozšíření. To znamená, že například rozhraní DynamicQuestionOne rozšiřuje DynamicQuestionOption a to rozšiřuje rozhraní DynamicQuestion. Třída, která rozšiřuje svého předka, dědí jeho metody. Výsledek všech výše popsaných faktů je v praxi takový, že pokud třída implementuje nějaké rozhraní, tak musí definovat všechny jeho metody a zároveň všechny metody rozhraním zděděné. Příkladem může být třída implementující DynamicQuestionOne. Pak tato třída musí definovat metody nejen z DynamicQuestionOne, ale i z rozhraní DynamicQuestionOption a DynamicQuestion. Tabulka 7.1 uvádí vzájemné vztahy mezi typy modulů a názvy rozhraní.
7.1
Popis rozhraní
Následující rozhraní popisují metody, které musí třídy modulů implementovat. Důležité je navíc to, že každý modul musí definovat implicitní konstruktor - tudíž konstruktor bez parametrů. Pokud se v kódu konstruktor vůbec neobjeví, pak kompilátor doplní implicitní konstruktor sám. Pokud ovšem tvůrce třídy definuje nějaký konstruktor s parametry, implicitní konstruktor automaticky doplněn není. V takovém případě nastane chyba při deserializaci modulu. 7.1.1
Rozhraní DynamicQuestion
Jak ukazuje obrázek 7.1, rozhraní DynamicQuestion zastřešuje všechna ostatní rozhraní. Každá třída implementující toto rozhraní musí implementovat dvě metody. public void generateQuestion(Locale locale, Random random) Tato metoda je vstupním bodem pro generování otázky. Mělo by zde proběhnout kompletní vytvoření obsahu otázky. V případě, že je otázka zaměřena na testování práce nějakého výpočetního algoritmu, mohou se v této metodě generovat vstupní podmínky algoritmu i konečný výpočet. Z něho mohou být připraveny odpovědi ve formě vhodné k položení otázky. Jelikož je obsah generované otázky závislý na zvoleném jazyku, je metodě předáván i parametr locale reprezentující jazyk, který má být pro generování obsahu použit. Zároveň se předpokládá, že obsah otázky bude ovlivněn jistým pseudonáhodným parametrem. Pro jeho vygenerování může sloužit objekt random. Záleží pouze na tvůrci modulu, zda předávané parametry využije, či nikoli.
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
61
public String getText() Tato metoda slouží k předání textu reprezentujícího zadání otázky. Jak bylo zmíněno v kapitole 6.2.6.1, toto zadání může obsahovat i XHTML formátovací tagy. V tomto textu však nejsou kontrolovány odkazy na statické obrázky. Text získaný touto metodou je přidán k zadání uvedeném přímo v šabloně otázky. Text vracený touto metodou je jedním z těch, které by měly být ovlivněny parametrem locale předávaného do předchozí metody. Proto je výhodné text zadání v předchozí metodě vygenerovat a metodou getString ho pouze zpřístupnit systému. 7.1.2
Rozhraní DynamicQuestionText
Toto rozhraní musí být implementováno modulem typu DynamicText. Je přímým potomkem rozhraní DynamicQuestion. Obsahuje také dvě metody. public String getResult() Tato metoda vrací správnou odpověď na otázku. Tato odpověď není použita k porovnání s uživatelským vstupem, ale slouží pouze pro zobrazení správného výsledku. Ten se zobrazuje až po vyhodnocení testu a student s ním může srovnávat svou vlastní odpověď. Text může opět používat XHTML tagy. Pokud je systém podporován ve více jazycích, pak by měl být text vracený touto otázkou také lokalizován. public boolean isAnswerCorrect(String answer) Tato velice důležitá metoda se používá pro kontrolu správnosti odpovědi. Kontrola správnosti je ponechána na modulu, protože otázku zadává de facto on sám. Proto sám nejlépe ví, jaký druh vstupních dat lze od uživatele očekávat. Má-li být například vstupem číslo, pak je důležité, aby modul přijímal číslo v co nejvíce povolených formátech. Z těchto důvodů je metodě předáván parametr answer, což je textový řetězec získaný od studenta. Je na implementaci modulu, aby posoudil, zda je studentova odpověď správná či nikoli. V závislosti na tomto rozhodnutí vrací metoda hodnotu true nebo false. 7.1.3
Rozhraní DynamicQuestionOption
Toto rozhraní je také potomkem DynamicQuestion, ale samo o sobě nereprezentuje žádný typ podporovaných modulů. Je pouze jakýmsi mezistupněm pro další dvě rozhraní. Definuje pouze jednu metodu. public List<String> getWrongAnswers(int wrongAnswersMaxCount) Ta se používá pro získání seznamu špatných odpovědí. Tyto odpovědi jsou studentovi nabídnuty jako možnosti odpovědí. Je ponecháno na metodě, aby generovala pouze unikátní
62
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
odpovědi. Zároveň algoritmus pro generování špatných odpovědí musí zaručit, že v seznamu nebude vygenerována správná odpověď. Stručně řečeno: pokud student označí v testu jednu z těchto odpovědí za správnou, bude mu otázka počítána jako špatně zodpovězená. Parametr wrongAnswersMaxCount určuje očekávaný počet vrácených odpovědí. V případě, že algoritmus není schopen vygenerovat tolik špatných unikátních odpovědí, může vrátit odpovědí méně. V testu budou zobrazeny pouze tyto odpovědi. Hodnota vstupního parametru závisí na nastavení parametrů v šabloně otázky. Vrácené odpovědi by měly být lokalizované. Proto je opět dobré vytvářet tyto odpovědi už v metodě generateQuestion(Locale locale, Random random) rozhraní DynamicQuestion. Zde se mohou odpovědi zpřístupňovat systému. V textech odpovědí se opět mohou objevit formátovací XHTML tagy. Metoda vrací objekt typu java.util.List, který sdružuje vytvořené odpovědi. 7.1.4
Rozhraní DynamicQuestionOne
Toto rozhraní slouží pro typ modulu DynamicOne. Deklaruje pouze jednu metodu. public String getCorrectAnswer() Ta vrací jednu správnou odpověď na otázku. Vracený řetězec má ty samé vlastnosti jako řetězce u metody getWrongAnswers(int wrongAnswersMaxCount). 7.1.5
Rozhraní DynamicQuestionMany
Toto rozhraní slouží pro typ modulu DynamicMany. Opět Deklaruje pouze jednu metodu. public List<String> getCorrectAnswers(int correctAnswersMaxCount) Tato metoda je ekvivalentem k metodě getWrongAnswers(int wrongAnswersMaxCount) s tím rozdílem, že vrací správné odpovědi. Pro vracené řetězce platí opět ta samá pravidla. Za zopakování stojí jen to, že je vhodné generovat odpovědi unikátní. Snadnou, ale ne příliš efektivní metodou je použití třídy UniqueAnswer, která se také nachází v balíčku elearning.question. Ta pracuje na principu porovnávání vygenerovaných řetězců. Její použití je vysvětleno v příkladech modulů.
7.2
Pořadí volaných metod
Pro správné rozvržení akcí do jednotlivých částí modulu je zapotřebí definovat pořadí, ve kterém se budou volat jednotlivé metody. Důležitým faktorem je existence serializace modulů. Serializací a opětovnou deserializací mohou být hodnoty některých proměnných přepsány implicitním nastavením, čímž se může ztratit důležitá informace pro správnou funkčnost modulu. Obrázek 7.2 zobrazuje posloupnost volaných metod v různých typech rozhraní. Metody jsou volány postupně odshora dolů. V dolní části je vyznačena fáze serializace a deserializace. Mezi
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
63
Obrázek 7.2: Pořadí volání metod zásuvných modulů
nimi je objekt uložen v databázi ve formě bytového pole. Z obrázku tedy vyplývá, že po deserializaci se volají dvě metody. Proto všechny proměnné, které jsou použité v těchto metodách a které jsou závislé na vygenerovaných vstupních podmínkách, musejí být serializovány. Metoda getGeneratedImage() ještě nebyla zmíněna a bude popsána v kapitole 7.4. Ta se volá pouze v případě, kdy modul podporuje vytváření dynamických obrázků.
Upozornění: Při návrhu modulu je důležité si uvědomit, že serializace objektu probíhá pouze jednou a to v době generování testu. Deserialozován může být objekt i vícekrát. Změny hodnot proměnných provedené v metodách uvedených v obrázku 7.2 až za serializací, se do databáze neukládají a tudíž se po opětovné deserializaci objektu neprojeví.
Poznámka: Ani metoda isAnswerCorrect(String answer) nemusí být vůbec volána. V případě, kdy student vůbec na otázku neodpoví, je tato otázka považována za chybně zodpovězenou a deserializace objektu s následnou kontrolou odpovědi vůbec neproběhne.
7.3
Serializace objektů
Pro správný návrh modulu je zapotřebí znalost technologie serializace objektů. Aby mohla být třída serializována, musí implementovat rozhraní Serializable. To je v případě modulů zajištěno tak, že je toto rozhraní rozšiřováno už rozhraním DynamicQuestion. Tím pádem všechny platné moduly rozhraní Serializable implementují. Detailnější popis serializace překračuje rozsah této práce. Jako zdroj informací může posloužit [9] nebo [3].
64
7.4
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
Generování dynamického obrázku
Každá dynamická otázka může generovat jeden dynamický obrázek. K tomu je zapotřebí, aby modul navíc implementoval rozhraní ImageGenerator z balíčku elearning.question. Toto rozhraní definuje pouze jednu metodu getGeneratedImage(), která vrací vygenerovaný obrázek ve formě objektu třídy BufferedImage nacházející se v balíčku java.awt.image. Je zapotřebí si uvědomit, že tato metoda je volána až po deserializaci a to tolikrát, kolikrát uživatel zašle požadavek na zobrazení otázky. Proto je zapotřebí správně serializovat potřebné proměnné. V případě, kdy je generování obrázku časově složité, je možné obrázek vygenerovat pouze jednou při vytváření otázky a uložit ho v serializované podobě do databáze. V metodě getGeneratedImage() se pak obrázek může pouze zpřístupňovat. V následujících příkladech bude použití tohoto rozhraní předvedeno.
7.5
Příklady implementace zásuvných modulů
Na následujících jednoduchých příkladech budou popsány dva typu modulů. Každý z příkladů bude představovat kromě samotného modulu i jiné mechanizmy, které lze při implementaci použít. Neznamená to ovšem to, že by představovaný mechanizmus nešel použít s jiným typem modulu. Kódy příkladů nejsou optimalizovány. Použité konstrukce mají za úkol kód zpřehlednit a projasnit základní myšlenku návrhu modulů. 7.5.1
Příklad 1 - Hledání podřetězců
Následují příklad si klade za cíl implementovat algoritmus, který bude generovat otázky na porovnávání řetězců. V zadání student dostane řetězec znaků a v nabídnutých odpovědích řetězce kratší. Jeho úkolem bude označit ty odpovědi, které obsahují podřetězce (faktory) hlavního řetězce. Všechny řetězce budou náhodně generovány. Toto je typický příklad pro použití otázky typu DynamicMany. Může být vygenerováno více správných odpovědí, ale nemusí být správná ani jedna. Proto modul, který bude svázaný se šablonou otázky, musí implementovat rozhraní DynamicQuestionMany. 01: package kod.question.retezce; 02: public class RetezecMany implements DynamicQuestionMany { 03: private static final long serialVersionUID = 1L; 04: private char[] characters = {’a’,’u’,’x’,’z’}; 05: private String mainString; 06: private Random random; 07: transient private ResourceBundle bundle; // polozka nebude serializovana 08: 09: public RetezecMany() { 10: }
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
65
Uvedený kód představuje strukturu třídy. Na začátku je seznam proměnných, které budou v modulu použity. Proměnná serialVersionUID slouží pro označování verzí tříd. Pokud proměnnou neuvedeme, tak ji kompilátor vygeneruje a její hodnotu určí sám. Pole characters představují množinu znaků, z nichž se budou řetězce generovat. Hlavní řetězec je reprezentován proměnnou mainString. Pro uchování generátoru pseudonáhodných čísel slouží proměnná random. Důležitou položkou je proměnná bundle. Ta je použita pro lokalizaci modulu. Použití bude vysvětleno dále. Důležité je klíčové slovo transient, které říká, že se hodnota této proměnné nebude serializovat. Z toho vyplývá, že všechny lokalizované texty musí vzniknout v metodách, jež jsou volány před serializací. Řádek 9 zdůrazňuje fakt, že všechny moduly musí definovat implicitní konstruktor. Následující kód definuje dvě metody. První z nich generuje znění otázky. Řádek 12 se stará o uchování generátoru pseudonáhodných čísel, který je použit i v následujících metodách. Použitím vstupního parametru locale lze získat balíček lokalizovaných zpráv, které se v otázce objevují. Existují tři možnosti realizace tohoto balíčku. Nejsnazší řešení, které může být použito v případě, kdy není zapotřebí velkého množství lokalizovaných textů, spočívá v nadefinování textů přímo v těle třídy a určení konkrétní mutace zprávy pomocí podmíněného příkazu if (locale.getLanguage()="..."){...}1 . Pokud je zpráv více, mohou se umisťovat do externích souborů - tzv. .properties souborů. Práce s nimi je popsána v kapitole 6.2.12. 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
public void generateQuestion(Locale locale, Random random) { this.random = random; bundle=ResourceBundle.getBundle(‘‘kod.question.retezce.Text’’,locale); int length = random.nextInt(20)+5; StringBuffer tmp = new StringBuffer(); for (int i = 0; i < length; i++) { tmp.append(znaky[random.nextInt(4)]); } mainString = tmp.toString(); } public String getText() { return ‘‘’’+bundle.getString(‘‘txtString’’)+mainString+‘‘
’’; }
Na 14. řádku je určena délka hlavního řetězce, který je v následující smyčce náhodně vygenerován. 19. řádek zajišťuje uložení hlavního řetězce do proměnné mainString, aby mohl být zpřístupněn z metody getText(). V ní je generován výstup, který se zobrazí na stránkách. Použitá konstrukce bundle.getString("txtString") zajistí vyhledání zprávy s klíčem txtString v požadované jazykové mutaci. Následující metoda je zodpovědná za generování správných odpovědí. K vygenerování unikátních odpovědí používá třídu UniqueAnswer, která je součástí balíčku elearning.question. 1
Obdobné řešení spočívá v použití řetězců, které jsou adresovány pomocí dvojice (klíč,jazyk )
66
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
Tato jednoduchá třída textově porovnává nový řetězec s již vygenerovanými. Její použití tedy není vždy výhodné. V příkladu byla použita pro zpřehlednění kódu. Generování správných odpovědí je založeno na náhodném volení indexů (řádek 30 a 31), podle nichž jsou z hlavního řetězce vybírány podřetězce (řádek 33). Tento proces se opakuje do té doby, dokud není vybrán podřetězec, který se neshoduje s již použitými. 24: public List<String> getCorrectAnswers(int correctAnswersMaxCount) { 25: List<String> retVal = new ArrayList<String>(); 26: UniqueAnswer ua = new UniqueAnswer(); 27: for (int i = 0; i < correctAnswersMaxCount; i++) { 28: int a=0,b=mainString.length(); 29: do { 30: a = random.nextInt(mainString.length(); 31: b = random.nextInt(mainString.length()-a) + a; 32: } while (!ua.isAnswerUnique(mainString.substring(a,b))); 33: retVal.add(‘‘’’+mainString.substring(a,b)+‘‘
’’); 34: } 35: return retVal; 36: } Důležitým bodem při implementaci podobných modulů je kontrola zacyklení. V případě, kdy vstupní parametr correctAnswersMaxCount začne nabývat velkých hodnot, není možné další unikátní řetězce najít a algoritmus se zacyklí. Takovéto zacyklení by mělo v průběhů generování testů katastrofální následky. Proto v případě, kdy vygenerování nové odpovědi již nelze provést, je možné vrátit menší počet odpovědí, než předepisuje vstupní parametr. Podobná předchozí je i metoda getWrongAnswers(int wrongAnswersMaxCount). Ta generuje sadu špatných odpovědí. Je navržena tak, aby pro každou odpověď generovala řetězec náhodných znaků o náhodné délce. Délka je zvolena na řádku 43. Kód na řádcích 44-46 generuje náhodné znaky a podmínka na řádku 47 kontroluje, zda je odpověď unikátní a zároveň, jestli vygenerované znaky nejsou součástí hlavního řetězce. V tom případě by se jednalo o správnou odpověď, což je v této metodě nežádoucí. Pokud vygenerovaný řetězec splňuje zmíněné podmínky, může být přidán k sadě odpovědí (řádek 49). 37: public List<String> getWrongAnswers(int wrongAnswersMaxCount) { 38: List<String> retVal = new ArrayList<String>(); 39: UniqueAnswer ua = new UniqueAnswer(); 40: for (int i = 0; i < wrongAnswersMaxCount; i++) { 41: StringBuffer answer = new StringBuffer(); 42: do { 43: int charCount = random.nextInt(mainString.length()-1) + 1; 44: for (int j = 0; j < charCount; j++) { 45: answer.append(znaky[random.nextInt(4)]); 46: }
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
67
47: } while (!ua.isAnswerUnique(answer.toString()) 48: || (mainString.indexOf(answer.toString())!=-1)); 49: retVal.add(‘‘’’+answer.toString()+‘‘
’’); 50: } 51: return retVal; 52: } 52:} // konec třídy 7.5.2
Příklad 2 - Huffmanovo kódování
Druhý příklad představuje obtížnější situaci. Cílem je vytvořit modul na testování znalosti Huffmanova kódování. Úkolem bude zakódovat náhodně generovaný vstupní řetězec podle postaveného binárního stromu s patřičným ohodnocením hran a uzlů. Strom bude mít sice stejnou strukturu, ale listy zastupující jednotlivé znaky budou náhodně proházeny. Pro lepší představu je podoba výsledného stromu na obrázku 7.3.
Obrázek 7.3: Generovaný obrázek k příkladu Huffmanovo kódování
Pro takovýto typ příkladu je vhodné použít modul typu DynamicText. Studenti budou zadávat výstupní binární řetězec v podobě jedniček a nul do textového pole. Modul pak zkontroluje, zda student odpověděl správně či nikoli. Jelikož se v zadání úlohy předpokládá, že obrázek znázorňující binární strom má mít v listech různé hodnoty, musí být obrázek generován až v době vytváření otázky. K tomuto účelu slouží rozhraní ImageGenerator, které se nachází opět v balíčku elearning.question. Rozhraní definuje jednu metodu getGeneratedImage(), která vrací objekt třídy java.awt.image.BufferedImage reprezentující vygenerovaný obrázek. Obrázek je generován pomocí Java tříd z balíčku java.awt. Jelikož kompletní vložení kódu příkladu by znepřehlednilo podstatné části, budou triviální segmenty kódu, jako jsou například get a set metody, vynechány. Zároveň se modul nebude zabývat otázkou lokalizace textů. Kompletní kód, společně s ostatními, je k nalezení přímo v aplikaci v balíčku kod.question.huffman. Implementace modulu využívá pomocnou neveřejnou třídu Node. Ta slouží jako základ
68
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
pro stavbu binárního stromu. Jelikož se společně s hlavní třídou serializuje, je nutné, aby také třída Node implementovala rozhraní Serializable. V proměnné label je uložen znak, který se má v uzlu zobrazit. Proměnná code reprezentuje posloupnost jedniček a nul, kterou je znak po zakódování zastoupen. Polohu grafického prvku určují x a y. Pokud uzel není listem, pak má levého a pravého potomka (edgeZero a edgeOne). 01: class Node implements Serializable { 02: private String label, code; 03: private int x,y; 04: private Node edgeZero=null,edgeOne=null; 05: ... 06: public void paint(Graphics2D g) { 07: g.drawOval(x,y,40,40); 08: char[] lab = label.toString().toCharArray(); 09: int w=g.getFontMetrics().charsWidth(lab, 0, lab.length); 10: int h=g.getFontMetrics().getHeight(); 11: g.drawChars(lab, 0, lab.length, x+40/2-w/2, y+h+2); 12: } 13: } Nejzajímavější je metoda paint(Graphics2D g). Ta je zodpovědná za vykreslení uzlu do obrázku. Předávaný objekt g představuje nástroj pro vykreslování grafických obrazců, vypisování textů, vykreslování obrázků, získávání a nastavování aktuální barvy atd. Pomocí jeho metod se uzel na řádku 7 vykreslí jako ovál o šířce a výšce 40 pixelů na souřadnice x a y. Do oválu se pomocí metody drawChars(...) zapíše znak(řádek 11). Aby se znak nacházel uprostřed oválu, je nejdříve z metriky použitého fonty zjištěna jeho šířka(9) a výška(10). Hlavní částí modulu je třída HuffmanText implementující rozhraní DynamicQuestionText a ImageGenerator. 14: public class HuffmanText implements DynamicQuestionText, ImageGenerator { 15: private List nodes = new ArrayList(); 16: private Map<String,Node> map = new HashMap<String,Node>(); 17: private String input; 18: private Node root=null; Uzly jsou uchovány v seznamu nodes. Na vrchol stromu zároveň ukazuje proměnná root. Pro rychlejší vyhledávání jsou instance listů zároveň obsaženy v mapě map, kde klíčem k položce je znak, který uzel reprezentuje. Všechny položky jsou důležité pro generování obrázku a kontrolu správnosti odpovědi. Z tohoto důvodu musejí být všechny položky serializovány. Vygenerování otázky probíhá v již známé metodě generateQuestion(Locale locale, Random random). Předávaný generátor slouží k promíchání(21) použitých znaků(20). Na řádcích 22-24 jsou vytvářeny listy stromu. Listy nemají žádné potomky, proto je v prvních dvou
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
69
parametrech předávána null hodnota. Každému listu je přidělen jeden znak a dvojice souřadnic x,y definující polohu pro zobrazení. Listy jsou zároveň přiřazeny do mapy(25-27) a nad nimi jsou vystavěny zbylé dva uzly stromu(28-30). Nad postaveným stromem je volána rekurzivní metoda evaluate(root,""), která listům naplní proměnnou code(31). Ve zbylé části metody je vygenerován vstupní text podobným způsobem, jako tomu bylo i v příkladu 1. Metoda getText() zpřístupňuje zadání otázky. 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
public void generateQuestion(Locale locale, Random random) { List chars = Arrays.asList(‘‘a’’,‘‘b’’,‘‘c’’); Collections.shuffle(chars,random); nodes.add(new Node(null,null,(String)chars.get(0),50,250)); nodes.add(new Node(null,null,(String)chars.get(1),200,250)); nodes.add(new Node(null,null,(String)chars.get(2),350,250)); map.put((String)chars.get(0),nodes.get(0)); map.put((String)chars.get(1),nodes.get(1)); map.put((String)chars.get(2),nodes.get(2)); nodes.add(new Node((Node)nodes.get(0),(Node)nodes.get(1),‘‘’’,125,150)); root = new Node((Node)nodes.get(3),(Node)nodes.get(2),‘‘’’,200,10); nodes.add(root); evaluate(root,‘‘’’); int length = random.nextInt(20)+5; StringBuffer tmp = new StringBuffer(); for (int i = 0; i < length; i++) { tmp.append(nodes.get(random.nextInt(3)).getLabel()); } input = tmp.toString(); } public String getText() { return ‘‘Vstupní řetězec: ’’+input+‘‘
’’; }
Metodami specifickými pro modul typu DynamicText jsou metoda pro vrácení správné odpovědi getResult() a metoda pro kontrolu správnosti isAnswerCorrect(String answer). Vzorová odpověď je generována pomocí mapy s uloženými listy. Při procházení vstupního řetězce se vyhledávají v mapě příslušné uzly a z jejich code sekvencí je sestavován výstup. Kontrola odpovědi nemůže být provedena jednoduchým porovnáním řetězců. Uživatel může například pro zlepšení čitelnosti použít mezi jednotlivými výstupními znaky formátovací mezeru, která by neměla být považována za chybu. Pro tyto účely se v balíčku elearning.question nachází různé nástroje. Pro tuto úlohu je použit StrictTokenizer(51), který z uživatelova vstupu pomocí metody nextBit() čte jedničky a nuly. Bílé znaky 2 jsou ignorovány. Při výskytu jakéhokoli jiného znaku vyhodí metoda výjimku WrongTokenException. 2 Termín bílé znaky (whitespaces) je používán souhrnně pro mezery, tabelátory a znaky pro ukončení řádku (CR a LF).
70
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
V takovém případě je odpověď považována za chybnou. Dalším nástrojem použitým v příkladu je PrefixComparator(52). Jeho metoda compareAndMerge(String prefix) pracuje s generovaným vstupním řetězcem, který zleva postupně kontroluje a „ukrajujeÿ podle předávaného textu. V případě nerovnosti vrací false. V opačném případě zkontrolovanou část odstraní a vrátí true. Samotná kontrola odpovědi pak tedy spočívá v postupném procházení uživatelova vstupu(55) a v přecházení z uzlu do uzlu po hranách(57) odpovídajících načítaným znakům(56). Pokud se aktuálním uzlem stane list(58), pak je jeho znak porovnán(59) s prefixem vstupu. Jestliže jsou rozdílné, pak se jedná o špatnou odpověď. V opačném případě se aktuálním uzlem stane opět kořen(60) a pokračuje se v kontrole. Odpověď může být uznána za správnou pouze v případě, kdy je přečten celý uživatelův vstup a comparator už neobsahuje žádné znaky(63). 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
public String getResult() { StringBuffer sb = new StringBuffer(‘‘’’); for (int i = 0; i < input.length(); i++) { sb.append(map.get(input.substring(i,i+1)).getCode()); } sb.append(‘‘
’’); return sb.toString(); } public boolean isAnswerCorrect(String answer) { StrictTokenizer tokenizer = new StrictTokenizer(answer); PrefixComparator comparator = new PrefixComparator(input); Node currentNode = root; try { while (tokenizer.hasNextToken()) { char bit = tokenizer.nextBit(); currentNode = currentNode.getChild(bit); if (currentNode.isLeaf()) { if (!comparator.compareAndMerge(currentNode.getLabel()))return false; currentNode=root; } } return ! comparator.hasNext(); } catch (WrongTokenException exc) { return false; } }
Zbylá část programu se stará o generování obrázku. Metoda getGeneratedImage() je volána pokaždé při požadavku na zobrazení otázky a vrací objekt BufferedImage. Při jeho vytváření(69) se určuje výška, šířka a typ obrázku. Voláním metody getGraphics() lze získat objekt Graphics2D, který svými metodami umožňuje ovlivňování výsledné podoby obrázku.
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
71
Nejdříve je nastavena barva pozadí(71), která je použita pro vykreslení obdélníku(72) přes celou plochu obrázku. Pro vykreslování stromu je použita černá barva(74) a tučné písmo(75). Po nastavení grafických vlastností společných pro všechny prvky jsou postupně procházeny všechny uzly a ty se díky volání metody Paint vykreslují(77). Všechny vnitřní uzly stromu se zároveň postarají o vykreslení přechodů ke svým potomkům(79 a 80). Poslední řádek vrací obrázek připravený pro zobrazení v otázce. 68: public BufferedImage getGeneratedImage() { 69: BufferedImage image=new BufferedImage(400,300,BufferedImage.TYPE_INT_RGB); 70: Graphics2D g = (Graphics2D) image.getGraphics(); 71: g.setColor(Color.white); 72: g.fillRect(0, 0, 400, 300); 73: Font def=g.getFont(); 74: g.setColor(Color.BLACK); 75: g.setFont(def.deriveFont(Font.BOLD,16f)); 76: for (Node node : nodes) { 77: node.paint(g); 78: if (!node.isLeaf()) { 79: paintCurve(g,node,node.getChild(‘‘0’’),‘‘0’’); 80: paintCurve(g,node,node.getChild(‘‘1’’),‘‘1’’); 81: } 82: } 83: return image; 84: } 85: public void paintCurve(Graphics2D g,Node parent,Node child,String str){ 86: GeneralPath gp=new GeneralPath(); 87: int x1 = parent.getX()+40/2; int y1 = parent.getY()+40; 88: int x2 = child.getX()+40/2; int y2 = child.getY(); 89: gp.moveTo(x1,y1); 90: int px=Math.min(x1,x2)+Math.abs(x1-x2)/2; 91: int py=Math.min(y1,y2)+Math.abs(y1-y2)/2; 92: int diff=x1<x2?10:-10; 93: gp.quadTo(px+diff,py-Math.abs(diff),x2, y2); 94: g.draw(gp); 95: int w=g.getFontMetrics().charsWidth(str.toCharArray(),0,str.length()); 96: diff=x1<x2?18-w:-18; 97: g.drawChars(str.toCharArray(), 0, str.length(), px+diff, py-4); 98: } 99:}// konec tridy Poslední metoda se stará o vykreslení přechodů mezi uzly. Ty jsou znázorněny křivkami, které lze tvořit pomocí třídy GeneralPath. Vlastnosti křivky jsou nastaveny na řádcích 87-93 a posléze vykresleny metodou draw(gp). U přechodů jsou vyznačeny symboly, podle kterých se
72
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
přechod mezi uzly řídí. Aby bylo možné tyto symboly umístit vedle křivky, je nejdříve zjištěna jejich šířka(95) a podle směru křivky i vzdálenost(96), o kterou se mají v horizontálním směru vůči křivce posunout, aby se zamezilo jejich překryvu.
7.6
Testování zásuvných modulů
Implementaci modulu je zapotřebí dobře otestovat. Důležitá je zejména kontrola reakcí modulu na okrajové podmínky. Mezi ty může patřit například to, když uživatel nezadá do odpovědi žádný text nebo když generátor pseudonáhodných čísel zvolí hodnoty parametrů příliš malé či naopak příliš velké. Pro tyto účely by stačily běžné testovací prostředky, které se při vývoji aplikací používají. V případě systému SyVyKoD však musí testování zacházet dále do větších detailů. Instance tříd modulů totiž neexistují v JVM po celou dobu a jsou v serializované podobě ukládány do databáze. Velice důležitou roli hraje ověření chování objektu po deserializaci. V tomto stavu totiž modul kontroluje správnosti odpovědí na otázky. V případě, že by se objekt nechoval přesně podle předpokladů vývojáře modulu, mohli by být uživatelé poškozeni nesprávným vyhodnocením otázky. Pro testovací účely je se systémem dodávána Java aplikace Plugin Tester, která při práci s moduly simuluje přesně ty samé podmínky, kterým jsou moduly vystaveny na straně aplikačního serveru při ostrém provozu webové aplikace. Pro chod aplikace není potřeba žádný server, databáze ani síťové připojení. Je distribuována ve formě spustitelného JAR archivu. Tento archiv navíc obsahuje i ty části systému SyVyKoD, které jsou nutné pro vývoj nových modulů. Ty mohou být pomocí obyčejného vývojového nástroje pro vývoj Java aplikací přiřazeny do proměnné CLASSPATH, a tak používány v jiných projektech. Vytváření nových dynamických otázkových šablon je tak velice snadnou záležitostí sestávající se pouze z vytvoření a otestování zásuvných modulů otázek nezávisle na webové aplikaci a nahrání těchto modulů na aplikační server. Aplikace Plugin Tester nemusí být použita pouze na testování hotových modulů. Mechanizmy použité v návrhu aplikace umožňují spoluúčast už v době jejich vytváření. Při vývoji modulů dochází k častým úpravám kódu a rekompilacím tříd. Aplikace umožňuje testování, u kterého se tyto změny projeví okamžitě, aniž by ji bylo nutné vypínat a znovu zapínat. Jazyk Java je postaven na principu nahrávání tříd do JVM až v době, kdy je třída potřeba (při prvním použití). O nahrávání tříd se starají tzv. zavaděče - objekty třídy ClassLoader. Při běžném programování se programátor o nahrávání tříd nemusí zajímat a tuto práci za něj dělá systémový zavaděč. Nevýhody tohoto přístupu, vzhledem ke spolupráci se třídami, které se v čase mění, jsou dvě. Zavaděč potřebuje znát umístění tříd, které má nahrát. Toto umístění se zadává do proměnné zvané CLASSPATH při spouštění aplikace. Druhou nevýhodou je fakt, že není možné ze zavaděče nahranou třídu odstranit. Proto při používání pouze systémového zavaděče by se třída nahrála do JVM pouze jednou a další změny v kódu a rekompilace by se v již nahrané třídě neprojevily. Řešení problému nabízí použití vlastního zavaděče. V Javě je možné vytvořit vlastní uživatelské zavaděče, které se o nahrání potřebných tříd postarají sami. Tyto zavaděče opět
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
73
potřebují znát umístění nahrávané třídy, ovšem ta se neudává pomocí proměnné CLASSPATH, ale při vytváření instancí zavaděče. Tak může nastat stav, kdy uživatelský zavaděč hledá třídy na jiných místech než zavaděč systémový. Proces vytváření třídy je následující. Když je uživatelský zavaděč požádán o nahrání nějaké třídy, nejdříve o toto nahrání požádá jemu nadřazený zavaděč. Takto se delegace požadavku opakuje až k systémovému zavaděči. Pokud některý ze zavaděčů již třídu do systému nahrál, zastaví požadavek a informuje o tom ostatní zavaděče. Pokud požadavek zastaven není, tak se systémový zavaděč pokusí třídu najít na těch místech, které má uvedené v CLASSPATH. Pokud třídu nenajde, informuje o tom svůj podřízený zavaděč a ten se pokusí o to samé s využitím vlastních cest. Pakliže není třída nalezena ani jedním zavaděčem, je vyhozena výjimka ClassNotFoundException. Každá třída si pamatuje zavaděč, který ji do JVM nahrál. V případě, že se třída odkazuje na jinou třídu, která ještě v JVM neexistuje, použije se k jejímu nahrání právě ten zavaděč, se kterým je spjata odkazující se třída. Při vývoji aplikace by bylo zapotřebí, aby zavaděč nahrál modul pokaždé, kdykoli je modifikován. Ovšem to, jak již bylo zmíněno výše, není možné, jelikož při vzniku požadavku na nahrání třídy zavaděč zjistí, že třídu již jednou nahrál a vrátí referenci na existující třídu. Jediný způsob, jak zajistit znovuzavedení třídy do JVM, spočívá v „zapomenutíÿ příslušného zavaděče a vytvoření nového. Když je nově vytvořený zavaděč požádán o nahrání třídy, předá požadavek nadřazeným zavaděčům. Ovšem jelikož ty nezavedly třídu předtím, nezavedou ji ani nyní a požadavek se dostane zpět k nově vytvořenému zavaděči. A protože ten třídu ještě nezavedl (prakticky nezavedl žádnou třídu, jelikož je nově vytvořený), najde ve svých cestách soubor reprezentující třídu a zavede ji. Popsaný mechanizmus vysvětluje, proč nemohou být v proměnné CLASSPATH uvedena umístění (adresáře, JAR nebo ZIP soubory), kde se nachází testované moduly. V případě, že by tomu tak bylo, by třídy modulů zavedl systémový zavaděč a odstraňování a znovuvytváření uživatelských zavaděčů by nebylo nic platné. Systémový zavaděč by vždy vrátil referenci na již zavedenou třídu. Umístění modulů se proto uvádí až v samotné aplikaci. Tato umístění jsou použita při vytváření uživatelského zavaděče. Jelikož se aplikace snaží o co nejpřesnější simulaci podmínek, kterým moduly podléhají na straně aplikačního serveru, dochází při testování modulů i k jejich serializaci a deserializaci. S deserializací vyvstává ovšem další problém. Deserializace je ve své podstatě vytváření objektů, u kterého probíhá stejný proces zavádění tříd, jako je popsán v předchozích odstavcích. Bylo také zmíněno, že třídy si pamatují zavaděč, který je nahrál, a ten pak žádají o nahrání tříd, na které se odkazují. To samé probíhá při deserializaci. Proto pokud třída obsahuje kód, který deserializuje objekt, ze serializovaného proudu zjistí název třídy, která je právě deserializována a požádá „svůjÿ zavaděč, aby příslušnou třídu nahrál. Pokud by se kód deserializace nacházel uvnitř nějaké běžné třídy aplikace, pak by byl o zavedení požádán systémový zavaděč, jelikož ten je zodpovědný za zavedení tříd aplikace. Ovšem bylo řečeno, že systémový zavaděč nezná umístění tříd modulů. Výsledkem pokusu o deserializaci by byla výjimka ClassNotFoundException. Deserializace musí tudíž probíhat ve třídě, která byla společně s třídou modulu nahrána uživatelským zavaděčem. Požadavek na implementaci deserializace v každém modulu by byl jistě
74
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
nerozumný. Proto aplikace Plugin Tester v adresáři deserializace sama obsahuje třídu, která se o deserializaci stará. Zavaděč nejdříve nahraje tuto třídu, pomocí níž deserializuje objekty. Ani umístění této třídy se nesmí objevit v proměnné CLASSPATH. Důvod je stejný jako u podmínky vztahující se k modulům. 7.6.1
Popis aplikace Plugin Tester
Aplikace Plugin Tester je Java aplikace s grafickým rozhraním využívající Swing komponenty. Na přiloženém CD se nachází v adresáři syvykod/plugin tester. Před samotným spuštěním je zapotřebí modifikovat spouštěcí soubory start.bat (v případě použití OS Windows) a start.sh (v případě použití OS Linux). Na prvním řádku musí být uvedena správná cesta k aplikaci Plugin Tester. set appPath=...cesta k aplikaci... v operačním systému Windows appPath=...cesta k aplikaci... v operačním systému Linux Poté je možné těmito soubory aplikaci spustit. Aby bylo možné zásuvné moduly testovat, musí být nastavena cesta, která je předána zavaděči pro nahrání tříd do JVM. To lze provést v dialogu dostupným v menu pod položkou Soubor - Nastavit CLASSPATH . . . . V dialogu je možné položky přidávat či odebírat. Přidat lze název adresáře, ZIP a JAR soubory3 . V případě adresáře se neuvádí jméno adresáře obsahující samotné .class soubory, ale jméno adresáře obsahující celý balíček. Příklad 7.1: Testovaná třída se nazývá Otazka1 a je v balíčku math.testovani. Struktura adresářů a souborů může vypadat takto: c:\predmety\math\testovani\Otazka1.class. V dialogu je zapotřebí vybrat adresář c:\predmety. Dále je zapotřebí vybrat konkrétní zásuvný modul. To lze provést v dalším dialogu dostupným v menu pod položkou Soubor - Vybrat třídu . . . . Dialog nabízí přehled všech tříd v doposud známých umístěních ve formě stromu. Existuje ještě jedna možnost, jak určit modul a to v menu Soubor - Zadat třídu jménem . . . . V textovém dialogu je možné vyplnit jméno třídy reprezentující modul. Po vybrání třídy proběhne kontrola, zda třída implementuje jedno z podporovaných rozhraní. Pokud ano, je možné zvolit jazyk, který se použije při generování otázky. Jelikož nelze s určitostí zjistit, které jazyky modul podporuje4 , rozbalovací seznam obsahuje přehled jazyků, které jsou konkrétní instalací Javy podporovány. Po zvolení jazyka lze generovat otázku. V závislosti na typu použitého modulu se zobrazí panel s obsahem otázky. V případě typu DynamicOne a DynamicMany panel obsahuje vygenerované možnosti odpovědí, s vyznačením těch, které jsou správné. Počet odpovědí lze zvolit při generování otázky v rozbalovacím seznamu. U typu DynamicText je zobrazeno správné řešení a zároveň nabídnuta možnost pro 3
Archivy ZIP a JAR musí mít běžnou strukturu, která se používá JVM Zásuvnému modulu je předáván objekt Locale a je ponecháno na něm, jak s tímto objektem naloží. Nemusí obsahovat .properties soubory, podle kterých by šel seznam podporovaných jazyků zjistit 4
KAPITOLA 7. ROZHRANÍ PRO VYTVÁŘENÍ DYNAMICKÝCH OTÁZEK
75
kontrolu přijímaného řetězce. Po stisku tlačítka Kontrola odpovědi se vstupní textové pole zabarví červeně (v případě špatné odpovědi) nebo zeleně (v případě správné odpovědi). Pokud otázka implementuje rozhraní ImageGenerator, pak je vygenerovaný obrázek zobrazen na pravém panelu. Vpravo dole na stavové liště je vidět velikost (v bytech) serializovaného objektu. Kdykoli se změní kód modulu, stačí použít tlačítko Načíst třídu a změny chování modulu se projeví ihned při novém generování otázky. Vzhled aplikace je zobrazen na obrázku 7.4
Obrázek 7.4: Aplikace Plugin Tester
Kapitola 8 Závěr Cílem práce bylo vytvoření webového rámce pro podporu výuky předmětu Komprese dat. Systém SyVyKoD je webová aplikace navržená tak, aby podporovala obě dvě hlavní části učebního procesu - výuky a testování. Modul pro prezentaci kompresních algoritmů definuje strukturu a vzhled výukové části. Spolu s obsahem, představovaným vizualizačními applety kompresních algoritmů vyvíjených studenty předmětu, tvoří velice přínosný a hlavně veřejně přístupný zdroj informací z oboru komprese dat. Fakt, že modul umožňuje prezentovat tyto informace i v anglickém jazyce, přiřazuje systém ke skupině již existujících vizualizačních aplikací, které se pomocí Internetu snaží o názorné zprostředkování podstaty algoritmů užívaných v různých vědeckých oborech. Druhý modul systému se zabývá testováním studentů. Při jeho vytváření bylo myšleno hlavně na jednoduchost a flexibilitu návrhu testů na straně administrátora a zároveň na co největší dostupnost a přehlednost systému na straně studenta. Podařilo se navrhnout obecný systém, který může být použit kdekoli, kde jsou kladeny požadavky na e-learningovou formu studia. Zvláště ojedinělou vlastnost nabízí systém v možnosti vytváření dynamických otázek pomocí Java programů, které lze se systémem snadno integrovat. Díky podpoře rozšíření jazykovými mutacemi a díky zvolené technologii Java, nebrání nasazení systému v různých zemích a na různých platformách žádné překážky. V současné době je systémem podporována anglická a česká mutace. Systém byl naplněn počátečními vzorovými šablonami testů z oblasti komprese dat, které mohou sloužit zároveň jako inspirace pro vytváření nových testovacích materiálů. Na těchto datech byl systém také otestován. U všech testů se systém choval podle očekávání a nebyly zjištěny žádné nepředpokládané události. Avšak kvalitu systému ověří až jeho nasazení do praxe. To bude zároveň zdrojem nových požadavků, jejichž implementace může vlastnosti systému ještě zlepšit. Díky strukturovanému návrhu aplikace nebude těžké takováto rozšíření do systému přidávat.
77
Kapitola 9 Literatura [1] Ondřej Hanousek. Kompresní algoritmy, jejich implementace a vizualizace, 2005. [2] Pavel Herout. Java - grafické uživatelské prostředí a čeština. Kopp, 2001. [3] Pavel Herout. Učebnice jazyka Java. Kopp, 2003. [4] Dušan Janovský. Informace o psaní webových stránek. http://dusan.pc-slany.cz/. [5] Ila Neustadt Jim Arlow. UML a unifikovaný proces vývoje aplikací. CP Books a.s., 2005. [6] Rastislav Škultéty. JavaScript - Kapesní přehled. Computer Press, a.s., 2005. [7] Ruppert Martin. Popis j2ee technologie. 2003. http://www.cssi.cz/publ_si_clanek.asp?typ=1&kod=366. [8] B. Melichar. Textové informační systémy. ČVUT Praha, 1994. [9] Sun Microsystems. Technologie java. http://java.sun.com. [10] Vojtěch Patrný. Popis j2ee technologie. 2002. http://www.linuxzone.cz/index.phtml?ids=2&idc=179. [11] Vojtěch Patrný. Podepisování jar souborů. 2003. http://www.linuxzone.cz/index.phtml?ids=2&idc=637. [12] Rudolf Pecinovský. Java 5.0 - Novinky jazyka a upgrade aplikací. CP Books, a.s., 2005. [13] Petr Staníček. CSS Kaskádové styly - Kompletní průvodce. Computer Press, a.s., 2003. [14] Wikipedia - zdroj obecných informací. http://cs.wikipedia.org. [15] The j2ee 1.4 tutorial. http://java.sun.com/j2ee/1.4/docs/tutorial/doc/. [16] Dokumentace a instalace jakarta tomcat. http://tomcat.apache.org/. [17] Domovská stránka projektu jakarta. http://jakarta.apache.org/. [18] Dokumentace a instalace postgresql. http://www.postgresql.org. 79
[19] Diskuzní fórum o java technologiích. http://forum.java.sun.com/index.jspa.
80
Příloha A Seznam použitých zkratek AJAX Asynchronous JavaScript And XML API Application Programming Interface BLOB Binary Large Object DAO Data Access Object DTD Document Type Definition GIF Graphical Interchange Format GNU GNU’s Not UNIX HTML HyperText Markup Language HTTP HyperText Transfer Protocol HTTPS HyperText Transfer Protocol Secure IIS Internet Information Services J2EE Java Platform, Enterprise Edition J2SE Java Platform, Standard Edition JAR Java Archive JAXP Java API for XML Processing JDBC Java Database Connectivity JDK Java Development Kit JNDI Java Naming and Directory Interface JPG Joint Photographic Experts Group JRE Java Runtime Environment JSF JavaServer Faces JSP JavaServer Pages MD5 Message-Digest algorithm 5 MVC Model-View-Controller 81
82
PŘÍLOHA A. SEZNAM POUŽITÝCH ZKRATEK
PNG Portable Network Graphics SAX Simple API for XML SQL Structured Query Language SyVyKoD Systém pro podporu výuky předmětu Komprese dat UML Unified Modeling Language W3C The World Wide Web Consortium XHTML Extensible HyperText Markup Language XML Extensible Markup Language
Příloha B Instalační příručka Systém SyVyKoD může být instalován na libovolný operační systém, na kterém je nainstalována Java 5.0 a servletový kontejner. Systém byl vyvíjen a testován na serveru Tomcat 5.5. Jako databázový server je využit PostgreSQL. Následující odstavce popisují základní instalaci těchto produktů na operačním systému Windows XP a Linux. V případě potřeby detailnější konfigurace je možné navštívit webové stránky produktů a kroky týkající se konkrétních požadavků vyhledat v dokumentaci. Na konci kapitoly je popsána podrobná instalace systému SyVyKoD.
B.1
Instalace PostgreSQL
Nejdříve je zapotřebí stáhnout produkt z Internetu. Nejaktuálnější verzí je PostgreSQL 8.1.3-1. Popis instalace se v závislosti na různých verzích může nepatrně lišit. B.1.1
Operační systém Windows XP
Z adresy http://www.postgresql.org/ftp/binary/v8.1.3/win32/ je možné stáhnout PostgreSQL pro operační systém Windows. Na stránce je možné vybrat několik souborů. Pro nejsnazší instalaci je vhodné zvolit soubor PostgreSQL 8.1.3-1.zip1 . Po stažení a rozbalení souboru je zapotřebí spustit instalátor, který nás provede instalací. Při této instalaci si uživatel zvolí hlavní přístupové heslo do databáze. Zároveň je dobré zvolit instalaci aplikace pgAdmin, což je grafický klient pro správu databáze. Další nastavení databáze bude popisováno s využitím tohoto klienta. Po instalaci je možné se s databází spojit přes aplikaci pgAdmin. K tomu je zapotřebí zvolené přístupové heslo. Po úspěšném přihlášení se v levé části aplikace zobrazí okno, představující objekty databáze. Kliknutím pravým tlačítkem na objekt Login Roles se rozbalí kontextové menu, kde vybereme položku New Login Role. V otevřeném dialogu vyplníme název nové role a zadáme heslo. Pomocí těchto údajů se systém SyVyKoD bude k databázi přihlašovat. Zvolená role se bude jmenovat syvykod. Další popis pro jednoduchost předpokládá, že heslo je nastaveno též na syvykod. Toto heslo by však z bezpečnostních důvodů mělo být nahrazeno jiným. Nyní vytvoříme novou databázi. Klikneme pravým tlačítkem na objekt Databases a z kontextového menu zvolíme příkaz New Database. Vyplníme název databáze. V našem případě se bude jmenovat syvykod. Za vlastníka zvolíme vytvořenou roli syvykod. Pro správné zobrazování textů je důležité zvolit kódování UTF8. Po vytvoření databáze je zapotřebí vytvořit tabulky, pohledy atd. K tomuto účelu slouží 1
Všechny zmiňované soubory jsou také součástí obsahu CD přiloženého k diplomové práci.
83
84
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA
skript tables.sql, který je na přiloženém CD v adresáři syvykod/modul testovani/. V pgAdmin označíme vytvořenou databázi a otevřeme okno pro vkládání SQL příkazů. To se nachází v menu pod položkou Tool - Query Tool. V tomto okně zvolíme File - Open . . . a otevřeme vytvářecí skript tables.sql. Kliknutím na ikonu Execute Query (zelená šipka) spustíme proces vytváření databázových objektů. Nyní je databáze připravena k použití. Spolu s aplikací jsou dodávány i ukázkové šablony otázek. Zavedení těchto šablon lze provést skriptem data.sql, který se nachází v adresáři syvykod/modul testovani/. Kvůli integritním omezením lze skript aplikovat pouze na prázdnou databázi. B.1.2
Operační systém Linux
Mnohé ze systémů Linux nabízejí nejrůznější balíčkové nástroje pro správu aplikací. Pokud cílová distribuce takovýto nástroj obsahuje, je doporučeno ho použít. Následující popis se zabývá instalací pomocí kompilace zdrojových kódů. Nejprve v systému vytvoříme nového uživatele se jménem postgres, který bude zodpovědný za správu databáze. Poté z adresy http://www.postgresql.org/ftp/source/v8.1.3/ stáhneme zdrojové kódy databáze. Rozbalením zdrojových kódů se vytvoří nový instalační adresář. Přepneme se do tohoto adresáře a pak postupně zadáme následující příkazy. $ $ $ $ $ $ $ $ $
./configure gmake su gmake install mkdir /usr/local/pgsql/data chown postgre /usr/local/pgsql/data su - postgres /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -E UTF8 /usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data >logfile 2>&1 &
V tuto chvíli je databázový server nainstalován. Nyní je zapotřebí vytvořit příslušné role, databázové tabulky atd. Pro komunikaci s databází využijeme nástroj /usr/local/pgsql/bin/psql. Po jeho spuštění vytvoříme novou roli. Pomocí této role se bude systém SyVyKoD k databázi přihlašovat. Zvolená role se bude jmenovat syvykod. Pro další popis se předpokládá, že heslo je také syvykod. Z bezpečnostního hlediska by toto heslo mělo být nahrazeno jiným. CREATE ROLE syvykod LOGIN NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE; Přiřadíme této roli heslo. ALTER ROLE syvykod PASSWORD ’syvykod’; Nyní vytvoříme databázi syvykod.
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA
85
CREATE DATABASE syvykod WITH OWNER = syvykod ENCODING = ’UTF8’; V takto vytvořené databázi můžeme definovat tabulky. K tomu slouží skript tables.sql, který je na přiloženém CD v adresáři syvykod/modul testovani/. Nejdříve se připojíme k vytvořené databázi a pak spustíme skript. \connect syvykod; \i CESTA/tables.sql; Nyní je databáze připravena k použití. Spolu s aplikací jsou dodávány i ukázkové šablony otázek. Zavedení těchto šablon lze provést skriptem data.sql, který se nachází v adresáři syvykod/modul testovani/. Kvůli integritním omezením lze skript aplikovat pouze na prázdnou databázi.
B.2
Instalace aplikačního serveru Apache Tomcat
Tomcat může být provozován přímo jako webový server nebo ho lze využít pouze jako servletový kontejner s napojením na jiný webový server. Následující odstavce popisují první možnost. Nejdříve je zapotřebí server stáhnout z Internetu. Stáhneme nejnovější verzi 5.5 z adresy http://tomcat.apache.org/download-55.cgi. Podle cílového operačního systému si můžeme vybrat nejvhodnější balíček.
B.2.1
Operační systém Windows XP
Ve Windows se můžeme rozhodnout, zda má server běžet jako systémová služba, nebo jako obyčejný program, který musíme sami spouštět. Pokud chceme, aby server běžel jako služba, pak pro instalaci zvolíme binární balíček s instalátorem. Při instalaci vybereme adresář, kam se má Tomcat nainstalovat, zvolíme port, na kterém bude server poslouchat, a přihlašovací údaje pro aplikaci Tomcat Manager. V dalším kroku označíme adresář s nainstalovaným JRE. Po instalaci přibudou v nabídce start ikony pro obsluhu serveru. Pokud si nepřejeme, aby byl server spouštěn jako systémová služba, pak stáhneme balíček bez instalátoru. Jeho obsah nakopírujeme do zvoleného adresáře. V tomto případě hraje důležitou roli správné nastavení systémových proměnných. Ty ve Windows můžeme nastavit pomocí dialogu Vlastnosti systému, který otevřeme přes ikonu Tento počítač. Na ni klikneme pravým tlačítkem a zvolíme Vlastnosti. Pod záložkou Upřesnit klikneme na tlačítko Proměnné prostředí a přidáme nové proměnné. Důležitá je proměnná JRE HOME ukazující na adresář, kde je nainstalovaná Java. Další proměnnou je CATALINA HOME, která ukazuje na adresář s rozbaleným Tomcatem. Jakmile zadáme systémové proměnné, je nutné se ze systému odhlásit a zase přihlásit. Tím se proměnné zaktivují. Pak už můžeme spustit server pomocí dávkového souboru CATALINA HOME\bin\start.bat.
86 B.2.2
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA Operační systém Linux
Instalace pod systémem Linux je podobná té předchozí. Stáhneme balíček s Tomcatem a rozbalíme ho do požadovaného adresáře. Důležité je nastavení proměnné CATALINA HOME, která musí ukazovat na adresář s rozbaleným programem. export CATALINA_HOME=’cesta_k_serveru’ Dále musíme zajistit, aby všechny skripty v adresáři CATALINA HOME/bin byly spustitelné. To můžeme zajistit příkazem chmod. chmod 744 *.sh Nyní lze server spustit skriptem startup.sh a následně zastavit shutdown.sh. B.2.3
Potřebná rozšíření
Pomocí webového prohlížeče můžeme ověřit, jestli instalace proběhla v pořádku. Nejdříve spustíme server a pak do webového prohlížeče zadáme adresu http://localhost:8080. Jestliže server naběhl, měli bychom spatřit úvodní stránku Tomcata. Konfigurací Tomcata lze docílit toho, že bude poslouchat na jiném portu než je tradiční port 8080. Další informace ohledně instalace a podrobnější konfigurace lze nalézt na webových stránkách [16]. Nyní musíme nakonfigurovat základní nastavení, aby bylo možné Tomcat používat. Nejprve zprovozníme aplikaci Tomcat Web Application Manager, pomocí níž můžeme přes webové rozhraní zapínat a vypínat běžící webové aplikace, aniž bychom museli restartovat server. Tato vlastnost se vyplatí při modifikaci konfiguračních souborů aplikací. Pokud není Tomcat instalován jako systémová služba Windows, musíme nejdříve nastavit přístupové jméno a heslo, pod kterým se budeme do aplikace přihlašovat. To lze provést v konfiguračním souboru CATALINA HOME/conf/tomcat-users.xml, kde vytvoříme nového uživatele, kterému přidělíme roli manager. Konfigurační soubor tedy může vypadat takto. ... <user username=‘‘jmeno’’ password=‘‘heslo’’ roles=‘‘manager’’/> ... Po restartování serveru můžeme na základní webové stránce http://localhost:8080 kliknout na odkaz Tomcat Manager (vlevo nahoře) a tím se přihlásit do aplikace. Při zobrazování stránky se server dotáže na přihlašovací údaje. Jako jméno očekává jmeno a jako heslo heslo - právě nastavené údaje v konfiguračním souboru. Tímto je aplikace Tomcat Manager nainstalována. Nyní k serveru přidáme rozšíření potřebná pro správný chod systému SyVyKoD.
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA
87
JDBC ovladače Aby se systém SyVyKoD mohl spojit s databází, potřebuje JDBC ovladače. Tyto ovladače dodává výrobce databáze. V našem případě je možné JDBC ovladače stáhnout ze stránek http://jdbc.postgresql.org/. Jedná se o soubor postgresql-8.1-405.jdbc3.jar. Tento JAR archiv nakopírujeme do adresáře CATALINA HOME/common/lib.
Jakarta Commons Komponenty commons rozšiřují základní funkčnost serveru Tomcat. Všechny uváděné komponenty lze stáhnout ze serveru http://jakarta.apache.org/commons/. Získané soubory JAR je potřeba nahrát opět do adresáře CATALINA HOME/common/lib. Pro databázový pooling jsou nutné komponenty DBCP, Pool a Collections. Pro hromadné vkládání uživatelů jsou zapotřebí komponenty FileUpload a Io.
JSTL specifikace Aby bylo možné v JSP stránkách používat tagy z množiny Standard Tag Library, je zapotřebí nakopírovat soubory jstl.jar a standard.jar do adresáře CATALINA HOME/common/lib. Na stránce http://jakarta.apache.org/site/downloads/downloads\_taglibs.html je možné tyto soubory stáhnout. V tuto chvíli je Tomcat plně připraven k nasazení systému SyVyKoD.
B.3
Instalace systému SyVyKoD
Nyní můžeme přistoupit k instalaci a konfiguraci systému SyVyKoD. První modul systému je obyčejná webová aplikace složená ze statických stránek, a proto není potřebná žádná speciální instalace. Stačí ji pouze nahrát do adresáře libovolného webového serveru. Pokud ji chceme provozovat také na serveru Tomcat, stačí ji nahrát do adresáře CATALINA HOME/webapps. Instalace druhého modulu je komplikovanější. Nejsnazší způsob instalace spočívá v překopírování adresáře syvykod/modul testovani/syvykod/ do adresáře CATALINA HOME/webapps. Od této chvíle by aplikace měla být dostupná na adrese http://localhost:8080/syvykod. Aby byla aplikace plně funkční, musí být nejdříve správně nakonfigurována. Konfigurace probíhá ve dvou souborech, které jsou umístěny v adresářích aplikace.
B.3.1
META-INF/context.xml
V tomto souboru se nastavují parametry potřebné pro připojení k databázi.
name Parametr name udává jméno datového zdroje. Pomocí něho se na datový zdroj budeme odkazovat ze souboru web.xml.
88
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA
driverClassName Tento parametr udává jméno SQL ovladače, který je použit pro navázání databázového spojení. V případě databáze PostgreSQL se ovladač nazývá org.postgresql.Driver. url Připojení k databázi je specifikováno url parametrem. V tomto parametru se udává typ databáze, jméno počítače, na kterém server běží a jméno databáze, k níž se chceme přihlásit. user Parametr user představuje uživatelské jméno pro přístup do databáze. password Parametr password představuje uživatelské heslo pro přístup do databáze. maxActive Tento parametr určuje maximální počet aktivních databázových spojení, které může pool v jeden okamžik držet. maxIdle Parametr maxIdle určuje maximální počet aktivních databázových spojení, které mohou být v poolu nevyužity. V případě, že je jich více, jsou nadbytečná spojení uzavřena. maxWait V případě, že jsou všechna spojení z poolu odebrána a přijde nový požadavek na další spojení, pool počká určitou dobu, zda se mu nějaké spojení nevrátí, aby ho mohl obratem „zapůjčitÿ. Pokud čekání na volné spojení přesáhne dobu určenou parametrem maxWait (zadáváno v milisekundách), pak pool vyhodí výjimku. Konfigurační soubor pro aplikaci může tedy vypadat následovně.
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA B.3.2
89
WEB-INF/web.xml
Druhý konfigurační soubor nastavuje chování zbytku aplikace. Jeho obsah je značně rozsáhlý, jelikož obsahuje i jména všech servletů a zároveň i adresy, na které jsou namapovány. Tyto položky by neměly být upravovány. Při konfiguraci tedy přichází v úvahu změna pouze těchto parametrů.
administratorPassword Administrátor se přihlašuje do systému pod uživatelským jménem administrator a heslem, které uvádí tento parametr.
applicationPath Parametr applicationPath popisuje absolutní cestu k adresáři, kde je aplikace umístěná. Jako oddělovače cesty musí být použita obyčejná lomítka (/).
questionImagePath Jméno adresáře se statickými obrázky je určeno tímto parametrem. Jedná se o zápis relativní cesty (vzhledem k umístění aplikace). Jako oddělovače cesty musí být použita obyčejná lomítka (/).
sessionTimeOut Tento parametr nastavuje dobu trvání session ve vteřinách. Po uplynutí této doby dojde k automatickému odhlášení uživatele.
dataSourceName Parametr dataSourceName představuje název datového zdroje, který je uveden v context.xml parametrem name.
defaultLanguage Obsahuje dvoupísmenný kód jazyka, který je v aplikaci použit jako implicitní. Problematika jazykových mutací je popsána v kapitole 4.1.2.
supportedLanguageVariations Tento parametr obsahuje seznam kódů dalších jazyků, které aplikace podporuje. Seznam je oddělený dvojtečkou. V případě, že by měla aplikace podporovat tři jazykové mutace (češtinu jako hlavní a dále angličtinu a španělštinu), pak by musel být tento atribut nastaven na hodnotu en:es. Aplikace sama těmto jazykům přizpůsobí prostředí. V sekci pro změnu jazyka se budou generovat odkazy na tyto tři jazyky, bude možné přidávat příslušné mutace do existujících otázek apod.
90
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA
doLog Nastavení tohoto parametru na hodnotu true zapíná logování událostí. Nastavení na hodnotu false tuto funkci vypíná. trialTestsAllowable Tento parametr určuje, zda systém podporuje skládání zkušebních testů. Hodnota true skládání takovýchto testů umožňuje, hodnota false naopak zakazuje. Pokud je zvoleno false, pak je možné skládat pouze ostré testy. studentsXmlSchema Parametr studentsXmlSchema specifikuje název dokumentu XML Schema, kde je definována podoba XML dokumentu, jímž se do systému hromadně vkládají noví uživatelé. Soubor se musí nacházet v adresáři WEB-INF. resource-ref Toto je skupina parametrů nastavující propojení aplikace a datového zdroje. Parametr res-refname specifikuje jméno zdroje uvedené v souboru context.xml. Pro popisované nastavení aplikace vypadá klíčová část souboru následovně: <param-name>administratorPassword <param-value>administrator <param-name>applicationPath <param-value>CATALINA_HOME/webapps/syvykod <param-name>questionImagePath <param-value>questions-img <param-name>sessionTimeOut <param-value>1800 <param-name>dataSourceName <param-value>jdbc/postgres <param-name>defaultLanguage
PŘÍLOHA B. INSTALAČNÍ PŘÍRUČKA
91
<param-value>cs <param-name>supportedLanguageVariations <param-value>en <param-name>doLog <param-value>true <param-name>trialTestsAllowable <param-value>true <param-name>studentsXmlSchema <param-value>students.xsd jdbc/postgres javax.sql.DataSource Container
Jakmile se v konfiguračních souborech aplikace provede nějaká změna, je zapotřebí aplikaci restartovat, aby se provedené změny projevily. Není zapotřebí restartovat celý server. Ve výše zmíněné webové aplikaci Tomcat Manager je možné restartovat samotnou aplikaci kliknutím na odkaz reload.
Příloha C Administrátorský manuál V této části je bodově popsán postup, pomocí něhož lze do systému vkládat nové testovací materiály. Může tak pomoci administrátorovi v rychlejším zorientování a seznámení se se systémem.
C.1
Přihlášení do systému
Administrátorský účet se nenastavuje v databázi, ale v konfiguračním souboru web.xml, jak je popsáno v příloze B.3.2. Pro přihlášení používá administrátor uživatelské jméno administrator a heslo zvolené v tomto konfiguračním souboru. Přihlásit se lze vyplněním těchto údajů do formuláře na stránce index.jsp. Odhlášení lze provést kdykoli pomocí odkazu v levém rámečku Přihlášení.
C.2
Vytváření skupin uživatelů
V levé části okna se nacházejí panely s odkazy, které se využívají pro ovládání aplikace. Prvním logickým krokem při vytváření testovacího prostředí je založení skupin uživatelů. V rámečku Skupiny je možné zobrazit seznam skupin již vytvořených nebo vytvořit skupinu novou. Při vytváření nové skupiny zadává administrátor pouze její název. Skupiny slouží k logickému rozčlenění studentů. Proto je vhodné volit názvy podle dnů cvičení, které studenti navštěvují - například středa 11:00. Po uložení se nová skupina objeví v seznamu skupin již existujících. Tento seznam je možné abecedně řadit podle názvu. Kliknutím na záhlaví tabulky dojde k vzestupnému seřazení. Při opětovném kliknutí se skupiny seřadí sestupně. Skupiny je možné editovat a odebírat pomocí ikon v tabulce. Při kliknutí na název skupiny se zobrazí seznam studentů, kteří jsou do této skupiny zařazeni.
C.3
Vytváření uživatelů
Pod pojmem uživatel bude nejčastěji vystupovat student předmětu. Administrátor se v tomto směru mezi uživatele neřadí - nemůže nastavovat své jméno, kontakt, nemůže skládat testy atd. Operace s uživateli lze volat z rámečku Uživatelé. Administrátor si může prohlížet záznamy uživatelů nebo může vytvářet uživatele nové. Nejsnazším způsobem je vytváření uživatelů postupným zadáváním. Pomocí odkazu Nový uživatel lze otevřít formulář pro takové vložení. Administrátor vyplní uživatelské jméno (login - tím se bude uživatel do systému přihlašovat), jméno, příjmení a email. Ten slouží pro kontaktování uživatele. Zároveň je uživatel přiřazen do některé ze založených skupin. Seznam skupin nabízí rozbalovací seznam. Uživatelské jméno 93
94
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL
musí být v rámci systému unikátní. Pokus o vložení dvou uživatelů se stejným uživatelským jménem skončí chybou. Druhým způsobem, jak naplnit systém studenty je tzv. hromadný import uživatelů. Ten se provádí pomocí XML souboru, kde jsou vyplněny informace o uživatelích. Formát tohoto souboru je popsán v kapitole 6.2.8.2. Soubor students.xsd, který definuje, jak má XML dokument vypadat, musí být umístěný na serveru a musí být aplikaci dostupný. V konfiguračním souboru web.xml lze jméno students.xsd změnit na jiné. Při použití operace Hromadný import v rámečku Uživatelé se otevře dialog pro vložení XML souboru s uživateli. Tento soubor musí mít administrátor uložený v souborovém systému počítače, na kterém běží webový prohlížeč. Není nutné mít tento seznam na serveru. Pomocí tlačítka Procházet lze otevřít dialog pro výběr souboru. Po zvolení souboru lze dokument odeslat stiskem tlačítka importovat. Systém bude postupně vkládat uživatele. Pokud při vkládání některých z uživatelů nastane chyba, budou tito uživatelé zobrazeni pomocí tabulky. K této chybě může dojít například pokud už v systému existuje uživatel se shodným uživatelským jménem. Po vložení uživatelů se objeví tabulka se všemi existujícími uživateli. Uživatelé mohou být odstraněni postupně pomocí ikony odstranit nebo hromadně pomocí zaškrtávacích políček a tlačítka Odstranit vybrané. Údaje o uživatelích lze upravovat pomocí ikony upravit. Při kliknutí na jméno uživatele se otevře detail jeho záznamu. Po kliknutí na emailovou adresu se otevře nastavený poštovní klient s nově vytvořenou zprávou pro dotyčného uživatele. Po kliknutí na název skupiny se otevře její detail a s ním i seznam pouze těch studentů, kteří do této skupiny patří. V seznamu je vidět, který z uživatelů má nastavené heslo. Nastavení hesla je velice důležité, jelikož bez jeho existence se může kdokoli přihlásit na uživatelský účet studenta a může tak provádět veškeré operace, k nimž má student oprávnění. Seznam též zobrazuje počet složených ostrých testů a zároveň dosavadní výsledky studentů. Pro zobrazení těchto výsledků je zvolená varianta hodnocení, která počítá výsledky z ostrých testů takových, jejichž šablony v systému stále existují. Mohou být aktivní i neaktivní. V součtech hodnocení testů se počítá minimálně s nulovou hodnotou. Popisovaná varianta odpovídá té, která je v příkladu 3.1 označovaná jako 2. skupina, 2. přístup hodnocení. Ostatní varianty hodnocení jsou dostupné v detailu uživatele. Detail uživatele nabízí přehled základních informací o studentovi. Kromě jiného je uživatelovi možné nastavit heslo. Minimální délka hesla je 5 znaků, maximální 50 znaků. Administrátor nemusí heslo přímo měnit. V případě, že uživatel své heslo zapomene, pak může administrátor toto heslo zrušit. Tím je uživateli dána možnost přihlásit se do systému bez použití hesla. Své vlastní heslo si pak může nastavit uživatel sám.
C.4
Vytváření kategorií
Stejnou funkci jako mají skupiny při rozdělování studentů, mají kategorie při rozdělování šablon otázek. Kategorie představuje skupinu šablon týkající se stejné problematiky. Může jít třeba o šablony testující znalosti stejného výpočetního algoritmu. Operace s kategoriemi nabízí
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL
95
rámeček Kategorie. Pomocí odkazu Nová kategorie lze nové kategorie vytvářet. Do otevřeného formuláře se vyplní pouze jméno kategorie. Po potvrzení se nová položka objeví v seznamu již existujících kategorií. S položkami lze provádět obdobné operace jako se skupinami studentů. Po kliknutí na název se otevře detail kategorie, ve kterém lze vidět šablony otázek do ní náležících.
C.5
Vytváření otázkových šablon
Jednou z nejdůležitější úloh administrátora je vytváření otázkových šablon. Ty slouží jako základ generovaným otázkám. Operace se šablonami nabízí rámeček Šablony otázek. Pro vytvoření nové šablony slouží odkaz Nová šablona. V otevřeném formuláři se vyplní následující údaje. Jméno Jméno slouží k identifikaci šablony. Může obsahovat až 100 znaků. Kategorie V rozbalovacím seznamu lze vybrat kategorii, pod kterou bude šablona spadat. Typ otázky Rozbalovací seznam typ otázky určuje, zda bude šablona dynamická (typu Dynamic) nebo statická (Static). Dynamická šablona spolupracuje se zásuvným modulem. Proto se při zvolení dynamické šablony v dolní části formuláře zobrazí textové pole Jméno třídy, do kterého se zadává jméno třídy reprezentující modul. Typ odpovědi Rozbalovací seznam typ odpovědi nabízí možnost výběru vlastnosti šablony AnswerOne (možnost jedna správná), AnswerMany (Více správných) nebo AnswerText (Textový vstup). Poslední volba je dostupná pouze pro šablony Dynamic. Tyto tři volby určují, zda budou studentovi nabízeny odpovědi (jedna správná či více správných) nebo jestli bude student vyzýván k zadání odpovědi do textového pole. Maximální počet odpovědí Tato položka je viditelná, pokud je v předchozím seznamu vybrána vlastnost Jedna správná nebo Více správných. Parametr uvádí maximální počet nabízených odpovědí ve vygenerované otázce. Počet bodů za správnou odpověď Tento parametr uvádí počet bodů, které uživatel obdrží za správně odpovězenou otázku. Počet bodů za špatnou odpověď Tento parametr uvádí počet bodů, které uživatel obdrží za špatně odpovězenou otázku.
96
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL
Čas na odpověď Uvedený čas v tomto parametru je čas doporučený na vypracování otázky. Z těchto dílčích časů je vypočítána celková doba na vypracování testu. Jméno třídy V případě, že se jedná o dynamickou šablonu, musí administrátor specifikovat jméno třídy reprezentující zásuvný modul otázky. Název se udává celým jménem třídy - tzn. i se jménem balíčku, ve kterém je třída obsažena. Název třídy může být reprezentován řetězcem o délce až 100 znaků. Aby administrátor nemusel zadávat celé jméno ručně, může použít tlačítko vedle textového pole, které otevírá dialog pro vložení názvu modulu. Tento dialog zobrazuje strukturu tříd, které jsou aplikačnímu serveru a tudíž i samotné aplikaci dostupné. Průchodem adresářové struktury se lze dostat až k požadované třídě. Po označení třídy se její název vloží do textového pole. Tento dialog lze použít pouze v případě, že webový prohlížeč podporuje JavaScript. O tom jak lze do aplikace přidávat nové moduly pojednává část C.7 Znění otázky Poslední položkou je Znění otázky. Zde se popisuje úkol, který má student vypracovat. Velikost vstupního textu je prakticky neomezena1 . V textu zadání může administrátor používat formátovací XHTML tagy. Pomocí těchto tagů lze do otázky vložit i odkaz na obrázek. K takovým odkazům slouží tlačítko Obrázek . . . . To otevírá podobný dialog jako pro vkládání názvu modulů. Rozdílný je ale strom adresářů, který lze tímto dialogem procházet. V konfiguračním souboru web.xml lze určit kořenový adresář tohoto stromu. Aplikace nepodporuje možnost nahrávání obrázků na server přes webové rozhraní. Tuto operaci je třeba provést jinou aplikací například FTP klientem. Vedle tlačítka Obrázek . . . se nacházejí i jiná tlačítka, která vkládají do znění otázky formátovací tagy. Pokud se jedná o dynamickou šablony, pak zásuvný modul může do zadání přidávat vlastní text. Ten je připojen na konec textu zadaného do pole Znění otázky. Znění otázky pak může vypadat třeba takto: Uvažujte <strong>Huffmanovo kódování. Následující obrázek znázorňuje strom, podle kterého byl zakódován vstupní řetězec.
Dekódujte výstupní řetězec a výsledek zapište do <em>textového pole
. Modul spojený s otázkou vygeneruje tento text, který bude připojen na konec zadání: 1
Jistěže existují jisté hardwarové hranice, ale těch se při zadávání otázek nemusíme obávat.
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL
97
Výstupní řetězec <strong>111010011010101 . Při používání formátovacích tagů je třeba dbát na pečlivé dodržování zásad XHTML standardu. Zobrazované zadání se totiž stává součástí celé webové stránky. Proto například špatně uzavřený párový tag může mít za následek její špatné zobrazení. Po uložení šablony se zobrazí její detail. V tomto stavu lze šabloně přidat jazykovou mutaci zadání. Po zvolení odkazu Přidat jazykovou mutaci se otevře nový formulář. V rozbalovacím seznamu je možné vybrat jazyk reprezentující nově vytvářenou mutaci. V přeloženém znění se mohou opět objevit formátovací XHTML tagy. Pokud se v textech zadání objeví neplatné odkazy na obrázky, pak je o tom administrátor v detailu šablony informován chybovou hláškou. Podobné upozornění se objeví, pokud se jedná o dynamickou šablonu a jméno modulu ukazuje na nesprávnou či neexistující třídu. Jestliže se jedná o statickou šablonu typu AnswerOne nebo AnswerMany, musí administrátor vytvořit i odpovědi, které budou studentům v testu nabízeny. Dynamická šablona tyto odpovědi generuje pomocí modulu. Pro přidání nové odpovědi slouží tlačítko přidat odpověď, které je umístěno v dolní části okna. U každé odpovědi musí být označeno, zda se jedná o správnou či špatnou odpověď. Podle této informace pak systém vyhodnocuje správnost studentových odpovědí. Znění odpovědi se zadává do textového pole. Odpověď může též obsahovat formátovací XHTML tagy, ale z důvodů uvedených v kapitole 6.2.6.1 se nedoporučuje používat tag pro vkládání obrázku. Stejně tak jako textu zadání otázky lze i odpovědím přidávat jazykové mutace. Počet odpovědí, které může administrátor k otázce přiřadit, není nijak omezen. Do vytvářené otázky se náhodně vybere tolik odpovědí, kolik stanovuje parametr Maximální počet odpovědí. K zobrazení kompletního seznamu šablon otázek slouží odkaz Seznam šablon. Pokud by se šablony zobrazovaly se všemi mutacemi, byl by seznam značně nepřehledný. Proto se v seznamu používá pouze ta mutace, která odpovídá aktuálně zvolenému jazyku prostředí.
C.6
Vytváření šablon testů
Posledním krokem v přípravě testovacích materiálů je vytvoření šablon testů. Podle těchto šablon se odvíjí generování testů. Administrátor má možnost stavět šablony testů z různých kategorií. U každé uvede, kolik otázek se z dané kategorie do generovaného testu použije. Nejdříve je zapotřebí vytvořit novou šablonu. To lze provést pomocí odkazu Nová Šablona v rámečku Šablony testů. Otevřený formulář obsahuje jedno textové pole, kam se zadává jméno šablony. To může obsahovat maximálně 100 znaků. Aby studenti mohli z těchto šablon generovat testy, je zapotřebí šablonu aktivovat. Aktivní šablony jsou pro studenty viditelné, neaktivní ne. Prázdná šablona však sama o sobě
98
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL
nemá velký význam. Proto dříve než bude aktivována, musí být naplněna kategoriemi, které budou použity při generování testů. V detailu je možné kategorie do šablony přidávat. V dolní části se nachází rozbalovací seznam, který obsahuje všechny doposud nepoužité kategorie. Po zvolení kategorie je možné určit, kolik šablon ze zvolené kategorie bude použito pro generování testových otázek. Jedná se o maximální počet. V případě, že kategorie takové množství šablon neobsahuje, použijí se pouze existující šablony. Je také možné zvolit variantu, kdy budou použity všechny šablony v kategorii. Kliknutím na tlačítko Přidat kategorii do šablony se kategorie přidá do seznamu těch, které šablona testu již obsahuje. Tento seznam je zobrazen v detailu šablony. Zároveň se v detailu kategorie zobrazuje seznam všech šablon testů, kterých je příslušná kategorie součástí. Názvům testových šablon lze také přiřazovat jazykové mutace. Dělá se tak v detailu šablony pomocí odkazu přidat mutaci. Po kompletním natavení a aktivování šablony je tato připravena pro generování testů.
C.7
Přidávání zásuvných modulů
V kapitole 7 byl popsán postup, jak vytvářet nové zásuvné moduly. Předchozí odstavce se zabývaly použitím modulu v šablonách. Zbývá vysvětlení toho, jakým způsobem lze moduly do systému přidávat. Po té co je modul vytvořen a otestován pomocí aplikace Plugin Tester, je ho nutné nahrát na aplikační server. Systém nepodporuje přenášení souborů z klienta na server, proto je zapotřebí toto přenesení zajistit jinou externí aplikací - například FTP klientem. Nezabalené třídy (ne JAR archivy) se nahrávají do adresáře WEB-INF/classes. Tento adresář je nastaven tak, aby v něm Tomcat hledal třídy, jež aplikace využívá. V tomto adresáři lze vytvářet libovolnou podadresářovou strukturu. Ovšem adresáře musí kopírovat názvy balíčků do nichž jsou třídy umisťovány. Například pokud třída Huffman.class deklaruje, že je z balíčku kod.question package kod.question public class Huffman { ... }, musí být třída umístěna v WEB-INF/classes/kod/question/Huffman.class. Jestliže se třída reprezentující modul objeví na serveru poprvé, není nutné aplikaci restartovat. Zavaděč tříd ji při prvním požadavku zavede. Pokud ale administrátor třídu upravil, zkompiloval a nahradil již existující třídu nově vytvořenou, je potřeba donutit aplikační server, aby novou verzi třídy znovu zavedl. Za tímto účelem není nutné restartovat celý server. Postačí restartování aplikace. To lze nejsnáze provést pomocí webové aplikace Tomcat Manager. V seznamu vybereme aplikaci, která má být restartována a zvolíme odkaz reload. Po provedení této akce jsou přidané moduly připravené k použití.
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL
C.8
99
Průběh testu
Administrátor má možnost sledovat průběh skládání testů u jednotlivých studentů. V detailu studenta lze vybrat jedno z možných zobrazení testů. První odkaz Šablony testů zobrazuje seznam šablon testů. U nich je vyznačeno, které z nich už student použil pro generování ostrého testu. Tímto způsobem se dá snadno zjistit, zda student splnil všechny požadavky. Další odkaz zobrazuje právě probíhající testy. Ty má administrátor možnost předčasně ohodnotit nebo odstranit. Zároveň může procházet i znění testových otázek. Jestliže doběhl časový limit stanovený na vypracování testu, přesune se test do seznamu testů čekajících na vyhodnocení. Tento seznam je dostupný pod dalším z řady odkazů v uživatelově detailu. S těmito druhy testů může administrátor provádět ty samé operace jako v předchozím případě. Navíc může obnovit časový měřič testu, a tak bude možné v jeho vypracovávání pokračovat. Poslední skupinou jsou testy již ohodnocené. Ty jsou dostupné pod odkazem Ohodnocené testy. V tomto seznamu jsou k dispozici i dosažené výsledky. Z tohoto seznamu je také možné obnovit časový měřič testu. Důležitou roli hraje ohodnocení studentů. To zpřístupňuje odkaz Celkové hodnocení (opět v detailu studenta). V hodnocení je k dispozici seznam všech ostrých testů, které student složil, a zároveň výsledků, kterých dosáhl. Ve spodní části jsou vypočítávány různé varianty hodnocení. Vysvětlení těchto variant je popsáno v kapitole 3.5.
C.9
Údržba aplikace
Následující odstavce popisují nástroje, které může administrátor použít pro zajištění bezproblémový chodu systému. Všechny popisované operace se vyvolávají pomocí odkazů z rámečku Údržba. C.9.1
Základní funkce
Po dokončení výukového kurzu není zapotřebí dále skladovat informace o testech ani uživatelích. Proto systém nabízí možnost tyto informace naráz odstranit. Pomocí odkazu Základní funkce se otevře stránka, kde jsou k dispozici 4 formuláře. Každý má svůj vlastní význam. Ve formuláři Hromadné odstranění uživatelů lze naráz odstranit informace o existujících studentech. Stačí vyplnit textové pole formuláře slovy DELETE ALL USERS a odeslat formulář. Pokud je nutné odstranit pouze existující testy lze využít druhý formulář. Do textového pole je zapotřebí zadat DELETE ALL TESTS a odeslat formulář. Další formulář slouží k odstranění logovacích záznamů. Zde se vyplní DELETE ALL LOGS. Po odeslání formuláře budou záznamy odstraněny. Poslední formulář slouží pro hromadné vložení uživatelů. Jedná se o tentýž formulář, který byl popsán na začátku kapitoly v odstavci zabývající se problematikou vytváření uživatelů.
100 C.9.2
PŘÍLOHA C. ADMINISTRÁTORSKÝ MANUÁL Logování událostí
Pro bezproblémový chod aplikace je zapotřebí administrátorův dohled nad událostmi, které se v systému odehrávají. Jestliže je funkce logování v konfiguračním souboru web.xml zapnuta, pak je o každé události vytvořen záznam. Tyto záznamy se dají zobrazit pomocí odkazu Logování událostí. Pro zpřehlednění výpisu lze použít filtr. Ten zajistí zobrazení jen takových údajů, které odpovídají hodnotám ve formuláři. Pokud je například v poli login uveden řetězec ova, pak budou zobrazeny pouze ty záznamy, které pochází od uživatelů, jejichž uživatelská jména obsahují tento řetězec. Čili v úvahu přicházejí například novak a balcarova. Záznamy od uživatele novotny se nezobrazí. Zobrazované záznamy lze omezit i časově. K tomu slouží pole od a do. Časové záznamy se udávají ve formátu rrrr-mm-dd hh:mm. Druhá část představující hodiny a minuty není povinná. Časový záznam může vypadat tedy třeba takto 2006-05-02 12:03 nebo takto 2006-05-02. Pokud prohlížeč podporuje JavaScript, je možné využít tlačítka vedle textových polí a v otevřeném kalendáři časový údaj kliknutím vybrat. Pro aplikaci filtru je zapotřebí odeslat formulář pomocí tlačítka Použít filtr. Základní nastavení filtru lze získat pomocí tlačítka Vymazat filtr C.9.3
Správa obrázků
Jelikož statické obrázky jsou na server nahrávány externími aplikacemi a nejsou přímo spjaty s jednotlivými šablonami, může se stát, že se na serveru začnou hromadit nepoužívané obrázky. Pro kontrolu závislostí mezi šablonami a obrázky nabízí systém SyVyKoD nástroj dostupný pod odkazem Správa obrázků. Kliknutím na tento odkaz se otevře stránka, která zobrazuje obsah adresáře s obrázky. Jméno tohoto adresáře je nastavitelné v konfiguračním souboru. Pomocí odkazů je možné procházet adresářovou strukturu obrázků. Nalevo od jmen položek jsou vidět dvě čísla. První představuje počet šablon, které se na obrázek odkazují, druhý počet testových otázek odkazujících se na obrázek. Při zajetí myší nad název souboru se objeví rámeček se seznamem jednotlivých šablon. Kliknutím na položky seznamu lze zobrazit detail příslušné šablony. Tato funkce je dostupná pouze v prohlížečích podporujících JavaScript.
Příloha D Obsah přiloženého CD D.1
Obsah
• obsah.html - XHTML dokument popisující obsah CD
D.2
Text diplomové práce
• prace/diplom.pdf - diplomová práce ve formátu PDF • prace/diplom.ps - diplomová práce ve formátu PS • prace/diplom.zip - zdrojové soubory diplomové práce ve formátu LATEX
D.3
Systém Syvykod
• syvykod/modul_prezentace/ - adresář s modulem pro prezentaci vizualizačních appletů • syvykod/modul_testovani/syvykod/ - adresář s modulem pro testování studentů • syvykod/modul_testovani/syvykod/tables.sql - SQL skript vytvářející tabulky • syvykod/modul_testovani/syvykod/data.sql - SQL skript s ukázkovými šablonami otázek • syvykod/plugin_tester/ - adresář s aplikací Plugin Tester
D.4
Potřebný software
• software/net.ouska.webtool/ - rámec pro vývoj webových aplikací • software/postgresql/ - databázový server PostgreSQL 8.1.3 • software/postgresql-8.1-405.jdbc3.jar - JDBC ovladač pro databázi PostreSQL • software/tomcat/ - aplikační server Apache Tomcat 5.5.17 • software/apache.jakarta.commons/ - komponenty rozšiřující Apache Tomcat • software/jakarta-taglibs-standard-1.1.2 - implementace JSP tagů
101