Aplikacja internetowa z wykorzystaniem

Transkrypt

Aplikacja internetowa z wykorzystaniem
Politechnika Warszawska
Wydział Elektroniki i Technik Informacyjnych
Instytut Informatyki
Rok akademicki 2013/2014
Praca dyplomowa inżynierska
Mateusz Dziurdziak
Aplikacja internetowa z wykorzystaniem
szkieletu Vaadin
Opiekun pracy:
dr inż. Jakub Janusz Koperwas
Ocena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.........................................
Podpis Przewodniczacego
˛
Komisji Egzaminu Dyplomowego
Specjalność:
Informatyka –
Inżynieria oprogramowania
i systemy informacyjne
Data urodzenia:
10 kwietnia 1991 r.
Data rozpoczecia
˛
studiów:
1 października 2010 r.
Życiorys
Nazywam sie˛ Mateusz Dziurdziak, urodziłem sie˛ 10 kwietnia 1991 roku w Łukowie. W 2010 roku ukończyłem I Liceum Ogólnokształcace
˛ im. Tadeusza Kościuszki
w Łukowie i rozpoczałem
˛
studia na wydziale Elektroniki i Technik Informacyjnych
Politechniki Warszawskiej na kierunku Informatyka. W czerwcu 2012 roku podja˛
łem staż w firmie Quality Business Software. We wrześniu 2013 roku rozpoczałem
˛
prac˛e w firmie Accenture. Obecnie kontynuuje˛ studia oraz pracuje˛ w e-point SA na
stanowisku młodszego programisty Java.
.....................................
podpis studenta
Egzamin dyplomowy
Złożył egzamin dyplomowy w dn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Z wynikiem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ogólny wynik studiów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dodatkowe wnioski i uwagi Komisji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
..........................................................................................
Streszczenie
Praca ta prezentuje procesu projektowania oraz implementacji aplikacji internetowej, która wykorzystuje szkielet Vaadin. Jako temat aplikacji wybrano system
wspierajacy
˛ rozliczanie wspólnych wydatków. Poczatek
˛
poświecony
˛
jest analizie
wymagań oraz zaznajomieniu czytelnika z dziedzina˛ problemu. W dalszej cze˛ ści dokonano analizy dostepnych
˛
bibliotek oraz szkieletów informatycznych, które mogły
zostać wykorzystane podczas tworzenia aplikacji. W ramach projektowania sformułowano model logiczny i fizyczny danych. W pracy zawarto również omówienie
sporzadzonego
˛
interfejsu graficznego oraz sposóbu integracji Vaadin ze przygotowanymi modułami bezpieczeństwa oraz nawigacji.
Słowa kluczowe: aplikacja internetowa, Vaadin, Apache Shiro, OAuth, wspólne
wydatki, wstrzykiwanie zależności.
Abstract
Title: Web application using Vaadin framework
This thesis describes process of design and implementation of web application
using Vaadin framework. System supporting accounting of shared expenses has
been chosen as the application subject. First part of the thesis is dedicated to
describe application requirements and to familiarize reader with problem domain.
Next part is about analysis of available libraries and frameworks, which could be
used in process of creating application. During design process author created logical
and physical data model. This thesis also contains description of grafic user interface
and method of integration Vaadin framework with newly implemented security and
navigation modules.
Key words: web application, Vaadin, Apache Shiro, OAuth, shared expenses, dependency injection.
Spis treści
1. Wstep
˛ . . . . . . . . . .
1.1. Motywacja . . . .
1.2. Cel i zakres pracy
1.3. Zawartość pracy .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
1
2
2. Specyfikacja wymagań . . . .
2.1. Dziedzinowy słownik pojeć
˛
2.1.1. Użytkownik . . . . .
2.1.2. Znajomy . . . . . .
2.1.3. Grupa . . . . . . . .
2.1.4. Konto . . . . . . . .
2.1.5. Operacja . . . . . .
2.2. Wymagania funkcjonalne
2.3. Reguły biznesowe . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
3
3
3
3
4
6
3. Analiza technologiczna . . . . . . . . . . . . . . . . . . .
3.1. Baza danych . . . . . . . . . . . . . . . . . . . . . . .
3.1.1. Oracle Database Express Edition . . . . . . .
3.1.2. SQL Server Express . . . . . . . . . . . . . . .
3.1.3. PostgreSQL . . . . . . . . . . . . . . . . . . . .
3.1.4. Wybrana baza danych . . . . . . . . . . . . .
3.2. Warstwa prezentacji . . . . . . . . . . . . . . . . . . .
3.2.1. AngularJS . . . . . . . . . . . . . . . . . . . .
3.2.2. Vaadin . . . . . . . . . . . . . . . . . . . . . .
3.2.3. Wybrany szkielet warstwy prezentacji . . . .
3.3. Mapowanie obiektowo-relacyjne . . . . . . . . . . . .
3.3.1. Java Persistence API . . . . . . . . . . . . . .
3.3.2. Hibernate . . . . . . . . . . . . . . . . . . . . .
3.3.3. EclipseLink . . . . . . . . . . . . . . . . . . . .
3.3.4. Wybrane rozwiazanie
˛
. . . . . . . . . . . . . .
3.4. Wstrzykiwanie zależności . . . . . . . . . . . . . . . .
3.4.1. Spring . . . . . . . . . . . . . . . . . . . . . . .
3.4.2. Context Dependency Injection . . . . . . . . .
3.4.3. Wybrany kontener wstrzykiwania zależności
3.5. Serwer aplikacyjny . . . . . . . . . . . . . . . . . . .
3.5.1. GlassFish . . . . . . . . . . . . . . . . . . . . .
3.5.2. WildFly . . . . . . . . . . . . . . . . . . . . . .
3.5.3. Wybrany serwer aplikacyjny . . . . . . . . . .
3.6. Moduł bezpieczeństwa . . . . . . . . . . . . . . . . .
3.6.1. Spring Security . . . . . . . . . . . . . . . . .
3.6.2. Apache Shiro . . . . . . . . . . . . . . . . . . .
3.6.3. OAuth . . . . . . . . . . . . . . . . . . . . . . .
3.6.4. Wybrany szkielet bezpieczeństwa . . . . . . .
3.7. Testowanie jednostkowe . . . . . . . . . . . . . . . .
3.7.1. JUnit . . . . . . . . . . . . . . . . . . . . . . .
3.7.2. TestNG . . . . . . . . . . . . . . . . . . . . . .
3.7.3. Wybrany szkielet testujacy
˛ . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
8
9
9
9
10
10
11
12
13
13
14
14
15
15
16
17
18
19
19
19
20
20
20
21
22
23
24
24
25
26
ii
Spis treści
3.8. Makietowanie . . . . . . . . . . . . . . .
3.8.1. Mockito . . . . . . . . . . . . . . .
3.8.2. EasyMock . . . . . . . . . . . . .
3.8.3. Wybrana biblioteka makietujaca
˛
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
26
26
27
28
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
29
29
30
31
34
34
38
39
39
39
41
5. Interfejs graficzny . . . . . . . . . . . . . . . . . .
5.1. Okno dodawania operacji grupowej . . . . . .
5.2. Okno dodawania operacji w parze . . . . . . .
5.3. Ekran szczegółów grupy . . . . . . . . . . . .
5.4. Ekran szczegółów konta z użytkownikiem . .
5.5. Ekran operacji pomiedzy
˛
użytkownikami . .
5.6. Ekran kont pomiedzy
˛
użytkownikami . . . .
5.7. Ekran wyświetlajacy
˛ informacje o znajomym
5.8. Formularz uwierzytelniania . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
42
43
43
44
44
45
46
46
6. Implementacja rozszerzeń szkieletu Vaadin . . .
6.1. Moduł bezpieczeństwa . . . . . . . . . . . . . .
6.1.1. Rozwiazanie
˛
dostepne
˛
w Apache Shiro .
6.1.2. Wymagania wobec nowego rozwiazania
˛
6.1.3. Integracja z baza˛ danych . . . . . . . . .
6.1.4. Rodzaje uprawnień . . . . . . . . . . . .
6.1.5. Sprawdzanie uprawnień . . . . . . . . .
6.2. MVP oraz nawigacja . . . . . . . . . . . . . . . .
6.2.1. Sposób nawigacji w Vaadin . . . . . . .
6.2.2. Wady nawigacji w Vaadin . . . . . . . . .
6.2.3. Wymagania wobec nowego rozwiazania
˛
6.2.4. Wykorzystane rozwiazanie
˛
. . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
47
47
47
47
48
51
52
53
53
53
54
54
7. Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4. Projekt systemu . . . . . . . . . .
4.1. Architektura . . . . . . . . . .
4.2. Podział pakietów . . . . . . . .
4.3. Testowanie . . . . . . . . . . .
4.4. Wyjatki
˛
. . . . . . . . . . . . .
4.5. Model logiczny . . . . . . . . .
4.6. Model klas operacji . . . . . .
4.7. Model klas kont . . . . . . . .
4.8. Model fizyczny . . . . . . . . .
4.8.1. Operacje oraz konta . .
4.8.2. Moduł bezpieczeństwa
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1. Wstep
˛
1.1. Motywacja
W środowisku studenckim powszechne jest dokonywanie wspólnych zakupów
lub wydatków, które naste˛ pnie należy podzielić pomiedzy
˛
grono osób. Zwiazane
˛
jest to z cze˛ stym w tym wieku współdzieleniem mieszkań oraz grupowym sp˛edzaniem wolnego czasu. W przypadku dokonywania dużej liczby wydatków do rangi
problemu urasta sposób dokonania rozliczenia.
W sieci Internet doste˛ pne sa˛ aplikacje majace
˛ usprawnić czynności zwiazane
˛
ze
wspólnym rozliczaniem np.:
— www.splitwise.com
— www.expensesplit.com
— www.kittysplit.com
Przedstawione powyżej strony internetowe maja˛ jednak mankamenty m.in.:
— Możliwość rozliczania tylko pojedynczego wyjazdu, wydarzenia.
— Ograniczona liczba osób bioracych
˛
udział w operacji.
— Możliwość przynależenia do tylko jednej grupy.
— Brak sposobności dodawania wydatków o nierównym podziale udziałów pomie˛
dzy uczestników.
— Brak polskiej wersji je˛ zykowej.
Nie każda z wymienionych wad dotyczy wszystkich serwisów, lecz żaden z nich
nie spełnia wszystkich stawianych przed nim wymagań. W zwiazku
˛
z tym autor tej
pracy podjał
˛ decyzje˛ o zaimplementowaniu aplikacji majacej
˛
niwelować trudności
wspólnego rozliczania, która w miare˛ możliwości pozbawiona bedzie
˛
niedostatków
przedstawionych powyżej stron internetowych.
1.2. Cel i zakres pracy
Celem pracy jest implementacja bogatej aplikacji internetowej (ang. Rich Internet Application) wspomagajacej
˛
rozliczanie wspólnych wydatków. Dodatkowym
elementem jest przeglad
˛ i poznanie dostepnych
˛
technik oraz technologii informatycznych.
Zadaniem, które należało wkomponować w proces pisania kodu źródłowego
była integracja technologii wybranych do tworzenia systemu. Skupiła sie˛ ona na
stworzeniu komponentu odpowiedzialnego za połaczenie
˛
modułu bezpieczeństwa
(Apache Shiro) z Vaadin oraz na opracowaniu własnego sposobu nawigacji. Oba
zaproponowane rozwiazania
˛
podczas swojego działania wykorzystuja˛ wstrzykiwanie
zależności.
Projektowana aplikacja ma za zadanie umożliwiać zarejestrowanym użytkownikom na przynależenie do grup, posiadanie znajomych w jej obrebie,
˛
dodawanie
1.3. Zawartość pracy
2
wydatków wspólnych oraz pomiedzy
˛
dwoma użytkownikami. Bilans operacji z innymi użytkownikami powinien być gromadzony na specjalnych kontach. Dodatkowa˛ funkcja˛ systemu powinno być ułatwienie uwierzytelniania poprzez możliwość
wykorzystania standardu OAuth.
1.3. Zawartość pracy
— Rozdział 2 (”Specyfikacja wymagań”) zawiera krótki spis pojeć
˛ zwiazanych
˛
z tematyka˛ aplikacji oraz omawia wymagania jakie bedzie
˛
musiał spełnić projektowany system.
— Rozdział 3 (”Analiza technologiczna”) jest zapisem przeprowadzonej w trakcie
pracy analizy doste˛ pnych technologii. Przedstawia biblioteki oraz szkielety aplikacyjne wraz z ich alternatywami, które mogły zostać wykorzystane w trakcie
implementacji systemu.
— Rozdział 4 (”Projekt systemu”) prezentuje sposób organizacji danych, które zostały wykorzystane w aplikacji oraz omawia decyzje, które wpłyneły
˛ na proces
tworzenia aplikacji.
— Rozdział 5 (”Interfejs graficzny”) prezentuje najważniejsze elementy interfejsu
graficznego aplikacji.
— Rozdział 6 (”Implementacja rozszerzeń szkieletu Vaadin”) zawiera opis pracy
wykonanej w celu integracji szkieletu Vaadin z zewnetrznymi
˛
bibliotekami. W
pierwszej cze˛ ści omówiony jest proces integracji z Apache Shiro. W drugiej
przedstawiono powody, dla których podjeto
˛ decyzje˛ o implementacji własnego
modułu nawigacyjnego oraz sposób jego wykonania oraz wykorzystania.
— Rozdział 7 (”Podsumowanie”) podsumowuje efekty pracy oraz przedstawia możliwe dalsze kierunki rozwoju.
2. Specyfikacja wymagań
2.1. Dziedzinowy słownik pojeć
˛
2.1.1. Użytkownik
Użytkownik jest osoba˛ korzystajac
˛ a˛ z aplikacji. Istnieja˛ dwa stany, w których
może przebywać użytkownik:
— nieuwierzytelniony,
— uwierzytelniony.
Użytkownik nieuwierzytelniony nie ma możliwości wykonania żadnej operacji z
wyjatkiem
˛
procedury rejestracji lub uwierzytelnienia.
Uwierzytelniony użytkownik ma możliwość tworzenia kont, operacji finansowych, grup, wysyłania zaproszeń do grona znajomych oraz grup, modyfikacji swoich danych.
2.1.2. Znajomy
Znajomy jest użytkownikiem, który zaakceptował badź
˛
wysłał zaproszenie do
grona znajomych, które zostało zaakceptowane. Gdy dwaj użytkownicy sa˛ znajomymi maja˛ możliwość dodawania operacji finansowych pomiedzy
˛
soba.
˛
2.1.3. Grupa
Grupa jest zbiorem użytkowników, którego członkowie maja˛ na celu wspólne
rozliczanie. Jest tworzona i zarzadzana
˛
prze użytkowników. Istnienie grupy umożliwia powiazanie
˛
z nia˛ operacji wspólnych obejmujacych
˛
wszystkich członków.
2.1.4. Konto
Konto jest obiektem służacym
˛
do grupowania operacji finansowych. Każde jest
przypisane do użytkownika, który jest jego właścicielem.
Istnieja˛ naste˛ pujace
˛ rodzaje kont:
— wirtualne – określane też własnymi, służa˛ do grupowania operacji wirtualnych,
— użytkownika – służace
˛ do notowania operacji pomiedzy
˛
użytkownikami
2.1.5. Operacja
Operacja˛ nazywa sie˛ pojedynczy fakt dokumentujacy
˛ wydatek poniesiony przez
użytkownika lub użytkowników.
Istnieja˛ naste˛ pujace
˛ rodzaje operacji:
— Wirtualna – operacja własna użytkownika. Służy np. do notowania bieżacych
˛
wydatków.
2.2. Wymagania funkcjonalne
4
— Pożyczka – operacja pomie˛ dzy dwoma użytkownikami, której wynikiem jest przekazanie pienie˛ dzy pomie˛ dzy nimi. Całość kwoty operacji zapisywana jest na
kontach użytkowników.
— W parze – wspólny wydatek dwóch użytkowników. Kwota operacji dzielona jest
pomie˛ dzy jej uczestników.
— Wspólna – operacja dotyczaca
˛ wiecej
˛
niż dwóch użytkowników. Całkowita kwota
operacji dzielona jest pomiedzy
˛
użytkowników.
— Grupowa – jest to operacja wspólna, której uczestnikami sa˛ członkowie jednej
grupy.
2.2. Wymagania funkcjonalne
WF 1.
Nieuwierzytelniony użytkownik może zarejestrować nowe konto do pracy z
aplikacja˛ podajac
˛ nastepuj
˛
ace
˛ dane:
— login,
— hasło,
— adres e-mail.
WF 2.
Nieuwierzytelniony użytkownik może zarejestrować nowe konto korzystajac
˛
z serwisów trzecich takich jak:
— Facebook,
— LinkedIn.
WF 3.
Po zarejestrowaniu użytkownika system wysyła wiadomość e-mail potwierdzajac
˛ a˛ te˛ operacje˛ .
WF 4.
Nieuwierzytelniony użytkownik ma możliwość uwierzytelnienia sie˛ podajac
˛
login i hasło.
WF 5.
Nieuwierzytelniony użytkownik ma możliwość uwierzytelnienia sie˛ z wykorzystaniem serwisów trzecich, o ile jego konto zostało wcześniej połaczone
˛
z
kontami tamtych serwisów.
WF 6.
Administrator systemu może zresetować hasło użytkownika. System w
takiej sytuacji wyśle nowe hasło na adres poczty elektronicznej powiazanej
˛
z kontem użytkownika.
WF 7.
Użytkownik ma możliwość zmiany swojego hasła o ile w trakcie tej czynności
poprawnie poda aktualne.
WF 8.
Użytkownik może zaprosić innego użytkownika do listy swoich znajomych
podajac
˛ jego login.
WF 9.
Zaproszony użytkownik ma prawo zaakceptować badź
˛ zignorować zaproszenie do grona znajomych.
WF 10.
Użytkownik ma możliwość podgladu
˛
listy swoich znajomych.
2.2. Wymagania funkcjonalne
5
WF 11.
Użytkownik ma możliwość utworzenia grupy. Podczas tego procesu musi
podać jej nazwe˛ .
WF 12.
Użytkownik ma możliwość podgladu
˛
listy grup, których jest członkiem.
WF 13.
Użytkownik może zaprosić innego użytkownika do członkostwa w grupie,
której sam jest członkiem.
WF 14.
Członkowie grupy maja˛ możliwość podgladu
˛
listy wysłanych zaproszeń.
WF 15.
Użytkownik ma możliwość utworzenia konta wirtualnego podajac
˛ jego nazwe˛ .
WF 16.
Użytkownik może utworzyć konto do rozliczeń z użytkownikiem wybierajac
˛
znajomego, którego konto to ma dotyczyć oraz nazwe˛ konta.
WF 17.
˛
list posiadanych kont wirtualnych oraz
Użytkownik ma możliwość podgladu
kont służacych
˛
do rozliczeń z innymi użytkownikami.
WF 18.
Użytkownik może zobaczyć liste˛ operacji własnych.
WF 19.
Użytkownik może zobaczyć liste˛ operacji z innymi użytkownikami.
WF 20.
Użytkownik może zobaczyć liste˛ operacji grupowych.
WF 21.
W widoku szczegółowym kont zobrazowany jest bilans dzienny operacji z
ostatnich trzydziestu dni.
WF 22.
Użytkownik może wyświetlić wykresy obrazujace
˛
podsumowanie bilansu
wszystkich kont do rozliczeń z użytkownikami. Dostepne
˛
wykresy to:
— dłużnicy wg kont rozliczeniowych,
— długi użytkownika wzgledem
˛
innych podzielone na konta.
WF 23.
Użytkownik ma możliwość dodania operacji wirtualnej podajac
˛ nastepuj
˛
ace
˛
dane: nazwa operacji, kwota, data operacji, konto wirtualne, opis (opcjonalnie).
WF 24.
Użytkownik ma możliwość dodania pożyczki podajac
˛ nastepuj
˛
ace
˛ dane: nazwa operacji, kwota, data operacji, znajomy, konto do rozliczeń ze znajomym
(o ile istnieje wie˛ cej niż jedno), opis (opcjonalnie) oraz kierunek pożyczki (kto
pożyczył komu).
WF 25.
Użytkownik ma możliwość dodania operacji w parze podajac
˛ nastepuj
˛
ace
˛
dane: nazwa operacji, kwota, data operacji, znajomy, konto do rozliczeń ze
znajomym (o ile istnieje wiecej
˛
niż jedno), opis (opcjonalnie), informacje˛ o
tym jak podzielić kwote˛ oraz dodatkowe informacje o sposobie zapłaty.
WF 26.
Użytkownik ma możliwość dodania operacji wspólnej podajac
˛ nastepuj
˛
ace
˛
2.3. Reguły biznesowe
6
dane: nazwa operacji, kwota, data operacji, lista znajomych bioracych
˛
udział w operacji, opis (opcjonalnie). Jeśli operacja wspólna była operacja˛ składkowa˛ możliwe jest również podanie kwoty wniesionej przez każdego
użytkownika. System umożliwia podglad
˛ operacji pomiedzy
˛
użytkownikami,
które zostana˛ wygenerowane w momencie akceptacji operacji.
WF 27.
Podczas dodawania operacji grupowej użytkownik musi podać te same dane
co w przypadku operacji wspólnej z wyłaczeniem
˛
listy uczestników operacji.
Lista ta zostanie automatycznie zbudowana na podstawie członków grupy,
której dotyczy operacja.
WF 28.
Użytkownik ma możliwość podgladu
˛
wszystkich operacji, których jest członkiem.
WF 29.
Użytkownik ma możliwość przegladu
˛
operacji pomiedzy
˛
nim, a innym użytkownikiem.
WF 30.
Aplikacja powinna blokować użytkownikowi dostep
˛ do ekranów oraz danych
dla niego niedozwolonych.
WF 31.
Aplikacja powinna poprawnie reagować na skorzystanie z opcji Wstecz przegladarki
˛
internetowej.
2.3. Reguły biznesowe
RB 1.
Login oraz adres e-mail użytkownika musza˛ być unikalne w obrebie
˛
systemu.
RB 2.
Hasło użytkownika przetrzymywane jest w postaci wielokrotnie przetworzonej za pomoca˛ algorytmu SHA-256.
RB 3.
Jeśli użytkownik pie˛ ciokrotnie poda nieprawidłowe hasło podczas uwierzytelniania sie˛ jego konto zostaje zablokowane na 5 minut.
RB 4.
Użytkownik nie może posiadać wiecej
˛
niż sześciu kont wirtualnych.
RB 5.
Osoba nieuwierzytelniona powinna być przekierowywana do ekranu uwierzytelniania.
RB 6.
Użytkownik nie może utworzyć wiecej
˛
niż dwudziestu grup.
RB 7.
Minimalna długość nazwy operacji to trzy znaki.
RB 8.
Minimalna długość loginu to trzy znaki.
RB 9.
Minimalna długość hasła to pieć
˛ znaków.
2.3. Reguły biznesowe
7
RB 10.
Użytkownik uwierzytelniony nie może mieć dostepu
˛
do ekranów uwierzytelniania oraz rejestracji.
RB 11.
W przypadku gdy dodawana jest operacja pomiedzy
˛
użytkownikami, a nie
istnieje jeszcze pomie˛ dzy nimi konto rozliczeniowe zostanie ono automatycznie utworzone.
3. Analiza technologiczna
Celem tego rozdziału jest przedstawienie technologii, których wykorzystanie
było rozważane podczas budowania aplikacji internetowej. Z uwagi na mnogość
istniejacych
˛
na rynku narze˛ dzi wybór nie był trywialny.
3.1. Baza danych
Skomplikowane aplikacje obsługujace
˛ wielu użytkowników oraz przetwarzajace
˛
duże wolumeny danych wymagaja˛ niezawodnego sposobu przechowywania informacji. Jako rozwiazanie
˛
już w latach sześćdziesiatych
˛
XX wieku zaproponowano
oddzielny system, którego dedykowanym zadaniem miało być zarzadzanie
˛
danymi.
W 1970 roku zaproponowano relacyjny model danych [13]. W modelu tym dane
przetrzymywane sa˛ w relacjach bed
˛ acych
˛
zbiorami krotek. Krotki sa˛ uporzadkowa˛
nymi listami wartości. W powszechnym zastosowaniu odpowiednikami relacji sa˛
dwuwymiarowe tabele składajace
˛ sie˛ z kolumn i wierszy.
Wraz z upowszechnieniem modelu relacyjnego powstały relacyjne systemy zarzadzania
˛
bazami danych. Obecnie najpopularniejszym tego typu oprogramowaniem jest Oracle Database [2]. Na rynku dostepnych
˛
jest jednocześnie wiele konkurencyjnych systemów wolnodostepnych.
˛
W ostatnich latach rosnac
˛ a˛ popularnościa˛ ciesza˛ sie˛ bazy danych wykorzystujace
˛ mechanizm NoSQL. Polega on na przechowywaniu danych w formie innej niż
relacyjna. Możliwymi rozwiazaniami
˛
sa˛ miedzy
˛
innymi:
— przechowywanie par klucz-wartość,
— przechowywanie dokumentów,
— bazy grafowe,
— bazy kolumnowe.
Z uwagi na tabelaryczny typ danych zastosowany w projektowanej aplikacji
oraz konieczność wsparcia dla transakcyjności zdecydowano sie˛ na wykorzystanie
relacyjnej bazy danych.
3.1.1. Oracle Database Express Edition
Korzenie systemu Oracle Database siegaj
˛
a˛ lat siedemdziesiatych.
˛
System oferowany jest w różnych wersjach, pośród których znalazła sie˛ Oracle Database Express
Edition (Oracle Database XE) bed
˛ aca
˛ jedyna˛ darmowa˛ opcja.
˛ Obecna wersja Oracle
XE to 11g. Pozostałe warianty dostepne
˛
sa˛ już w nowszej wersji 12c.
Oracle poleca darmowa˛ wersje˛ bazy programistom, niezależnym twórcom oprogramowania, instytucjom edukacyjnym oraz studentom [6]. Swoja˛ opinie˛ popiera
zapewnieniami o dużych możliwościach, stabilności, niskim wykorzystaniu zasobów sprze˛ towych oraz intuicyjnym zarzadzaniu.
˛
Dzieki
˛ dużej popularności tego
systemu bardzo łatwo jest znaleźć rozwiazania
˛
typowych problemów. Podobnie jak
płatne warianty Oracle XE oferuje obsługe˛ szerokiej gamy poleceń SQL i PL/SQL,
3.1. Baza danych
9
wspiera przechowywanie dokumentów XML oraz indeksowanie, przeszukiwanie i
składowanie tekstów w wysokowydajny sposób [9].
Duża˛ wada˛ tego rozwiazania
˛
sa˛ ograniczenia nałożone przez producenta. Oracle
XE może przechowywać maksymalnie 11GB danych, używać nie wiecej
˛
niż 1GB
pami˛eci operacyjnej oraz wykorzystywać tylko jeden watek
˛
procesora. Użytkownicy
tej wersji systemu pozbawieni sa˛ oficjalnego wsparcia Oracle Support.
3.1.2. SQL Server Express
Firma Microsoft, założona w 1975 roku, jest znana głównie ze swojego flagowego
produktu Microsoft Windows. Jest on najpopularniejszym system operacyjnym
przeznaczonym na komputery osobiste [8]. W 1989 roku Microsoft po raz pierwszy
udoste˛ pnił baze˛ danych o nazwie SQL Server. Obecnie najnowsza˛ wersja˛ jest
SQL Server 2014, jest ona dwunastym wydaniem tego systemu. Podobnie jak w
przypadku Oracle, Microsoft oferuje swój system w wielu wariantach różniacych
˛
si˛e możliwościami i cena.
˛
SQL Server Express jest darmowa˛ wersja˛ bazy danych o znacznie okrojonych,
w stosunku do wariantów płatnych, możliwościach. Pozwala ona na stosowanie
j˛ezyka Transact-SQL be˛ dacego
˛
rozszerzeniem jezyka
˛
SQL wprowadzajacym
˛
możliwość programowania proceduralnego oraz wsparcie dla funkcji przetwarzajacych
˛
dane. Oprócz tego baza danych zapewnia wsparcie dla przechowywania dokumentów XML. Niestety jest to jedna z niewielu funkcji dostepnych
˛
w bogatszych
wariantach, która została udostepniona
˛
bezpłatnie. Oprócz pozbawienia wersji
darmowej możliwości wyszukiwania pełnotekstowego, modułu analitycznego, raportujacego
˛
oraz łatwości skalowania odmiana ta nie może korzystać ze wszystkich
możliwości sprze˛ tu, na którym pracuje. Maksymalna wielkość bazy danych została
ograniczona do 10GB, wykorzystanie pamieci
˛ operacyjnej do 1GB, zaś możliwość
wykonywania obliczeń do czterech watków
˛
procesora [10].
3.1.3. PostgreSQL
PostgreSQL jest obiektowo-relacyjnym systemem zarzadzania
˛
bazami danych o
otwartym kodzie źródłowym, który został zapoczatkowany
˛
w 1986 roku. Przez lata
zdobył uznanie użytkowników na całym świecie oraz stał sie˛ jednym z głównych
konkurentów Oracle Database [2]. Charakteryzuja˛ go możliwość stosowania wielu
typów indeksów, wyzwalaczy, typów danych, a nawet jezyków
˛
programowania wykorzystywanych do pisania funkcji składowych. PostgreSQL zapewnia wsparcie dla
zdecydowanej wie˛ kszości konstrukcji jezyka
˛
SQL zaproponowanych w standardzie
SQL:2011 [11] oraz wielu innych ułatwiajacych
˛
tworzenie zapytań oraz schematu
bazy danych [3].
3.1.4. Wybrana baza danych
Na system zarzadzania
˛
bazami danych, który został wykorzystany w trakcie tworzenia aplikacji wybrano PostgreSQL w wersji 9.3. Za wyborem tym przemawiały:
— pełne wsparcie dla transakcyjności,
— duża zgodność ze standardem SQL, w tym SQL:2011,
— brak ograniczeń licencyjnych,
— znaczaca
˛
liczba użytkowników zgromadzona wokół systemu gwarantujaca
˛
szybka˛ pomoc,
3.2. Warstwa prezentacji
10
— łatwość rozszerzania oraz administracji poprzez graficzne narzedzia.
˛
PostgreSQL w przeciwieństwie do SQL Server Express oraz Oracle Database
Express Edition nie nakłada na użytkownika ograniczeń na maksymalny rozmiar
bazy danych oraz stopień wykorzystania pozostałych zasobów sprzetowych.
˛
3.2. Warstwa prezentacji
Warstwa prezentacji jest cześci
˛ a˛ aplikacji odpowiedzialna˛ za wyświetlanie danych oraz komunikacje˛ z użytkownikiem. Od wyboru sposobu zarzadzania
˛
tym
elementem systemu zależy nie tylko wyglad,
˛ lecz również wydajność oraz sposób
tworzenia systemu. Szkielety warstwy prezentacji moga˛ narzucać programiście
określone wzorce projektowe lub korzystanie z konkretnych jezyków
˛
programowania.
Podstawowym podziałem szkieletów warstwy prezentacji jest miejsce wykonywania obliczeń majacych
˛
na celu ustalenie wygladu
˛
aplikacji. W zwiazku
˛
z tym
kryterium dzielimy je na biblioteki strony serwerowej oraz strony klienckiej. W
przypadku stosowania pierwszego podejścia serwer odpowiada za przetworzenie
danych wprowadzanych przez użytkownika oraz reakcje˛ na jego zachowanie. Do
zadań aplikacji pracujacej
˛
na serwerze należy ustalenie wpływu tych operacji na
zmiane˛ prezentowanego wygladu
˛
oraz przekazanie wyniku jego modyfikacji przegladarce
˛
internetowej. Przegladarka
˛
wyświetla zmieniony widok użytkownikowi.
W podejściu opartym na architekturze klienckiej cześć
˛
operacji może zostać wykonana bez interakcji z aplikacja˛ serwerowa.
˛ Dzieje sie˛ tak dzieki
˛ zastosowaniu
j˛ezyków takich jak JavaScript, które służa˛ do dynamicznej zmiany struktury dokumentu html. Rozwiazanie
˛
to wpływa na mniejsze obcia˛żenie łacza
˛
sieciowego oraz
zapewnia szybsza˛ modyfikacje strony w odpowiedzi na zachowanie użytkownika.
3.2.1. AngularJS
AngularJS jest stosunkowo nowym szkieletem aplikacyjnym zaprezentowanym
przez Google w 2009 roku. Projekt ten jest przedstawicielem podejścia gdzie przetwarzanie widoku odbywa sie˛ w przegladarce
˛
internetowej użytkownika. Na rysunku 3.1 przedstawiony jest gwałtowny wzrost zainteresowania fraza˛ AngularJS
w ostatnich latach.
Rysunek 3.1: Zainteresowanie fraza˛ “AngularJS” [5]
Celem AngularJS jest przezwycie˛ żenie niedoskonałości jezyka
˛
HTML polegaja˛
cych na niewielkim wsparciu dla dynamicznie zmieniajacej
˛
sie˛ zawartości. Twórcy
3.2. Warstwa prezentacji
11
projektu jako rozwiazanie
˛
proponuja˛ zestaw autorskich znaczników oraz atrybutów, które przeznaczone sa˛ do wykorzystania wewnatrz
˛ plików *.html. Zastosowanie
tych elementów pozwala na deklaratywne projektowanie widoków, które automatycznie zmieniaja˛ sie˛ w odpowiedzi na modyfikacje modelu, z którym sa˛ połaczone.
˛
Dzi˛eki skorzystaniu z tych komponentów możliwe jest budowanie aplikacji zgodnie ze wzorcem Model-Widok-Kontroler. Aplikacje takie charakteryzuja˛ sie˛ luźnymi
powiazaniami
˛
pomie˛ dzy widokami, a logika˛ biznesowa˛ oraz łatwiej jest w nich wykorzystać proces testowania jednostkowego.
AngularJS jest łatwo rozszerzalny o dodatkowe moduły, które programista może
pisać samodzielnie. Komponenty te moga˛ dostosowywać możliwości szkieletu do
potrzeb autora aplikacji. W szczególności możliwe jest przyłaczanie
˛
zestawów klas
CSS takich jak Bootstrap, które standaryzuja˛ wyglad
˛ wszystkich elementów widoku. Istnieje również możliwość tworzenia własnych znaczników, których używanie w trakcie deklarowania widoku ułatwia jego późniejsze zrozumienie i modyfikacje.
Dane pomie˛ dzy aplikacja˛ serwerowa,
˛ a kliencka˛ wymieniane sa˛ w formacie
JSON (JavaScript Object Notation). Modyfikacje danych w modelu przechowywanym w przegladarce
˛
użytkownika sa˛ automatycznie propagowane i wyświetlane.
Jedna˛ z najciekawszych funkcji AngularJS jest wbudowany odpowiednik wstrzykiwania zależności. Możliwe jest zarejestrowanie komponentów, które szkielet bedzie
˛
potem przekazywał do wywoływanych metod.
Programowanie w AngularJS wymaga od programisty znajomości JavaScript,
CSS, HTML oraz Javy.
3.2.2. Vaadin
Vaadin jest szkieletem tworzenia aplikacji internetowych, którego historia siega
˛
2002 roku. Poczatkowo
˛
był zalewie zestawem narzedzi
˛
majacych
˛
ułatwiać prace˛
programistom firmy IT Mill. Z czasem projekt urósł do rozmiarów pełnoprawnego
szkieletu aplikacyjnego. W 2007 roku porzucono koncepcje˛ własnego modułu wyświetlajacego
˛
interfejs użytkownika na rzecz Google Web Toolkit (GWT ). Jednocześnie udoste˛ pniono kod źródłowy i umożliwiono jego modyfikacje. W maju 2009
roku zmieniono nazwe˛ szkieletu na Vaadin. Od tego momentu można zaobserwować rosnace
˛ zainteresowanie tym rozwiazaniem,
˛
które ustabilizowało sie˛ w roku
2012.
Rysunek 3.2: Zainteresowanie fraza˛ “Vaadin” [4]
3.2. Warstwa prezentacji
12
Rysunek 3.2 przedstawia zainteresowanie fraza˛ Vaadin od momentu wykorzystania jej jako nazwy szkieletu aplikacyjnego do lipca 2014 roku.
Architektura
Rozważania na temat architektury Vaadina silnie wia˛ża˛ sie˛ z GWT. Można wyróżnić dwa podstawowe moduły:
— silnik po stronie klienta (ang. Client Side Engine - CSE),
— cze˛ ść serwerowa.
˛
Dzie˛ ki wbudowanemu w GWT kompilatorowi Javy do JavaScript otrzymywany
jest zestaw klas tworzacych
˛
CSE. Klasy umieszczone w pakiecie client tłumaczone
sa˛ na JavaScript, by naste˛ pnie być uruchamianymi w przegladarce
˛
użytkownika.
Pakiet server służy do przetrzymywania odpowiedników klas z pakietu client. Odpowiedniki tworzone sa˛ po stronie serwera aplikacyjnego. Komunikacja miedzy
˛
dwiema stronami wykorzystuje protokoły AJAX oraz RPC.
Niezwykle istotne jest to, że podział na cześć
˛
serwerowa i kliencka˛ jest ukryty
przed programista.
˛ Nie musi on posiadać szczegółowej wiedzy na temat zachodzacej
˛
wymiany danych, żeby tworzyć aplikacje [17].
Możliwe jest tworzenie własnych komponentów bed
˛ acych
˛
elementami interfejsu
użytkownika.
Dodatki
Vaadin Directory powstało w 2010 roku. Jest to repozytorium dodatków, które
można dołaczać
˛
do aplikacji tworzonych z wykorzystaniem szkieletu Vaadin. Celem
utworzenia zbioru była che˛ ć ułatwienia tworzenia, znajdowania, integrowania oraz
kupowania dodatków [14].
Każdy programista ma prawo utworzenia oraz zamieszczenia swojego dodatku
z możliwościa˛ wyboru licencji oraz ceny. Zdecydowana wiekszość
˛
dodatków jest
darmowa. Obecnie w repozytorium znajduje sie˛ ponad 450 dodatków podzielonych
na naste˛ pujace
˛ kategorie:
— komponenty UI (ang. UI Components),
— komponenty danych (ang. Data Components),
— motywy (ang. Themes),
— narze˛ dzia (ang. Tools),
— poboczne (ang. Miscellaneous) [12].
Olbrzymia liczba doste˛ pnych dodatków, ich różnorodność oraz łatwość integracji
sa˛ jednym z czynników wpływajacych
˛
na popularność Vaadin.
3.2.3. Wybrany szkielet warstwy prezentacji
Wybór szkieletu odpowiedzialnego za prezentacje˛ danych był jedna˛ z najważniejszych decyzji projektowych. Od tego elementu aplikacji w dużym stopniu zależy
dobór bibliotek odpowiedzialnych za pozostałe moduły.
Rozważane były AngularJS i Vaadin bed
˛ ace
˛ przedstawicielami skrajnie różnych
podejść do tworzenia interfejsu graficznego. AngularJS opera sie˛ na tworzeniu i
modyfikowaniu grafiki po stronie klienta zaś Vaadin po stronie serwera aplikacyjnego.
Jako szkielet warstwy prezentacji wybrano Vaadin motywujac
˛ to:
3.3. Mapowanie obiektowo-relacyjne
13
— Duża˛ liczba˛ wbudowanych komponentów gotowych do wykorzystania, które
znaczaco
˛
przewyższaja˛ możliwościami podstawowe elementy generowane poprzez HTML doste˛ pne w AngularJS.
— Brakiem konieczności znajomości JavaScript, który jest wymagany podczas
pracy z AngularJS.
— Podejściem serwerowym ułatwiajacym
˛
zapewnienie bezpieczeństwa.
— Bogatym zbiorem doste˛ pnych dodatków, które w znaczacy
˛ sposób moga˛ ułatwić
prace programistyczna.
˛
— Preferencjami autora pracy, pragnacego
˛
zapoznać sie˛ z nieznanym szkieletem
aplikacyjnym.
W przeciwieństwie do AngularJS, Vaadin w dużym stopniu wpływa na warstwe˛
logiki biznesowej aplikacji. Jego komponenty maja˛ bezpośrednie odwzorowanie w
cz˛eści serwerowej aplikacji, zaś generowanie widoku nie jest tak dokładnie odseparowane od pozostałej cze˛ ści aplikacji jak w AngularJS.
3.3. Mapowanie obiektowo-relacyjne
Java jest obiektowym je˛ zykiem programowania. Prowadzi to do niekompatybilności typów pomie˛ dzy aplikacja˛ operujac
˛ a˛ na obiektach, a systemem zarzadzania
˛
baza˛ danych opartym na tabelach. Jest to powszechny problem i zaproponowano
wiele sposobów jego zwalczania. Rozwiazaniem
˛
łatwo dostepnym
˛
oraz niezwykle
popularnym jest skorzystanie z techniki odwzorowywania obiektowo-relacyjnego,
której zadaniem jest konwersja danych pomiedzy
˛
aplikacja,
˛ a baza˛ danych.
3.3.1. Java Persistence API
Java Persistence API (JPA) jest oficjalnym standardem przekształcania informacji z podejścia obiektowego do relacyjnego. Należy on do platformy Java Enterprise
Edition (JEE). JPA jest specyfikacja˛ działania, zaś zadaniem dostawców jest stworzenie bibliotek oraz zagwarantowanie poprawności ich działania. Istnieje wiele
implementacji tego standardu m.in. Hibernate, TopLink oraz OpenJPA. W skład
specyfikacji wchodzi również jezyk
˛
JPQL. Dzieki
˛ niemu możliwe jest pobieranie danych bez znajomości struktury relacyjnej oraz bez konieczności tworzenia kwerend
SQL, które moga˛ różnić sie˛ w zależności od zastosowanej bazy danych.
W JPA programista definiuje klasy domenowe majace
˛ swoje odpowiedniki w
encjach relacyjnych. Poprzez wykorzystanie mechanizmu adnotacji oraz analize˛
struktury klasy i jej zależności podejmowane sa˛ decyzje o poprawności modelu,
sposobie odwzorowywania danych oraz możliwości ich modyfikacji.
Przykładowa klasa domenowa opisana adnotacjami została przedstawiona na
wydruku 3.1.
1
package pl . dziurdziak . easyReckoning . model . r o l e ;
import java . u t i l . Set ;
5
import javax . persistence . ∗ ;
import pl . dziurdziak . easyReckoning . model . user . User ;
10
@Entity
@Table (name = " r o l e s " )
3.3. Mapowanie obiektowo-relacyjne
14
public class Role {
@Id
@GeneratedValue
private long id ;
15
@Column(name = " role_name " , length = 20, nullable = false , unique = true )
private String roleName ;
@Version
private int version ;
20
@ManyToMany( mappedBy = " r o l e s " )
private Set<User> users ;
25
}
Wydruk 3.1: Przykładowa klasa domenowa
Dzie˛ ki adnotacji @Entity klasa zostaje uznana, za klase˛ należac
˛ a˛ do modelu
dziedziny. @Table określa nazwe˛ odpowiadajacej
˛
klasie tabeli bazodanowej. Pozostałe adnotacje sa˛ wykorzystywane do definiowania kolumn, ich własności oraz
powiaza
˛ ń do innych obiektów. Szczególna˛ funkcje˛ pełni adnotacja @Version, która˛
oznaczane jest pole potrzebne do zastosowania strategii optymistycznego blokowania (ang. Optimistic locking) rekordów.
Adnotacje te sa˛ odczytywane i sprawdzane przez biblioteke˛ implementujac
˛ a˛
standard JPA podczas uruchamiania aplikacji. Dzieki
˛ nim możliwe jest utworzenie
kontekstu niezbe˛ dnego do pracy z baza˛ danych.
3.3.2. Hibernate
Historia Hibernate sie˛ ga 2001 roku. Już wtedy zaobserwowano potrzebe˛ istnienia łatwej w użytkowaniu oraz bogatej w możliwości biblioteki oferujacej
˛
funkcje˛
mapowania obiektowo-relacyjnego. Tym samym proces powstawania Hibernate o
pi˛eć lat wyprzedził pierwsza˛ wersje˛ specyfikacji JPA, która w dużej cześci
˛
została
oparta na jego sposobie działania [15]. Hibernate w pełni implementuje standard
JPA zapewniajac
˛ jednocześnie dodatkowe funkcjonalności. W szczególności dostarcza on je˛ zyk HQL be˛ dacy
˛ nadzbiorem JPQL.
Hibernate jest jednym z najpopularniejszych narzedzi
˛
odwzorowywania
obiektowo-relacyjnego.
3.3.3. EclipseLink
EclipseLink wywodzi sie˛ od projektu TopLink zaś historia tego siega
˛
pomysłu
realizowanego w latach dziewiećdziesi
˛
atych
˛
w jezyku
˛
Smalltalk. Nieco później powstała wersja dla je˛ zyka Java, a cała inicjatywa została przejeta
˛ przez firme˛ Oracle.
W 2006 roku projekt TopLink został wzorcowa˛ implementacja˛ standardu JPA. Po
krótkim okresie rozwoju firma Oracle udostepniła
˛
kod źródłowy oraz przekazała go
Eclipse Foundation. Tym sposobem powstał EclipseLink, który rozwijany jest do
tego momentu.
3.4. Wstrzykiwanie zależności
15
Podobnie jak Hibernate, EclipseLink oferuje funkcjonalności daleko wykraczajace
˛ poza standard JPA. Wśród nich można znaleźć wsparcie dla pamieci
˛ podrecz˛
nej (ang. cache), rozszerzona˛ składnie˛ jezyka
˛
JPQL oraz dodatkowe możliwości w
tworzeniu zapytań.
3.3.4. Wybrane rozwiazanie
˛
Jako sposób doste˛ pu do danych wybrano standard JPA wspierany przez JPAContainer. JPAContainer jest dodatkiem do Vaadina umożliwiajacym
˛
tabelom pobieranie danych bezpośrednio z bazy danych.
Konieczny był jeszcze wybór implementacji standardu. Z uwagi na da˛żenie
do jak najrzadszego wykorzystywania funkcjonalności typowych tylko dla jednej
implementacji była to decyzja o marginalnym znaczeniu. Nie chciano uzależnić działania projektowanego systemu od żadnej biblioteki służacej
˛
mapowaniu
obiektowo-relacyjnemu. Zdecydowano sie˛ na Hibernate ponieważ jest to projekt
o ugruntowanej pozycji na rynku, do którego można znaleźć olbrzymia˛ liczbe˛ materiałów pomocniczych.
3.4. Wstrzykiwanie zależności
Wie˛ kszość obecnie tworzonego oprogramowania ma za zadanie wspieranie procesów zachodzacych
˛
w rzeczywistym świecie. Procesy te sa˛ zmienne, w zwiazku
˛
z
czym raz napisane aplikacje wymagaja˛ późniejszych aktualizacji. Cz˛esto prowadzi
to do sytuacji, w których najkosztowniejszym etapem dostarczania oprogramowania jest jego utrzymanie oraz modyfikacje majace
˛ na celu nada˛żanie za zachodza˛
cymi zmianami [18].
W drodze niwelowania tych kosztów wprowadzono wiele metodyk programowania oraz narze˛ dzi majacych
˛
ułatwić wprowadzanie zmian. Na szczególna˛ uwage˛
zasługuje tutaj idea programowania sterowanego testami (ang. Test-driven development), które w znaczacy
˛ sposób upraszcza modyfikacje˛ poprzez możliwość zagwarantowania poprawności działania niezmienianych elementów systemu.
Jednym z czynników majacy
˛ najwiekszy
˛
wpływ na koszt wprowadzania zmian
oraz na zwie˛ kszenie trudności testowania aplikacji sa˛ ścisłe powiazania
˛
pomiedzy
˛
klasami. Zaproponowano kilka sposobów majacych
˛
służyć jako rozwiazania
˛
tego
problemu m.in.:
— wzorzec fabryki,
— wzorzec lokalizator serwisów (ang. Service Locator)),
— wstrzykiwanie zależności (ang. Dependency Injection - DI).
Najlepszym rozwiazaniem
˛
jest wstrzykiwanie zależności oferujace
˛
najwie˛ ksza˛
elastyczność, możliwości oraz wygode˛ programowania. Wzorzec lokalizator serwisów zaś coraz cze˛ ściej uznawany jest za antywzorzec [19].
Podejście be˛ dace
˛ esencja˛ wstrzykiwania zależności najłatwiej opisać jako oddelegowanie tworzenia oraz zarzadzania
˛
zależnościami obiektów do oddzielnego komponentu aplikacji. Element ten, zwany kontenerem, odpowiedzialny jest za dostarczenie odpowiednio zainicjalizowanych obiektów w odpowiedzi na żadania
˛
przychodzace
˛ z innych cze˛ ści aplikacji. Rozwiazanie
˛
to spełnia paradygmat odwrócenia
sterowania (ang. Inversion of Control - IoC).
Rozwiazanie
˛
to prowadzi do luźnych powiaza
˛ ń pomiedzy
˛
klasami, gdyż te zazwyczaj uzależnione sa˛ tylko od interfejsów specyfikujacych
˛
zachowanie, a nie od
16
3.4. Wstrzykiwanie zależności
klas je implementujacych.
˛
Dzieki
˛
temu możliwe jest bezproblemowe testowanie
klas w izolacji od pozostałych składników tworzonego systemu. Możliwe jest również wprowadzanie zmian, o ile nie wpływaja˛ one na modyfikacje˛ kontraktu klasy
zawieranego poprzez implementowanie interfejsów.
Dzie˛ ki oddelegowaniu zadania dostarczania obiektów do zewnetrznego
˛
komponentu programista nie musi już śledzić wszystkich odwołań do obiektów modyfikowanej klasy w istniejacym
˛
systemie, gdyż o poprawność ich inicjalizacji dba
kontener.
Do najpopularniejszych kontenerów wstrzykiwania zależności należa:
˛
— Spring,
— Guice,
— PicoContainer i NanoContainer,
— Weld.
3.4.1. Spring
Spring Framework jest szkieletem aplikacyjnym, którego jednym z głównym
komponentów jest kontener IoC. Projekt ten ma ugruntowana˛ pozycje˛ na rynku
rozwiaza
˛ ń technologicznych. Pierwsza wersja została wydana już w 2002 roku.
Wraz z rozwojem do podstawowego modułu przyłaczano
˛
coraz wiecej
˛
komponentów.
Obecnie Spring może wspomagać wiekszość
˛
realizowanych przez typowe aplikacje
zadań.
Poczatkowo
˛
konfiguracja modułu wstrzykiwania zależności odbywała si˛e poprzez plik konfiguracyjny zazwyczaj nazywany Beans.xml. Szkielet takiego pliku
przedstawiony jest na wydruku 3.2. Programista w obrebie
˛
znacznika <beans>
definiuje kolejne beany be˛ dace
˛ obiektami Javy. W obrebie
˛
znacznika <bean> znajduja˛ sie˛ też szczegółowe instrukcje o tym jak należy zainicjalizować żadany
˛
obiekt.
Każdy bean zostaje nazwany co umożliwia wykorzystanie go przy definicji nastep˛
nych. Podejście to charakteryzuje sie˛ olbrzymimi możliwościami konfiguracyjnymi.
1
5
<?xml version= " 1.0 " encoding= "UTF−8" ?>
<beans xmlns= " h t t p : //www. springframework . org/schema/beans "
xmlns:xsi= " h t t p : //www.w3. org/2001/XMLSchema−instance "
xsi:schemaLocation= " h t t p : //www. springframework . org/schema/beans
h t t p : //www. springframework . org/schema/beans/spring−beans . xsd " >
<bean id= " . . . " class= " . . . " >
< !−− i n s t r u k c j e i n i c j a l i z a c j i obiektu
</bean>
−−>
10
</beans>
Wydruk 3.2: Szkielet pliku Beans.xml
Wraz z rozwojem je˛ zyka Java oraz popularyzacja˛ korzystania z adnotacji twórcy
szkieletu Spring wprowadzili alternatywna˛ wersje˛ definiowania przebiegu wstrzykiwania zależności przedstawiona˛ na wydruku 3.3. W podejściu tym konfiguracja z
pliku Beans.xml została przeniesiona do klas Javy oznaczonych adnotacjami @Configuration. Do głównych zalet tego rozwiazania
˛
należa˛ bezpieczeństwo typowania
oraz wykrywanie problemów już na etapie kompilacji aplikacji.
1
@Configuration
public class ConfigurationClass {
3.4. Wstrzykiwanie zależności
@Bean( initMethod = " i n i t " )
@Scope ( " prototype " )
public SomeBean createBean ( ) {
// t u t a j dokonywana j e s t i n i c j a l i z a c j a obiektu
}
5
10
17
}
Wydruk 3.3: Konfiguracja metody tworzacej
˛
bean
Przykład wykorzystania wstrzykiwania zależności skonfigurowanego za pomoca˛
pliku beans.xml przedstawiony jest na wydruku 3.4.
1
import org . springframework . beans . f a c t o r y . BeanFactory ;
import org . springframework . context . ApplicationContext ;
import org . springframework . context . support . ClassPathXmlApplicationContext ;
5
public class Main {
public static void main ( String [ ] args ) {
ApplicationContext context =
new ClassPathXmlApplicationContext ( "META−INF/beans . xml " ) ;
BeanFactory f a c t o r y = context ;
MyBean t e s t = (MyBean) f a c t o r y . getBean ( "myBean" ) ;
}
}
10
Wydruk 3.4: Przykład wykorzystania wstrzykiwania zależności w Spring
Spring Framework jest dojrzałym szkieletem oferujacym
˛
wiele możliwości rozszerzajacych
˛
samo poje˛ cie wstrzykiwania zależności. Należy do nich miedzy
˛
innymi
programowanie aspektowe poprzez wykorzystanie jezyka
˛
AspectJ.
3.4.2. Context Dependency Injection
Context Dependency Injection (CDI) jest jedna˛ ze specyfikacji należacych
˛
do
platformy JEE. Wzorcowa˛ implementacja˛ tego standardu jest Weld, bed
˛ acy
˛ zintegrowany z wieloma doste˛ pnymi na rynku serwerami aplikacyjnymi. CDI zawiera
nie tylko opis działania wstrzykiwania zależności w Javie lecz jednocześnie specyfikuje zestaw usług majacych
˛
za zadanie znaczace
˛ ułatwienie programowania w
środowisku JEE.
Najważniejszym poje˛ ciem zwiazanym
˛
ze wstrzykiwaniem zależności w CDI jest
zakres (ang. scope). Proces tworzenia, wykorzystywania oraz usuwania obiektów
określa sie˛ mianem cyklu życia obiektu. Obiekty różnia˛ sie˛ od siebie długościa˛
swego istnienia oraz okresami przydatności. By poradzić sobie z tym problemem
kontener musi posiadać informacje o cyklu życia obiektów, by w odpowiedni sposób
zajmować sie˛ ich tworzeniem oraz usuwaniem. Cykl życia obiektu został powiazany
˛
z zakresami.
Standard CDI definiuje nastepuj
˛
ace
˛ zakresy:
— żadania
˛
(ang. request),
— sesji (ang. session),
— aplikacji (ang. application), którego odpowiednikiem jest singleton,
— zależny (ang. dependend), zakres domyślny,
— konwersacji (ang. conversation).
3.4. Wstrzykiwanie zależności
18
Każdy zakres ma określona˛ długość. Po rozpoczeciu
˛
zakresu, pierwsze żadania
˛
obiektów klas o danym cyklu życia bed
˛ a˛ skutkowały ich zainicjalizowaniem. Gdy
nastapi
˛ zakończenie zakresu powiazane
˛
z nim obiekty klas nie bed
˛ a˛ już wiecej
˛
wstrzykiwane.
Oprócz wstrzykiwania zależności CDI umożliwia programowanie aspektowe poprzez zastosowanie wzorca dekorator, oraz sposobności przechwytywania wywołań
metod wstrzyknie˛ tych obiektów.
CDI wspiera architekture˛ aplikacji opartych na zdarzeniach dostarczajac
˛ szyne˛
zdarzeń (ang. event bus). Konfigurowanie sposobu przekazywania obiektów zdarzeń odbywa sie˛ poprzez mechanizm adnotacji.
Przykład obrazujacy
˛ zalety korzystania z CDI został przedstawiony na wydruku
3.5. W momencie żadania
˛
obiektu klasy Example kontener CDI stworzy go wykorzystujac
˛ do tego konstruktor oznaczony adnotacja˛ @Inject. CDI zadba również
o odpowiednie przekazania parametrów do konstruktora. Po inicjalizacji zostanie
wywołana metoda oznaczona za pomoca˛ @PostConstruct. Tak utworzony obiekt
zostanie zwrócony do komponentu, który go potrzebuje.
1
public class Dependent {
}
public class Example {
5
private Dependent dependent ;
@Inject
public Example ( Dependent dependent ) {
this . dependent = dependent ;
}
10
@PostConstruct
private void i n i t ( ) {
}
15
}
Wydruk 3.5: Przykład wykorzystania CDI
Bardzo ważna˛ funkcja˛ CDI jest możliwość przechwytywania wywołań metod.
Działanie to można wykorzystać miedzy
˛
innymi do automatycznego rejestrowania
wywołań, otwierania transakcji bazodanowych oraz sprawdzania uprawnień użytkownika. Aby skorzystać z tych możliwości należy wykonać nastepuj
˛
ace
˛ kroki:
— Utworzenie adnotacji, której obecność przy metodzie bedzie
˛
sygnalizowała, że
wywołanie powinno być przechwycone.
— Utworzenie klasy, której metoda oznaczona za pomoca˛ adnotacji AroundInvoke
ma zostać uruchomiona podczas próby wywołania przechwytywanej metody.
— Oznaczenie metod lub klas utworzona˛ adnotacja,
˛ by odpowiednie funkcje były
przechwytywane.
3.4.3. Wybrany kontener wstrzykiwania zależności
Jako komponent odpowiedzialny za wstrzykiwanie zależności wybrano CDI, a
decyzje˛ o doborze implementacji uzależniono od wybranego serwera aplikacyjnego,
którego zadaniem be˛ dzie jej dostarczenie.
3.5. Serwer aplikacyjny
19
Spring mimo swych oczywistych zalet takich jak olbrzymia popularność, łatwość
konfiguracji, duże możliwości został odrzucony z uwagi na konieczność uzależnienia aplikacji od biblioteki w sytuacji gdy istnieje standard platformy Java EE be˛
dacy
˛ jej odpowiednikiem. Oprócz tego za wyborem CDI przemawiaja:
˛
— Dodatki Vaadin CDI oraz CDI Properties dostepne
˛
dla Vaadina, które ułatwiaja˛
integracje˛ z CDI oraz wprowadzaja˛ udogodnienia polegajace
˛ na automatycznym
budowaniu komponentów interfejsu graficznego.
— Możliwość programowania aspektowego.
— Niewielka ilość konfiguracji potrzebnej do uruchomienia biblioteki.
3.5. Serwer aplikacyjny
Serwer aplikacyjny jest środowiskiem, w którym działaja˛ aplikacje napisane
zgodnie z architektura˛ JEE. Oprócz zapewniania możliwości pracy aplikacjom serwer zajmuje sie˛ zarzadzaniem
˛
transakcjami bazodanowymi, utrzymywaniem poła˛
czeń do zewne˛ trznych zasobów oraz dostarczaniem implementacji standardów JEE.
Oddelegowanie dostarczania implementacji specyfikacji JEE sprawia, że aplikacje w wie˛ kszym stopniu skupione sa˛ na działaniach biznesowych oraz gwarantuje
możliwość przenoszenia ich pomiedzy
˛
różnymi serwerami.
Wybranie serwera aplikacyjnego jako środowiska pracy aplikacji zapewnia możliwość łatwego zarzadzania
˛
zasobami konsumowanymi przez aplikacje˛ oraz znaczaco
˛ zwie˛ ksza możliwości skalowania.
Do zalet serwerów aplikacyjnych należa:
˛
— konfiguracja w jednym miejscu,
— zwie˛ kszona wydajność,
— możliwość skalowania,
— bezpieczeństwo,
— zarzadzanie
˛
transakcjami.
Na rynku istnieje wiele serwerów różniacych
˛
sie˛ miedzy
˛
soba˛ wydajnościa,
˛ poziomem skomplikowania, wersjami specyfikacji, które wspieraja˛ oraz doborem implementacji wymaganych standardów.
3.5.1. GlassFish
GlassFish jest system oferowanym przez firme˛ Oracle. Pierwsza wersja tego serwera aplikacyjnego została wydana w 2006 roku. Obecnie na rynku dostepna
˛
jest
wersja czwarta w pełni wspierajaca
˛ standard Java EE 7, którego jest ona wzorcowa˛
implementacja.
˛ Serwer ten do niedawna rozpowszechniany był w dwóch wersjach:
darmowej oraz komercyjnej. Jednak najnowsza wersja serwera nie zostanie obj˛eta komercyjnym wsparciem. GlassFish jest obecnie drugim najpopularniejszym
serwerem w pełni zgodnym ze standardem JEE [7].
3.5.2. WildFly
WildFly jest serwerem aplikacyjnym rozwijanym przez Red Hat bed
˛ acym
˛
kontynuacja˛ serwera znanego jako JBoss. Do najważniejszych cech charakteryzujacych
˛
ten produkt należa˛ publicznie dostepny
˛
kod źródłowy oraz wykorzystanie otwartego oprogramowania jako implementacji standardów JEE. Dzieki
˛ skorzystaniu z
3.6. Moduł bezpieczeństwa
20
istniejacych,
˛
niezależnie rozwijanych rozwiaza
˛ ń serwer bardzo szybko adaptowany
jest do uaktualnianych specyfikacji.
3.5.3. Wybrany serwer aplikacyjny
W toku analizy technicznej zdecydowano, że serwerem aplikacyjnym, na którym zostanie uruchomiona aplikacja bedzie
˛
Wildfly w wersji 8.1. Oba rozważane
serwery aplikacyjne w pełni spełniaja˛ standard Java EE 7 lecz wybrano Wildfly
kierujac
˛ sie˛ krótkim czasem uruchomienia oraz niewielkim wykorzystaniu zasobów systemowych. Nie bez znaczenia było też wykorzystywanie przez ten serwer
Hibernate jako implementacji standardu JPA.
3.6. Moduł bezpieczeństwa
Zapewnienie bezpieczeństwa przechowywanych danych oraz kontrola możliwości wykonywania operacji przez użytkowników jest jednym z najważniejszych zadań programistów tworzacych
˛
aplikacje internetowe. Biblioteki wykorzystywane
do zabezpieczenia aplikacji powinny być łatwo integrowalne, zapewniać możliwość
mieszania danych oraz wspierać procesy zarzadzania
˛
uprawnieniami.
Do zadań modułu bezpieczeństwa aplikacji należy:
— Uwierzytelnianie – proces majacy
˛ na celu zweryfikowanie tożsamości użytkownika.
— Autoryzacja – proces sprawdzajacy
˛
uprawnienia użytkownika żadaj
˛ acego
˛
dost˛epu do zasobu lub pragnacego
˛
wykonać chroniona˛ operacje.
˛
— Obsługa kryptografii – zestawu operacji zajmujacych
˛
sie˛ przekazywaniem oraz
przechowywaniem informacji w bezpieczny sposób.
3.6.1. Spring Security
Spring Security jest biblioteka˛ odpowiedzialna˛ za autoryzacje,
˛ uwierzytelnianie oraz zapewnianie bezpieczeństwa aplikacjom internetowym. Projekt powstał w
2003 pod nazwa˛ Acegi Security, by w 2007 roku zostać przemianowany na Spring
Security. Biblioteka ta jest czesto
˛
wybierana jako szkielet bezpieczeństwa aplikacji
korporacyjnych. Znana jest z olbrzymich możliwości konfiguracyjnych oraz łatwości integracji.
Działanie Spring Security opiera sie˛ na możliwościach filtrów, które zostały
zdefiniowane w standardzie JEE. Filtrami nazywamy komponenty wywoływane w
celu obsłużenia przychodzacego
˛
żadania
˛
nim zostanie ono przekazane do elementu
odpowiedzialnego za jego obsługe.
˛ Uruchomienie modułu Spring Security odbywa
si˛e poprzez aktywacje filtra (przedstawiona˛ na wydruku 3.6).
1
5
10
<filter>
< f i l t e r −name>springSecurityFilterChain</ f i l t e r −name>
< f i l t e r −class>
org . springframework . web . f i l t e r . DelegatingFilterProxy
</ f i l t e r −class>
</ f i l t e r >
< f i l t e r −mapping>
< f i l t e r −name>springSecurityFilterChain</ f i l t e r −name>
<url−pattern>/∗</url−pattern>
3.6. Moduł bezpieczeństwa
21
</ f i l t e r −mapping>
Wydruk 3.6: Fragment pliku web.xml aktywujacy
˛ filtr Spring Security
Po aktywacji usługi konieczne jest jeszcze zdefiniowanie sposobu pobierania danych potrzebnych do autoryzacji i uwierzytelniania użytkowników. Spring Security
zawiera wbudowane mechanizmy ułatwiajace
˛ integracje˛ z LDAP, OpenID, JAAS,
Kerberos oraz wieloma innymi standardami. Oprócz elementów dostarczonych
przez twórców szkieletu istnieja˛ gotowe rozwiazania
˛
programistyczne pozwalajace
˛
zintegrować biblioteke˛ z wieloma innymi systemami oraz protokołami.
Jednym z mankamentów Spring Security jest silne uzależnienie od całej platformy Spring Framework. Istnieje możliwość wykorzystania tylko tego modułu lecz
jest to podejście niezalecane. Przez długi czas moduł bezpieczeństwa był tworzony
jako cze˛ ść szkieletu Spring i by w skorzystać z jego najbardziej zaawansowanych
możliwości potrzebny jest dostep
˛ do pozostałych komponentów wspomagajacych
˛
m.in. programowanie aspektowe.
3.6.2. Apache Shiro
Historia projektu Apache Shiro siega
˛ 2004 roku, w którym została stworzona biblioteka JSecurity be˛ daca
˛ jego bezpośrednim poprzednikiem. Powodem powstania
prekursora była nieche˛ ć jego twórców do Java Authentication and Authorization
Service (JAAS), be˛ dacego
˛
implementacja˛ mechanizmu autoryzacji oraz uwierzytelniania użytkowników wbudowana˛ w platforme˛ Java SE. Z czasem projekt został
obj˛ety patronatem Apache Software Fundation w ramach programu inkubacyjnego. W lipcu 2010 roku udostepniona
˛
została pierwsza oficjalna wersja Apache
Shiro [16].
Rysunek 3.3: Architektura Apache Shiro
3.6. Moduł bezpieczeństwa
22
Z grona swoich konkurentów Apache Shiro wyróżnia sie˛ przede wszystkim małym rozmiarem, szybkościa˛ działania, niewielkimi zależnościami od innych bibliotek oraz możliwościa˛ działania w środowisku nieserwerowym.
Architektura Apache Shiro zbudowana jest wokół zarzadcy
˛
bezpieczeństwa (ang.
Security Manager). Zazwyczaj jest on konfigurowany za pomoca˛ pliku bed
˛ acego
˛
zbiorem właściwości oraz wartości, odczytywanego podczas inicjalizacji aplikacji.
Zarzadca
˛
bezpieczeństwa jest punktem dostepu
˛
do pozostałych funkcji biblioteki.
Nadzoruje moduł uwierzytelniania (ang. Authenticator), moduł autoryzujacy
˛ (ang.
Authorizer), zarzadc
˛ e˛ sesji (ang. Session Manager), pamieć
˛ krótkotrwała˛ (ang.
cache) oraz dziedziny (ang. Realms).
Dziedziny sa˛ zasobami wykorzystywanymi podczas procesów autoryzacji oraz
uwierzytelniania. W odpowiedzi na przekazane tokeny z informacjami o tożsamości
użytkownika lub podanymi przez niego danymi autoryzujacymi
˛
zwracaja˛ odpowiedź
zawierajac
˛ a˛ informacje˛ o tym czy użytkownik poprawnie sie˛ zidentyfikował badź
˛
uzyskał doste˛ p do zasobu. Programiści tworzacy
˛ aplikacje˛ moga˛ tworzyć własne
dziedziny oraz podłaczać
˛
je do Apache Shiro dzieki
˛ zapewnionej przez jego twórców swobodzie integracji. Dane, które wykorzystywane sa˛ w dziedzinach w zachodzacych
˛
procesach moga˛ być pobierane z dowolnego źródła. Najpopularniejszymi
źródłami sa˛ pliki konfiguracyjne oraz bazy danych.
Dane zalogowanego użytkownika przetrzymywane sa˛ w obiekcie sesji. Apache
Shiro udoste˛ pnia specjalny komponent DAO, który umożliwia wykorzystanie biblioteki również w systemach nieserwerowych, gdy nie istnieje obiekt HttpSession.
W pamie˛ ci krótkotrwałej przechowywane sa˛ wyniki ostatnich zapytań wykonanych przez dziedziny do zewnetrznych
˛
zasobów. Dzieki
˛ zapamietaniu
˛
rezultatów
możliwe jest znaczace
˛ przyspieszenie działania w przypadku próby ponownego pobrania tych samych danych.
Całość uzupełniona jest o obiektowy, łatwy w użytkowaniu interfejs zapewniajacy
˛ doste˛ p do funkcji kryptograficznych wbudowanych w maszyne˛ wirtualna.
˛ W
momencie połaczenia
˛
z aplikacja˛ biblioteka umożliwia korzystanie zarówno z szyfrowania symetrycznego jak i różnorodnych funkcji skrótu.
3.6.3. OAuth
OAuth jest standardem pozwalajacymi
˛
aplikacjom na limitowany doste˛ p do
serwisów internetowych w imieniu użytkownika. Protokół ten powstał w 2006 roku.
Obecnie doste˛ pna jest już druga wersja skupiajaca
˛ sie˛ na uproszczeniu przebiegu
autoryzacji.
Nim powstał OAuth jeśli użytkownik chciał przekazać aplikacji uprawnienia do
serwisu zmuszony był udostepnić
˛
swój login i hasło. Skutkowało to oddaniem
aplikacji pełni możliwości zarzadzania
˛
serwisem. Użytkownik zmuszony był zaufać
intencjom twórców oraz zapewnieniom o nieszkodliwości oprogramowania. Protokół OAuth pozwala nie tylko na powierzenie limitowanego dostepu
˛
lecz jednocześnie
zezwala na deklarowanie elementów serwisu, które maja˛ być objete
˛ pozwoleniem.
Na wydruku 3.4 przedstawiono przebieg logowania do aplikacji z wykorzystaniem serwisu wspierajacego
˛
protokół OAuth. Nim zostanie wykonana ta operacja
twórca aplikacji powinien zarejestrować ja˛ w serwisie poświadczajacym,
˛
by uzyskać unikalny klucz i sekret, które w dalszym procesie posłuża˛ do wygenerowania
tokenu żadania.
˛
W momencie gdy użytkownik chce sie˛ zalogować pobierany jest
3.6. Moduł bezpieczeństwa
23
Rysunek 3.4: Przebieg uwierzytelniania z wykorzystaniem OAuth
token żadania,
˛
który naste˛ pnie przesyłany jest wraz z przekierowaniem użytkownika na strone˛ serwisu. Serwis na podstawie tokenu ustala aplikacje,
˛ która chce
uzyskać doste˛ p do danych oraz pyta użytkownika czy ten wyraża zgode˛ na ich
udoste˛ pnienie. W przypadku odpowiedzi pozytywnej do aplikacji zwracana jest
informacja, że token żadania
˛
został autoryzowany, a użytkownik zostaje ponownie przekierowany na strone˛ aplikacji. Dzieki
˛ posiadanemu tokenowi możliwe jest
otrzymanie tokenu doste˛ pu, który zezwala na pobieranie danych potrzebnych do
zalogowania.
Przedstawiony tutaj proces przebiega podobnie również w sytuacji gdy dotyczy
on nie logowania lecz doste˛ pu do innych zasobów lub możliwości wykonania operacji.
Protokół OAuth wspierany jest miedzy
˛
innymi przez takie serwisy jak:
— Facebook,
— Dropbox,
— Twitter,
— LinkedIn,
— Google.
3.6.4. Wybrany szkielet bezpieczeństwa
Podje˛ to decyzje˛ , że proces zabezpieczania aplikacji bedzie
˛
wspierany przez Apache Shiro. Spring Security mimo swoich zalet takich jak popularność, łatwość
konfiguracji i duże możliwości został odrzucony z powodu ścisłego powiazania
˛
z
pozostałymi komponentami Spring Framework. Za Apache Shiro przemawiały niewielki rozmiar, szybkość działania, jasno zdefiniowana architektura oraz możliwość
3.7. Testowanie jednostkowe
24
integracji z pozostałymi elementami systemu. W toku analizy zauważono, że konieczne be˛ dzie dodanie warstwy łacz
˛ acej
˛
Apache Shiro z repozytorium użytkowników przetrzymywanym w bazie danych oraz stworzenie wsparcia dla standardu
OAuth.
3.7. Testowanie jednostkowe
Etap testowania jest niezwykle ważny w cyklu tworzenia aplikacji. Pozwala
twórcy upewnić sie˛ czy produkt spełnia wymagania oraz sprawdzić jego zgodność z
dokumentacja.
˛ Niestety odsuniecie
˛
etapu testów w czasie do momentu zakończenia
fazy implementacyjnej skutkuje zwiekszonym
˛
kosztem modyfikacji oraz ryzykiem
wprowadzenia innych błe˛ dów.
By zapobiec tym niedogodnościom wprowadzono metode˛ tworzenia oprogramowania sterowana˛ testami (ang. Test Driven Development). Opiera sie˛ ona na tworzeniu testów jednostkowych sprawdzajacych
˛
działanie pojedynczych klas oraz metod
aplikacji.
Dzie˛ ki dużej liczbie testów jednostkowych błedy
˛
niskiego poziomu sa˛ szybko odkrywane oraz na bieżaco
˛ poprawiane. Wprowadzanie zmian do aplikacji obarczone
jest mniejszym ryzykiem, ponieważ programista ma pewność, że jego modyfikacja
nie wpłyne˛ ła na poprawność działania pozostałych elementów systemu.
Wraz z koniecznościa˛ pisania dużej liczby testów jednostkowych zaistniała potrzeba zautomatyzowania procesu ich wykonywania. Powstało wiele szkieletów majacych
˛
spełnić to zadanie.
3.7.1. JUnit
JUnit jest jednym ze szkieletów odpowiedzialnych za zautomatyzowane wykonywanie testów jednostkowych. Biblioteka ta jest jedna˛ z najcześciej
˛
wykorzystywanych podczas tworzenia projektów w jezyku
˛
Java. Należy ona do rodziny szkieletów
xUnit.
Prostota korzystania z JUnit jest jedna˛ z jego najwiekszych
˛
zalet. Konfiguracja testów jednostkowych jest tworzona z wykorzystaniem adnotacji. Przykład
przedstawiony jest na wydruku 3.7. W notacji JUnit opisanie metody adnotacja˛
@Test oznacza, że metoda ta jest testem jednostkowym i powinna zostać wywołana
podczas procesu testowania. Jeśli metoda zgłosi wyjatek
˛
test jednostkowy zostaje
uznany za nieudany. Metoda oznaczona adnotacja˛ @Before zostanie wykonana
przed każdym testem, zaś oznaczona za pomoca˛ @After po.
Istnieje wiele innych adnotacji majacych
˛
na celu np. :
— określenie momentu wywołania metod,
— określenie klasy majacej
˛
wywołać test klasy,
— ignorowanie testu,
— zdefiniowanie parametrów do kolejnych wywołań metod testowych.
1
import static org . a s s e r t j . core . api . Assertions . assertThat ;
import org . j u n i t . ∗ ;
public class JUnitTest {
5
@Before
public void setUp ( ) {
3.7. Testowanie jednostkowe
25
// . . .
}
10
@Test
public void testParsePln ( ) {
assertThat ( false == false ) ;
}
15
@After
public void tearDown ( ) {
// . . .
}
20
}
Wydruk 3.7: Przykład wykorzystania biblioteki JUnit
3.7.2. TestNG
TestNG jest szkieletem testujacym
˛
silnie zainspirowanym działaniem JUnit oraz
NUnit. Został stworzony w 2004 roku jako alternatywa dla JUnit. Wspiera nie tyko
testy jednostkowe leczy równocześnie zapewnia możliwość testowania integracyjnego i funkcjonalnego.
Podstawowe działania przeprowadza sie˛ w sposób identyczny co w JUnit.
TestNG dostarcza zestaw adnotacji o takich samych nazwach, które w identyczny
sposób steruja˛ przebiegiem testowania. Zalety TestNG ujawniaja˛ sie˛ w momencie
przeprowadzania testów parametryzowanych lub stosowania testowania sterowanego danymi (ang. data-driven testing). Szkielet wspiera również testowanie kodu
wielowatkowego
˛
poprzez wsparcie dla jednoczesnego uruchamiania wielu testów
jednostkowych.
Na wydruku 3.8 przedstawione jest wykorzystanie adnotacji @DataProvider ułatwiajacej
˛
testowanie sterowane danymi. Metoda testData jest uznawana za test
jednostkowy dzie˛ ki obecności @Test. Funkcja ta zostanie uruchomiona wielokrotnie, gdyż jako jej parametry zostana˛ wykorzystane elementy macierzy zwróconej
przez createData. Połaczenie
˛
rezultatu createData z danymi wejściowymi testData
nast˛epuje poprzez wykorzystanie adnotacji @DataProvider oraz parametru dataProvider adnotacji @Test.
1
import org . testng . annotations . ∗ ;
public class DataProviderTest {
@DataProvider (name = " test1 " )
public Object [ ] [ ] createData ( ) {
return new Object [ ] [ ] { { " Tekst−1" , new Integer ( 1 ) } ,
{ " Tekst−4" , new Integer ( 4 ) } } ;
}
5
10
@Test ( dataProvider = " test1 " )
public void testData ( String n1, Integer n2 ) {
// . . .
}
15
}
Wydruk 3.8: Przykład wykorzystania adnotacji @DataProvder
3.8. Makietowanie
26
3.7.3. Wybrany szkielet testujacy
˛
Zdecydowano, że szkieletem testujacym
˛
wykorzystanym w aplikacji bedzie
˛
JUnit. Mimo wie˛ kszych możliwości oferowanych przez TestNG nie zdecydowano sie˛ na
t˛e biblioteke˛ ponieważ nie zostana˛ one wykorzystane podczas tworzenia systemu.
Za wybraniem JUnit przemawiał również fakt zaznajomienia autora niniejszej pracy
z ta˛ biblioteka.
˛
3.8. Makietowanie
Jedna˛ z podstawowych idei testowania jednostkowego jest wykonywanie testów
w izolacji od innych klas systemu informatycznego. W pewnych sytuacjach takie
przeprowadzanie testów jest niezwykle trudne. Czesto
˛
przyczyna˛ sa˛ odniesienia
do zewne˛ trznych zasobów, metod statycznych lub czasochłonnych obliczeń. Możliwe jest tworzenie prostych implementacji interfejsów z których korzystaja˛ klasy
testowe lecz takie rozwiazanie
˛
jest czasochłonne oraz pozostawia możliwość popełnienia błe˛ du. W takiej sytuacji bezpieczniej jest skorzystać z biblioteki oferujacej
˛
automatyczne budowanie makiet, których zadaniem jest zastapienie
˛
odwołań do
niepożadanych
˛
elementów systemu.
3.8.1. Mockito
Mockito jest popularna˛ biblioteka˛ ukierunkowana˛ na ułatwienie tworzenia testów jednostkowych poprzez umożliwienie budowania makiet (ang. mock) obiektów.
W Mockito utworzenie makiety odbywa sie˛ poprzez wywołanie statycznej metody
mock lub poprzez skorzystanie z adnotacji @Mock wraz ze zmiana˛ klasy uruchamiajacej
˛
testy na MockitoJUnitRunner.
1
package pl . dziurdziak . easyReckoning . s e r v i c e . user ;
import static org . mockito . Matchers . ∗ ;
import static org . mockito . Mockito .when;
5
import
import
import
import
org . j u n i t . ∗ ;
org . j u n i t . runner . RunWith ;
org . mockito .Mock;
org . mockito . runners . MockitoJUnitRunner ;
import
import
import
import
pl . dziurdziak . easyReckoning . dto . s e t t i n g s . ChangePasswordDto ;
pl . dziurdziak . easyReckoning . model . user . ∗ ;
pl . dziurdziak . easyReckoning . u t i l s . errors . BusinessException ;
pl . dziurdziak . easyReckoning . u t i l s . security . VaadinSecurityUtil ;
10
15
20
25
@RunWith ( MockitoJUnitRunner . class )
public class UserServiceTest {
@Mock private UserDao userDao ;
@Mock private VaadinSecurityUtil vaadinSecurityUtil ;
@Mock private User currentUser ;
private UserService userService ;
@Before
public void setUp ( ) {
userService = new UserService ( userDao , 1 , vaadinSecurityUtil ) ;
}
3.8. Makietowanie
27
@Test ( expected = BusinessException . class )
public void testChangePasswordOldNotCorrect ( ) {
when ( userDao . findById ( eq (1L ) ) ) . thenReturn ( currentUser ) ;
when ( currentUser . getPassword ( ) ) . thenReturn ( " oldHash " ) ;
when ( vaadinSecurityUtil
. hashPassword ( anyString ( ) , anyString ( ) ) )
. thenReturn ( " calculatedOldHash " ) ;
30
35
userService . changePassword (
new ChangePasswordDto ( " oldPass " , " newPass " , " newPass " ) ) ;
}
40
}
Wydruk 3.9: Przykład wykorzystania biblioteki Mockito
W powyższym przykładzie skorzystano z adnotacji @Mock do inicjalizacji makiet.
Nast˛epnie w metodzie oznaczonej adnotacja˛ @Before (wywoływanej przed każdym
testem) tworzony jest obiekt klasy podlegajacej
˛
testowi. Utworzenie tego obiektu
odbywa sie˛ poprzez przekazanie mu referencji do makiet dzieki
˛ czemu uniezależniony jest on od pozostałych klas systemu.
W ramach testu wywoływane sa˛ statyczne metody when, które definiuja˛ działanie makiet w odpowiedzi na wywołania ich metod. Dopiero po określeniu zachowania makiet naste˛ puje wywołanie metody, której działanie jest testowane w teście
jednostkowym.
3.8.2. EasyMock
EasyMock jest biblioteka˛ Java konkurujac
˛ a˛ z Mockito. Oferuje bardzo podobne
możliwości lecz różni sie˛ składnia˛ oraz sposobem prezentacji błedów.
˛
Na poniższym wydruku przedstawiony jest przykład wykorzystania biblioteki
EasyMock. Należy zwrócić uwage,
˛ że definiowanie makiet jest równie proste jak w
Mockito. Różnica wyste˛ puje w konieczności jawnego podania w jakiej fazie znajduja˛
si˛e aktualnie makiety. Po utworzeniu i podaniu oczekiwanych wywołań metod
należacych
˛
do makiet konieczne jest odwołanie do funkcji replayAll. Weryfikacja
nast˛epuje w momencie wywołania funkcji verifyAll.
1
public class EasyMockTest extends EasyMockSupport {
private Collaborator c o l l a b o r a t o r ; ]
private ClassTested classUnderTest ;
5
@Before
public void setUp ( ) {
classUnderTest = new ClassTested ( ) ;
}
10
15
@Test
public void addDocument ( ) {
// faza tworzenia
c o l l a b o r a t o r = createMock ( Collaborator . class ) ;
classUnderTest . addListener ( c o l l a b o r a t o r ) ;
// faza definiowania zachowania
c o l l a b o r a t o r . documentAdded ( "New Document" ) ;
replayAll ( ) ;
3.8. Makietowanie
28
20
// t e s t
classUnderTest . addDocument ( "New Document" , new byte [ 0 ] ) ;
// weryfikacja
verifyAll ( ) ;
25
}
}
Wydruk 3.10: Przykład wykorzystania biblioteki EasyMock
3.8.3. Wybrana biblioteka makietujaca
˛
Na biblioteke˛ odpowiedzialna˛ za makietowanie obiektów wybrano Mockito. Charakteryzuje sie˛ ona czytelniejszym interfejsem niż EasyMock, a jej popularność
gwarantuje możliwość znalezienia pomocy w przypadku wystapienia
˛
problemów z
działaniem.
4. Projekt systemu
4.1. Architektura
Przez lata tworzenia aplikacji inżynierowie oprogramowania zaproponowali wiele
wzorców opisujacych
˛
podział aplikacji. Podczas tworzenia aplikacji graficznych jednym z najcze˛ ściej wykorzystywanych jest wzorzec MVC (ang. Model-View-Controller,
pol. Model-Widok-Kontroler).
Wzorzec MVC opiera sie˛ na podziale aplikacji na trzy moduły:
— model,
— widok,
— kontroler.
Model reprezentuje logike˛ aplikacji oraz przetrzymuje aktualny stan. Widok
zajmuje sie˛ wizualizacja˛ modelu oraz interakcja˛ z użytkownikiem, ma możliwość
modyfikacji modelu. Kontroler wspiera interakcje˛ z użytkownikiem oraz służy jako
ich źródło.
Pochodna˛
tego
niezwykle
popularnego
wzorca
jest
MVP
(ang.
Model-View-Presenter, pol. Model-Widok-Prezenter) wystepuj
˛
acy
˛
w dwóch wariantach:
— pasywny widok (ang. Passive view),
— kontroler nadzorujacy
˛ (ang. Supervising Controller).
Główna˛ różnica˛ mie˛ dzy MVC, a MVP jest mniejsza rola widoku, który w MVP
służy wyłacznie
˛
jako wizualna reprezentacja modelu. Wszystkie akcje użytkownika
przekazywane sa˛ do prezentera, który ma zwiekszon
˛
a˛ (w przeciwieństwie do MVC)
wiedze˛ na temat budowy widoku i może powodować jego zmiany.
Rysunek 4.1: Schemat wzorca MVP w wariancie kontrolera nadzorujacego
˛
4.2. Podział pakietów
30
MVP charakteryzuje sie˛ możliwościa˛ łatwego testowania aplikacji z wykorzystaniem testów jednostkowych. Używajac
˛ makiet możliwe jest testowanie komponentów w odseparowaniu od pozostałych. Wada˛ MVP jest zwiekszona
˛
ilość kodu źródłowego (w stosunku MVC), która przypada na dodatkowa˛ komunikacje˛ miedzy
˛
widokiem, a prezenterem.
Podczas tworzenia aplikacji wykorzystano wzorzec MVP w wariancie kontrolera
nadzorujacego.
˛
Główna˛ motywacja˛ tej decyzji jest trudność w testowaniu graficznej
cz˛eści aplikacji pisanej w szkielecie Vaadin. Przeniesienie wiekszości
˛
logiki aplikacji
do warstwy prezentera pozwoliło na pełniejsze pokrycie kodu źródłowego testami.
4.2. Podział pakietów
Rysunek 4.2: Diagram pakietów wewnatrz
˛
pakietu pl.dziurdziak.easyReckoning
W aplikacji można wyróżnić nastepuj
˛
ace
˛ pakiety (przedstawione na rysunku
4.2):
— pl.dziurdziak.easyReckoning.dto - pakiet przechowujacy
˛ klasy, których instancje służa˛ do komunikacji pomiedzy
˛
warstwami aplikacji
— pl.dziurdziak.easyReckoning.model - pakiet przechowujacy
˛
klasy domenowe
oraz DAO (ang. Data Access Object), których obiekty służa˛ jako źródło obiektów
klas domenowych
— pl.dziurdziak.easyReckoning.presenter - w tym pakiecie znajduja˛ sie˛ klasy należace
˛ do warstwy Prezenter
— pl.dziurdziak.easyReckoning.service - zawiera implementacje˛ klas wykonuja˛
cych operacje˛ na modelu
4.3. Testowanie
31
— pl.dziurdziak.easyReckoning.utils - zawiera implementacje˛ klas narzedziowych
˛
szeroko wykorzystywanych w pozostałej cześci
˛
aplikacji. W szczególności zawiera podpakiety:
— errors - definicje wyjatków,
˛
— localization - klasy odpowiadajace
˛ za wielojezyczność,
˛
— security - klasy modułu bezpieczeństwa,
— validations - klasy odpowiadajace
˛ za walidacje˛ danych wprowadzanych przez
użytkownika.
— pl.dziurdziak.easyReckoning.view - zawiera klasy należace
˛ do warstwy Widoku.
Szczególna˛ uwage˛ należy zwrócić na podpakiet ui zawierajacy
˛ definicje własnych
elementów interfejsu użytkownika takich jak: nagłówek, stopka, nowe pola,
okna modalne oraz kolumny tabel.
4.3. Testowanie
Testowanie aplikacji składało sie˛ z dwóch elementów:
— testów jednostkowych,
— testów interfejsu graficznego wykonywanych przez programiste.
˛
W idealnym przypadku całość kodu źródłowego zostałaby pokryta poprzez testy
jednostkowe. Niestety testowanie interfejsu użytkownika wymaga aplikacji działajacej
˛
w tle. Z uwagi trudności w sprawdzaniu tej cześci
˛
aplikacji twórcy szkieletu
Vaadin udoste˛ pnili narze˛ dzie Vaadin TestBench zbudowane na bazie Selenium. Ma
ono za zadanie umożliwić testowanie interfejsu użytkownika oraz jego współpracy z
różnymi przegladarkami
˛
internetowymi. Narzedzie
˛
to jest płatne przez co nie może
zostać użyte podczas tworzenia aplikacji.
Jako próbe˛ zaradzenia problemowi podjeto
˛ decyzje˛ o testowaniu interfejsu użytkownika poprzez programiste˛ oraz objecie
˛
warstwy Prezentera testami jednostkowymi.
Testy jednostkowe pokrywaja˛ kod nastepuj
˛
acych
˛
pakietów:
— pl.dziurdziak.easyReckoning.presenter,
— pl.dziurdziak.easyReckoning.service,
— pl.dziurdziak.easyReckoning.utils.
Każda testowana klasa ma odpowiadajac
˛ a˛ jej klase˛ testujac
˛ a,
˛ znajdujac
˛ a˛ sie˛
w tym samym pakiecie, lecz w innym folderze. Metody klas testujacych
˛
maja˛ za
zadnie sprawdzać działanie klasy testowanej w zależności od przekazywanych parametrów oraz ustalonego stanu systemu. Przebieg procesu testowania jednostkowego przedstawiono na rysunku 4.3, zaś na wydruku 4.1 zaprezentowano przykładowa˛ klase˛ testujac
˛ a˛ wykorzystana˛ w aplikacji.
1
5
10
@RunWith ( MockitoJUnitRunner . class )
public class ResetUserPasswordPresenterTest {
@Mock
private
@Mock
private
@Mock
private
@Mock
private
ResetUserPasswordView view ;
UserService userService ;
VaadinStaticUtils v a a d i n S t a t i c U t i l s ;
TextBundle textBundle ;
4.3. Testowanie
32
private ResetUserPasswordPresenter resetUserPasswordPresenter ;
@Before
public void setUp ( ) {
resetUserPasswordPresenter = new ResetUserPasswordPresenter ( view ,
userService ,
new BusinessErrorHandler ( textBundle , v a a d i n S t a t i c U t i l s ) ,
vaadinStaticUtils ,
textBundle ) ;
}
15
20
@Test
public void testReset ( ) {
resetUserPasswordPresenter . resetPassword ( " userLogin " ) ;
25
v e r i f y ( userService , times ( 1 ) ) . resetPassword ( eq ( " userLogin " ) ) ;
v e r i f y ( vaadinStaticUtils , times ( 1 ) )
. showSuccessNotification ( anyString ( ) , anyString ( ) ) ;
30
}
}
Wydruk 4.1: Klasa testujaca
˛ prezenter ResetUserPasswordPresenter
4.3. Testowanie
Rysunek 4.3: Przebieg procesu testowania jednostkowego
33
4.4. Wyjatki
˛
34
4.4. Wyjatki
˛
Wyjatki
˛
generowane przez elementy systemu zostały podzielone na dwa rodzaje:
— biznesowe,
— techniczne.
Mianem wyjatków
˛
biznesowych określa sie˛ wszystkie klasy dziedziczace
˛ po klasie pl.dziurdziak.easyReckoning.utils.errors.BusinessException. Cecha˛ charakterystyczna˛ obiektów tych klas jest obowiazkowe
˛
przenoszenie wiadomości informuja˛
cej o powodzie zgłoszenia błe˛ du.
Wyjatkami
˛
technicznymi określa sie˛ wszystkie wyjatki
˛
nie zaliczane do poprzedniej grupy. Wśród nich znajduja˛ sie˛ również wyjatki
˛
generowane przez biblioteki
trzecie.
Obsługa dwóch wymienionych wcześniej rodzajów wyjatków
˛
jest różna. Błedy
˛
biznesowe zwiazane
˛
sa˛ zazwyczaj z niepoprawnymi danymi podanymi przez użytkownika, badź
˛ próba˛ wykonania operacji niedozwolonej w danej chwili. Jako takie
sa˛ wyjatkami,
˛
których obsłużenie czesto
˛
zapewnia możliwość dalszej pracy użytkownika nad aktualnie wykonywanym zadaniem. Błedy
˛
techniczne prowadza˛ do
sytuacji, w których kontynuacja operacji przez użytkownika jest niemożliwa.
Błe˛ dy biznesowe obsługiwane sa˛ na dwa sposoby:
— wyświetlenie notyfikacji o błedzie
˛
- działanie wspierane przez klase˛
pl.dziurdziak.easyReckoning.utils.errors.BusinessErrorHandler,
— przekierowanie do podstrony error, która może zawierać szczegółowe informacje
o prawdopodobnej przyczynie błedu.
˛
W przypadku zgłoszenia wyjatku
˛
technicznego moduł nawigacyjny aplikacji
przekierowuje użytkownika do podstrony error, która w sposób ogólny informuje
o wystapieniu
˛
błe˛ du wewnatrz
˛
systemu.
4.5. Model logiczny
Użytkownik (User) - Reprezentuje osobe˛ zarejestrowana˛ i uprawniona˛ do korzystania z aplikacji.
Encja ta przechowuje nastepuj
˛
ace
˛ informacje o osobie:
— sztuczny identyfikator (id),
— unikalny login,
— unikalny e-mail,
— skrót hasła,
— sól używana do konstruowania skrótu hasła,
— date˛ rejestaracji,
— czy konto zostało zablokowane.
Encja Użytkownik połaczona
˛
jest z encjami Rola, Członek grupy, Znajomy,
Zaproszenie do grupy oraz Zaproszenie do znajomych. Oprócz tego łaczy
˛
sie˛ ona z
encjami be˛ dacymi
˛
typami operacji badź
˛ kont.
Rola (Role) - Reprezentuje role pełniona˛ przez użytkownika w systemie bezpieczeństwa.
Identyfikatorem roli jest jej nazwa, która musi być unikalna. Jest to jedyny
atrybut tej encji.
4.5. Model logiczny
35
Rola jest połaczona
˛
z encjami Użytkownik oraz Uprawnienie.
Uprawnienie (Permission) - Encja ta reprezentuje uprawnienie przypisane roli.
Uprawnienie może oznaczać możliwość wykonania akcji lub dostep
˛ do zasobu przez
użytkownika. Jedynym atrybutem encji Uprawnienie jest jej nazwa.
Encja Uprawnienie jest połaczona
˛
z encja˛ Rola.
Znajomy (Friend) - Encja ta reprezentuje fakt znajomości pomiedzy
˛
dwoma
użytkownikami.
Identyfikatorem encji jest sztuczne pole id, jednak kombinacja pól zapraszajacy
˛
oraz zapraszany powinna być unikalna.
Encja Znajomy jest w podwójnym zwiazku
˛
z encja˛ Użytkownik. Jedno połaczenie
˛
dotyczy użytkownika zapraszajacego,
˛
drugie zapraszanego.
Zaproszenie do znajomych (Friend request) - Encja reprezentuje fakt zaproszenia użytkownika, przez innego, do grona swoich znajomych.
Encja posiada sztuczny identyfikator oraz nastepuj
˛
ace
˛ atrybuty:
— zapraszajacy,
˛
— zapraszany,
— wiadomość do zapraszanego,
— status zaproszenia,
— date˛ wysłania.
Zaproszenie może znajdować sie˛ w nastepuj
˛
acych
˛
statusach:
— nowe (new),
— zaakceptowane (accepted),
— odmówione (refused),
— anulowane (cancelled).
Encja Zaproszenie do znajomych łaczy
˛
sie˛ z encja˛ Użytkownik. Jedno połaczenie
˛
dotyczy użytkownika zapraszajacego,
˛
drugie zapraszanego.
Grupa (Group) - Encja reprezentuje zbiór użytkowników.
Grupa posiada sztuczny identyfikatora, nazwe,
˛ opis oraz admina. Adminem
grupy jest jej założyciel, który automatycznie staje sie˛ członkiem grupy.
Encja Grupa łaczy
˛
sie˛ z encja˛ Użytkownik. Jedno połaczenie
˛
dotyczy admina
grupy, drugie jej członków.
Zaproszenie do grupy (Group invitation) - Encja reprezentuje fakt zaproszenia
użytkownika do członkostwa w grupie.
Łaczy
˛
sie˛ z encja˛ Użytkownik informujac
˛ o zapraszajacym,
˛
zapraszanym oraz z
encja˛ Grupa, której dotyczy zaproszenie.
Operacja wirtualna (Virtual operation) - Encja ta reprezentuje fakt dokonania
operacji finansowej przez użytkownika, który jest jej jedynym uczestnikiem.
Posiada sztuczny identyfikator, kwote,
˛ nazwe,
˛ opis, date˛ operacji, date˛ utworzenia.
Encja ta jest połaczona
˛
z encja˛ Konto wirtualne.
Pożyczka (Loan) - Encja opisujaca
˛ przekazanie pieniedzy
˛
pomiedzy
˛
użytkownikami.
4.5. Model logiczny
36
Połaczona
˛
jest z encjami Użytkownik oraz Konto użytkownika.
Operacja w parze (Pair operation) - Encja reprezentujaca
˛ operacje˛ finansowa˛
dokonana˛ przez pare˛ użytkowników.
Od encji Pożyczka odróżnia ja˛ to, że kwota operacji jest dzielona pomiedzy
˛
uczestników w podanym przez tworzacego
˛
ja˛ użytkownika stosunku.
Encja Operacja w parze powiazana
˛
jest z encjami Użytkownik oraz Konto
użytkownika.
Operacja wspólna (Shared operation) - Encja ta reprezentuje operacje˛ finansowa˛
dokonana˛ przez wie˛ cej niż jednego użytkownika.
Kwota operacji dzielona jest po równo pomiedzy
˛
jej uczestników. Członków
operacji ustala jej twórca. Dodajacy
˛ operacje˛ może zdefiniować ja˛ jako operacje˛
składkowa˛ podajac
˛ kwote˛ , która˛ wpłacili poszczególni uczestnicy.
Encja powiazana
˛
jest z encja Użytkownik.
Operacja grupowa (Group operation) - Encja ta reprezentuje fakt dokonania
operacji finansowej przez grupe˛ użytkowników.
Jest to szczególny przypadek operacji wspólnej, w której wszyscy członkowie
należa˛ do jednej grupy. Twórca nie ma możliwość dodawania lub usuwania osób z
operacji.
Encja powiazana
˛
jest z encjami Użytkownik oraz Grupa.
Konto użytkownika (User account) - Encja grupujaca
˛
operacje dokonywane
pomi˛edzy użytkownikami.
Posiada właściciela, bilans, nazwe˛ oraz użytkownika, z którym przeprowadzane
sa˛ operacje˛ .
Łaczy
˛
sie˛ z encjami Użytkownik oraz encjami operacji.
Konto wirtualne (Virtual account) - Encja grupujaca
˛ operacje własne użytkownika.
Posiada właściciela, bilans oraz nazwe.
˛
Łaczy
˛
sie˛ z encjami Użytkownik oraz Operacja wirtualna.
4.5. Model logiczny
37
Rysunek 4.4: Model logiczny (z uwagi na czytelność cześć
˛ encji została pominieta)
˛
38
4.6. Model klas operacji
4.6. Model klas operacji
Podczas tworzenia hierarchii klas operacji została wyodrebniona
˛
klasa abstrakcyjna Operation be˛ daca
˛ klasa˛ bazowa˛ dla pozostałych klas modelujacych
˛
operacje.
Klasa Operation zawiera składowe wspólne dla wszystkich rodzajów operacji takie
jak:
— identyfikator,
— kwota,
— nazwa,
— opis,
— data operacji,
— data utworzenia,
— wersja (pole wykorzystywane przez JPA).
Klasy dziedziczace
˛ po klasie Operation można podzielić na trzy typy:
— operacje własne,
— operacje pomie˛ dzy dwoma użytkownikami - podzielone na pożyczke,
˛ prosta˛
operacje˛ w parze oraz operacje˛ bed
˛ ac
˛ a˛ wynikiem operacji wspólnej,
— operacje wspólne (pomie˛ dzy wieloma użytkownikami) - które moga˛ lecz nie musza˛ być powiazane
˛
z grupa.
˛
Zastosowane rozwiazanie
˛
przedstawione jest na diagramie 4.5.
Rysunek 4.5: Model klas operacji
39
4.7. Model klas kont
4.7. Model klas kont
Hierarchie˛ klas kont zamodelowano poprzez wykorzystanie klasy abstrakcyjnej
Account zawierajacej
˛
pola wspólne dla dwóch rodzajów istniejacych
˛
kont:
— użytkownika,
— wirtualnych.
Zastosowane rozwiazanie
˛
przedstawione jest na diagramie 4.6.
Rysunek 4.6: Model klas kont
4.8. Model fizyczny
4.8.1. Operacje oraz konta
Model fizyczny obrazujacy
˛ strukture˛ kont, operacji oraz ich wzajemne połacze˛
nia przedstawiony jest na diagramie 4.7.
Klasy operacji zostały zamodelowane korzystajac
˛ z podejścia łaczonych
˛
tabel (ang. joined tables). Podejście to zakłada istnienie jednej tabeli głównej
przechowujacej
˛
atrybuty wspólne dla wszystkich operacji oraz po jednej tabeli dla
innych rodzajów operacji. Pozostałe tabele operacji połaczone
˛
sa˛ z podstawowa˛
relacja˛ współdzielenia klucza głównego (ang. shared primary key). Relacja ta
polega na tym, że klucze główne tabel operacji sa˛ jednocześnie kluczami obcymi do
identyfikatora tabeli podstawowej. Tabela˛ główna˛ jest tabela operations.
Tworzac
˛ model klas kont zostało zastosowane odmienne podejście. Z uwagi na
niewielki poziom skomplikowania hierarchii klas skorzystano z rozwiazania
˛
pojedynczej tabeli (ang. single table). W podejściu tym w jednej tabeli przechowywane
sa˛ dane kont obu rodzajów. Ustalenie typu konta odbywa sie˛ na podstawie pola
discriminator przechowujacego
˛
łańcuch znaków jednoznacznie go identyfikujacy.
˛
Konieczność wypełnienia pól charakterystycznych dla konta użytkownika zapewniana jest przez wyzwalacz.
40
4.8. Model fizyczny
Rysunek 4.7: Model fizyczny operacji i kont
4.8. Model fizyczny
41
4.8.2. Moduł bezpieczeństwa
Model fizyczny modułu bezpieczeństwa zaprezentowany jest na diagramie 4.8.
W modelu tym każdy użytkownik może mieć przypisanych wiele ról, zaś każda
rola może dawać wiele uprawnień. Kluczami głównymi ról oraz uprawnień sa˛ ich
nazwy, co gwarantuje ich unikalność. Każde uprawnienie może być połaczone
˛
tylko
z jedna˛ rola.
˛
Z uwagi na charakter połaczenia
˛
pomiedzy
˛
użytkownikami, a rolami została
wprowadzona tabela łacz
˛ aca
˛ user_roles.
Rysunek 4.8: Model fizyczny modułu bezpieczeństwa
5. Interfejs graficzny
W rozdziale tym zostana˛ przedstawione fragmenty zaprojektowanego interfejsu
użytkownika wraz z informacjami jakie wymagania stawiane aplikacji realizuja.
˛
Układ komponentów wyste˛ pujacych
˛
na zaprezentowanych przykładach został zadeklarowany w szablonach html. Rozwiazanie
˛
to ułatwiło tworzenie tego modułu
systemu poprzez oddzielenie wygladu
˛
od logiki biznesowej.
5.1. Okno dodawania operacji grupowej
Rysunek 5.1: Okno dodawania operacji grupowej
Na rysunku 5.1 przestawiono okno dodawania operacji grupowej. Realizuje
on wymaganie WF 27. W oknie oprócz podstawowych pól wyświetlona jest lista
użytkowników bioracych
˛
udział w operacji zbudowana na podstawie przypisanej
grupy. Pole wyboru ”Operacja składkowa” uaktywnia dodatkowa˛ kolumne˛ gdzie
można podać wkład wniesiony przez każdego uczestnika. Przycisk ”Pokaż podglad”
˛
wyświetla tabele˛ operacji, które zostana˛ wygenerowane pomiedzy
˛
użytkownikami
po zaakceptowaniu operacji.
5.2. Okno dodawania operacji w parze
43
5.2. Okno dodawania operacji w parze
Na rysunku 5.2 przedstawione jest okno dodawania operacji pomiedzy
˛
para˛
użytkowników. Realizuje ono wymaganie WF 25. Niezaznaczone pole ”Podziel po
połowie” aktywuje suwak ”Mój udział (%)”, w którym użytkownik może podać za
jaka˛ cze˛ ść wartości operacji odpowiada. Lista wyboru ”Kto zapłacił” umożliwia
wybór pomie˛ dzy wartościami: ”Ja”, ”Znajomy”, ”Dzielone”. W przypadku wybrania ostatniej opcji aktywuje sie˛ dodatkowe pole, w którym należy podać składke˛
aktualnego użytkownika.
Rysunek 5.2: Okno dodawania operacji w parze
5.3. Ekran szczegółów grupy
Rysunek 5.3: Ekran szczegółów grupy
5.4. Ekran szczegółów konta z użytkownikiem
44
Na rysunku 5.3 przedstawiono ekran szczegółów grupy, do której należy uwierzytelniony użytkownik. Realizuje on wymagania WF 13 oraz WF 14. W górnej
cz˛eści znajduje sie˛ przycisk rozpoczynajacy
˛ proces dodawania operacji grupowej.
Poniżej znajduje sie˛ lista członków grupy, przycisk służacy
˛ zapraszaniu nowych
członków oraz lista aktualnie wysłanych zaproszeń.
5.4. Ekran szczegółów konta z użytkownikiem
Rysunek 5.4: Ekran szczegółów konta z użytkownikiem
Na rysunku 5.4 przedstawiono ekran szczegółów konta, które aktualny użytkownik posiada z innym. Realizuje on wymaganie WF 21. W górnej cześci
˛
ekranu
znajduja˛ sie˛ podstawowe informacje o koncie oraz odnośnik do ekranu wyświetlajacego
˛
dane znajomego. W środkowej cześci
˛
ekranu znajduje sie˛ tabela operacji
przypisanych do prezentowanego konta. Poniżej znajduje sie˛ wykres obrazujacy
˛
bilans dzienny operacji wykonanych na koncie w przeciagu
˛ ostatniego miesiaca.
˛
5.5. Ekran operacji pomiedzy
˛
użytkownikami
Na rysunku 5.5 przedstawiono ekran operacji pomiedzy
˛
użytkownika realizujacy
˛
wymaganie WF 19. W górnej cześci
˛
ekranu znajduja˛ sie˛ przyciski rozpoczynajace
˛
procesy dodawania pożyczki oraz operacji w parze. Poniżej umieszczono tabele,
˛
która prezentuje dane wykonanych operacji.
5.6. Ekran kont pomiedzy
˛
użytkownikami
45
Rysunek 5.5: Ekran operacji pomiedzy
˛
użytkownikami
5.6. Ekran kont pomiedzy
˛
użytkownikami
Na rysunku 5.6 zaprezentowany jest ekran kont pomiedzy
˛
użytkownikami, z
aktywna˛ funkcja˛ podsumowania. W takim stanie realizuje on wymagania WF 16,
WF 17 oraz WF 22. W górnej cześci
˛
ekranu znajduje sie˛ przycisk uruchamiajacy
˛
proces dodawania nowego konta użytkownika. W tabeli zaprezentowana jest lista
aktywnych kont. W dolnej cz˛eści ekranu prezentowane jest podsumowanie kont w
formie wykresów.
Rysunek 5.6: Ekran kont pomiedzy
˛
użytkownikami
5.7. Ekran wyświetlajacy
˛ informacje o znajomym
46
5.7. Ekran wyświetlajacy
˛ informacje o znajomym
Na rysunku 5.7 przedstawiono ekran informacji o znajomym. Oprócz informacji
podstawowych prezentowane sa˛ informacje o kontach posiadanych z danym użytkownikiem oraz o wykonanych z nim operacjach. Ekran ten realizuje wymaganie
WF 29.
Rysunek 5.7: Ekran wyświetlajacy
˛ informacje o znajomym
5.8. Formularz uwierzytelniania
Na rysunku 5.8 przedstawiony jest formularz uwierzytelniania.
wymagania WF 4 oraz WF 5.
Rysunek 5.8: Formularz uwierzytelniania
Spełnia on
6. Implementacja rozszerzeń szkieletu Vaadin
6.1. Moduł bezpieczeństwa
W zwiazku
˛
z wykorzystaniem Apache Shiro jako szkieletu zapewniajacego
˛
bezpieczeństwo zaszła potrzeba zintegrowania go z tworzona˛ aplikacja.
˛ Czesto
˛
stosowane oraz opisywane w poradnikach podejście opisywania uprawnień, ról oraz
użytkowników w plikach konfiguracyjnych okazało sie˛ niewystarczajace
˛ w przypadku tworzonego systemu. Moduł bezpieczeństwa musi zapewniać poprawne
działanie w przypadku rejestrowania nowych kont oraz zmiany kategorii użytkownika. Podje˛ to decyzje˛ o przechowywaniu danych użytkowników w bazie danych.
6.1.1. Rozwiazanie
˛
dostepne
˛
w Apache Shiro
Apache Shiro dostarcza JDBCRealm, który pobiera dane wykorzystujac
˛ do tego
interfejs programowania JDBC oraz zdefiniowane zapytania. Gdy użytkownik próbuje sie˛ zalogować lub uzyskać dostep
˛ do określonej cześci
˛
systemu parametry
odpowiednich zapytań sa˛ wypełnianie, a tak przygotowane kwerendy wysyłane sa˛
do bazy danych. Rozwiazanie
˛
to ma jednak wady:
— Korzysta ono z interfejsu JDBC, mimo że w aplikacji wykorzystywane jest JPA.
— Współpracuje tylko z podstawowym modelem bezpieczeństwa, na który składaja˛
si˛e użytkownicy oraz uprawnienia. Nie ma wsparcia dla uwierzytelniania z
wykorzystaniem OAuth.
6.1.2. Wymagania wobec nowego rozwiazania
˛
Nowo utworzone elementy modułu bezpieczeństwa musza˛ spełnić nastepuj
˛
ace
˛
wymagania:
— zapewnienie współpracy z baza˛ danych z wykorzystaniem JPA oraz JTA,
— integracja z CDI,
— umożliwienie definiowania wymaganych uprawnień w prosty sposób,
— sprawdzanie uprawnień powinno być wywoływane automatycznie,
— umożliwienie rejestrowania oraz uwierzytelniania użytkowników z wykorzystaniem OAuth.
W sieci Internet pod adresem github.com/davidsowerby/v7 dostepne
˛
jest rozwiazanie
˛
integrujace
˛ Vaadin z Shiro. Niestety oprócz zapewnienia sposobu łaczenia
˛
sesji modułu bezpieczeństwa z sesja˛ Vaadin nie spełnia ono wymagań. Skorzystanie z tego rozwiazania
˛
wiazałoby
˛
sie˛ również z koniecznościa˛ zastapienia
˛
CDI przez
Guice oraz wykorzystania pozostałych komponentów tej biblioteki wpływajacych
˛
na
architekture˛ aplikacji.
6.1. Moduł bezpieczeństwa
48
6.1.3. Integracja z baza˛ danych
Integracja z baza˛ danych polegała na stworzeniu własnych dziedzin wykorzystujacych
˛
działanie szkieletu CDI oraz warstwy dostepu
˛
do danych JPA.
Rysunek 6.1: Cze˛ ść architektury Apache Shiro odpowiedzialna za uwierzytelnianie
i autoryzacje˛ użytkowników
Twórcy szkieletu Apache Shiro ułatwiaja˛ konstrukcje˛ własnych dziedzin poprzez
udoste˛ pnienie klasy abstrakcyjnej AuthorizingRealm. Rozszerzajac
˛ te˛ klase˛ należy
zaimplementować dwie metody:
— doGetAuthenticationInfo
— doGetAuthorizationInfo.
Po zaimplementowaniu tych metod nowo utworzona dziedzina bedzie
˛
wspierać
zarówno operacje uwierzytelniania jak i autoryzacji.
Uwierzytelnianie z wykorzystaniem hasła
W projektowanym systemie została utworzona klasa VaadinAuthorizingRealm,
której zadaniem jest pobieranie danych potrzebnych modułowi bezpieczeństwa.
Rozszerza ona wspomniana˛ wyżej klase˛ AuthorizingRealm. W celu zwiekszenia
˛
wydajności dziedzina ta wykorzystuje zarzadc
˛ e˛ pamieci
˛ cache (ang. CacheManager)
By zagwarantować bezpieczeństwo dopasowanie haseł odbywa sie˛ poprzez porównanie skrótów wygenerowanych z wielokrotnym wykorzystaniem SHA-256. Dodatkowym elementem zwie˛ kszajacym
˛
bezpieczeństwo jest wykorzystanie soli (ang.
salt) losowo generowanych dla każdego użytkownika.
1
protected AuthenticationInfo doGetAuthenticationInfo (
f i n a l AuthenticationToken token )
throws AuthenticationException {
checkArgument ( token instanceof UsernamePasswordToken ) ;
5
f i n a l UsernamePasswordToken userPassToken = ( UsernamePasswordToken ) token ;
10
i f ( userPassToken . getUsername ( ) == null ) {
throw new AccountException ( " Null usernames are not allowed " ) ;
}
f i n a l User user = userDao . findByLogin ( userPassToken . getUsername ( ) ) ;
6.1. Moduł bezpieczeństwa
49
i f ( user == null ) {
throw new AuthenticationException ( ) ;
}
15
f i n a l SimpleAccount simpleAccount =
new SimpleAccount ( user . getLogin ( ) , user . getPassword ( ) ,
ByteSource . U t i l . bytes ( user . g e t S a l t ( ) ) , REALM_NAME) ;
20
return simpleAccount ;
}
Wydruk 6.1: Metoda pobierajaca
˛ dane użytkownika w procesie uwierzytelniania
Na wydruku 6.1 przedstawiono kod metody odpowiedzialnej za pobranie danych użytkownika potrzebnych w trakcie procesu uwierzytelniania. Istnieja˛ metody
uwierzytelniania nie polegajace
˛ na sprawdzeniu loginu oraz hasła wiec
˛ pierwszym
krokiem jest sprawdzenie, czy przekazane dane zawieraja˛ te informacje. Niemożliwa jest sytuacja gdy login jest nieokreślony co sprawdzane jest w nastepnym
˛
warunku. Po weryfikacji poprawności przekazanych danych nastepuje
˛
wyszukanie
obiektu User w bazie danych oraz wypełnienie obiektu przechowujacego
˛
informacje o odnalezionym koncie. Obiekt ten zostaje zwrócony do funkcji wywołujacej.
˛
Na podstawie otrzymanego rezultatu funkcja wywołujaca
˛ może kontynuować procedure˛ uwierzytelniania.
1
protected AuthorizationInfo doGetAuthorizationInfo (
final PrincipalCollection principals ) {
return databaseUtils . invokeReturn ( ( ) −> {
f i n a l String l o g i n = ( String ) p r i n c i p a l s . getPrimaryPrincipal ( ) ;
5
f i n a l User user = userDao . findByLogin ( l o g i n ) ;
f i n a l Set<String > r o l e s = new HashSet< >( user . getRoles ( ) . s i z e ( ) ) ;
user . getRoles ( ) . forEach ( r o l e −> r o l e s . add ( r o l e . getRoleName ( ) ) ) ;
10
f i n a l Set<org . apache . shiro . authz . Permission > permissions =
new HashSet < > ( ) ;
user . getRoles ( ) . forEach ( r o l e −> {
for ( f i n a l Permission permission : r o l e . getPermissions ( ) ) {
permissions . add (new WildcardPermission ( permission . getPermission ( ) ) ) ;
}
});
15
f i n a l SimpleAuthorizationInfo authorizationInfo =
new SimpleAuthorizationInfo ( r o l e s ) ;
authorizationInfo . setObjectPermissions ( permissions ) ;
return authorizationInfo ;
});
20
}
Wydruk 6.2: Metoda zwracajaca
˛ dane potrzebne do autoryzacji użytkownika
Na wydruku 6.2 zaprezentowano metode,
˛ która odpowiada za przekazanie do
modułu bezpieczeństwa ról oraz uprawnień użytkownika. Całość operacji odbywa
si˛e w transakcji bazodanowej. Na poczatku
˛
nastepuje
˛
pobranie obiektu User na
podstawie loginu. Wykorzystujac
˛ otrzymany obiekt ustalane sa˛ role użytkownika,
a dzi˛eki nim jego uprawnienia. Tak zdobyte informacje wpisywane sa˛ w instancje
6.1. Moduł bezpieczeństwa
50
obiektu SimpleAuthorizationInfo zwracanego jako rezultat metody. Apache Shiro
może wykorzystać wynik działania tej funkcji do sprawdzania uprawnień użytkownika.
Komunikacja z serwisami poświadczajacymi
˛
Komunikacja z serwisami internetowymi oferujacymi
˛
usługe˛ OAuth odbywa
si˛e za pomoca˛ dodatku do Vaadin o nazwie OAuth Popup Add-on. Komponent
ten dostarcza API służace
˛ do otwierania okna, w którym użytkownik bedzie
˛
mógł
potwierdzić swoja˛ tożsamość oraz przekazać odpowiednie uprawnienia aplikacji.
Zadaniem programisty aplikacji jest zaimplementowanie interfejsu OAuthListener wymagajacego
˛
stworzenia dwóch metod:
— authSuccessful - wywoływanej w przypadku pozytywnej odpowiedzi serwisu,
— authDenied - wywoływanej w przypadku negatywnej odpowiedzi serwisu.
W przypadku odpowiedzi pozytywnej należy, za pomoca˛ API oferowanego przez
biblioteke˛ Scribe OAuth Library oraz otrzymanego tokenu dostepu,
˛
pobrać dane z
serwisu.
Uwierzytelnianie z wykorzystaniem serwisów poświadczajacych
˛
Oprócz VaadinAuthorizingRealm stworzono też dziedzine˛ OAuthAuthorizingRealm, która wykorzystuje dane otrzymane dzieki
˛ protokołowi OAuth do uwierzytelnienia użytkownika. Podobnie jak druga ze stworzonych dziedzin OAuthAuthorizingRealm dziedziczy ona po klasie AuthorizingRealm.
Jednym z pierwszych kroków tworzenia dziedziny było wyłaczenie
˛
dopasowywania hasła. Zostało to zrobione poprzez stworzenie własnej implementacji CredentialsMatcher i ustawienie jej jako domyślnej dla OAuthAuthorizingRealm. Realizacja ta
zwraca pozytywny wynik dopasowania dla każdego tokenu. Sposób realizacji tego
zadania przedstawiony jest na wydruku 6.3.
1
5
10
@Override
public CredentialsMatcher getCredentialsMatcher ( ) {
return new CredentialsMatcher ( ) {
@Override
public boolean doCredentialsMatch ( f i n a l AuthenticationToken token ,
f i n a l AuthenticationInfo i n f o ) {
return true ;
}
};
}
Wydruk 6.3: Implementacja klasy dopasowujacej
˛
dane uwierzytelniajace
˛
Naste˛ pnym krokiem było stworzenie klasy tokena, który bedzie
˛
wymagany przez
nowa˛ dziedzine˛ . Proponowana klasa OAuthAuthenticatingToken zawiera dwie składowe:
— service - be˛ dac
˛ a˛ tekstowa reprezentacja˛ serwisu, z którego pobierane sa˛ dane,
— id - be˛ dacy
˛ identyfikatorem użytkownika we wspomnianym serwisie.
Tak przygotowany token przetwarzany jest przez metode˛ doGetAuthenticationInfo klasy OAuthAuthorizingRealm. Jej implementacja przedstawiona jest na wydruku 6.4.
1
@Override
protected AuthenticationInfo doGetAuthenticationInfo (
6.1. Moduł bezpieczeństwa
51
f i n a l AuthenticationToken token )
throws AuthenticationException {
checkArgument ( token instanceof OAuthAuthenticatingToken ) ;
5
f i n a l OAuthAuthenticatingToken oAuthAuthenticatingToken =
( OAuthAuthenticatingToken ) token ;
checkNotNull ( oAuthAuthenticatingToken . getService ( ) ) ;
checkNotNull ( oAuthAuthenticatingToken . getId ( ) ) ;
10
OAuthAccount oAuthAccount = oAuthAccountDao .
findBySerivceAndServiceId ( oAuthAuthenticatingToken . getService ( ) ,
oAuthAuthenticatingToken . getId ( ) ) ;
15
i f ( oAuthAccount == null ) {
throw new AuthenticationException ( ) ;
}
20
User user = oAuthAccount . getUser ( ) ;
f i n a l SimpleAccount simpleAccount = new SimpleAccount ( user . getLogin ( ) ,
user . getPassword ( ) ,
ByteSource . U t i l . bytes ( user . g e t S a l t ( ) ) ,
REALM_NAME) ;
25
return simpleAccount ;
}
Wydruk 6.4: Pobieranie danych uwierzytelniajacych
˛
w klasie OAuthAuthorizingRealm
Pierwszym krokiem, po sprawdzeniu poprawności przekazanych parametrów,
jest pobranie konta OAuth zarejestrowanego w systemie dla danego serwisu i identyfikatora użytkownika. Jeśli takie konto nie istnieje zwracany jest bład
˛ uwierzytelniania. W przeciwnym przypadku pobierana jest instancja klasy User reprezentujaca
˛ użytkownika, z którym połaczone
˛
jest konto OAuth. Na podstawie tego
konta budowany jest obiekt SimpleAccount wykorzystywany przez Apache Shiro do
przetrzymywania danych użytkownika. Niezależnie od hasła zostanie on zaakceptowany przez zdefiniowana˛ na wydruku 6.3 klase.
˛
Podejście takie jest bezpieczne ponieważ instancje klasy OAuthAuthenticatingToken tworzone sa˛ wyłacznie
˛
po stronie serwera aplikacyjnego w sytuacji pozytywnej
odpowiedzi serwisu poświadczajacego.
˛
6.1.4. Rodzaje uprawnień
Apache Shiro dostarcza adnotacje które określaja˛ jakie wymagania musi spełnić
użytkownik by moduł bezpieczeństwa zezwolił na wywołanie funkcji. Ich lista
przedstawiona jest poniżej.
— RequiresUser - Użytkownik musi być uwierzytelniony.
— RequiresAuthentication - Użytkownik musi być uwierzytelniony lecz nie jest akceptowane uwierzytelnienie poprzez skorzystanie z opcji "Pamietaj
˛
mnie".
— RequiresGuest - Użytkownik nie może być uwierzytelniony.
— RequiresPermissions - Użytkownik musi posiadać uprawnienia bed
˛ ace
˛
argumentami adnotacji.
— RequiresRoles - Użytkownik musi posiadać role bed
˛ ace
˛ argumentami adnotacji.
6.1. Moduł bezpieczeństwa
52
6.1.5. Sprawdzanie uprawnień
W celu integracji modułu bezpieczeństwa z tworzonym systemem należało zaimplementować funkcje˛ sprawdzania adnotacji Apache Shiro w sposób niewymagajacy
˛ każdorazowego wywoływania metod weryfikujacych.
˛
Tak zaprogramowany
komponent gwarantuje niemożliwość jego pominiecia
˛
podczas wywołania metody
oraz znaczaco
˛ ułatwia tworzenie aplikacji. W zwiazku
˛
z powyższymi wymaganiami
zdecydowano sie˛ na wykorzystanie możliwości przechwytywania wywołań metod
obiektów utworzonych z wykorzystaniem CDI. W tym celu wykorzystano rozwiaza˛
nie zaproponowane przez Bauke Scholtz [1].
Pierwszy krokiem było utworzenie adnotacji ShiroSecured służacej
˛
do oznaczania metod oraz klas, które powinny podlegać przechwytywaniu. Nastepnie
˛
należało utworzyć klase˛ zawierajac
˛ a˛ metode˛ obsługi punktu przeciecia.
˛
W stworzonej
aplikacji odpowiada za to klasa ShiroSecuredInterceptor. Na wydruku 6.5 przedstawiono najważniejsze elementy jej budowy. Adnotacja Interceptor sprawia, że przy
uruchomieniu aplikacji CDI automatycznie zarejestruje˛ te˛ klase˛ jako przechwytywacz dla metod oznaczonych adnotacjami ShiroSecured. W momencie wywołania
chronionych metod zostanie najpierw wykonana treść metody interceptShiroSecurity. Dzieje sie˛ tak dzie˛ ki obecności adnotacji AroundInvoke. Kod wspomnianej
funkcji został pominie˛ ty w celu zwiekszenia
˛
czytelności wydruku.
1
package pl . dziurdziak . easyReckoning . u t i l s . security . permissionChecker ;
import javax . i n t e r c e p t o r . ∗ ;
import org . apache . shiro . subject . Subject ;
5
@Interceptor
@ShiroSecured
public class ShiroSecuredInterceptor {
@Inject
private Subject subject ;
10
@AroundInvoke
public Object interceptShiroSecurity ( f i n a l InvocationContext context )
throws Exception {
//code omitted
}
15
}
Wydruk 6.5: Najważniejsze elementy budowy klasy ShiroSecuredInterceptor
W wyniku tych działań możliwe stało sie˛ deklaratywne opisywanie zabezpieczeń
metod. Na wydruku 6.6 przedstawiono sposób zabezpieczenia metody, który zezwoli na jej wywołanie tylko uwierzytelnionemu użytkownikowi.
1
@ShiroSecured
@RequiresUser
public void viewEntered ( ) {
}
Wydruk 6.6: Przykład metody zabezpieczonej za pomoca˛ adnotacji
6.2. MVP oraz nawigacja
53
6.2. MVP oraz nawigacja
Vaadin jako zaawansowany szkielet aplikacyjny dostarcza szeregu komponentów i modułów wykorzystywanych podczas tworzenia systemu. Wśród nich znajduje sie˛ moduł nawigacji wykorzystujacy
˛ analize˛ adresu url. Niestety domyślne
rozwiazanie
˛
nie spełniało stawianych przed nim wymagań w zwiazku
˛
z czym podj˛eto decyzje˛ o stworzeniu własnego rozszerzenia odpowiedzialnego za nawigacje.
˛
6.2.1. Sposób nawigacji w Vaadin
Podstawowym sposobem nawigacji w aplikacji napisanej w szkielecie Vaadin jest
skorzystanie z klasy Navigator. Przykład wykorzystania takiego sposobu przedstawiony jest na wydruku 6.7.
1
public class NavigationTestUI extends UI {
@Override
public void i n i t ( VaadinRequest request ) {
Navigator navigator = new Navigator ( this , this ) ;
navigator . addView ( "main" , new MainView ( ) ) ;
navigator . addView ( " count " , CountView . class ) ;
}
5
10
}
Wydruk 6.7: Wykorzystanie nawigacji za pomoca˛ klasy Navigator
W pierwszej linii metody init rejestrowany jest nowy Navigator, który bedzie
˛
odpowiadał za zmiany zawartości głównego okna aplikacji. Navigator śledzi zmiany
adresu w pasku przegladarki
˛
i na jego podstawie ustala jaki widok ma zostać
wyświetlony. Decyzja o widoku, który ma zostać wyświetlony podejmowana jest
dzi˛eki jego nazwie podawanej w metodzie addView. W prezentowanym przykładzie
adres postaci
1
www. example .com/#main
sprawi, że zostanie wyświetlony widok MainView.
Domyślnie Navigator ustala jakie instancje widoku maja˛ zostać wyświetlone w
dwojaki sposób. Jeśli do metody addView zostanie przekazany obiekt oznacza to,
że ten obiekt zostanie wyświetlony. Gdy do tej funkcji zostanie przekazana klasa
widoku Navigator zainicjalizuje jej instancje˛ za pomoca˛ domyślnego konstruktora i
dopiero tak otrzymany obiekt wyświetli.
Wszystkie znaki znajdujace
˛ sie˛ w adresie strony po nazwie widoku oraz znaku
traktowane sa˛ jako parametry. Na poniższym przykładzie do widoku MainView
parametrem be˛ dzie ciag
˛ znaków parameters/second/first.
1
www. example .com/#main/parameters/second/ f i r s t
6.2.2. Wady nawigacji w Vaadin
Podstawowy sposób nawigacji w aplikacji stworzonej za pomoca˛ Vaadina nie
ustrzegł sie˛ wad. Do mankamentów tej metody można zaliczyć:
6.2. MVP oraz nawigacja
54
— Brak zaawansowanego wsparcia dla przekazywania parametrów do widoków.
Otrzymany łańcuch tekstowy, który jest parametrem musi zostać zanalizowany
i przetworzony przez kod klasy widoku.
— Brak wsparcia dla automatycznej budowy hierarchii widoków zagnieżdżonych
wewnatrz
˛
innych.
— Wykorzystywanie przekazanych instancji obiektów lub ich inicjalizacja za pomoca˛ domyślnego konstruktora. Jest to duża wada w środowisku działajacym
˛
w
oparciu o szkielet wspierajacy
˛ wstrzykiwanie zależności. Nowo powstałe widoki
pozbawione sa˛ referencji do obiektów zazwyczaj wstrzykiwanych przed odpowiedni komponent.
— W przypadku zastosowania wzorca MVP konieczne jest powiazanie
˛
otrzymanego
widoku z prezenterem.
6.2.3. Wymagania wobec nowego rozwiazania
˛
Nowo powstały mechanizm nawigacji powinien być pozbawiony wad nawigatora
domyślnego. Stawiane przed nim wymagania to:
— wsparcie dla widoków zagnieżdżonych,
— możliwość przekazywania parametrów dla widoków na dowolnym poziomie zagnieżdżenia,
— korzystanie z dobrodziejstw wstrzykiwania zależności,
— obsługa wzorca MVP,
— wysoki poziom automatyzacji.
6.2.4. Wykorzystane rozwiazanie
˛
Architektura MVP
Na rysunku 6.2 przedstawiono klasy i interfejsy należace
˛ do wykorzystanego
modelu MVP. Każdy widok aplikacji musi implementować interfejs MvpView, który
wymaga stworzenia dwóch metod:
— enter - wywoływanej w momencie otwarcia widoku,
— getComponent - służacej
˛
do pobrania treści widoku w celu jej wyświetlenia.
Widoki przyjmujace
˛ parametry musza˛ implementować interfejs ParametrizedView.
Interfejs ten nie wymaga od klas posiadania żadnych metod ponieważ różne widoki
moga˛ oczekiwać różnej liczby oraz innego rodzaju argumentów. Sposób przekazywania parametrów zostanie omówiony w dalszej cześci
˛
tego rozdziału. Klasy
widoku, które moga˛ zawierać widoki zagnieżdżone musza˛ implementować interfejs NavigatableView. Jego dwie metody służa˛ do ustawiania (setMvpView) oraz
pobierania (getMvpView) aktualnego widoku zagnieżdżonego.
Interfejsy widoków posiadaja˛ odpowiadajace
˛ im interfejsy prezenterów. Podstawowa˛ klasa˛ hierarchii prezenterów jest MvpPresenter, zawierajacy
˛
deklaracje
wyłacznie
˛
jednej metody, która zostanie wywołana w momencie otwarcia widoku.
Pozostałe elementy struktury dziedziczenia służa˛ do zapewnienia, że do widoków
odpowiednich typów zostana˛ przekazane właściwe prezentery.
Interfejs NavigatableUI powinna implementować główna klasa aplikacji. Zapewnia on, że możliwe be˛ dzie ustawianie widoków.
Oprócz wymienionych powyżej interfejsów nowy szkielet nawigacji dostarcza
dwie klasy abstrakcyjne warstwy widoku. W konstruktorach tych klas pobierane sa˛
właściwe instancje prezenterów dzieki
˛ czemu programista ma zapewniony dostep
˛
6.2. MVP oraz nawigacja
55
Rysunek 6.2: Zastosowana architektura wzorca MVP
do tych obiektów. AbstractNavigatableView zapewnia również obsługe˛ ustawiania i
pobierania widoków zagnieżdżonych.
Konfiguracja
Każdy widok musi posiadać odpowiadajaca
˛ mu klase˛ prezentera, który odpowiada za nadzorowanie jego zachowania oraz obsługe˛ przychodzacych
˛
zdarzeń.
Dzi˛eki temu, że klasy AbstractMvpView oraz AbstractNavigatableView sa˛ typami
generycznymi warunek ten jest zawsze spełniony.
6.2. MVP oraz nawigacja
56
Oprócz powiazania
˛
z prezenterem każdy widok musi zostać oznaczony adnotacja˛
@ViewName przechowujac
˛ a˛ informacje˛ o nazwie widoku. Nazwa widoku musi być
unikalna.
Obecnie dla poprawnego działania modułu nawigacji widoki musza˛ być powia˛
zane z zakresem interfejsu graficznego użytkownika. Osiaga
˛ sie˛ to poprzez stosowanie adnotacji UIScoped.
Ze wzgle˛ dów bezpieczeństwa widoki, w których moga˛ być zagnieżdżane inne
musza˛ być oznaczone niepusta adnotacja˛ @NavigateTo. Adnotacja ta przechowuje
informacje o klasach widoków, których obiekty moga˛ być prezentowane wewnatrz
˛
widoku nadrze˛ dnego.
1
5
@ViewName( " userAccounts " )
@NavigateTo ( { UserAccountDetailsView . class , UserAccountsSummaryView . class } )
@UIScoped
public class UserAccountsView extends
AbstractNavigatableView <UserAccountsPresenter > {
Wydruk 6.8: Konfiguracja widoku UserAccountsView
Widoki przyjmujace
˛ argumenty musza˛ posiadać metode˛ oznaczona˛ adnotacja˛
@ParamMethod, która sprawi, że podczas pracy modułu nawigacji parametry odczytane z adresu url zostana˛ przekazane przed wywołaniem funkcji enter. Metoda
ta musi przyjmować co najmniej jeden parametr. Wszystkie argumenty funkcji
powinny zostać oznaczone adnotacjami @Param, dzieki
˛ którym możliwe bedzie
˛
dopasowanie nazw parametrów odczytanych z adresu url z zadeklarowanymi argumentami metody.
1
@ParamMethod
public void setParams (@Param( " tabId " ) f i n a l Integer tabId ) {
presenter . setParams ( tabId ) ;
}
Wydruk 6.9: Przykład metody przyjmujacej
˛
parametry
Mimo, że parametry odczytywane z adresu url sa˛ łańcuchami znaków istnieje
możliwość deklarowania parametrów dowolnego typu w metodzie oznaczonej adnotacja˛ @ParamMethod. Moduł nawigacji wspiera przekazywanie argumentów typu
Integer oraz Long. Jeśli programista pragnie odczytywać parametry innych typów
musi zaimplementować interfejs Deserializer<T> oraz zarejestrować implementacje˛
klasy w module nawigacji.
1
public interface D e s e r i a l i z e r <T> {
T d e s e r i a l i z e r ( String s e r i a l i z e d ) throws DeserializationException ;
Class <? extends T> getDeserializedClass ( ) ;
5
}
Wydruk 6.10: Interfejs Deserializer<T>
57
6.2. MVP oraz nawigacja
Uruchomienie aplikacji
Moduł nawigacji korzysta z możliwości udostepnianych
˛
przez CDI. Do jednej
z nich należy stworzenie własnego rozszerzenia, które może nasłuchiwać zdarzeń
zwiazanych
˛
z procesem odkrywania klas, który zachodzi podczas startu aplikacji.
Naste˛ pujace
˛ operacje wykonywane sa˛ podczas uruchamiania aplikacji:
— Sprawdzenie czy każda klasa implementujaca
˛ interfejs MvpView oznaczona jest
adnotacja˛ @ViewName.
— Analiza czy wszystkie widoki posiadaja˛ unikalne nazwy.
— Sprawdzenie czy każdy widok implementujacy
˛
interfejs NavigatableView posiada niepusta adnotacje˛ @NavigateTo.
— Sprawdzenie czy każdy widok implementujacy
˛ interfejs ParametrizedView posiada metode˛ oznaczona˛ adnotacja˛ @ParamMethod oraz czy wszystkie parametry
tej metody oznaczone sa˛ za pomoca˛ @Param.
— Budowana jest dwukierunkowa mapa odwzorowujaca
˛
nazwy widoków na ich
klasy. Przetrzymywana jest ona w obiekcie ViewResolver.
Niespełnienie któregokolwiek z powyższych warunków skutkuje zgłoszeniem błedu,
˛
który uniemożliwia start aplikacji.
Proces nawigacji
Moduł nawigacji reaguje na zmiany adresu url. Pierwszym krokiem jest podział
adresu według schematu przedstawionego na rysunku 6.3. W wyniku tego podziału
zwracana jest lista obiektów przetrzymujacych
˛
nazwy kolejnych widoków wraz z
ich parametrami. Na szczególna˛ uwage˛ zasługuje tutaj znak "#", którego obecność
sprawia, że modyfikacje cze˛ ści adresu url za nim nie skutkuja˛ przeładowaniem
strony.
Rysunek 6.3: Podział adresu url
Lista otrzymana w poprzednim kroku poddawana jest dalszemu przetwarzaniu.
Proces ten został zobrazowany na rysunku 6.4.
Moduł nawigacji zwróci bład
˛ w przypadku gdy nazwy lub krotność parametrów
odczytanych z adresu url nie bed
˛ a˛ zgodne z argumentami oczekiwanymi przez
metode˛ widoku.
6.2. MVP oraz nawigacja
Rysunek 6.4: Przebieg procesu nawigacji
58
7. Podsumowanie
Celem niniejszej pracy inżynierskiej było zaprojektowanie i zaimplementowanie aplikacji internetowej wspierajacej
˛
proces wspólnego rozliczania wydatków.
Wszystkie wymagania przedstawione w rozdziale drugim zostały spełnione przez
stworzone oprogramowanie. Pobocznym zadaniem, które należało wykonać podczas implementacji systemu było zintegrowanie bibliotek i szkieletów programistycznych wykorzystanych podczas pracy implementacyjnej.
Ze wzgle˛ du na ograniczenia czasowe poświecono
˛
niedostateczna˛ uwage˛ dopracowaniu wygladu
˛
graficznego interfejsu użytkownika. Nie wpłyneło
˛ to na możliwości
powstałej aplikacji.
W trakcie tworzenia aplikacji autor niniejszej pracy zapoznał sie˛ z nieznanymi
sobie do tej pory bibliotekami, szkieletami aplikacyjnymi, wzorcami projektowymi.
Implementacja wymogła na nim zaznajomienie sie˛ ze sposobami administrowania
serwerami aplikacyjnymi oraz baza˛ danych. Zaowocowało to zdobyciem cennej wiedzy na temat programowania, możliwości jezyka
˛
Java oraz zarzadzania
˛
projektem.
Otwartych pozostaje wiele ścieżek rozwoju aplikacji.
Dalsze prace moga˛
uwzgle˛ dniać zmodernizowanie interfejsu graficznego oraz implementacje˛ dodatkowych funkcji systemu. Interesujacym
˛
zagadnieniem może również być stworzenie
aplikacji na platformy mobilne współpracujacej
˛
ze specjalnie w tym celu zmodernizowanym systemem.
Bibliografia
[1] Analiza
Apache
Sshiro
w
środowisku
Java
EE
6.
balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html.
[Online; dostep
˛ 22 sierpnia 2014].
[2] DB-Engines ranking. db-engines.com/en/ranking. [Online; dostep
˛ 3 sierpnia
2014].
[3] Funkcjonalności postgreSQL. www.postgresql.org/about/featurematrix/. [Online; dostep
˛ 24 sierpnia 2014].
[4] Google trends - popularność frazy Vaadin. www.google.pl/trends/explore?q=vaadin.
[Online; dostep
˛ 15 lipca 2014].
[5] Google trends - popularość frazy AngularJS. www.google.pl/trends/explore?q=AngularJS.
[Online; dostep
˛ 25 sierpnia 2014].
[6] Opis Oracle Database Express Edition 11g.
www.oracle.com/technetwork
/database/database-technologies/express-edition/overview/index.html.
[Online; dostep
˛ 24 sierpnia 2014].
[7] Popularność serwerów aplikacyjnych. http://www.javacodegeeks.com/2013/03
/most-popular-application-servers.html. [Online; dostep
˛ 25 sierpnia 2014].
[8] Porównanie popularności systemów operacyjnych. www.netmarketshare.com. [Online; dostep
˛ 24 sierpnia 2014].
[9] Porównanie wersji Oracle Database.
www.oracle.com/us/products/database
/enterprise-edition/comparisons/index.html. [Online; dostep
˛ 24 sierpnia
2014].
[10] Porównanie wersji SQL Server 2014.
msdn.microsoft.com/en-us/library
/cc645993.aspx. [Online; dostep
˛ 24 sierpnia 2014].
[11] Standardy sql w postgreSQL. www.postgresql.org/docs/current/static/features.html.
[Online; dostep
˛ 24 sierpnia 2014].
[12] Vaadin directory. vaadin.com/directory. [Online; dostep
˛ 15 lipca 2014].
[13] Christian Bauer, Gavin King. Java Persistence with Hibernate. Manning Publications
Co., Greenwich, 2007.
[14] Sami
Ekblad.
Vaadin
directory
celebrates
3
years.
vaadin.com/blog/-/blogs/vaadin-directory-celebrates-3-years.
[Online;
dostep
˛ 10 lipca 2014].
[15] Antonio Goncalves. Beginning Java EE 6 Platform with GlassFish 3. Apress, 2010.
[16] Les
Hazlewood.
Application
Security
With
Apache
Shiro.
www.infoq.com/articles/apache-shiro. [Online; dostep
˛ 20 lipca 2014].
[17] Bartek Kuczyński. Vaadin 7 - naprawde˛ szybkie tworzenie aplikacji web w javie.
Programista, listopad 2013.
[18] Krzysztof Sacha. Inżynieria oprogramowania. Wydawnictwo Naukowe PWN SA, Warszawa, 2010.
[19] Mark Seemann. Dependency Injection in .NET, strony 155–156. Manning Publications
Co., Shelter Island, 2012.

Podobne dokumenty