Aby stworzenie Star Trek API w zaplanowanym kształcie miało sens, musiało znaleźć się źródło danych, które byłoby relatywnie kompletne i które umożliwiałoby dostęp do danych przez sensowne i legalne API. Tym źródłem jest Wikia, wraz z dwoma hostowanymi tam wiki – Memory Alpha i Memory Beta.
Wszystkie wiki na Wikii działają na oprogramowaniu MediaWiki, rozwijanym od wielu lat na potrzeby Wikipedii. MediaWiki udostępnia własne API – niezbyt ustandaryzowane, ani SOAP-owe, ani REST-owe. Na Bitbuckecie istnieje projekt Bliki engine, javowy klient, który, chociaż nie idealny, oszczędza dużo pracy przy kwerendowaniu API stron opartych na MediaWiki.
Samo zasilenie składa się z trzech zasadniczych kroków. Readery i writery opisałem w poście o Spring Batchu. W tym wpisie skupię się na przybliżeniu szczegółów implementacji procesorów.
Po pierwsze, trzeba zbudować zbiór stron, z których zostanie zasilony dany model. Wymaga to ręcznego przejrzenia kategorii, w których pogrupowane są strony na wiki. Przykładowo, aby zbudować listę stron postaci fikcyjnych, które zostaną przeparsowane w następnym kroku, należy pobrać strony z czterech kategorii, z uwzględnieniem stron w kategoriach, które znajdują się we wskazanej czwórce. Przykładowo, kategorią, którą trzeba pobrać wraz z podkategoriami, jest kategoria Individuals. Trzeba uważać, by przy przechodzeniu do podkategorii odfiltrować te, z których strony były już pobierane, inaczej skończyłoby się to nieskończoną pętlą. Zdarza się bowiem tak, że jedna z podkategorii jest w więcej niż jednej kategorii wyższego poziomu.
Następnie wszystkie strony, które do tej pory były reprezentowane jako nagłówki, zostają pobrane wraz z całą treścią, kategoriami, i sparsowanymi szablonami. Wikia nie udostępnia sparsowanych szablonów, ponieważ jej wersja MediaWiki nie daje tej możliwości, dlatego trzeba pobraną z Wikii stronę przepuścić przez dodatkowy parser, np. przez ten publicznie dostępny na Wikipedii, chociaż ja używam postawionego lokalnie MediaWiki z powodów wydajnościowych. Zanim strony będą procesowane, następuje odfiltrowanie tych, które nie powinny się tu znaleźć. W tej grupie zawierają się strony zbiorcze i przeglądowe, które, chociaż znajdują się w pożądanych kategoriach, nie reprezentują postaci fikcyjnych, a, przykładowo, opisują jakąś ich grupę w egzotycznym kontekście, np. grupują postacie, które były tylko złudzeniami innych postaci, lub grupują reprezentantów jakiejś rasy, którzy nie byli znani z imienia.
Następnie dla większości encji, które mają być stworzone, poszukiwane są szablony znany z Wikipedii jako infoboksy – to te tabelki po prawej stronie na Wikipedii, z wypisanymi w nich najważniejszymi informacjami. Te szablony są, obok kategorii, w których znajduje się strona, głównymi źródłem danych w modelu. Infoboksy z Memory Alpha są w Star Trek API reprezentowane przez osobne obiekty względem encji bazodanowych, i w jeszcze kolejnych obiektach trzymany jest metamodel dla szablonów, czyli lista pól, które w nich występują, przykładowo, data urodzenia, płeć lub rasa, do której przynależy postać. Chociaż oddzielenie szablonów od encji może wydawać się nadmiarowe, posługiwanie się tą samą encją dla dwóch różnych zadań, wydawało mi się z kolei niezgodne z dobrymi praktykami. Z czasem okazało się też słuszne, bo czasami jednak procesor wypluwający z siebie encję reprezentującą szablon jest używany do czego innego, niż stworzenie na jego podstawie encji bazodanowej.
Procesory mogą być całkiem proste, i ograniczać się do jednej klasy bez zależności, jak w przypadku tego procesora, jak i całkiem skomplikowane, jak ten, który i tak tylko deleguje parsowanie kolejnych pól szablonu do swoich zależności. Dane zawarte w szablonach mogą i często są niekompletne, dlatego też model w Star Trek API ma niewiele obowiązkowych kolumn. Zwłaszcza w przypadku informacji ze świata fikcyjnego ciężko o komplet informacji – jeżeli postać epizodyczna nie miała podanej rasy, prawdopodobnie nigdy już nie będzie jej miała, chyba że wystąpi jeszcze w przyszłości w jakimś komiksie.
Zasadniczo w Star Trek API istnieją dwa typy procesorów. Jednym typem procesorów są te ze Spring Batcha o sygnaturze O process(I item) throws Exception
, a drugi typ to – napisany już przeze mnie – ItemEnrichingProcessor o sygnaturze void enrich(I enrichablePair) throws Exception
. Mój procesor do transportu obiektów używa EnrichablePair, czyli obiektu, który przechowuje zarówno wejściowy, jak i wyjściowy obiekt – a więc ten, który ma zostać wzbogacony. Ten drugi procesor jest używany wówczas, gdy zachodzi konieczność ustawienia więcej niż jednego pola w obiekcie reprezentującym szablon, lub zaczerpnięcia danych z więcej niż jednego pola. O bojach z danymi, które przechodzą przez procesory, będę pisał więcej w kolejnych tygodniach.