POLITECHNIKA LUBELSKA Walidacja Modeli Xtext
1. Wstęp 1.1. Czym jest walidacja Podczas opracowywania języka programowania analiza statyczna jest jednym z najważniejszych aspektów. W naukach technicznych i informatyce przyjęło się, że walidacja jest działaniem mającym na celu potwierdzenie, że wykonywane procedury, procesu lub czynności prowadzi do zaplanowanych rezultatów. Walidacja ma być potwierdzeniem poprzez dostarczenie obiektywnego dowodu o spełnieniu wymagań dotyczących konkretnego zastosowania. Proces walidacji ma na celu odpowiedzieć na pytanie czy tworzony obiekt jest prawidłowy. 2. Część teoretyczna 2.1. Walidacja w Xtext W Xtext podobnie jak w innych językach programowania występują mechanizmy pozwalające na zweryfikowanie poprawności wykorzystywanych części składowych języka pod względem poprawności różnych aspektów m.in. poprawności składniowej czy poprawności integralności danych. Tworząc język dziedzinowy Xtext pozwala na walidowanie języka i tworzonego przy jego pomocy kodu. Korzystając z Xtext przy tworzeniu języka już na poziomie definiowania gramatyki framework zapewnia mechanizmy, które zostaną wykorzystane przy automatycznym sprawdzaniu chociażby poprawności składniowej języka. Ponad to mamy do dyspozycji również mechanizm pozwalający tworzyć własne, dostosowane do konkretnego rozwiązania reguły walidujące modele tworzone za pomocą zdefiniowanego przez nas języka 2.2. Walidacja automatyczna W Xtext istnieją trzy różne mechanizmy walidacyjne które działają automatycznie dla stworzonego języka dziedzinowego. Wpływ na to mają aspekty wdrożeniowe języka tj. np. gramatyka. Wśród mechanizmów automatycznych w XText możemy wyróżnić: Lexer/Parser: Syntactical Validation walidator składnowy wejsc tekstowych Cross-reference Validation walidator powiązań Concrete Syntax Validation twarda walidacja składni Walidacja składni: Podstawowym mechanizmem walidacji każdego języka jest mechanizm sprawdzania poprawności składni. W Xtext odbywa się to w sposób automatyczny przy użyciu parsera języka. Definiując gramatykę oraz poszczególne w niej zależności wradzamy reguły według których może być tworzone rozwiązanie w oparciu o dany język. 1 S t r o n a
2.3. Walidacja niestandardowa Po za automatycznymi mechanizmami walidacji istnieje możliwość stworzenia niestandardowych reguł walidacyjnych dla modelu. Generator jezyka Xtext daje do dyspozycji dwie klasy Języka Java. Pierwszą z nich jest klasa generowana do katalogu../src-gen. Nazwa klasy oraz pakietu do jakiego należy jest uzależniona nazwą języka jaki tworzymy. W tym przypadku pakiet jest dostępny pod nazwą org.pollub.xtext.validation natomiast wygenerowana klasa jest dostępna pod nazwą AbstractPollDslValidator.java. 2-1. Lokalizacja pliku AbstractPollDslValidator.java w drzewie projektu Studencie zwróć uwagę, że Twoja u Ciebie jest Polls..., a nie Poll. Sama wygenerowana klasa rozszerza możliwości klasy AbstractDeclarativeValidator z pakietu oferowanego przez Xtext dostępnego jako org.eclipse.xtext.validation. 2-2. Kod wygenerowanej klasy AbstractPollDslValidator.java 2 S t r o n a
Drugą z dostępnych klas jest klasa znajdująca się w katalogu../src w tym samym pakiecie co poprzednia klasa abstrakcyjna. Klasa jest klasą jezyka Java o rozszerzeniu.xtend i bezpośrednio dziedziczy po klasie AbstractPollDslValidator.java. Nazwa klasy walidującej jest tworzona według schematu <<NazwaJezyka>>Validator. W naszym przypadku będzie to PollDslValidator.xtend z pakietu org.pollub.xtext.validation. 2-3. Lokalizacja pliku PollDslValidator.xtend w drzewie projektu Zmian możemy dokonywać właśnie w klasie PollDslValidator.xtend. Ta klasa odpowiada za logikę metod walidacyjnych. 2-4. Klasa PollDslValidator zlokalizowana w pliku PollDslValidator.xtend W późniejszej części praktycznej w ramach przykładu klasa PollDslValidator zostanie rozszerzona i uzupełniona o nowe metody sprawdzania poprawności tworzonych rozwiązań przy użyciu języka PollDsl. 3 S t r o n a
3. Część praktyczna 3.1. Cel Przewodnika Celem przewodnika jest przedstawienie możliwości walidacji języka dziedzinowego stworzonego przy pomocy Xtext. Do tego celu został wykorzystany przykład języka dziedzinowego służącego do generowania testów dla studentów który generuje test w postaci sformatowanego dokumentu HTML. Podstawowym celem jest stworzenie reguł walidacyjnych które nie pozwolą na wygenerowanie testu w sytuacji gdy program napisany przy użyciu użytego języka dziedzinowego będzie wskazywał na nie poprawne lub nie zrozumiałe dla użytkownika działanie wygenerowanego formularza HTML, który będzie wynikiem działania programu. W tym rozdziale pokazane zostaną przykładowe rozwiązania problemów walidacji. Dla potwierdzenia zostaną przedstawione odpowiednie zrzuty ekranu z opisem sytuacji. 3-1. Zrzut ekranu z wykorzystania przykładu języka dziedzinowego do tworzenia testów dla studentów 3.2. Użyte technologie Do realizacji projektu został wykorzystany Framework Xtext w wersji 2.10.0 oraz framework EMF w wersji 2.12.0. Metody walidacyjne zostały stworzone w języku Java w wersji 8. 3-2. Dołączone biblioteki, Xtext oraz EMF 4 S t r o n a
5 S t r o n a
3.3. Walidacja nabyta z gramatyki Tworząc gramatykę języka dziedzinowego tak jak na poniższym obrazie sztywno określiliśmy ręgułę, że Pytaniem może być PytanieOtwarte, PytanieJednokrotnegoWyboru lub PytanieWielokrotnegoWyboru, natomiast PytanieJednokrotnegoWyboru składa się z odpowiedzi które mogą być tylko i wyłącznie typu OdpowiedzPojedyncza oraz może się składać z jednego lub więcej elementów typu OdpowiedzPojedyncza. Tak zdefiniowana gramatyka nie pozwoli nam na stworzenie kodu w którym w ramach PytanieJednokrotnegoWyboru chcieli użyć odpowiedzi typu OdpowiedzWielokrotna. Jak widzimy parser składni zwraca nam błąd i informuje, że tego typu rozwiązanie jest błędne. 3.4. Tworzenie reguł walidacyjnych Do stworzenia własnych reguł walidacyjnych posłużymy się wspomnianą w części teoretycznej klasą PollDslValidator z pakietu org.pollub.xtext.validation. Do tego celu musimy napisać odpowiednie metody w ramach których sprawdzane zostaną interesujące nas warunki a następnie w oparciu o ich wynik zwrócimy rezultat. Każda metoda walidacyjna musi być opisana atrybutem @Check nad swoja sygnaturą. Aby skorzystać z atrybutu @Check należy zaimportować paczkę z pakietu: 6 S t r o n a
W ramach sprawdzania poprawności jeśli jakiś warunek nie zostanie spełniony i uznamy to jako błąd walidacyjny możemy posłużyć się jedną z metod klasy bazowej AbstractPollDslValidator. W przypadku błędu posłużymy się metodą error() która nie pozwoli na zbudowanie projektu. Metoda która jest mniej restrykcyjna i wygeneruje tylko ostrzeżenie jest metoda warning(). 3.5. Przykłady stworzonych reguł i ich działanie Wyobraźmy sobie sytuację w której chcemy stworzyć test a w ramach pytania odpowiednie do niego odpowiedzi. Sytuacja niedopuszczalną jest taka w której tworzymy za pomocą języka odpowiedź ale odpowiedz ta jest pusta a jej tytuł nie wskazuje na żadną wartość. Z punktu widzenie odbiorcy końcowego odpowiedź która jest pusta nie wskazuje na to czy jest odpowiedzią poprawną czy nie poprawna wiec walidator nie powinien pozwolić stworzyć twórcy testu w którym występują tego rodzaju nieprawidłowości. Do obsłużenia tej sytuacji zostałą stworzona metoda checkodpowiedzisnullorempty która przyjmuje jako parametr obiekt typu OdpowiedzPojedyncza i sprawdza czy jej tytuł jest null lub czy jest pusty. W przypadku napotkania takiej sytuacji wywoływana jest metoda error z błędem zwracanym do środowiska deweloperskiego. 3-3. Metoda walidująca 3-4. Rezultat metody walidacyjnej Wynik próby stworzenia odpowiedzi o pustej treści: Sytuacją w której nie należało by blokować możliwości wygenerowania testu jest sytuacja kiedy treść odpowiedzi nie zaczynała by się z dużej litery lub na końcu zdania nie było by znaku interpunkcyjnego tj. kropka lub znak zapytania. Stworzenie takiej odpowiedzi jest częściowo niepoprawne a wiec w takiej sytuacji można posłużyć się ostrzeżeniem. 3-5. Kod metody walidujacej 7 S t r o n a
Metoda check jako parametr przyjmuje obiekt typu Pytanie i sprawdza czy pierwsza litera tytułu zaczyna się wielką literą. Jeśli nie wywoływana jest metoda warning(), która ostrzega i wyświetla informację w środowisku deweloperskim. 3-6. Rezultat próby tworzenia pytania którego tytuł rozpoczyna się małą literą Ważnym aspektem walidacji może okazać się sprawdzanie możliwości odwołania się do innego obiektu. Na przykładzie testu dla studentów, możemy odwołać się w jednym pytaniu do pytania poprzedniego lub innego dowolnego. Aby było to możliwe a cały test posiadał logiczną spójność musimy mieć pewność że odwołanie w pytaniu jest możliwe i wskazuje na istniejący obiekt w teście. Dla realizacji tego celu, by nie zmieniać gramatyki języka, założono że odwołanie do innego pytania poprzez jego treść będzie realizowane przy pomocy operatorów << na początku i >> na końcu odwołania. W ten sposób wskazujemy pytanie do którego zamierzamy się odnieść. Metoda walidacyjna checkreferencetootherquestionbytitle() sprawdza czy dla istniejących pytań w teście istnieją odwołania do innych pytań i jeśli tak jest następuje weryfikacja ile tych odwołań jest. Jeśli nie wystąpią odwołania mamy pewność, że w takim przypadku nie istnieje pytanie i powoduje to bład. W takiej sytuacji zostaje wykonana metoda error() która powoduje błąd kompilatora. Ponieżej został przedstawiony kod metody walidującej oraz rezultat jej działania. 8 S t r o n a 3-7. Kod metody walidującej odwołanie do innego pytania poprzez tytuł
Gdy w teście nie znajdziemy pytania o konkretnej treści, wybranej jako referencja zostaje zwrócony bład co skutkuje że kompilator nie jest w stanie zbudować projektu. W poniższym przykłądzie (zrzut ekranu 3-7) brakuje pytania o treści Pytanie-Referencja. Po dodaniu takiego pytania o takiej treści (zrzut ekranu 3-8). metoda walidacyjna wykonuje się poprawnie i nie zwraca 3-9. Wynik działania metody walidacyjnej 3-9. Poprawne działanie języka błędu kompilatora. 9 S t r o n a
Jako kolejną regułę walidacyjną możemy wprowadzić sprawdzanie czy w obremie danego testu istnieją jakiekolwiek pytania. Do obsłużenia tej sytuacji powstała metoda checktesthasoneormorequestions(), która weryfikuje czy dany test posiada pytania. W przypadku kiedy kolekcja pytań okazuje się być pusta zostaje wywołana metoda error() blokująca możliwość kompilacji kodu. 3-11. Treść metody walidacyjnej ilość pytań w teście 3-11. Efekt działania metody walidacyjnej W obrębie walidacji liczebności poszczególnych elementów jezyka możemy również sprawdzać poprawność pod kątem liczby możliwych odpowiedzi do pytania. Do celów testowych zostało postawione założenie, że pytanie wielokrotnego wyboru reprezentowane przez typ PytanieWielokrotnegoWyboru może zawierać maksymalnie 4 możliwe odpowiedzi. Dla rozwiazania tego problemu powstała metoda walidacyjna checkpytaniehasmorethan4odpowiedzi(). Gdy ilość pytań przekracza założoną liczbę zostaje wywołana metoda error(). 10 S t r o n a 3-12. Metoda sprawdzająca czy ilość odpowiedzi do pytania nie przekracza liczby 4.
3-15. Wynik sprawdzania liczebności odpowiedzi do pytania. Ostatnim przykładem walidacji jest sprawdzenie czy zawarte w teście pytania są poukładane w kolejności alfabetycznej. Aspekt ten nie powoduje problemów z odczytaniem i zrozumieniem testu, stanowi jedynie tylko podstawę do zwrócenia uwagi na problem i możliwości jego rozwiązania. Z tego względu stworzona metoda checkquestionsareinalphabeticalorder() w przypadku stwierdzenia, sortowania niezgodnego z kolejnością alfabetyczną zwraca ostrzeżenie dla środowiska 3-14 Kod metody walidacyjnej 3-14. Wynik działania metody walidacyjnej programistycznego o zaistniałej sytuacji. Metody walidacyjne sprawiają że tworzne przez nas oprogramowanie już na etapie pisania kodu programu jest sprawdzane pod względem sensowności pewnych zachowań i rozwiązań zarówno w aspekcie składniowym wykorzystywanego języka jak i sensu logicznego i użyteczności końcowego produktu dla konsumentów. 11 S t r o n a
4. Podsumowanie Celem pracy było zapoznanie czytającego z możliwościami walidacji w narzędziu Xtext. Praca we wstępie wprowadza czytelnika w tematykę walidacji a następnie wskazuje na mechanizmy walidacyjne dostępne w narzędziu. Poprzez przedstawienie mechanizmów automatycznej walidacji do nakreślenia problematyki walidacji niestandardowej w części teoretycznej czytelnik zdobywa ogólne rozeznanie w problemie. Część praktyczna została oparta na, niezbyt skomplikowanym a jednocześnie odkrywającym ogromny potencjał tego typu rozwiązań, przykładnie języka dziedzinowego umożliwiającego tworzenie zestawów testowych dla studentów w postaci dokumentu HTML. Przykład języka DSL został w tej pracy rozszerzony o metody sprawdzające poprawność tworzonego rozwiązania pod względem zrozumiałości rezultatu końcowego dla odbiorcy. Metody przygotowane w języku Java w wersji 1.8 będące rozszerzeniem języka stworzonego przy użyciu narzędzia Xtext w wersji 2.10.0 pozwoliły na weryfikację kluczowych aspektów spójności logicznej tworzonego języka oraz testu generowanego przy jego pomocy. Całość została udokumentowana odpowiednimi zrzutami ekranu wraz ze stosownym wyjaśnieniem. 12 S t r o n a