Włodzimierz WYSOCKI, Walery SUSŁOW

9
86 Włodzimierz WYSOCKI, Walery SUSŁOW Katedra Inżynierii Komputerowej, Politechnika Koszalińska E–mail: [email protected], [email protected] Moduł generatora dokumentów tekstowych oparty o otwartą bibliotekę ODFDOM Streszczenie: W artykule przedstawiono koncepcję typowego modułu ge- neratora dokumentów tekstowych do zastosowań biznesowych. Autorzy wykorzystują otwarty format dokumentów biurowych OpenDocument oraz opierają konstrukcję modułu na wykorzystaniu biblioteki języka Java ODFDOM. Poza ogólnym opisem idei działania modułu generatora, w artykule przedstawiono architekturę zbudowanej realizacji oraz wska- zano możliwe kierunki rozwoju zbudowanego modułu. Artykuł zawiera również link do repozytorium z kodem modułu. 1. Wstęp Nowoczesne systemy informatyczne najczęściej tworzą raporty i inne dokumenty tek- stowe jako pliki PDF, potem wysyłają je do przeglądarki użytkownika, gdzie można je obejrzeć, wydrukować lub zapisać na dysk. Żeby zmienić wygląd lub zawartość tak powstałych dokumentów trzeba mieć dostęp do komercyjnych narzędzi do edycji pli- ków PDF. Podobne ograniczenia występują także, gdy dokumenty i raporty są tworzone w formacie DOC. Jest to również format zamknięty, komercyjny tak jak aplikacje słu- żące do edycji dokumentów w tym formacie. „Open Document Format for Office Applications” jest to format otwarty, którego specy- fikacja jest publicznie dostępna. Został utworzony jako alternatywa dla komercyjnych, zamkniętych formatów dokumentów używanych przez Microsoft Office. Swoim zakre- sem obejmuje dokumenty tekstowe, arkusze kalkulacyjne, wykresy i prezentacje. Roz- wojem standardu zajmuje się niezależna organizacja OASIS, do której należą najwięk- sze firmy informatyczne jak: IBM, Microsoft, Oracle oraz organizacje rządowe USA. Rozwiązaniem, które umożliwi użytkownikowi systemu informatycznego zmianę wy- glądu i treści tworzonych raportów bez dostępu do komercyjnych edytorów, jest wyge- nerowanie raportu w postaci dokumentu ODT, który można edytować, na przykład popularnym, darmowym edytorem tekstu Writer z pakietu OpenOffice. Takie rozwiąza- nie wymuszałoby jednak na użytkowniku, żeby za każdym razem po wygenerowaniu raportu od nowa korygował jego wygląd. Większą elastyczność zapewni umożliwienie użytkownikowi edycji szablonu, według którego tworzony jest raport czy inny doku-

Transcript of Włodzimierz WYSOCKI, Walery SUSŁOW

Page 1: Włodzimierz WYSOCKI, Walery SUSŁOW

86

Włodzimierz WYSOCKI, Walery SUSŁOW Katedra Inżynierii Komputerowej, Politechnika Koszalińska

E–mail: [email protected], [email protected]

Moduł generatora dokumentów tekstowych oparty o otwartą bibliotekę ODFDOM

Streszczenie: W artykule przedstawiono koncepcję typowego modułu ge-neratora dokumentów tekstowych do zastosowań biznesowych. Autorzy wykorzystują otwarty format dokumentów biurowych OpenDocument oraz opierają konstrukcję modułu na wykorzystaniu biblioteki języka Java ODFDOM. Poza ogólnym opisem idei działania modułu generatora, w artykule przedstawiono architekturę zbudowanej realizacji oraz wska-zano możliwe kierunki rozwoju zbudowanego modułu. Artykuł zawiera również link do repozytorium z kodem modułu.

1. Wstęp Nowoczesne systemy informatyczne najczęściej tworzą raporty i inne dokumenty tek-stowe jako pliki PDF, potem wysyłają je do przeglądarki użytkownika, gdzie można je obejrzeć, wydrukować lub zapisać na dysk. Żeby zmienić wygląd lub zawartość tak powstałych dokumentów trzeba mieć dostęp do komercyjnych narzędzi do edycji pli-ków PDF. Podobne ograniczenia występują także, gdy dokumenty i raporty są tworzone w formacie DOC. Jest to również format zamknięty, komercyjny tak jak aplikacje słu-żące do edycji dokumentów w tym formacie.

„Open Document Format for Office Applications” jest to format otwarty, którego specy-fikacja jest publicznie dostępna. Został utworzony jako alternatywa dla komercyjnych, zamkniętych formatów dokumentów używanych przez Microsoft Office. Swoim zakre-sem obejmuje dokumenty tekstowe, arkusze kalkulacyjne, wykresy i prezentacje. Roz-wojem standardu zajmuje się niezależna organizacja OASIS, do której należą najwięk-sze firmy informatyczne jak: IBM, Microsoft, Oracle oraz organizacje rządowe USA.

Rozwiązaniem, które umożliwi użytkownikowi systemu informatycznego zmianę wy-glądu i treści tworzonych raportów bez dostępu do komercyjnych edytorów, jest wyge-nerowanie raportu w postaci dokumentu ODT, który można edytować, na przykład popularnym, darmowym edytorem tekstu Writer z pakietu OpenOffice. Takie rozwiąza-nie wymuszałoby jednak na użytkowniku, żeby za każdym razem po wygenerowaniu raportu od nowa korygował jego wygląd. Większą elastyczność zapewni umożliwienie użytkownikowi edycji szablonu, według którego tworzony jest raport czy inny doku-

Page 2: Włodzimierz WYSOCKI, Walery SUSŁOW

87

ment. Szablon taki powinien zawierać nazwy pól, które będą następnie wypełniane treścią wygenerowaną lub odczytaną przez aplikację z bazy danych. Użytkownik za pomocą znanych mu narzędzi edytora Writer do formatowania tekstu będzie mógł do-stosować wygląd i treść raportu do swoich indywidualnych potrzeb. Co ważne, zmiany te wprowadzone raz do szablonu będą odzwierciedlone w każdym dokumencie genero-wanym według tego szablonu przez system.

W ramach niniejszego artykułu prezentowana jest autorska koncepcja budowy typowe-go modułu generatora dokumentów tekstowych, wykorzystująca opisany pomysł edy-towalnego szablonu i oparta o funkcjonalność biblioteki ODFDOM [1]. Istnieje szereg innych bibliotek przydatnych do zbudowania podobnego modułu, chociażby JODRe-ports [2]. Wybór na korzyść ODFDOM został dokonany z powodu solidności wsparcia dla projektu tej biblioteki.

Artykuł przybliża konstrukcję modułu generatora dokumentów opracowaną w wersji prototypowej w trakcie przygotowania magisterskiej pracy dyplomowej [3], gdzie mo-duł ten został użyty po raz pierwszy do generowania raportów z przebiegu prac testo-wych na podstawie danych zapisanych w bazie systemu „bug traker'a”. Wcześniejsze próby utworzenia modułu generatora, przeprowadzone przy pomocy OpenOffice SDK (dostarcza on technologii Unified Network Objects [4] pozwalającej na dostęp do kom-ponentów OpenOffice'a niezależnie od platformy sprzętowej, systemu operacyjnego czy języka programowania) okazały się nieudane. Dopiero użycie biblioteki ODFDOM przyspieszyło prace i umożliwiło realizację założonych celów.

2. Krótki opis biblioteki ODFDOM Biblioteka ODFDOM jest częścią większego projektu o nazwie ODF Toolkit [5]. Jest to projekt utrzymywany przez społeczność Open Source, która powstała w celu rozwoju i utrzymania narzędzi ułatwiających pracę z dokumentami w formacie ODF. ODFDOM jest najaktywniejszą częścią tego projektu. Interfejs programistyczny biblioteki jest tak zaprojektowany, żeby można było łatwo tworzyć, zmieniać, odczytywać i zapisywać dokumenty ODF przy pomocy kilku linijek kodu. Użycie biblioteki nie wymaga od programisty szczegółowej znajomości specyfikacji formatu ODF.

Biblioteka powstała by zrealizować dwa główne cele. Pierwszym z nich jest zapewnie-nie łatwiejszego i wygodniejszego dostępu do dokumentów ODF niż przez aplikacje takie jak OpenOffice czy IBM Lotus Symphony. Drugim jest umożliwienie programi-stom realizacji typowych w przemyśle informatycznym scenariuszy przypadków uży-cia, do których odnoszą się:

• automatyczne generowanie wielkiej liczby dokumentów tekstowych w środowisku korporacyjnym zgodnie ze specyficznymi wymaganiami biznesowymi na podstawie szablonów i danych z baz danych; np. wygenerowanie odcinków płac dla wszystkich pracowników organizacji w postaci dokumentów ODF.

• walidacja dokumentów – sprawdzenie, czy i z którą wersją specyfikacji ODF doku-ment jest zgodny;

Page 3: Włodzimierz WYSOCKI, Walery SUSŁOW

88

• przeszukiwanie treści dokumentów w celu znalezienia fragmentów wg zadanych kryteriów.

Biblioteka ODFDOM (patrz rysunek 1) ma strukturę złożoną z dwóch warstw, są to: warstwa paczki ODF i warstwa XML.

Warstwa paczki ODF zapewnia dostęp do zasobów (plików), strumieni XML, grafiki, wbudowanych obiektów umieszczonych w paczce ZIP, którą jest plik ODF. Warstwa ta zapewnia wszystkie opisane w trzeciej części specyfikacji ODF 1.2 [6] funkcje, opierające się na obsłudze plików ZIP, obsłudze szyfrowania W3C, obsłudze podpisu cyfrowego W3C i obsłudze metadanych W3C. Warstwa XML gwarantuje dostęp do wszystkich ele-mentów, które mogą być umieszczone w pliku ODF (tabele, grafika, numeracja). Dostęp-ne elementy zdefiniowane są w pierwszej części specyfikacji ODF opisującej schemat XML ODF.

Warstwa XML składa się z dwóch interfejsów programistycznych reprezentujących dwa różne podejścia do zapewnienia funkcjonalności. Pierwsze z nich dostarcza niskopo-ziomowy API drzewa DOM, co umożliwia dostęp do elementów XML. Interfejs pro-gramistyczny umożliwia manipulowanie węzłami drzewa DOM w sposób zgodny ze standardem DOM API W3C [7] znanym z przeglądarek internetowych. Klasy Javy składające się na API są wygenerowane automatycznie na podstawie gramatyki ODF zdefiniowanej w języku RelaxNG, co zapewnia zgodność ze specyfikacją i łatwość dostosowania do przyszłych wersji standardu. Drugie podejście realizuje wysokopo-ziomowy API dokumentu – ten interfejs programistyczny jest zorientowany na użytecz-ność, ukrycie przed użytkownikiem szczegółów implementacji i realizację najczęściej wykorzystywanych przypadków użycia, na przykład zmianę zawartości pewnej komór-ki arkusza kalkulacyjnego.

Rys. 1. Model warstwowy interfejsów programistycznych biblioteki ODFDOM

W niskopoziomowym ODF DOM API każda z klas reprezentuje węzeł XML ODF, w wysokopoziomowym API jedna klasa odpowiada wielu elementom XML ODF i ich atrybutom. Szczegóły dotyczące ODFDOM można poznać z publikacji [8-13].

Page 4: Włodzimierz WYSOCKI, Walery SUSŁOW

89

3. Idea typowego modułu generatora dokumentów tekstowych

Ideę generatora przedstawia schemat kontekstowy podany na rys. 2. Generator dokumen-tów czyta szablon dokumentu i następnie za pomocą mechanizmów refleksji języka Java wyszukuje nazwy pól zdefiniowanych w szablonie wśród obiektowych reprezentacji da-nych odczytanych z bazy danych. Iterując po kolekcjach rekordów bazy Db i pobierając właściwe dane, generator buduje tabele umieszczone w dokumencie szablonu, a następnie zapisuje utworzony na podstawie szablonu dokument w formacie ODF i przesyła go do przeglądarki użytkownika. Użytkownik może sporadycznie redagować dokument wyni-kowy lub wprowadzić zmiany do szablonu dokumentu, co spowoduje stałą zmianę budo-wy generowanych dokumentów wynikowych. W obu przypadkach może on korzystać z oprogramowania biurowego, czyli nie musi mieć nawyków programisty.

W opisywanej realizacji projektu komunikacja generatora z bazą danych została wykonana w oparciu o komponenty (ziarna) EJB 3.0 [14] i standard mapowania obiektowo-relacyjnego firmy Sun Microsystems Java Persistence API (skrót JPA [15]) dla języka Java.

Podstawowym wymaganiem dla generatora dokumentów jest wypełnienie zawartości pól użytkownika umieszczonych w szablonie dokumentu. Równie niezbędnym wyma-ganiem jest możliwość odwzorowania danych pochodzących z bazy na treść tabelarycz-ną dokumentu wynikowego. By moduł był użyteczny, algorytm generowania tabeli powinien obsługiwać następujące przypadki tego odwzorowania:

• Tworzenie tabeli prostych – wiersz tabeli odpowiada rekordowi z bazy danych. • Tworzenie tabeli zagnieżdżonych – w komórce tabeli dane są umieszczane w po-

staci tabeli. • Tworzenie tabeli „pionowych” – kilka wierszy tabeli tworzonych jest z jednego

rekordu. • Autonumeracja wierszy tabeli.

Rys. 2. Schemat kontekstowy działania generatora dokumentów

Page 5: Włodzimierz WYSOCKI, Walery SUSŁOW

90

4. Proponowana architektura modułu generatora dokumentów

Budowa modułu jest zoptymalizowana względem procesu generowania dokumentu, który składa się z dwóch faz. W pierwszej fazie wyszukiwane są deklaracje pól użyt-kownika w dokumencie-szablonie. W drugiej fazie wyszukiwane są odwołania do pól użytkownika. Nazwy umieszczone w odwołaniach są następnie wyszukiwane w kom-ponentach trwałych dzięki mechanizmom refleksji języka Java i przekształcane na re-prezentacje obiektowe. Finalizacja drugiej fazy to iterowanie po kolekcjach i budowanie elementów dokumentu z zawartością rekordów wczytanych z bazy danych.

Rys. 3. Diagram klas generatora dokumentów

Page 6: Włodzimierz WYSOCKI, Walery SUSŁOW

91

W przypadku, kiedy generator dokumentów nie odnajdzie w drugiej fazie komponentu trwałego, do którego odnoszą się odwołania, w logach serwera aplikacji zostaje zarejestro-wany błąd, a w zawartości odpowiedniego pola użytkownika pojawia się stosowny komuni-kat błędu. Jeżeli typ danych odnalezionego komponentu trwałego jest inny niż znakowy (np. walutowy lub numeryczny), to dane są automatycznie skonwertowane na tekst.

Klasa główna generatora dokumentów DocumentGenerator (patrz diagram na rysunku 3) zawiera najważniejszą metodę generate(), której wywołanie z parametrami: odwołaniem do komponentu trwałego, nazwą szablonu i nazwą pliku wynikowego spowoduje wypełnienie szablonu danymi z obiektu trwałego i zapisanie go jako dokumentu wynikowego w katalogu tymczasowym oraz wysłanie dokumentu wynikowego do przeglądarki użytkownika.

Klasy bazowe, które odpowiadają za obiektową reprezentację szablonu dokumentu, są zdefiniowane w sposób następujący:

• FieldDecl – opisuje deklarację pola użytkownika umieszczoną w szablonie dokumentu, • FieldRef – opisuje odwołanie do pola użytkownika występujące w szablonie

dokumentu.

Obiekty klasy FieldDecl są tworzone przez generator dokumentów tylko dla pól bezpo-średnio występujących w przekazanym do generatora komponencie trwałym. Obiekty te są zapamiętywane w mapie obiektów i następnie są używane do zapisania wartości obiektów, do których się odwołują w deklaracjach pól w dokumencie wynikowym.

Obiekty klasy FieldRef są tworzone w czasie wyszukiwania w przekazanych do genera-tora komponentach trwałych nazwy odwołania do pola użytkownika. Klasa ta służy jako klasa bazowa dla klas RelationRef i CollRef, realizujących montowanie tabeli w do-kumencie wynikowym.

Do opisu tabeli umieszczonej w szablonie dokumentu służy klasa TableDefinition. Klasa ta zawiera kolekcję obiektów klasy FieldRef opisujących odwołania do pól komponentów trwałych, których wartości należy umieścić w tabeli. Warto tutaj podkreślić, że postać tabela-ryczna jest bardzo powszechna w wydrukach i generator powinien być w stanie sprytnie obsługiwać nie tylko tabele proste, ale i tabele tabel, czyli konstrukcje zagnieżdżone.

W przypadku tabeli prostych obsługę danych załatwia klasa RelationRef, która opisuje relację jeden do jednego lub wiele do jednego. Mianowicie w tej relacji znajdują się pola wskazywane przez nazwę wpisaną w odwołanie do pola użytkownika umieszczone w szablonie dokumentu.

Bardziej skomplikowana obsługa danych niezbędna jest w przypadku tabeli tabel. Służy do tego klasa CollRef, która ma opisywać kolekcję, czyli relację jeden do wielu umieszczoną w komponencie trwałym przekazanym do generatora. Obiekt klasy CollRef zawiera infor-mację o tabelach w szablonie dokumentu, wewnątrz których znajdują się pola tej kolekcji i dla których tabeli trzeba tworzyć nowe wiersze podczas iteracji po kolekcji. Informacja o tabelach przechowywana jest jako kolekcja obiektów klasy TableDefinition.

Mapowanie na obiekty klasy CollRef dokumentów zawierających tabele zagnieżdżone powoduje zagłębienie kolekcji w kolekcji. Do obsługi iteracji kolekcji umieszczonych w kolekcjach służy klasa CollRefStack implementująca metody push() i pop(), które po-zwalają na utworzenie stosu obiektów klasy CollRefComponent odwzorowującego aktual-

Page 7: Włodzimierz WYSOCKI, Walery SUSŁOW

92

ne zagłębienie iterowanej kolekcji. Klasa CollRefComponent zawiera odwołanie do obiek-tu klasy CollRef i komponentu trwałego, wewnątrz którego kolekcja jest umieszczona.

Tab. 1. Porównanie modułu generatora dokumentów i biblioteki JODReports

Aspekt porównania

Moduł generatora dokumentów

Biblioteka JODReports

Pola szablonu

Standardowe pola użytkownika edytora Writer

Pola oznaczone przez znak dola-ra i nawiasy klamrowe

${nazwa_pola} – składnia FreeMarker, jest opcjonalna

możliwość użycia pól użytkownika edytora Writer

Edycja szablonu

Wsparcie edytora dla zarządzania polami – wsta-

wianie z listy, itd.

Brak wsparcia, edytor nie odróżnia pól od zwykłego tekstu,

złożona składnia szablonów, potrzeba znajomości wewnętrz-nej budowy dokumentów ODF

Budowa szablonu

Brak instrukcji przetwarzania, odpowiedzialność przeniesio-

na na klasy Java, zmiana wymaga ponownej

kompilacji kodu

Złożone instrukcje przetwarzania, możliwość

modyfikacji szablonów bez kompilacji kodu Java

Iteracja kolekcji i wypełnianie

zawartości tabel Automatyczne i uproszczone

Za pomocą instrukcji przetwa-rzania umieszczanych

w specjalnych miejscach dokumentu

Złożoność generowanych dokumentów

Proste dokumenty bezpośrednio

odzwierciedlające zawartość obiektów Java

Złożone dokumenty ze względu na możliwość umieszczenia wyrażeń arytmetycznych,

wyrażeń logicznych i instrukcji warunkowych

Łatwość użytkowania

Przygotowanie szablonu przez programistę,

jest możliwość tworzenia i edycji szablonów przez zwykłych użytkowników

Przygotowanie i zmiana szablonów przez programistów,

teoretycznie jest możliwość edycji szablonu przez

użytkownika zaawansowanego

Powyższa tabela przedstawia możliwość porównania zaproponowanej konstrukcji mo-dułu z rozwiązaniem dostarczanym przez wspomnianą wyżej bibliotekę JODReport w kontekście warunków pracy użytkownika systemu informatycznego.

Page 8: Włodzimierz WYSOCKI, Walery SUSŁOW

93

5. Podsumowanie Zaprezentowana konstrukcja modułu generatora przeszła testy akceptacyjne. Próbna eksploatacja potwierdziła poprawność podjętych decyzji projektowych. Kod modułu jest dostępny do pobrania ze strony http://code.google.com/p/gen-dok-odf.

Przewidywalny rozwój opisanego modułu może być związany z refaktoryzacją istnieją-cego kodu poprzez zamianę ścisłych powiązań między klasami powstałymi przez użycie dziedziczenia na luźne powiązania i wprowadzenie mechanizmu rozszerzania interfej-sów. Rozluźnienie powiązań między klasami i wypracowanie bardziej uniwersalnych kontraktów dla klas umożliwiłoby zniesienie zależności od klas biblioteki JBoss Seam oraz od technologii EJB3, w której muszą być obecnie wykonane komponenty trwałe dostarczane do generatora dokumentów. W oparciu o technologię EJB3 jest zbudowany mechanizm iterowania po kolekcjach i budowania tabel w dokumencie wynikowym.

Drugim pożytecznym zabiegiem rozwojowym może być wprowadzenie dynamicznej podmiany nazwy pola oraz samego komponentu trwałego. W tej chwili trzeba używać dokładnie takich samych nazw, jakie są użyte w komponencie EJB, przez to wartości wprowadzane w pola użytkownika w szablonie stają się bardzo długie i nieczytelne. Rozwiązaniem tego problemu może być zastosowanie pliku konfiguracyjnego do defi-niowania aliasów – nowych, krótszych nazw komponentów i ich pól.

Literatura 1. ODFDOM - the OpenDocument API,

http://odftoolkit.org/projects/odfdom/pages/Home

2. Java OpenDocument Reports, http://jodreports.sourceforge.net/

3. Wysocki W., Projekt aplikacji wspomagającej testowanie oprogramowania, zgodny z metodologią Unified Software Development Process, praca dyplomowa magister-ska, Politechnika Koszalińska, Koszalin 2011.

4. UNO - interfejs komponentów pakietu OpenOffice, http://wiki.services.openoffice.org/wiki/Uno

5. ODF Toolkit Union, http://odftoolkit.org/

6. Open Document Format for Office Applications, Version 1.2, http://docs.oasis-open.org/office/v1.2/part1/cd04/OpenDocument-v1.2-part1-cd04.html

7. Document Object Model, http://www.w3.org/DOM/

8. ODFDOM Tutorial, http://opendocument.xml.org/news/odfdom-tutorial

9. Ming Fei Jia, ODFDOM for Java: Simplifying programmatic control of documents and their data, Part 1, http://www.ibm.com/developerworks/lotus/library/symphony-odfdom-pt1/index.html

10. Wei Hua Wang, ODFDOM for Java: Simplifying programmatic control of documents and their data, Part 2, http://www.ibm.com/developerworks/lotus/library/symphony-odfdom-pt2/index.html

Page 9: Włodzimierz WYSOCKI, Walery SUSŁOW

94

11. Li Wei, ODFDOM for Java: Simplifying programmatic control of documents and their data, Part 3, http://www.ibm.com/developerworks/lotus/library/symphony-odfdom-pt3/?ca=drs-

12. Florian Hopf, Template based document generation using ODFDOM, http://blog.synyx.de/2010/06/template-based-document-generation-using-odfdom/

13. OpenDocument Format and the ODFDOM API, http://langintro.com/odfdom_tutorials/odf_internals.html

14. EJB 3.0 Tutorial, http://docs.jboss.org/ejb3/app-server/tutorial/index.html

15. Introduction to the Java Persistence API, http://download.oracle.com/javaee/5/tutorial/doc/bnbpz.html