You are on page 1of 92

Spis treści

1/2007 (145)

Aktualności 6
Noworoczne postanowienia
Ho ho ho zaczęło wydobywać się z naszego redakcyjnego serwera. Wzbu-
dziło to w nas niejaką konsternację, ale nie do takich rzeczy jesteśmy przy-
Opis CD 12
zwyczajeni. Dochodzące nie wiadomo skąd dźwięki dzwoneczków też nie
dały nam specjalnie do myślenia. Przemykające to tu to tam grupki rado-
snych kolędników obudziły w nas lekkie podejrzenia. Ale pewności nabrali-
śmy dopiero kiedy jedna z koleżanek wpadła do redakcji z okrzykiem Świą-
Sprostowanie 23
teczne wyprzedaże!!!
No tak, to właśnie nadeszła TA pora. Trzeba sie sprężyć i wymyślić coś
ekstra. Komisja złożona z najszacowniejszych członków naszej małej społecz-
ności po spędzeniu nocy na selekcjonowaniu genialnych i megakreatywnych
Tam byliśmy 24
pomysłów stwierdziła co następuje:

l Primo – Z okazji Świat Bożego Narodzenia naszym czytelnikom wszyst-


Wywiad z Dave'em Chappelem 68
kiego co najlepsze! Howgh!
Secundo – Świątecznego bonusa w postaci 8 dodatkowych stron! Howgh!
72
l

l Tertio – Stały i niezwykle interesujący- brand new-dział Kasa dla Progra- Kasa dla programisty
misty, a w nim same smaczności. Możliwości jakie oferują polskie firmy
informatyczne swoim pracownikom. Doświadczenia programistów, którzy
przeszli od hobby do zawodowstwa. Odsłona pierwsza: wywiad z Marci-
nem Kuciębą – Software Developer Manager Centrum Rozwoju Oprogra-
mowania Sabre w Krakowie. Howgh!
Algorytmy: Licytacja 74
Żeby dopieścić Wasz zmysł estetyczny zmieniliśmy design płytek. Ponadto,
uroczyście przyrzekamy, i niech nas to i owo, jeśli zełgaliśmy, nadal ciężko
Felieton 86
pracować i oddać w Wasze ręce płytkę z czytelnym i łatwym w obsłudze
indeksem. Howgh!

DO SIEGO ROKU!!!
Księgozbiór 87
Magdalena Filip
sdj@software.com.pl Zapowiedzi 90
Miesięcznik Software Developer’s Journal (12 numerów w roku) Adres korespondencyjny:
Software-Wydawnictwo Sp. z o. o., ul. Bokserska 1, 02-682 Warszawa
jest wydawany przez Software-Wydawnictwo Sp. z o. o. www.sdjournal.org redakcja@software.com.pl tel. (22) 887 10 10
Dyrektor wydawniczy: Jarosław Szumski
Redaktor naczelny: Sylwia Pogroszewska sylwiap@software.com.pl
Redaktor: Magdalena Filip magdalena.filip@software.com.pl Redakcja dokłada wszelkich starań, by publikowane w piśmie i na towarzyszących mu nośnikach informacje
Asystent redaktora: Katarzyna Kober katarzyna.kober@software.com.pl i programy były poprawne, jednakże nie bierze odpowiedzialności za efekty wykorzystania ich; nie gwarantuje
Kierownik produkcji: Marta Kurpiewska marta@software.com.pl także poprawnego działania programów shareware, freeware i public domain. Uszkodzone podczas wysyłki
Opracowanie graficzne: Robert Zadrożny robert.zadrozny@software.com.pl płyty wymienia redakcja.
Skład i łamanie: Robert Zadrożny robz@software.com.pl
Projekt okładki: Agnieszka Marchocka Wszelkie znaki firmowe zawarte w piśmie są własnością odpowiednich firm i zostały użyte wyłącznie
Opracowanie CD: Aurox Core Team aurox@aurox.org w celach informacyjnych.
Opracowanie aktualności: Rafał Kocisz
Tłumaczenie: Rafał Kocisz Płyty CD dołączona do magazynu przetestowano programem AntiVirenKit firmy G DATA Software Sp. z o.o.
Korekta: Piotr Ozaist Redakcja używa systemu automatycznego składu
Stali współpracownicy: Stefan Turalski
Sprzedaż aktualnych lub archiwalnych numerów pisma po innej cenie niż wydrukowana na okładce
Betatesterzy: K. Boguś, K. Kokosa, Ł. Lechert, Ł. Witczak, M. Cylke, M. Mucha, R. Zacharczyk
– bez zgody wydawcy – jest działaniem na jego szkodę i skutkuje odpowiedzialnością sądową.
Dział reklamy: reklama@software.com.pl
Prenumerata: Marzena Dmowska pren@software.com.pl tel.: (22) 887 14 44
Nakład: 6 000 egz. Pismo ukazuje się w następujących wersjach językowych: polskiej , angielskiej .

4 www.sdjournal.org Software Developer’s Journal 01/2007


Warsztaty
GWT – WEB 2.0 na maksa 50
David de Rosier
David roztoczy przed nami kuszące możliwości Google Web Toolkit. Opisze
prace z projektami GTW, pisanie własnych komponentów oraz transfer kodu
Java na JavaScript.

Bazy Danych
Rozszerzenia środowiska bazodanowego Kexi 60
Jarosław Staniek
Jarek przedstawi rozszerzenia środowiska Kexi, które to narzędzie przekłada
łatwość tworzenia i rozwijania aplikacji bazodanowych nad bogactwo zaawan-
sowanych opcji.

Kluby techniczne
Progress Software Progress Sonic ESB 78
– tworzenie usług w środowisku
Progress Sonic Workbench
Artykuł przybliży pojęcia związane z usługami ESB oraz zaprezentuje w jaki
sposób stworzyć nową klasę usług przy uzyciu Progress Sonic Workbench.

Magic eDeveloper 80
Biblioteka Miesiąca – zadaniowe podejście do programowania
Artykuł przybliży ideę stosowania zdarzeniowego podejścia do programowania.

Quartz – zarządzanie zadaniami w J2SE/J2EE 16


Piotr Anioła
Piotr przedstawi otwartą bibliotekę wspomagającą harmonogramowanie
zadań, którą można zintegrować z dowolną aplikacją J2EE lub J2SE. Pokaże
nam jak budować proste i złożone harmonogramy.

Aplikacje Biznesowe
e-Poltax 26
Janusz Ganczarski
Janusz przedstawi w artykule budowę i funkcjonowanie aplikacjii elekronicz-
nych na podstwie elektronicznych formularzy rozliczeń podatkowych (PIT)
systemu e-Poltax.

Business Process Execution Language 36


Piotr Skrobisz
Piotr zapozna nas z podstawami i najczęściej używanymi elementami języka
Oracle Business Process Execution Language.

Programowanie w Java
Aplikacje Java w telewizji interaktywnej 44
Tomasz Kuprowski
Tomasz przedstawi w artykule wykorzystanie Javy w telewizji interaktywnej.
Pokaże w jaki sposób napisać zananą wszystkim grę Snake.

Software Developer’s Journal 01/2007 www.sdjournal.org 5


Aktualności www.sdjournal.org

Microsof t nawiązuje Firefox 2

P
współpracę z Zend Technologies o długim i burzliwym okresie
Microsoft zawarł porozumienie z Zend Technolo-
gies – firmą odpowiedzialną za rozwijanie języka oczekiwania Mozilla wypuściła
PHP. Współpraca między obydwoma firmami ma stabilną wersję swojej sztandaro-
opierać się przede wszystkim na podejmowaniu
działań mających na celu zwiększenie integra- wej, otwartej przeglądarki Firefox, ozna-
cji języka PHP z takimi platformami jak Win- czonej wersją 2.0. Nowy Lisek w porów-
dows Server 2003 oraz Windows Server code-
name Longhorn. Owocem tego przedsięwzięcia naniu do poprzedniej wersji (1.5.0.7)
ma stać się również wzbogacenie funkcjonalno- wnosi całkiem sporo nowości. Pierw-
ści języka w odniesieniu do technologii Micro-
softu. Jak dotychczas Zend skupiał uwagę jedy-
sze, co rzuca się w oczy to odświeżony
nie na rozwiązaniach otwartych, przez co PHP interfejs użytkownika i nowa domyślna
był dedykowany głównie do współpracy z ser- skórka. Prócz tego mamy do dyspozy-
werem Apache. W momencie zawarcia poro-
zumienia, firmy zadeklarowały zmodyfikować cji wbudowaną ochronę przed stronami
i usprawnić swoje produkty w taki sposób, aby służącymi do kradzieży danych poprzez na przeczytać w blogu Beltznera. Prze-
jeszcze lepiej mogły one ze sobą współpra-
cować. Microsoft ma stworzyć między innymi podszywanie się pod inne witryny (na glądarka Mozilla Firefox 2.0 przebojowo
nowy składnik FastCGI dla wbudowanego przykład banków czy systemów aukcyj- weszła na rynek, niestety, pojawiły się
w Windows Server 2003 serwera IIS, który zin-
tegruje IIS i PHP. Składnik ten będzie dostępny
nych). Firefox może weryfikować strony też problemy rzucające cień na ten suk-
na stronie www.iis.net dla użytkowników Win- z wewnętrzną listą lub odpytywać Go- ces. Dla przykładu serwis listvine.com
dows XP, Windows Server 2003, Windows Vista ogle. Wbudowana wyszukiwarka posia- wymienia powody, które mogą postawić
oraz Widnows Server codename Longhorn.
Zend będzie z kolei opracowywał w swoim labo- da teraz funkcję podpowiedzi (działają- migrację z wersji 1.5 na 2.0 pod zna-
ratorium nowe wersje PHP oraz przygotowy- cą obecnie tylko w przypadku Google, kiem zapytania. Wielu użytkownikom
wał je do działania na platformie serwerowej
Microsoft. Planowane jest także dostosowanie Yahoo! i Answers.com), automatycznie nie spodobał się nowy interfejs, który
produktów Zend Technologies (między innymi uzupełniającą wpisywane przez nas fra- uznano za mało ergonomiczny. Funk-
Zend Core) do współpracy z Windows Server,
aby zoptymalizować działanie aplikacji PHP
zy, uproszczono także dodawanie no- cje antyphishingowe są dosyć proste
oraz przeprowadzać testy wydajnościowe. Jak wych wyszukiwarek. Poprawiono obsłu- a ponadto mogą stanowić zagrożenie
widać plany są bardzo ambitne, oraz co ważne gę kart, każda karta posiada przycisk dla prywatności. Często pojawiają się
– korzystne dla obu stron: Microsoft zdobędzie
nowych odbiorców dla swoich produktów, zaś zamykania, dostępna jest też wygodna problemy z kompatybilnością istnieją-
Zend może liczyć na zwiększone zainteresowa- lista wszystkich otwartych kart. Z menu cymi dodatkami. Firefox 2.0 na skutek
nie językiem PHP w gronie użytkowników plat-
formy Windows Server System. Historia mamy także dostęp do ostat- wycieku pamięci potrafi zajmować du-
http://betanews.com/ nio zamkniętych kart. Domyślnym za- żą ilość RAMu. Problem ten był często
chowaniem przeglądarki jest otwiera- zgłaszany przed wydaniem wersji final-
OpenBSD 4.0
Pojawiła się kolejna stabilna wersja dystrybucji nie stron w nowej karcie zamiast w no- nej. Występują problemy z obsługą CSS
typu UNIX z rodziny BSD: OpenBSD 4.0. System wym oknie. W przypadku awarii przeglą- co przeszkadza w wyświetlaniu niektó-
ten powstał powstał w 1995 roku jako efekt roz-
łamu w zespole NetBSD. Nowe OpenBSD to darki mamy możliwość przywrócenia se- rych stron. Firefoksowi 2.0 zdarza się
już 20 wydanie na płycie CD (21 udostępnio- sji, czyli otwartych stron, tekstu wpisa- zawiesić w losowych momentach. Użyt-
ne jest na serwerach FTP). Autorzy są bardzo
dumni z tej dystrybucji miedzy innymi dlatego,
nego w formularzach i aktualnie pobie- kownicy narzekają też na problemy z hi-
że przez 10 lat istnienia systemu odnotowano ranych plików. Bezpośrednio z poziomu storią, a także, gorszą niż w wersji 1.5,
tylko jedną dziurę w standardowym instalatorze. przeglądarki możemy podglądać kana- obsługą RSS. Z kolei SecurityFocus po-
W wersji 4.0 znajdziemy pokaźną listę popra-
wek, aktualizacji i nowości, z którymi można ły RSS i sprawdzać pisownię w polach daje, że krytyczna dziura wykryta przez
szerzej zapoznać się na przeznaczonej po temu tekstowych (także po polsku). Mene- Michała “lcamtufa” Zalewskiego istnie-
witrynie internetowej (http://www.openbsd.org/
plus40.html). Przedstawiona jest tam lista dżer zakładek rozszerzony został o tak je nadal w Firefoksie 2.0 mimo, że za-
wprowadzonych zmian w stosunku do ostatniej zwane mikro-podsumowania, czyli za- łatano ją w Firefoksie 1.5.0.5. Przykła-
stabilnej odsłony systemu oznaczonej numerem
3.9. Najnowszą wersję OpenBSD można pobrać
kładki w których zamiast tytułu wyświe- dy te, a także szybko wykrywane dziury
ze strony twórców. tlają się na bieżąco aktualizowane dane w Internet Explorerze pokazują, jak trud-
http://www.openbsd.org/ z treści strony. Nowy Firefox obsługuje nym zadaniem jest obecnie tworzenie
Google Code także język skryptowy JavaScript w wer- przeglądarek. Nie wystarczy samo prze-
Jam 2006 zakończone sji 1.7. Jak można przeczytać na blo- twarzanie kodu HTML; trzeba wspierać
Zakończył się tegoroczny konkurs programi- gu Mike'a Beltzner – dewelopera Fire- wiele standardów, rozszerzeń a przy tym
styczny Code Jam organizowany przez Google.
Zwyciężył dwudziestojednoletni Petr Mitrichev foxa – wersja 2.0 przeglądarki w ciągu cały czas pamiętać o bezpieczeństwie.
z Rosji, drugie miejsce zdobył Ying Wang z USA, pierwszych 24 godzin od wypuszczenia Wygląda na to, że chwilą wydania Fire-
trzeci był Andrey Stankevich, także z Rosji.
w wersji stabilnej została pobrana po- Fox 2.0 i Internet Explorera 7.0 wojna
Nagroda za pierwsze miejsce wyniosła 10 tysię-
cy dolarów, osoby które zajęły miejsca od dru- nad 2 miliony razy. Daje to średnią przeglądarek rozgorzeje na nowo, zaś
giego do dziesiątego dostały o połowę mniej. przekraczającą 30 ściągnięć na sekun- jej wyniki będą zależeć głównie od szyb-
Tegoroczna, czwarta edycja Code Jam zgroma-
dziła 21 tysięcy uczestników z ponad stu krajów. dę. Wynik ten jest bardzo dobry; dla kości wydawania łatek na dziury i błędy
Tysiąc osób zakwalifikowało się do dwuetapo- porównania największy konkurent Fi- zgłaszane przez użytkowników.
wych rozgrywek, z czego setka przeszła do ści-
słego finału, który odbył się w siedzibie firmy refox 2.0 – Internet Explorer 7 w cią-
w Nowym Jorku. Uczestnicy w zależności od wła- gu pierwszych 4 dni od premiery odno- http://www.slashdot.org/
snych preferencji programowali w języku Java,
tował trochę ponad 3 mln pobrań. Jest http://www.beltzner.ca/mike/
C++, C#, Python lub VB.NET.
http://www.google.com/ to zapewne ciekawy materiał do analizy http://listvine.com
i przemyśleń – więcej na ten temat moż- http://www.securityfocus.com

6 www.sdjournal.org Software Developer’s Journal 01/2007


www.sdjournal.org

Ubuntu 6.10 Edgy Eft Microsof t walczy

Z
godnie z zapowiedziami ukazała z piractwem na aukcjach
Firma Microsoft rozpoczęła akcję przeciwko
się kolejna wersja najpopularniej- osobom sprzedającym nielegalne oprogramowa-
szej dystrybucji Linuksa – Ubun- nie na internetowych aukcjach. Przygotowano już
50 pozwów, z czego 15 złożono w Stanach Zjed-
tu 6.10 Edgy Eft. Nowe Ubuntu to przede noczonych, 10 w Niemczech i Holandii, a po pięć
wszystkim nowa wersja środowiska GNO- we Francji i Wielkiej Brytanii. Dodatkowe sprawy
zostały złożone także w Polsce, Argentynie,
ME (2.16), oba projekty są ściśle ze so- Australii, Belgii i Korei. Akcja przeciwko aukcjom
bą związane, można pokusić się o stwier- jest kolejnym krokiem szeroko zakrojonej kampa-
nii przeciwko piratom. Według szacunków organi-
dzenie, że to właśnie w tym systemie GNO- zacji Business Software Alliance, około jedna trze-
ME najlepiej prezentuje swoje możliwo- cia instalowanego oprogramowania jest nielegal-
ści. Pierwszą rzucającą się w oczy nowo- na. Z przeprowadzonych przez Microsoft testów
wynika, że prawie połowa aukcji sprzedających
ścią jest odświeżony wygląd ikon systemo- programy firmy Microsoft oferuje nielegalne opro-
wych, a także poprawa szybkości działania klienta poczty Evolution (2.8.0), pakiet biu- gramowanie. Firma Microsoft ostrzega też, że
w wielu przypadkach sprzedawane produkty są
środowiska i wchodzących w jego skład rowy OpenOffice 2.0.4 RC2 i betę komu- zarażane wirusami, trojanami i innymi szkodni-
narzędzi. Nowe GNOME lepiej zarządza nikatora Gaim 3.1. Do dyspozycji mamy kami. Od czerwca 2005 roku ponad 500 milio-
nów użytkowników uruchomiło na swoich kompu-
energią, co w laptopach pozwala na dłuż- także najnowszą wersję przeglądarki Fire- terach narzędzie do sprawdzania legalności (Win-
szą pracę na baterii, a dodatkowo w pane- fox 2.0. Jedną z istotniejszych zmian w no- dows Genuine Advantage). Spośród nich, 21 pro-
lu ustawień dostępny jest wykres, z które- wym Ubuntu jest Upstart. Jest to nowocze- cent systemów zostało zidentyfikowane jako nie-
legalne.
go łatwo można zorientować się na ile pra- sny zamiennik procesu init, który mówiąc http://www.cnet.com/
cy starczy prądu. Nowe narzędzie Baobab w dużym uproszczeniu odpowiada za uru-
pozwoli usprawnić kontrolę wolnego miej- chamianie wszystkich innych procesów w
Vista za droga dla
sca na dysku. Osoby niewidome z pewno- systemie. Init jest rozwiązaniem wywodzą-
producentów komputerów
Gigant z Redmond wyraził sprzeciw wobec sprze-
ścią ucieszą się z nowego czytnika ekra- cym się jeszcze z czasów początków Linuk- dawania przedsiębiorstwom domowych wersji
nowego Orca używającego technologii AT- sa i mimo wielu poprawek niezbyt dobrze systemów operacyjnych. Sprzedawcy sprzętu
komputerowego w celu minimalizacji kosztów
SPI. Przeglądarka WWW Epiphany posia- radzi sobie na przykład z dynamicznie pod- proponują klientom zakup tańszej, ale wystar-
da funkcję sprawdzania pisowni w polach łączanymi urządzeniami. Ubuntu jest pierw- czającej do prowadzenia małej firmy, domowej
wersji oprogramowania. Różnica cenowa między
tekstowych, a wbudowana nagrywarka płyt szym systemem w którym został wdrożony domową i biurową wersją systemu operacyj-
CD ma już możliwość bezpośredniego na- Upstart. Najnowszą wersję Ubuntu Edgy nego Windows XP waha się od 25 do 50 USD.
W przypadku nowej Visty, różnica ta ma być dużo
grywania DVD. Odnośnie kwestii specy- Eft 6.10 można pobrać ze strony twórców. wyższa, bo sięgająca aż 100 USD. W ofercie
ficznych dla Ubuntu to dla wydania Edgy Kolejne Ubuntu (wersja 7.04) ma ukazać firmy Microsoft znajdą się trzy wersje domowe
Eft przygotowano nowy schemat graficz- się 19 kwietnia 2007, będzie nosiło nazwę oraz dwie biurowe nowego systemu. Producent
oprogramowania zapowiedział, że będzie kładł
ny, obejmujący wygląd środowiska, okna The Feisty Fawn. większy nacisk na odpowiednie dopasowanie
logowania, tapetę, skórkę dla Firefoksa, danej wersji do jego zastosowania. Microsoft
zamierza zlikwidować lukę rynkową, powodo-
a także ekran pokazywany podczas star- http://www.ubuntu.com/ waną przez próbujących obniżyć koszty sprzętu
tu systemu. W nowym Ubuntu znajdziemy https://wiki.ubuntu.com/ sprzedawców i wymusić dostarczanie biurowych
wersji oprogramowania do firm, a wersji domo-
domyślnie zainstalowany system notatek EdgyReleaseNotes/ wych do prywatnych użytkowników.
Tomboy, program do zarządzania zdjęcia- http://kubuntu.org/ http://www.4press.pl/
mi F-spot, nową wersję rozbudowanego http://www.edubuntu.org/

R E K L A M A
Aktualności www.sdjournal.org

Więzienie i grzywny za torrenty IE7

P
Jak donosi serwis CDRInfo.pl, po raz pierwszy
w historii do więzienia trafiła osoba za prowa- o długich pracach Microsoft
dzenie strony z plikami torrent. Mimo, iż strona udostępnił do pobrania finalną
nie zawierała żadnych plików naruszających
prawa autorskie, a tylko pliki z informacją skąd wersję swojej flagowej przeglą-
je pobrać sąd uznał administratora winnym. darki webowej: Internet Explorer 7. Naj-
Wyrok to 5 miesięcy więzienia plus 5 miesięcy
dozoru domowego i 3.000 grzywny dla 23-let- nowsza wersja tej jak dotąd najpopular-
niego Granta Stanleya z USA. Stanley przyznał niejszej na świecie przeglądarki inter-
się do winy. Jest jednym z trzech oskarżonych
w wyniku akcji FBI i MPAA. Podobna sprawa ma
netowej przynosi wiele nowości. Naj-
równolegle miejsce w Finlandii. W ciągu trzech ważniejszą z nich jest bardzo długo wy-
miesięcy roku 2004 za pomocą strony Finreac- czekiwana i niezwykle przydatna możli- nych w formacie PNG. Najnowszego In-
tor użytkownicy wymienili 29.625 terabajtów
danych. 16.000 gier, 136.000 filmów, 274.000 wość przeglądania wielu witryn z pozio- ternet Expolrera 7 można pobrać z pol-
albumów z muzyką... Czterech administratorów mu jednego okna aplikacji. Właściwość skiej witryny firmy Microsoft. Na stro-
strony Finreactor przyznało się do winy. Zosta-
li ukarani grzywnami w wysokości 60.000 dola- ta zwana potocznie obsługą zakładek nie tej można znaleźć również pełne in-
rów każdy. Kolejnych 21 administratorów zosta- od bardzo dawna dostępna była w pro- formacje o nowej przeglądarce, w tym
ło uznanych winnymi przez sąd w Finlandii. Będą
musieli zapłacić odszkodowania w wysokości
duktach konkurencji. Kolejne uspraw- instrukcję instalacji. Na razie nie wia-
700.000 dolarów. Sprawy kolejnych osób nadal nienia to zmieniony i uproszczony in- domo dokładnie kiedy zostanie wyda-
się toczą – oskarżonych zostało łącznie 32 terfejs zapewniający więcej powierzch- na wersja polskojęzyczna. Microsoft na
administratorów fińskiej strony.
http://cdrinfo.pl/ ni na wyświetlanie witryn (szczególnie blogu IE7 ujawnił nieco statystyk doty-
w trybie pełnoekranowym, dostępnym czących pobrań nowej przeglądarki In-
MTS 2006 po wciśnięciu klawisza F11), zintegro- ternet Explorer 7. Tylko w ciągu czte-
Zakończył się Microsoft Technology Summit
2006 – największa tegoroczna konferencja tech- wany czytnik wiadomości nadawanych rech pierwszych dni nową przeglądar-
niczna Microsoft w Polsce, kierowana do specja- przy pomocy kanałów RSS, zintegro- kę pobrało ponad trzy miliony użytkow-
listów IT i programistów. Dla wszystkich, którzy
nie mieli okazji uczestniczyć w tym wydarzeniu wane okienko wyszukiwarki, ulepszo- ników! Wynik jest z pewnością imponu-
osobiście organizatorzy przygotowali transmisje ne drukowanie dzięki automatyczne- jący, a będzie prawdopodobnie jeszcze
na żywo w Internecie, z wybranych sesji konfe-
rencji. Podczas tegorocznej, drugiej już edycji mu dopasowywaniu wielkości tekstu, większy gdy Internet Explorer 7 zacznie
konferencji Microsoft Technology Summit, funkcje anty-phishingowe zabezpiecza- być dystrybuowany wraz z bieżącymi
odbyło się 114 sesji technicznych i 9 bizneso-
wych pokrywających aż 9 obszarów tematycz-
jące przed kradzieżą osobistych da- poprawkami systemowymi w ramach
nych, stanowiących przekrój przez wszystkie nych i kradzieżą tożsamości, udosko- automatycznych aktualizacji.
technologie Microsoftu. Sesje były prowadzone nalona obsługa stylów CSS 2.1. No-
przez 86 najlepszych ekspertów z Polski i zagra-
nicy. Wśród prelegentów byli między innymi wa wersja przeglądarki obsługuje po- http://www.microsoft.com/poland/
Rafał Łukawiecki (ekspert w dziedzinie bezpie- nadto przezroczystość plików graficz- http://blogs.msdn.com/ie/default.aspx
czeństwa IT, wybrany najlepszym wykładowcą
konferencji jak IT Forum i TechEd 2005), oraz
Fred Baumhardt – wybitny konsultant do spraw
bezpieczeństwa firmy zatrudniony w Microsof- Google Code Search

F
cie. W konferencji uczestniczyło ponad 2500
osób. Uczestnicy korzystali z laboratorium irma Google uruchomiła no-
wyposażonego w ponad 70 komputerów, sieci wą usługę Google Code Search
WiFi, a także salonu multimedialnego Windows
Media Center. Patrząc na ogromne zaintereso- umożliwiającą przeszukiwanie
wanie środowiska konferencją, którego efektem kodu źródłowego dostępnego w Inter-
jest ponad 2500 zarejestrowanych uczestni-
ków, można stwierdzić, że wydarzenie to ma już necie. Serwis ten pozwala między in-
ugruntowaną pozycję w kalendarzu imprez tech- nymi na znalezienie fragmentów ko-
nologicznych odbywających się w Polsce.
http://wss.pl/
du, w których można precyzyjnie okre-
ślić rodzaj licencji i język programowa-
Wyniki finansowe Microsof tu nia. Dodatkowo umożliwia stosowanie
wyższe od spodziewanych wyrażeń regularnych (wspierana jest
Microsoft opublikował swoje wyniki finansowe
za pierwszy kwartał roku fiskalnego 2007 (trzeci rozszerzona składnia wyrażeń regular- wy kompleksowego zestawu serwisów
kwartał roku kalendarzowego 2006). Korpora- nych POSIX), ciągów znaków czy nazw dedykowanych dla tego właśnie środo-
cja odnotowała 11-procentowy wzrost zarów-
no obrotów jak i zysków w stosunku do analo- paczek. Użytkownicy nowej usługi mo- wiska. Na dzień dzisiejszy trudno prze-
gicznego okresu w roku poprzednim. Przycho- gą korzystać zarówno z uproszczone- widzieć powodzenie tego przedsięwzię-
dy wyniosły 10,8 miliarda dolarów w stosunku
go jak i zaawansowanego interfejsu wy- cia. Problem w tym, że rozwiązanie Go-
do prognozowanych 10,7 mld dolarów. Dochód
osiągnął poziom 3,48 mld dolarów. Na oprogra- szukiwania. Ponieważ rezultaty poszu- ogle będzie musiało wytrzymać konku-
mowaniu klienckim, na które składa się głównie kiwań dostępne są w formatach GData rencję istniejących już na rynku podob-
system Windows, Microsoft zarobił 2,6 miliarda
dolarów. Oprogramowanie serwerowe przynio- oraz XML feed, można spodziewać się, nych, lub pokrewnych rozwiązań – cho-
sło 827 milionów dolarów. Znaczący udział miał że niedługo powstaną wtyczki do IDE ciażby Krugle czy Planet Source Code.
tutaj SQL Server 2005. Dział usług online przy-
niósł 539 mln dolarów dochodu przy 136 milio- pozwalające korzystać z dobrodziejstw
nach dolarów straty. MS Office i oprogramowa- Google Code Search z wewnątrz tych http://www.google.com/codesearch
nie biznesowe wygenerowały przychody rzędu
aplikacji. Google Code Search jest http://www.google.com/codesearch/
3,4 miliarda dolarów. Sprzedaż w dziale Enter-
tainment and Devices wzrosła o 70%, głównie kolejnym ukłonem ze strony Google w advanced_code_search
dzięki konsoli Xbox. kierunku społeczności programistów, http://www.google.com/help/faq_code-
http://wss.pl/
a jednocześnie świadczy o próbie budo- search.html

8 www.sdjournal.org Software Developer’s Journal 01/2007


www.sdjournal.org

Rewolucyjna współpraca Microsoft i Novell Konferencja Adobe MAX 2006

F
23-26 października w Las Vegas odbyła się pierw-
irmy Microsoft Corporation i Novell nie opracują ofertę w dziedzinie wirtualizacji sza konferencja od czasu połączenia Adobe
Inc. poinformowały o zawarciu sze- systemów Windows i Linux. Usługi Web se- z Macromedią. W spotkaniu wzięli udział specja-
liści i pasjonaci z całego świata. Głównym tema-
regu umów dotyczących działalności rvices i architektura zorientowana na usługi tem była technologia Apollo, będąca rozszerze-
i współpracy technicznej. Umowy te przewi- ciągle są podstawowym sposobem zapew- niem technologii Flex, oraz nakreślenie przyszłości
i kierunku rozwoju Adobe. Apollo jest projektem,
dują opracowanie serii nowych rozwiązań niania korzyści klientom przez firmy z bran- który pozwoli uruchamiać Rich Internet Applica-
usprawniających współdziałanie produk- ży oprogramowania. W tym kontekście Mi- tions (RIA) na każdym komputerze bez pośrednika
jakim obecnie jest przeglądarka internetowa. Pre-
tów firm Novell i Microsoft, wprowadzenie crosoft i Novell podejmą prace nad ułatwie- zenterzy poruszali także kwestię technologii Flash
ich na rynek oraz oferowanie odpowiedniej niem klientom zarządzania mieszanymi śro- Lite na urządzenia mobilne oraz inne nadchodzą-
pomocy technicznej. Przedsiębiorstwa pod- dowiskami systemów Windows i SUSE Li- ce produkty. Podczas imprezy zostały także rozda-
ne nagrody MAX 2006. W ciągu trzech dni odbyło
pisały również porozumienie, które gwaran- nux Enterprise oraz uproszczeniem łącze- się aż 100 warsztatów i zajęć praktycznych.
tuje klientom prawo do korzystania z obję- nia usług katalogowych Microsoft Active Di- http://www.adobe.com/
http://www.adobe.com/events/max/
tych patentami elementów oprogramowa- rectory z oprogramowaniem Novell eDirec-
nia każdej z tych firm. Umowy będą obowią- tory. Obydwie firmy chcą się również skon- Monachium pomyślnie
zywać przynajmniej do 2012 r. Nowy model centrować na poprawieniu zgodności mię- migruje na Linuksa
współpracy Microsoftu z Novellem zapew- dzy aplikacjami biurowymi współpracując Stolica Bawarii jest w zaawansowanej fazie migra-
cji 80% komputerów administracji publicznej na
ni klientom niespotykane wcześniej możli- nad najlepszymi sposobami współużytko- Linuksa. Proces ten rozpoczął się 3 lata temu,
wości wyboru i elastyczność dzięki lepszej wania dokumentów przez użytkowników pa- zaś termin jego zakończenia planowany jest na
2008 rok. Burmistrz miasta, Christine Strobel,
zgodności operacyjnej systemów Windows. kietów OpenOffice i Microsoft Office. Ujaw- powiedziała, że jest zadowolona z dotychczaso-
Dzięki porozumieniu z Microsoftem Novell niono również plany opracowania mechani- wych wyników. Podkreśliła dużą łatwość z jaką
odbywa się migracja. Do końca roku 2008 zdecy-
uzyska znaczną przewagę nad innymi pro- zmów translacji mających poprawić zgod- dowana większość komputerów będzie pracować
ducentami systemu Linux i oprogramowa- ność operacyjną między formatami Open pod kontrolą klienta LiMux. Jeśli wszystko przebie-
nia open source, w odniesieniu do zgod- XML i OpenDocument. Proces integracyjny gnie pomyślnie, w ciągu dwóch lat migrację przej-
dzie większość z 14 tysięcy komputerów. Migracja
ności operacyjnej środowisk o mieszanym obejmie również platformy deweloperskie pokazuje łatwość przejścia na Linuksa pod kątem
dostępie do kodu źródłowego. Microsoft Mono i .NET. Microsoft i Novell urucho- zastosowań biurowych. Okazuje się, że chociaż
użytkownicy musieli zmienić niektóre swoje przy-
będzie oficjalnie zalecać system SUSE Li- mią placówkę badawczą, w której specja- zwyczajenia, to obyło się to bez większych proble-
nux Enterprise klientom wdrażającym roz- liści obu firm będą projektować i testować mów. Nie trzeba było też wielu szkoleń, czego się
początkowo obawiano. Szkolenia obejmują 38%
wiązania oparte na systemach Windows oprogramowanie. Specjaliści są zdania, że z 35 milionów euro przeznaczonych na migrację.
i Linux, oraz dystrybuować kupony na usłu- nawiązanie współpracy Microsoftu z Novel- Wykorzystywana jest dystrybucja Debian GNU/
gi utrzymania i pomocy technicznej do sys- lem to punkt zwrotny w procesie populary- Linux 3.1, środowisko graficzne KDE 3.5 oraz
pakiet biurowy OpenOffice 2.0. Wilhelm Hoegner,
temu SUSE Linux Enterprise Server. Klienci zacji systemu Linux, a jednocześnie krok szef miejskiego działu IT uważa, że jak dotąd
będą więc mogli odnosić korzyści zarówno milowy w procesie eliminowania konfliktów udana migracja na Linuksa nie stanie się prędko
wzorem dla innych miast. Choć Monachium ściśle
z używania zgodnej operacyjnie wersji sys- między producentem Okienek a społeczno- współpracuje na tym polu z Wiedniem i Paryżem,
temu Linux bez naruszania prawa patento- ścią open source. to rządzący w innych miastach politycy wciąż zbyt
mało wiedzą o otwartym oprogramowaniu.
wego, jak i z efektów wspólnej pracy obu http://www.heise.de/
przedsiębiorstw. Microsoft i Novell wspól- http://7thguard.net

R E K L A M A
Aktualności www.sdjournal.org

Tort dla Firefoksa NetBeans 5.5

O
Twórcy Internet Explorera przysłali programistom
Firefoksa tort z okazji wydania przez nich wersji statnimi czasy na rynku IDE dla
2.0 otwartej przeglądarki. Programiści Firefoksa platformy Java liczą się tak na-
za prezent podziękowali i zdementowali pogłoski
mówiące o tym, jakoby tort był zatruty. prawdę tylko dwaj gracze. Mo-
http://fredericiana.com/2006/10/24/from-red- wa tu oczywiście o otwartych projek-
mond-with-love/
tach Eclipse i NetBeans. Obydwa przed-
Zniknie największy sięwzięcia mają zarówno swoich zwo-
bazar z piratami lenników jak i przeciwników, i można
Warszawski Stadion X-lecia zostanie zlikwidowa- powiedzieć, że wzajemnie się napędza-
ny, a w jego miejscu powstanie nowoczesny kom-
pleks sportowy. Oznacza to likwidację funkcjonu- ją. Dla programistów Javy jest to nie-
jącego na terenie Stadionu targowiska o dumnej wątpliwie komfortowa sytuacja – nie ma
nazwie "Jarmark Europa". Będzie to tym samym
koniec handlu pirackimi płytami prowadzonego nic lepszego niż zdrowa konkurencja.
w tym miejscu na olbrzymią skalę. Na funkcjonu- Po silnym natarciu ze strony Eclipse Ca-
jącym od 1989 roku, na terenie Stadionu X-lecia,
targowisku handluje około 5 tys. podmiotów
listo przyszła kolej na uderzenie ze stro-
gospodarczych. Większość sprzedawanych towa- ny NetBeans. I tak, po długim okresie
rów to odzież i obuwie, nie jest jednak tajemnicą, oczekiwania projekt NetBeans docze-
że można tam również bez większego problemu
kupić pirackie płyty z oprogramowaniem, grami, kał się wypuszczenia kolejnej stabilnej
filmami czy muzyką. Jak dotąd próby ukrócenia wersji oznaczonej numerem 5.5. Odsło- nych aplikacji webowych czy nawet apli-
tego procederu przypominały walkę z wiatraka-
mi. Choć Policja przeprowadziła na terenie Stadio- na ta oferuje szereg nowych możliwo- kacji J2SE. Dodatkowo NetBeans silnie
nu szereg nalotów, a ilość zarekwirowanych pirac- ści, przy czym główny nacisk położono wspiera technologię EJB 3.0, integruje
kich nagrań liczy się już w dziesiątkach milionów
sztuk, to handel nielegalnymi płytami trwa w naj-
na wsparcie technologii Java EE 5, Web się z API języka Java do obsługi serwi-
lepsze. Likwidacja targowiska choć z pewnością services oraz Ajax. Twórcy NetBeans sów webowych, a także udostępnia re-
nie rozwiąże definitywnie problemu nielegalnego nie ukrywają, że ich głównym celem by- wolucyjny zestaw narzędzi do budowa-
handlu nośnikami w stolicy, będzie jednak niewąt-
pliwie poważnym ciosem dla piratów działających ło odciążenie w pracy programistów nia aplikacji GUI w oparciu o bibliotekę
tam na wielką skalę. J2EE. Poniżej przedstawimy kilka udo- Swing. Dodatkowa, ukryta moc pakietu
http://www.msport.gov.pl/
godnień oferowanych przez to rozwiąza- leży w jego rozszerzeniach. Dla przykła-
Google: wirtualny potentat nie. Jeśli chodzi o podstawowe wspar- du rozszerzenie Mobility Pack uważane
Użytkownicy Internetu zdają sobie sprawę, że
cie dla J2EE 5, to warto wspomnieć in- jest za jedno z najlepszych środowisk
Google to potężna firma. Mało kto jednak w pełni
pojmuje prawdziwą skalę tej potęgi. Szacuje się, tegrację NetBeans z Sunowskim Serwe- do tworzenia aplikacji J2ME. Nowością
iż obecna wartość Google to ok. 147 mld USD. rem Aplikacji Glassfish, kompletowanie jest rozszerzenie Enterprise Pack – udo-
Tym samym ta 8-letnia firma przewyższa giganta
o niemal stuletniej tradycji: firmę IBM (139 mld). kodu oraz integrację z dokumentacją stępniana tam funkcjonalność wywo-
Inni giganci Internetu dalece odstają od Google: API oferowanych przez J2EE 5, wspar- dzi się z komercyjnego rozwiązania for-
eBay (45 mld), Yahoo (32 mld), Amazon (14 mld).
Na wyobraźnię działa jeszcze bardziej porówna- cie dla technologii Servlet 2.5, JavaSe- my Sun: Java Studio Enterprise. Kluczo-
nie Google z gigantami motoryzacyjnymi, których rver Pages 2.1, JavaServer Faces 1.2 wymi możliwościami oferowanymi przez
wartość na nowojorskiej giełdzie znacznie odbie-
oraz wbudowane przykłady J2EE. W ra- to rozszerzenie jest zaawansowana ob-
ga od wirtualnego potentata: DaimlerChrysler
(54 mld USD), General Motors (20 mld), Ford (15 mach wsparcia dla mechanizmów skła- sługa XML (włącznie z refaktoringiem)
mld). Oczywiście Google nie wytrzymuje jeszcze dowania NetBeans potrafi generować i UML. NetBeans 5.5 udostępnia jeszcze
konkurencji z największym potentatem IT; wartość
Microsoft na giełdzie sięga obecnie 279 mld USD. klasy Javy z istniejących schematów całe krocie innych udogodnień – szczegó-
http://www.pap.com.pl/ baz danych i odwrotnie – na bazie klas łowe informacje na ten temat można zna-
Współpraca Novella zbudowanych z poziomu IDE można ge- leźć na domowej witrynie projektu. Jedno
i British Telecommunications nerować warstwę DB (NetBeans wyko- jest pewne – programiści innych języków
Novell zawarł z gigantem świata telekomunikacji, rzystuje w tym przypadku technologię mogą zazdrościć deweloperom Javy jed-
firmą British Telecommunications porozumienie, DB-from-Java oferowaną przez Glass- nego – świetnych, darmowych rozwiązań
które dotyczy zarządzania profilami i cyfrową toż-
samością milionów klientów uruchamianej przez fish). Co ciekawe, silnik NetBeans od- typu IDE – czego NetBeans 5.5 jest ide-
BT sieci nowej generacji o nazwie 21CN. W ramach powiedzialny za składowanie potra- alnym przykładem.
porozumienia dwa strategiczne produkty Novella,
wieloplatformowe usługi katalogowe Novell eDirec- fi działać bez serwera aplikacji, dzięki
tory oraz zaawansowane rozwiązanie do zarządza- czemu można dołączać go do zwyczaj- http://www.netbeans.org/
nia tożsamością Novell Identity Manager, zapew-
nią obsługę oraz ochronę bazy profili i tożsamości
http://www.artima.com/forums/flat.jsp?
w sieci 21CN. Technologie Novella umożliwią zaofe- forum=276&thread=182775
rowanie klientom BT spersonalizowany sposób zin-
tegrowanego zarządzania transmisją głosu, danych
i usług szerokopasmowych, świadczonych na rzecz
komunikacji mobilnej, transmisji wideo na żąda-
nie i usług teleinformatycznych takich jak bezprze-
wodowy dostęp do sieci Wi-Fi czy obsługa wirtu-
alnych sieci prywatnych VPN. Według wypowiedzi
wysoko postawionych pracowników Novella, pro-
gram 21CN jest pierwszym etapem wprowadzania
nowatorskich rozwiązań firmy BT na całym świecie.
Pozwoli on udostępnić usługi telekomunikacyjne
nowej generacji klientom w Wielkiej Brytanii oraz
w wielu innych krajach.
http://www.novell.pl/

10 www.sdjournal.org Software Developer’s Journal 01/2007


Zawartość
CD-ROM

Turbo Delphi for .NET oraz Turbo C#

W
poprzednim numerze Software Developer’s Jour-
nal (12/2006) przedstawiliśmy Turbo Delphi i Turbo
C++, dwa pierwsze z czterech nowych środowisk
programistycznych firmy Borland. Obecnie zajmiemy się śro-
dowiskami przeznaczonymi dla platformy .NET - Turbo Delphi
for .NET oraz Turbo C#.
Każde ze środowisk Turbo dostępne jest w dwóch wer-
sjach Explorer i Professional. Narzędzia w wersji Explorer są
bezpłatne, niezależnie od sposobu jego wykorzystania (edu-
kacyjnego, komercyjnego, domowego). Są one w pełni funk-
cjonalne, lecz nie można w nich zainstalować dodatkowych
komponentów.
Wersje Turbo nie do końca są nową linią produktów.
W rzeczywistości jest to uproszczona wersja bardziej zaawan-
sowanego pakietu Borland Developer Studio 2006. Jedną
z różnic jest liczba wbudowanych kompilatorów. BDS 2006 za-
Rysunek 1. Turbo Delphi for .NET oraz Turbo C#
wiera cztery języki programowania, Delphi, Delphi .NET, C++,
w wydajnym środowisku RAD
C#, a wersje Turbo zawierają tylko jeden z nich.
Turbo Delphi for .NET oraz Turbo C# służą do tworzenia tego o model UML (tzw. model driven development) dzięki śro-
aplikacji typu desktop oraz aplikacji sieciowych dla platfor- dowisku ECO III. Możliwe jest tworzenie usług sieciowych, apli-
my .NET Framework w wersji 1.1. Pierwsze z nich pozwala na kacji ASP.NET oraz aplikacji webForms opartych na platformie
wykorzystanie języka Delphi do tworzenia rozwiązań dla Win- ECO. Wbudowana funkcja dwukierunkowego projektowania
Forms, VCL.NET i ASP.NET, drugie służy do tworzenia apli- pozwala wprowadzać zmiany do modelu UML i obserwować
kacji dla technologii WinForms i ASP.NET z wykorzystaniem efekty w kodzie źródłowym i na odwrót. Obiekty tworzone pod-
języka C#. Oba narzędzia pozwalają na tworzenie usług sie- czas działania aplikacji opartej o platformę ECO można zapi-
ciowych .NET, serwerów i klientów .NET Remoting oraz kom- sać w pliku XML dzięki wbudowanej funkcji mapowania mode-
ponentów dla WinForms oraz ASP.NET (a w Turbo Delphi for lu obiektowego na strukturę relacyjną. W przyszłości aplikacja
.NET także komponentów dla VCL.NET). taka może być dalej rozwijana w BDS 2006 (w wersji Enterpri-
Środowiska Turbo skracają proces programowania dzię- se lub wyższej), gdzie istnieje możliwość składowania obiektów
ki zastosowaniu wielu ułatwień dla programistów, w tym: dy- w serwerach SQL. Zarówno Turbo Delphi for .NET jaki i Tur-
namicznych szablonów, refaktoryzacji, uzupełnień kodu, ana- bo C# pozwalają na tworzenie kompletnych modeli klas UML,
liz kodu i uzupełnień bloków. Dostarczany zbiór komponentów a następnie konwertowanie ich na kod źródłowy. Wprowadze-
pozwala na tworzenie różnorodnych aplikacji oraz, co warto nie zmian do kodu źródłowego prowadzi do zaktualizowania
podkreślić, aplikacji bazodanowych. Ponadto środowiska Tur- modelu. Przy okazji automatycznie powstaje dokumentacja
bo w wersjach Professional można rozbudować o komponenty aplikacji w postaci diagramów UML.
własne, komponenty pochodzące od firm trzecich oraz dodatki Wykorzystanie technologii ASP.NET pozwala tworzyć
do środowiska IDE. Turbo Delphi for .NET oraz Turbo C# łączą w pełni funkcjonalne dynamiczne witryny internetowe zawiera-
wydajne środowisko RAD, łatwość dostępu do danych i wydaj- jące dane z serwerów SQL oraz powiązane z danymi elemen-
ne wzorce z ulubionym językiem programowania, zapewniając ty ASP.NET sterujące dostępem do tych informacji. Ponadto
wydajność oraz elastyczność w tworzeniu aplikacji klienckich dostępne jest alternatywne rozwiązanie nazwane IntraWeb for
dla serwerów oraz aplikacji sieciowych. Zawarty w pakietach .NET, w którym można tworzyć interaktywne serwisy WWW.
Borland Data Provider (BDP) pozwala łączyć się z serwerami
baz danych InterBase, mySQL, Microsoft SQL Server i Access. Właściwości Turbo Delphi for .NET
BDP zapewnia zarządzany dostęp do danych poprzez wpro- (wersje Explorer i Professional)
wadzenie i abstrakcję interfejsów ADO.NET co oznacza, że dla Język ikompilator
wielu baz danych wystarczy napisać jeden kod.
Turbo Delphi for .NET oraz Turbo C# umożliwiają popra- • Możliwość tworzenia aplikacji w wydajnym, nowoczesnym ję-
wienie kodu przy wykorzystaniu kilkunastu automatycznych zyku obiektowym Delphi - pochodnej języka Object Pascal;
funkcji refaktoryzacji, takich jak zadeklarowanie zmiennej, wy- • Wysoko wydajny zarządzany kompilator kodu Delphi dla
łączenie metody i wiele innych funkcji pomocnych w zarzą- Microsoft .NET Framework 1.1.
dzaniu hierarchiami klas. Rozszerzalne i adaptowalne „dyna-
miczne szablony” (Live Templates) ułatwiają tworzenie wspól- Szkielety i pakiety SDK
nych części kodu, funkcja uzupełniania bloku (Block Comple-
tion) dba o prawidłowe uporządkowanie kodu, a zintegrowa- • VCL.NET do szybkiego rozwoju aplikacji Borland Develo-
ne środowisko IDE przyspiesza programowanie, uzupełniając per Studio dla Microsoft .NET Framework 1.1 – z pełnym
identyfikatory Użytkownika oraz znajdując dla nich odpowied- szybkim projektowaniem wizualnym;
nie metody, właściwości i funkcje. Narzędzia umożliwiają pro- • .NET Windows Forms 1.1 z pełną funkcjonalnością szyb-
gramistom tworzącym aplikacje wykorzystanie podejścia opar- kiego projektowania wizualnego;

12 www.sdjournal.org Software Developer’s Journal 01/2007


Zawartość
CD-ROM

• Możliwość tworzenia i instalacji nowych komponentów Szkielety i pakiety SDK


open source i komercyjnych (tylko wersja Turbo Delphi for
.NET Professional); • .NET Windows Forms 1.1 z pełną funkcjonalnością szyb-
• Microsoft .NET Framework SDK 1.1. kiego projektowania wizualnego
• Możliwość tworzenia i instalacji nowych komponentów
Zintegrowane środowisko rozwoju open source i komercyjnych (tylko wersja Turbo C# Pro-
fessional)
• W pełni funkcjonalny Projektant formularzy bibliotek VCL.NET • Foundation Class Library (FCL) 1.1 – ponad 4500 klas ob-
z wizualnymi wskaźnikami położenia obiektów, pełną obsługą fitujących w funkcjonalność: XML, dostęp do danych, po-
techniki przeciągania i upuszczania i Inspektorem obiektów do bieranie plików, regularne wyrażenia, tworzenie obrazów,
adaptacji komponentów i interfejsów użytkownika; monitorowanie parametrów i logowanie, transakcje, kolej-
• Wydajny Edytor kodów przyspiesza programowanie dzięki kowanie komunikatów, poczta SMTP, itd.
wykorzystaniu dynamicznych szablonów oraz funkcji pod-
świetlania elementów składni, uzupełniania klas, pomocy Zintegrowane środowisko programistyczne
i analizy błędów, uzupełniania kodu, adaptowalnego przy-
pisywania klawiszy i refaktoryzacji; • Wydajny Edytor kodów przyspiesza programowanie
• Debugowanie kodu z dostępem do najniższego poziomu dzięki wykorzystaniu dynamicznych szablonów oraz
w ramach zintegrowanego środowiska rozwoju; funkcji podświetlania elementów składni, uzupełniania
• Wbudowane funkcje testowania w środowiskach DUnit i Nunit. klas, pomocy i analizy błędów, uzupełniania kodu, ada-
ptowalnego przypisywania klawiszy i refaktoryzacji;
Rozwój i dostępność baz danych: • Debugowanie kodu z dostępem do najniższego poziomu
w ramach zintegrowanego środowiska rozwoju;
• Eksplorator baz danych z interfejsem dbExpress i obsługą • Projektant oparty na języku UML i platformie modelowania
techniki przeciągania i upuszczania; wizualnego Together;
• InterBase 7.5.1 Developer Edition – maksymalnie 20 użyt- • Wbudowane funkcje testowania w środowisku Nunit.
kowników i 80 logicznych połączeń lokalnych;
• Sterownik dostępu do lokalnej bazy danych Borland Data Rozwój i dostępność baz danych;
Provider (BDP) dla baz Borland InterBase 7.5 i MySQL.
• Eksplorator baz danych ze źródłem Borland Data Provider
Rozwój aplikacji internetowych/sieciowych i obsługą techniki przeciągania i upuszczania;
• Pełna obsługa ADO.NET 1.1 z .NET Framework;
• Pełna obsługa ASP.NET 1.1 z projektantem formularzy, • InterBase 7.5.1 Developer Edition – maksymalnie 20 użyt-
edytorem etykiet i modelem kodu zakulisowego; kowników i 80 logicznych połączeń lokalnych;
• Szybkie tworzenie witryn internetowych techniką WYSI- • Sterownik dostępu do lokalnej bazy danych Borland Da-
WYG w narzędziu IntraWeb v8.0 (tylko wersja Turbo Del- ta Provider (BDP) dla baz Borland InterBase 7.5 i My-
phi for .NET Professional); SQL.
• Komponenty Internet Direct (Indy) zapewniające do-
stęp do wszystkich głównych protokołów internetowych, Rozwój aplikacji internetowych/sieciowych;
a w tym TCP/IP, HTTP, POP3, SMTP, UDP, FTP, Gopher,
Finger, MAP4, NNTP, Telnet oraz Whois dla serwerów • Pełna obsługa ASP.NET 1.1 z projektantem formularzy,
i klientów (tylko wersja Turbo Delphi for .NET Professional). edytorem etykiet i modelem kodu zakulisowego;
• Szybkie tworzenie witryn internetowych techniką WYSI-
Modelowanie w środowisku Borland Together WYG w narzędziu IntraWeb v8.0 (tylko wersja Turbo C#
Professional).
• W pełni dwukierunkowe diagramy klas LiveSource;
• Modelowanie w języku UML; Modelowanie w środowisku Borland Together
• Tworzenie dokumentacji.
• W pełni dwukierunkowe diagramy klas LiveSource;
Aplikacje oparte o model UML: • Modelowanie w języku UML;
• Tworzenie dokumentacji.
• Wbudowane funkcje dwukierunkowego modelowania, mapo-
wania obiektowego i relacyjnego oraz automatycznego utrwa- Aplikacje oparte o model UML
lania obiektów. Możliwość zapisania obiektów i danych w ba-
zie danych XML lub w korporacyjnych bazach danych. • Wbudowane funkcje dwukierunkowego modelowania,
mapowania obiektowego i relacyjnego oraz automatycz-
Właściwości Turbo C# (wersje Explorer i Professional) nego utrwalania obiektów pomocne w tworzeniu klas
Język i kompilator: Microsoft Visual C#, wersja 1.1 – zarzą- i baz danych. Możliwość zapisania obiektów i danych
dzany kompilator kodu dla .NET w bazie danych XML lub w korporacyjnych bazach danych.

Software Developer’s Journal 01/2007 www.sdjournal.org 13


Zawartość
CD-ROM

TrustPort Internet Gateway 4.5

W
dzisiejszym świecie coraz więcej zależy od obie-
gu informacji w sieci. Wszystkie znaczące fir-
my mają dostęp do internetu i posiadają sieć w
swojej firmie – jest to ich główne źródło wymiany informa-
cji przechowywania danych itp. Jakiekolwiek niepożądane
oprogramowanie typu spyware, spam, wirusy, robaki inter-
netowe itd. może spowodować dotkliwe straty finansowe i
bezcenne straty w postaci utraty danych ważnych dla danej
korporacji. Oczywiście można założyć „Mnie ten problem
nie dotyczy, nie będę wydawał pieniędzy niepotrzebnie”.
Nic bardziej błędnego – rozprzestrzenianie się niepożąda-
nego oprogramowania w internecie jest na porządku dzien-
nym i prędzej czy później dotknie każdego. Przykładem tu
może być odbieranie codziennie spamu ze skrzynki poczto-
Rysunek 2. Skaner antywirusowy podczas pracy
wej. Tutaj naprzeciw wychodzi Czeska firma AEC która ofe-
ruje swój najnowszy produkt TrustPort Internet Gateway i Internet Gateway. I tutaj również zostałem miło zaskoczony
TrustPort Servers – który miałem przyjemność testować. obszernymi możliwościami tego narzędzia. Pierwsza rzecz
Jest to kompletny pakiet do ochrony komputera przed wszel- jaka rzuca się w oczy to bardzo czytelny interface w którym
kim niepożądanym oprogramowaniem internetowym, spamem, widać trzy zakładki : E-mail, Web, Common.
spyware i wirusami. Całość pakietu składa się z dwóch części: Zakładka E-mail odpowiada za ochronę poczty. Pierw-
TrustPort Internet Gateway – odpowiedzialnej za ochronę poczty szą rzeczą jaką trzeba zrobić jest skonfigurowanie ustawień
i internetu oraz TrustPort Server – dodatkowe narzędzia, w skład poczty. Następnie można przejść do dostępnych opcji –
których wchodzi antywirus i firewall (klucz do pobrania ze strony możliwości mamy bardzo wiele, między innymi: konfigurację
http://www.sdjournal.org/pl/01_2007.php). antywirusa dla poczty, konfigurację ustawień anty-spamo-
Po instalacji pakietu – która jest bardzo prosta i czytel- wych takich jak czarna, szara i biała lista adresów e-mail,
na, musimy poświęcić chwilę na odpowiednie skonfiguro- filtr Bayesa, który analizuje zawartość wiadomości i stwier-
wanie oprogramowania. Pierwszą rzeczą, na którą zwróci- dza czy dana wiadomość jest spamem czy nie. Inne to: Ima-
łem uwagę, był skaner TrustPort Antivirus (otrzymał w paź- ge Checker – wykrywa spam, który ma postać obrazka, Re-
dzierniku 2006 ocenę Virus Bulletin 100%), który poza pod- gular phrases filter – wyszukuje teksty typowe dla spamu,
stawowymi możliwościami skanowania dysków twardych i Public RBL and DSBL lists – jest to publiczna czarna lista
napędów, posiada również możliwość skanowania rejestru. z informacjami o spamerach. Oczywiście są też inne opcje,
Wielkim plusem jest możliwość obszernej konfiguracji ska- ale nie sposób je tu wszystkie opisać.
nera i jego wszelkich opcji. Z czystej ciekawości i przeska- Zakładka Web odpowiada za ochronę komunikacji inter-
nowałem swój dysk i byłem bardzo pozytywnie zaskoczo- netowej. Tutaj również najpierw trzeba skonfigurować usta-
ny kiedy zobaczyłem rezultaty – zostały usunięte wszelkie wienia i następnie przejść do dostępnych opcji takich jak:
szkodliwe pliki, których inne skanery nawet nie pokazywa- dodawanie zaufanych adresów URL oraz blokowaniedostę-
ły jako zagrożenie. Następnie przyszedł czas na TrustPort pu do niepożądanych adresów. Mamy również możliwość
ustawienia antywirusa dla internetu oraz inne narzędzia
do kontroli. Ostatnia zakładka to Common, w której mamy
możliwość ustawienia antywirusa i wszystkich innych usług.
Następnym dostępnym narzędziem jest TrustPort Servers,
który może pomóc w rozwiązaniu problemu wirusów i spy-
ware znajdujących się w różnych dokumentach i plikach roz-
syłanych za pomocą sieci. W skład TrustPort Server wcho-
dzą: Server Antivirus i Server Firewall.
Pakiet firmy AEC udostępnia nam bardzo szeroką możli-
wość konfigurowania skutecznego sposobu ochrony naszego
komputera i sieci przed wszelkim szkodliwym oprogramowa-
niem. W mojej ocenie pakiet sprawdził się bardzo dobrze. Jak
będzie u innych? Zapraszam do sprawdzenia.

Jacek Łapiński

TTS Company Sp. z o.o.


ul. Słowicza 53
02-170 Warszawa
Rysunek 1. Okno konfiguracyjne narzędzia TrustPort Internet tel. (022) 868-40-42
Gateway http://www.OprogramowanieKomputerowe.pl

14 www.sdjournal.org Software Developer’s Journal 01/2007


II część multimedialnego kursu na Microsoft Certified System Administration – CD 2
Lekcja 1. Opisuje instalację Microsoft SQL Servera 2000. Oprócz Lekcja 3. Opisuje zarządzanie rolami i uprawnieniami z nimi związa-
tego pokazane są podstawowe narzędzia do administrowania bazą nymi. Nauczymy się też tworzyć skrypty przywracające dane i upraw-
danych takie jak: Enterprise Manager czy SQL Query Analyzer. nienia w bazie danych, a także urządzenia archiwizujące. Sprawdzi-
Lekcja 2. Opisuje zarządzanie bazą danych i jej właściwościa- my też spójność bazy danych czy stworzymy kopię różnicową.
mi. Nauczymy się tworzyć grupy plików, dodawać i usuwać pliki Lekcja 4. Opisuje tworzenie nowych tabel i zarządzanie prawa-
z danymi i logami, a także ustawiać grupę domyślną. Na koniec mi dostępu do nich. Nauczymy się także wykorzystywać na róż-
poznamy tajniki administracji hasłami i kontami użytkowników. ne sposoby polecenie select.
Biblioteka

miesiąca

Quartz - zarządzanie
Piotr Anioła
zadaniami w J2SE / J2EE
Z
Materiały do artykułu biblioteką Quartz po raz pierwszy na poważ-
zamieszczone zostały
na płycie CD 1
nie spotkałem się w 2004 roku podczas pro- Zawartość katalogu /quartz-1.5.2/
jektowania modułu programu lojalnościowego
na platformie J2EE. Na zakończenie każdego miesiąca • docs/api – Javadoc API dla Quartz;
• docs/dbTables – skrypty do założenia tabel Quartz
podliczane były punkty i na tej podstawie system wy-
w bazie danych;
syłał żądania gratyfikacji do innego modułu. W uprosz-
• docs/wikidocs – główna dokumentacja Quartz (za-
czeniu problem sprowadzał się do tego, aby aplikacja cznij od index.html);
wykonała zadania w określonym czasie lub w określo- • examples – przykłady użycia biblioteki;
nych odstępach czasu bez interakcji z użytkownikiem. • lib – biblioteki wykorzystywane przez Quartz;
Oczywiście, jak zazwyczaj, problem można było • src – kod źródłowy.
rozwiązać na kilka sposobów. Po pierwsze mogliśmy to
zaimplementować sami, na przykład korzystając z klas
java.util.Timer lub java.util.TimerTask dodanych w Ja- Quartz pozwala aplikacji na zaplanowanie zdarzeń
va SDK 1.3. Jednak, klasy te są zaledwie zalążkiem te- (ang. events), które powinny pojawić się w określo-
go co oczekiwałoby się od pełnej biblioteki do planowa- nym punkcie (ang. trigger point) czasu. Wywołanie
nia zadań, a w dodatku wymagałoby to sporo czasu, zdarzenia oznacza w tym przypadku uruchomienie
którego jak zwykle brakuje w napiętym harmonogramie mniejszego podprogramu (ang. job) w tle, bez inte-
projektu. Na koniec implementacja takiej biblioteki nie rakcji z użytkownikiem, niezależnie od innych zadań
jest wcale trywialnym zadaniem i wymaga sporej wie- aktualnie przetwarzanych przez główną aplikację.
dzy o programowaniu wątków w Java. Stosowanie mechanizmu planowania zdarzeń
Dobrze, w takim razie najzwyczajniej można było jest nieodzowne dla całej gamy przedsięwzięć in-
zakupić gotowy komercyjny produkt i problem z głowy. formatycznych, poczynając od dużych komercyj-
Po co wyważać otwarte drzwi? Niestety budżet tego nych rozwiązań korporacyjnych (ang. enterprise),
nie przewidywał i w tym przypadku słusznie, ponieważ a kończąc na małych samodzielnych (ang. stand-
doskonałą alternatywą okazała się być darmowa biblio- alone) aplikacjach lub narzędziach do monitorowa-
teka Quartz, którą postaram się poniżej przybliżyć. nia i utrzymania systemów. Wśród typowych zasto-
sowań biblioteki Quartz można wymienić:
O bibliotece
Projekt Quartz został założony przez James House- • Tworzenie różnego rodzaju raportów. Często wy-
'a w 1988. W 2001 roku trafił na SourceForge jako pro- generowanie skomplikowanego sprawozdania wy-
jekt typu Open Source i od tamtej pory stopniowo za- maga przeszukania wielu źródeł danych i naraża
czął skupiać wokół siebie sporą grupę doświadczonych użytkownika na długotrwałe oczekiwanie na wynik.
programistów. Po pewnym czasie został przeniesiony W takim przypadku lepszym podejściem może oka-
na witrynę http://www.opensymphony.com/quartz/ pro- zać się uruchomienie w nocy zadania polegające-
jektu OpenSymphony, skąd można ściągnąć jego naj- go na wypełnieniu tymczasowego widoku raportu.
nowsze wydanie (artykuł jest oparty na wersji numer Dzięki temu część aplikacji odpowiedzialna za ra-
1.5.2). Tak wygląda w skrócie tło historyczne z burzli- portowanie działa bardziej dynamicznie, co pozwa-
wych dziejów rozwoju biblioteki (bardziej dociekliwym la uniknąć skarg sfrustrowanego użytkownika;
czytelnikom polecam Changelog projektu). • Ciągłe testowanie i monitorowanie systemów
Quartz pozwala programistom korzystać z za- w celu utrzymania jakości świadczonych usług;
let programowania zdarzeniowego i świetnie wypeł- • Wysyłanie przypomnień lub ostrzeżeń na przykład
nia obszar jaki przez długi czas pozostawał zanie- poprzez email lub SMS. Typowym przykładem
dbany w specyfikacjach J2SE i J2EE. Dopiero ostat- jest tutaj codzienne sprawdzanie czy ważność ha-
nio w specyfikacji EJB 2.1 pojawiły się pierwsze ja- seł użytkowników wkrótce nie wygaśnie i powiado-
skółki w postaci Timer Services. W szczególności mienie ich o tym kilka dni przed unieważnieniem.

Autor tekstu pracuje obecnie w firmie BLStream na Do podstawowych zalet biblioteki należy możliwość:
stanowisku Techniczny Kierownik Projektu. Od ponad
10 lat zajmuje się zarządzaniem projektami, projektowa- • uruchamiania Quartz zarówno w ramach samo-
niem i implementacją systemów komputerowych. dzielnej aplikacji J2SE, jak i serwera aplikacji J2EE;
Kontakt z autorem: piotr.aniola@blstream.com. • uruchamiania Quartz jako samodzielnego progra-
mu wywoływanego poprzez RMI;

16 www.sdjournal.org Software Developer’s Journal 1/2007


Quartz

Oczywiście Quartz nie jest kryształem bez skazy. Jego zale-


Wymagane/Opcjonalne biblioteki zewnętrzne ty i wady postaram się przybliżyć w kolejnych punktach niniej-
używane przez Quartz szego artykułu. Na początek spróbujmy uruchomić krótki pro-
gram typu Hello World aby zapoznać się z podstawowymi me-
• activation.jar – opcjonalna, głównie używana przez JavaMail; chanizmami biblioteki.
• commons-beanutils.jar – wymagana;
• commons-collections-3.1.jar – wymagana; Przygotowanie środowiska
• commons-dbcp-1.2.1.jar – wymagana, jeśli zadania przecho- Do uruchomienia naszego pierwszego przykładu potrzebna bę-
wujemy w bazie danych;
dzie oczywiście wirtualna maszyna Java w wersji 1.3 lub wyż-
• commons-digester.jar – wymagana, jeśli używamy niektórych
szej. Zakładam, że czytelnik zna podstawowe technologie J2SE
wtyczek Quartz;
• commons-logging.jar – wymagana;
/ J2EE i ograniczę do minimum wyjaśnienia odnośnie tej materii.
• commons-pool-1.2.jar – opcjonalna; Link do ściągnięcia pakietu Quartz znajduje się na stronie domo-
• jdbc2_0-stdext.jar – wymagana, jeśli zadania przechowujemy wej biblioteki. W tym miejscu warto nadmienić, że wspomniany
w bazie danych; adres można znaleźć w ramce "W sieci". Pobrany plik możemy
• jta.jar – wymagana, jeśli zadania przechowujemy w bazie da- rozpakować, korzystając przykładowo z programu Java jar:
nych;
• log4j.jar – opcjonalna, ale praktycznie domyślnie wykorzysty- jar -xvf quartz-1.5.2.zip
wana do zapisu logów.
Po rozpakowaniu archiwum w bieżącym katalogu powstanie
Zwróćmy uwagę, że Quartz został zbudowany i przetestowany
w oparciu o określone wersje bibliotek zewnętrznych. Serwery apli-
katalog /quartz-1.5.2, którego pełną ścieżkę dostępu oznaczy-
kacji niejednokrotnie również są dostarczane z tymi samymi biblio- my nazwą QUARTZ_HOME. Podczas kompilacji naszych przy-
tekami, ale niekoniecznie w tej samej wersji. Dlatego należy zacho- kładów będziemy potrzebowali przede wszystkim binarną wer-
wać ostrożność podczas instalowania aplikacji Quartz na serwerach sję biblioteki Quartz (quartz-1.5.2.jar) oraz zewnętrzne biblioteki
aplikacji i unikać duplikowania bibliotek. umieszczone w podkatalogach katalogu QUARTZ_HOME/lib.

Hello World
• uruchamiania Quartz w architekturze klastrowej; W pierwszym przykładzie zaimplementujemy proste zada-
• wywoływania zadań w określonym punkcie czasu (z do- nie, polegające na wpisywaniu tekstu „Hello World!” do logów.
kładnością do milisekund) lub z określoną częstotliwością Zgodnie z naszymi ustawieniami, Quartz będzie uruchamiał to
(wykorzystując podobną semantykę jak popularne narzę- zadanie co minutę. Podczas implementacji przykładu będzie-
dzie UNIX Cron); my korzystać z następujących kluczowych klas i interfejsów
• przechowywania stanu zadań w relacyjnej bazie danych biblioteki umieszczonych w pakiecie org.quartz :
pomiędzy kolejnymi uruchomieniami programu;
• rozszerzania funkcjonalności dzięki zastosowaniu me- • interfejs Job − reprezentuje zadanie, które chcemy urucho-
chanizmu wtyczek (plug-in) oraz interfejsów typu liste- mić;
ners monitorujących lub kontrolujących działanie biblio- • klasa JobDetail − reprezentuje szczegółowe informacje
teki; o właściwościach konkretnej instancji zadania (Job );
• uruchamiania na wielu różnych platformach dzięki imple- • klasa JobDataMap − przechowuje informacje o stanie in-
mentacji w języku Java. stancji zadania;

Listing 1. Zadanie HelloWorldJob

package listing1; // Zapisz do logów, o której uruchomiono zadanie


import java.util.Date; logger.info(jobDetail.getName() +
import org.apache.commons.logging.Log; " uruchomiony o " + new Date());
import org.apache.commons.logging.LogFactory; // Parametry zadania są przechowywane w JobDataMap
import org.quartz.Job; JobDataMap jobDataMap = context.getMergedJobDataMap();
import org.quartz.JobDataMap; String invitation = jobDataMap.getString("POWITANIE");
import org.quartz.JobDetail; // Sprawdź wymagane parametry
import org.quartz.JobExecutionContext; if (invitation == null) {
import org.quartz.JobExecutionException; throw new JobExecutionException(
// Przykład Hello World. "Parametr POWITANIE nie ustawiony" );
public class HelloWorldJob implements Job { }
private static final Log logger = LogFactory.getLog( // Wykonaj właściwą część zadania, czyli zapisz powitanie
HelloWorldJob.class); // do logów
public void execute(JobExecutionContext context) logger.info(invitation);
throws JobExecutionException { }
// Szczegóły o zadaniu pobierz z klasy JobDetail }
JobDetail jobDetail = context.getJobDetail();

Software Developer’s Journal 1/2007 www.sdjournal.org 17


Biblioteka
miesiąca

• klasa abstrakcyjna Trigger − reprezentuje mechanizm, parametr przechowujący tekst powitania. Na zakończenie meto-
który pozwala na planowanie zadań. Określa kiedy i z jaką dy execute() pozostaje już tylko wypisanie tekstu powitania do
częstotliwością ma być uruchamiane zadanie; logów. Mamy już zadanie, więc zobaczmy jak można je urucho-
• interfejs Scheduler − reprezentuje główny interfejs progra- mić. Do tego celu wykorzystamy mechanizm Quartz Scheduler.
mu do planowania zadań Quartz. Program ten zarządza re- Listing 2 pokazuje podstawowe kroki potrzebne do utworzenia
jestrem instancji JobDetail i Trigger, a po rozpoczęciu dzia- i uruchomienia obiektu typu Scheduler. Zadania można planować
łania jest odpowiedzialny za wywoływanie zadań (Job ) zaini- w sposób programowy lub deklaratywny. Listing 2 przedstawia
cjowanych w momencie określonym przez związane z nimi pierwszy ze sposobów. Obiekt Scheduler, po pobraniu z StdSche-
obiekty typu Trigger. dulerFactory, jest przesyłany jako argument do metody schedule-
Job(), która odpowiada za powiązanie tego obiektu z zadaniem
Przykład zaczniemy od utworzenia klasy zadania HelloWorl- HelloWorldJob. W następnym kroku tworzony jest obiekt JobDe-
dJob. Każde zadanie musi implementować interfejs org.qu- tail dla zadania typu HelloWorldJob. W obiekcie tym rejestruje-
artz.Job, co w praktyce sprowadza się do wypełnienia jednej my obiekt JobDataMap służący do przesłania w parametrze "PO-
metody o nazwie execute(): WITANIE" tekstu powitania. Do szczęścia potrzebny nam jest już
tylko obiekt Trigger, który poinformuje Scheduler o tym aby uru-
public void execute(JobExecutionContext context) chamiał zadanie co minutę, od bieżącego czasu, bez określenia
throws JobExecutionException; czasu zakończenia. Do utworzenia obiektu Trigger wykorzysta-
na została klasa użytkowa TriggerUtils, która udostępnia wiele
Kiedy Quartz Scheduler ustali, że nadszedł już czas na urucho- przydatnych metod upraszczających tworzenie i konfigurowanie
mienie zadania, tworzy odpowiednią instancję typu Job i wywo- obiektów Trigger. Na zakończenie pozostało tylko zarejestrowa-
łuje metodę execute(). Scheduler wywołując zadanie nie spodzie- nie obiektów typu Job i Trigger oraz uruchomienie instancji Sche-
wa się żadnych informacji zwrotnych poza wyjątkiem JobExecu- duler. Zanim uruchomimy nasz przykład potrzebujemy jeszcze
tionException w przypadku wystąpienia błędu. Na Listingu 1 po- dwóch plików konfiguracyjnych. Jeden z parametrami bibliote-
kazany jest kod źródłowy naszego przykładowego zadania. Pod- ki Quartz (Listing 3), drugi z parametrami biblioteki log4j do za-
czas wywołania metody execute() Quartz przesyła kontekst Jo- pisu logów (Listing 4). Oba pliki powinny znajdować się w miej-
bExecutionContext, który zawiera wiele cennych informacji o śro- scu dostępnym podczas uruchomienia dla mechanizmu class lo-
dowisku uruchomieniowym biblioteki, programie Scheduler, in- ader'a Java (na przykład w katalogu WEB-INF/classes dla apli-
stancji zadania oraz klasy rozpoczynającej zadanie (Trigger). kacji WEB J2EE). Parametry biblioteki Quartz powinny być za-
W szczególności JobExecutionContext udostępnia referencję do pisane w pliku o nazwie quartz.properties. W pliku tym moż-
klasy JobDetail. na skonfigurować wiele różnych aspektów Quartz. Domyślne
Z klasy JobDetail można odczytać wiele cennych informacji wartości wymaganych parametrów są ustawione w pliku qu-
o zadaniu jak na przykład nazwę zadania lub nazwę grupy, do artz.properties umieszczonym w pakiecie JAR biblioteki Qu-
której zadanie należy. JobExecutionContext zawiera również od- artz. W przykładzie ustawione są następujące parametry:
wołanie do JobDataMap. Klasa JobDataMap przechowuje parame-
try zdefiniowane przez użytkownika, skonfigurowane dla danego • org.quartz.scheduler.instanceName − nazwa instancji
zadania. W naszym przykładzie z obiektu JobDataMap pobieramy Scheduler. W naszym przykładzie jest „QuartzSchedu-

Listing 2. Uruchomienie przykładu Hello World

package listing1; }
import java.util.Date; }
import org.apache.commons.logging.Log; // Utwórz i zaplanuj HelloWorldJob
import org.apache.commons.logging.LogFactory; private void scheduleJob(Scheduler scheduler)
import org.quartz.*; throws SchedulerException {
import org.quartz.impl.StdSchedulerFactory; // Utwórz JobDetail dla zadania
// Przykład Hello World. JobDetail jobDetail = new JobDetail("HelloWorldJob",
public class Listing2 { Scheduler.DEFAULT_GROUP, HelloWorldJob.class);
private static final Log logger = LogFactory.getLog( // Ustaw tekst powitania
Listing2.class); obDetail.getJobDataMap().put("POWITANIE",
public static void main(String[] args) { "Hello World!");
Listing2 listing2 = new Listing2(); // Utwórz trigger, który jest uruchamiany co minutę
try { Trigger trigger = TriggerUtils.makeMinutelyTrigger();
// Utwórz i uruchom Scheduler trigger.setName("helloWorldTrigger");
Scheduler scheduler = // Uruchom trigger od teraz
StdSchedulerFactory.getDefaultScheduler(); trigger.setStartTime(new Date());
listing2.scheduleJob(scheduler); // Połącz trigger z zadaniem w Scheduler
scheduler.start(); scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException ex) { }
logger.error(ex); }

18 www.sdjournal.org Software Developer’s Journal 1/2007


Quartz

Listing 3. quartz.properties dla przykładu Hello World Listing 4. log4j.properties dla przykładu Hello World
#Konfiguracja parametrów głównego programu Scheduler log4j.rootLogger=error, stdout # Utwórz appender stdout
org.quartz.scheduler.instanceName = QuartzScheduler # Konfiguracja stdout
org.quartz.scheduler.instanceId = AUTO log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#Konfiguracja ThreadPool log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
org.quartz.threadPool.threadCount = 5 log4j.appender.stdout.layout.ConversionPattern=%5p
org.quartz.threadPool.class = [%t] (%F:%L) - %m%n
org.quartz.simpl.SimpleThreadPool # Wypisz wiadomości poziomu INFO lub wyższego
#Konfiguracja JobStore # dla przykładu Hello World
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore log4j.logger.listing1=INFO

ler”. W konfiguracji klastrowej instancje powinny mięć ne na konsolę. W logach pojawią się wiadomości z poziomu
unikalną nazwę; ERROR , jedynie dla naszego przykładu w logach mogą pojawić
• org.quartz.scheduler.instanceId − identyfikator instancji się wiadomości z poziomu INFO lub wyższego.
Scheduler. W konfiguracji klastrowej ta wartość powinna Po uruchomieniu przykładu na konsoli powinniśmy ujrzeć
być również unikalna; zapis podobny do przedstawionego na Listingu 5.
• org.quartz.threadPool.threadCount − określa ile wątków
jest utworzonych i dostępnych do obsługi zadań; Deklaratywne definiowanie zadań
• org.quartz.threadPool.class − określa klasę obsługującą Oprócz programowego podejścia, Quartz pozwala również na
pulę wątków o stałym rozmiarze, implementującą interfejs deklaratywne zaplanowanie zadań w zewnętrznym pliku XML.
org.quartz.spi.ThreadPool. Dostarczona w bibliotece Quartz Jest to zalecane podejście, ponieważ zmiana ustawień w pli-
klasa org.quartz.simpl.SimpleThreadPool powinna spełnić ku XML nie wymaga ponownej kompilacji kodu źródłowego. Qu-
potrzeby większości użytkowników. Jest możliwe, że w przy- artz, podobnie jak inne popularne biblioteki, udostępnia mecha-
szłości dostarczona zostanie nowa implementacja puli wąt- nizm wtyczek, które pozwalają na rozszerzanie jego możliwości.
ków oparta na wprowadzonych niedawno koncepcjach w Ja- Do deklaratywnej konfiguracji zadań można użyć klasy org.qu-
va 1.5 w klasie java.util.concurrent.ThreadPoolExecutor; artz.plugins.xml.JobInitializationPlugin. Domyślnie wyszuku-
• org.quartz.jobStore.class − określa jak obiekty typu Job je ona plik o nazwie quartz_jobs.xml w ścieżce classpath Java,
i Trigger są przechowywane podczas cyklu działania instan- a następnie ładuje informacje o zadaniach i czasie ich urucho-
cji Scheduler. Wartość org.quartz.simpl.RAMJobStore ozna- mienia z pliku XML. Wtyczki w Quartz rejestrujemy w pliku qu-
cza, że obiekty te będą przechowywane w pamięci RAM i in- artz.properties używając następnującej konwencji:
formacja o ich stanie jest tracona po zatrzymaniu działania
instancji Scheduler. org.quartz.plugin.<nazwa wtyczki>.class=
<pełna nazwa klasy wtyczki>
W drugim z plików konfiguracyjnych log4j.properties ustawio- org.quartz.plugin.<nazwa wtyczki>.
ne jest, że podczas działania programu logi będą zapisywa- <nazwa parametru wtyczki>=<wartość>

R E K L A M A
Biblioteka
miesiąca

Listing 6 przedstawia przykład dla JobInitializationPlugin.


Podane parametry mają następujące znaczenie: Licencja
Biblioteka Quartz jest zupełnie darmowa, dostępna na licencji Apache Li-
• overWriteExistingJobs − określa, czy zadania zdefiniowane
cense 2.0. Jedyną rzeczą, o której w praktyce należy pamiętać jest dołą-
w XML mają nadpisać już istniejące o tej samej nazwie, czenie jej kopii do naszego produktu. Pełny tekst licencji można przeczy-
• failOnFileNotFound − określa, czy inicjalizacja wtyczki po- tać pod adresem: http://www.apache.org/licenses/LICENSE-2.0.
winna zakończyć się wyjątkiem w przypadku nie znalezie-
nia pliku XML,
• validating − określa, czy struktura pliku XML powinna być Szczegółowy opis formatu wyrażenia znajduje się w JavaDoc
zweryfikowana. API klasy org.quartz.CronExpression.
Przykładowo, skonfigurowanie Triggera, który będzie wy-
Pozostało nam jeszcze zapoznanie się ze strukturą samego pli- woływał zadanie co 10 minut, pomiędzy godzianami 9:00 i 16:
ku quartz_jobs.xml. Listing 7 przedstawia definicję zadań dla 00 od poniedziałku do piątku, wygląda następująco :
przykładu Hello World. Element <job> reprezentuje zadanie, któ-
re chcemy zarejestrować w mechanizmie Scheduler Quartz. Za- CronTrigger cTrigger = new CronTrigger
wartość tagów <job-detail> i <trigger> odpowiada parametrom ("myTrigger", Scheduler.DEFAULT_GROUP,
ustawionym programowo w przytoczonym powyżej przykładzie "0 0/10 9-16 ? * MON-FRI");
Listing 2, w metodzie scheduleJob(). Oczywiście jest możliwe
zdefiniowanie wielu zadań w jednym pliku XML. Oczywiście tę samą konfigurację można zadeklarować w pliku
quartz_ jobs.xml w tagu <trigger>. Pokazuje to Listing 8.
Trigger Ostatni z listy − NthIncludedDayTrigger − został niedaw-
W Quartz wyróżniamy trzy rodzaje Trigger'ów: no dodany do biblioteki. Pozwala na wywołanie zadania n-te-
go dnia w zadanych interwałach czasu. Na przykład wywoła-
• org.quartz.SimpleTrigger; nie zadania każdego 10-tego dnia miesiąca wymaga zdefinio-
• org.quartz.CronTrigger; wania Triggera w następujący sposób:
• org.quartz.NthIncludedDayTrigger.
NthIncludedDayTrigger nTrigger =
Pierwszy z nich został zaprojektowany z myślą o zadaniach, któ- new NthIncludedDayTrigger
re powinny być rozpoczęte w określonym momencie i powtarzać ("MyTrigger", Scheduler.DEFAULT_GROUP);
się n razy w pewnych odstępach czasu. Poniższy fragment kodu nTrigger.setN(10);
przedstawia Trigger, który rozpocznie pracę od razu, a następnie nTrigger.setIntervalType
będzie uruchamiany co minutę, aż do zakończenia programu: (NthIncludedDayTrigger.
INTERVAL_TYPE_MONTHLY);
Trigger trigger = new SimpleTrigger
("myTrigger", Scheduler.DEFAULT_GROUP, new Date(), Dodatkowym udogodnieniem w Quartz są klasy implemen-
null, SimpleTrigger. tujące interfejs org.quartz.Calendar. Pozwalają one na zablo-
REPEAT_INDEFINITELY, 60000L); kowanie wywołania zadań w pewnych zadanych przedziałach
czasu, na przykład w dni wolne od pracy. Biblioteka dostarcza
CronTrigger pozwala na znacznie bardziej skomplikowane pla- kilka gotowych implementacji w pakiecie org.quartz.impl.ca-
nowanie zadań. Format wyrażenia Quartz Cron jest bardzo lendar, na przykład HolidayCalendar. Listing 9 przedstawia
podobny do jego odpowiednika w Unix. Składa się z siedmiu fragment kodu z wykorzystaniem tej klasy.
elementów:
Użycie na platformie J2EE
<sekundy> <minuty> <godziny> Częstym problemem, z jakim spotykają się nowi użytkownicy bi-
<dzień miesiąca> <miesiąc> blioteki, jest sposób umieszczania i uruchamiania Quartz na plat-
<dzień tygodnia> <rok opcjonalnie> formie J2EE. Zasadniczo można wyróżnić dwie strategie. Pierw-
sza polega na wywołaniu Quartz jako standardowego klien-
Listing 5. Przykładowy zapis logów na konsoli dla ta J2SE poza kontenerem J2EE. Druga polega na umieszcze-
zadania Hello World niu Quartz w aplikacji Web (w pliku WAR) i uruchomieniu w ra-

INFO [QuartzScheduler_Worker-0] – Listing 6. Parametry dla JobInitializationPlugin w pliku


HelloWorldJob uruchomiony o Mon Sep 25 15:12:15 EDT 2006 quartz.properties
INFO [QuartzScheduler_Worker-0] - HelloWorld!
INFO [QuartzScheduler_Worker-0] – org.quartz.plugin.jobInitializer.class =
HelloWorldJob uruchomiony o Mon Sep 25 15:13:15 EDT 2006 org.quartz.plugins.xml.JobInitializationPlugin
INFO [QuartzScheduler_Worker-0] - HelloWorld! org.quartz.plugin.jobInitializer.overWriteExistingJobs =
INFO [QuartzScheduler_Worker-1] – true
HelloWorldJob uruchomiony o Mon Sep 25 15:14:15 EDT 2006 org.quartz.plugin.jobInitializer.failOnFileNotFound = true
INFO [QuartzScheduler_Worker-1] - HelloWorld! org.quartz.plugin.jobInitializer.validating=false

20 www.sdjournal.org Software Developer’s Journal 1/2007


Quartz

ną aplikacją, a nie dwoma. Poza tym zainstalowanie Quartz


Produkty pokrewne w aplikacji J2EE daje dostęp do zasobów oferowanych przez
serwer aplikacji, jak sesje z serwisem pocztowym, zdefiniowa-
• Flux Scheduler ne źródła danych lub adaptery do innych zasobów.
http://www.fluxcorp.com/;
Uruchomienie Quartz jako klienta J2EE jest trochę bardziej
• Enterprise Batching Queuing
skomplikowane, niż jako klienta J2SE. Wynika to częściowo
http://www.argent.com/p/qe/qe.html;
• Vexus consulting Avatar Job Scheduling Suite
z bardziej złożonego procesu konfigurowania aplikacji, ale rów-
http://www.vexus.ca; nież z faktu nałożenia pewnych ograniczeń w specyfikacji
• Oracle Scheduler J2EE na komponenty uruchamiane w ramach serwera aplikacji.
http://www.oracle.com/technology/products/database/ W szczególności to kontener odpowiada za zarządzanie zasoba-
scheduler/index.html; mi serwera, w tym za tworzenie nowych wątków. Natomiast Qu-
• Przykładowy opis programu Cron pod Linux artz sam zarządza pulą wątków Java. Dlatego ważne jest zacho-
http://www.linuxhelp.net/guides/cron/; wanie pewnych reguł, które zapewnią poprawne i stabilne dzia-
• Tutorial o Timer Services w EJB 3.0 łanie aplikacji. Załóżmy, że już mamy aplikację EAR z zaim-
http://java.sun.com/javaee/5/docs/tutorial/doc/Session4.html; plementowanymi komponentami EJB. Najprostszym sposo-
• JavaDoc klasy java.util.Timer
bem jest zbudowanie oddzielnego pliku Web WAR, który bę-
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html;
dzie zawierał wszystkie potrzebne pliki do uruchomienia za-
• JavaDoc klasy java.util.concurrent.ThreadPoolExecutor
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/
dań Quartz, a następnie umieszczenie go w aplikacji EAR.
ThreadPoolExecutor.html; W standardowej strukturze katalogów aplikacji Web należy
• OSWorkflow zadbać, aby znalazły się następujące pliki:
http://www.opensymphony.com/osworkflow/.
• web.xml (w /WEB-INF);
• quartz.properties (w /WEB-INF/classes);
mach aplikacji J2EE na serwerze. Pierwsze podejście stosuje- • quartz_ jobs.xml (w /WEB-INF/classes);
my najczęściej wtedy, gdy mamy już zdefiniowane komponen- • pliki binarne Quartz (w /WEB-INF/lib);
ty EJB i nie możemy wprowadzać zmian na serwerze. Pole- • wymagane biblioteki zewnętrzne (w /WEB-INF/lib).
ga ono na prostym wywołaniu serwisów EJB, poprzez ich in-
terfejsy Home i Remote, lub na utworzeniu i wstawieniu wiadomo- Listing 10 przedstawia deskryptor web.xml aplikacji Web.
ści JMS, która następnie jest przetwarzana przez odpowiedni Zawiera on konfigurację Listenera org.quartz.ee.servlet.Qu-
komponent MDB ( Message Driven Bean ). W przypadku wywoła- artzInitializerListener implementującego standardo-
nia komponentu EJB zalecane jest użycie klasy zadania org.qu- wy interfejs javax.servlet.ServletContextListener. Jego
artz.jobs.ee.ejb.EJBInvokerJob. Wymaga ona przekazania odpo- zadaniem jest inicjalizacja/zatrzymanie Quartz podczas
wiednich parametrów w obiekcie JobDataMap, opisanych szcze- startu/zamykania kontekstu Servletów w kontenerze J2EE.
gółowo w dokumentacji JavaDoc API biblioteki, np. nazwa JNDI W web.xml można również podać wartości dla opcjonalnych
i nazwa metody komponentu EJB. parametrów Listenera:
Drugie podejście ma przewagę nad pierwszym z kilku po-
wodów. Przede wszystkim występuje tu mniejsza liczba po- • − ścieżka i nazwa pliku z parametrami Quartz.
config-file
tencjalnych punktów awarii, ponieważ zarządzamy tylko jed- Domyślna wartość: quartz.properties;

Listing 7. quartz_ jobs.xml dla przykładu Hello World

<quartz> </entry>
<job> </job-data-map>
<job-detail> </job-detail>
<name>HelloWorldJob</name> <trigger>
<group>DEFAULT</group> <simple>
<description> <name>helloWorldTrigger</name>
Zadanie Hello World. <group>DEFAULT</group>
</description> <job-name>HelloWorldJob</job-name>
<job-class> <job-group>DEFAULT</job-group>
listing1.HelloWorldJob <start-time>2006-10-10 7:10:00 PM</start-time>
</job-class> <!-- uruchom Trigger co minutę -->
<volatility>false</volatility> <repeat-count>-1</repeat-count>
<durability>false</durability> <repeat-interval>60000</repeat-interval>
<recover>false</recover> </simple>
<job-data-map allows-transient-data="true"> </trigger>
<entry> </job>
<key>POWITANIE</key> </quartz>
<value>Hello World!</value>

Software Developer’s Journal 1/2007 www.sdjournal.org 21


Biblioteka
miesiąca

• – zaprojektowa-
org.quartz.impl.jdbcjobstore.JobStoreCMT
Listing 8. Przykład konfiguracji Triggera w pliku quartz_ na dla zastosowań, gdy obsługa transakcji mechanizmu
jobs.xml
JobStore powinna być zarządzana przez kontener J2EE.
<trigger>
<cron> Obie implementacje są oparte na protokole JDBC i pozwalają
<name>myTrigger</name> na przechowywanie zadań w bazie danych. Skrypty SQL po-
<group>DEFAULT</group> trzebne do założenia struktury tabel Quartz znajdują się w ka-
<job-name>myJob</job-name> talogu QUARTZ _ HOME/docs/dbTables.
<job-group>DEFAULT</job-group> Opis parametrów jakie należy ustawić dla poszczegól-
<cron-expression>0 0/10 9-16 ? * MON-FRI nych implementacji JobStore znajduje się na stronie: http://
</cron-expression> wiki.opensymphony.com/display/QRTZ1/Configuration.
</cron>
</trigger> Praktyczne porady
Poniżej znajduje się kilka praktycznych porad dla użytkowni-
ków Quartz:
• start-scheduler-on-load − określa czy metoda schedu-
ler.start() ma być wywołana podczas startu kontenera. • Do pobrania obiektu JobDataMap w metodzie execute() za-
Domyślna wartość: „true” dania używaj metody getMergedJobDataMap() z argumen-
• shutdown-on-unload − określa, czy metoda scheduler.shut- tu typu JobExecutionContext. Metoda ta zwraca obiekt po-
down() ma być wywołana podczas zatrzymania kontene- wstały z połączenia obiektów JobDataMap znajdujących się
ra. Domyślna wartość: „true”. zarówno w obiekcie JobDetail , jak i obiekcie Trigger;
• Scheduler tworzy nową instancję typu Job podczas każde-
Reszta plików konfiguracyjnych (quartz.properties i quartz_ go kolejnego wywołania zadania. Oznacza to, że wszel-
jobs.xml) nie wyróżnia się niczym specjalnym. Istnieje również al- kie wartości przechowywane w instancji obiektu zadania
ternatywne podejście do zaprezentowanego rozwiązania, oparte są tracone. Można to zmienić poprzez zamianę interfej-
na klasie org.quartz.ee.servlet.QuartzInitializerServlet i stan- su org.quartz.Job na org.quartz.StatefulJob w implemen-
dardowym mechanizmie ładowania Servletów przez kontener tacji zadania. Powoduje to dwie główne zmiany. Po pierw-
J2EE. Jednak zastosowanie Listenera jest uważane za imple- sze obiekt JobDataMap zostaje zachowany w JobStore po
mentację bardziej przenośną i właściwą w tym przypadku. każdym wywołaniu zadania. Po drugie dwie instancje te-
go samego zadania StatefulJob nie mogą być uruchomio-
JobStore ne równocześnie;
Quartz wykorzystuje JobStore do przechowywania informacji
o zadaniach Job, obiektach Trigger, Calendar oraz Scheduler. Listing 10. Plik web.xml
W przykładzie Hello World użyta została implementacja org.qu-
artz.simpl.RAMJobStore oparta na pamięci RAM. To wyjaśnia dla- <?xml version="1.0" encoding="UTF-8"?>
czego po ponownym uruchomieniu instancji Scheduler jego stan <!DOCTYPE web-app PUBLIC "-//Sun Microsystems,
i informacja o zadaniach były ładowane całkowicie od nowa. Inc. //DTD Web Application 2.3//EN"
Quartz udostępnia dwie implementacje JobStore pozwala- "http://java.sun.com/dtd/web-app_2_3.dtd">
jące na zachowanie stanu zadań: <web-app>
<!-- Użyjemy domyślnej nazwy quartz.properties
• org.quartz.impl.jdbcjobstore.JobStoreTX – zaprojektowana <context-param>
z myślą o uruchomieniu w środowisku 'stand-alone', gdy <param-name>config-file</param-name>
nie ma potrzeby integracji z serwisem transakcji w konte- <param-value>/path/my_quartz.properties</param-value>
nerze J2EE; </context-param>
-->

Listing 9. Przykładowe użycie klasy HolidayCalendar <context-param>


<param-name>shutdown-on-unload</param-name>
HolidayCalendar quartzCal = new HolidayCalendar(); <param-value>true</param-value>
// zablokuj 1 styczeń </context-param>
Calendar gCal = GregorianCalendar.getInstance(); <context-param>
gCal.set(Calendar.MONTH, Calendar.JANUARY); <param-name>start-scheduler-on-load</param-name>
gCal.set(Calendar.DATE, 1); <param-value>true</param-value>
quartzCal.addExcludedDate(gCal.getTime()); </context-param>
// Dodaj do scheduler, zastąp istniejący, <listener>
// uaktualnij Trigger'y <listener-class>
scheduler.addCalendar("holidaysCal", quartzCal, true, true); org.quartz.ee.servlet.QuartzInitializerListener
Trigger trigger = TriggerUtils.makeImmediateTrigger( </listener-class>
"myTrigger", -1, 60000L); </listener>
trigger.setCalendarName("holidaysCal"); </web-app>

22 www.sdjournal.org Software Developer’s Journal 1/2007


Quartz

• Liczba wątków w puli Quartz ma spory wpływ na wydaj-


ność aplikacji. Dlatego należy dobrać właściwą wartość
zależnie od potrzeb. Zazwyczaj domyślna wartość 5 wy-
W Sieci
starcza dla wiekszości zastosowań. Można ją zmniejszyć • Strona domowa
nawet do 1, jeśli aplikacja uruchamia zaledwie kilka za- http://www.opensymphony.com/quartz/;
dań parę razy w ciągu dnia. Wartości pomiędzy 50 a 100 • Download
stosuje się w przypadku planowania kilku tysięcy zadań, http://www.opensymphony.com/quartz/download.action;
z których wiele uruchamianych jest co kilka minut. Przy ta- • Forum użytkowników Quartz
kich obciążeniach należy przeprowadzić odpowiednie te- http://forums.opensymphony.com/forum.jspa?forumID=6;
sty wydajnościowe; • Lista znaczących użytkowników Quartz
http://wiki.opensymphony.com/display/QRTZ1/Quartz+Users.
• Duże znaczenie dla wydajności aplikacji ma wybór Job-
Store. RAMJobStore jest oczywiście o wiele szybszy od JDB-
CJobStore ;
• Quartz udostępnia mechanizm Listener. Pozwala on na • Niewielu użytkowników wie, że w repozytorium CVS bi-
obsługę różnych zdarzeń związanych z realizacją zadań blioteki jest dostępna również aplikacja Web do zarządza-
(JobListener), obsługą obiektów typu Trigger (TriggerLi- nia konfiguracją Quartz z poziomu przeglądarki. Znajduje
stener) czy działaniem samego obiektu Scheduler (Schedu- się ona w katalogu /web i nie jest dostarczana w wersji bi-
lerListeners). Jednak użycie dużej liczby obiektów Liste- narnej.
ner może znacznie spowolnić działanie aplikacji. Należy
również unikać zbyt długiej obsługi monitorowanych zda- Podsumowanie
rzeń; W ostatnim czasie w specyfikacjach J2SE i J2EE poja-
• Quartz nie udostępnia bezpośrednio obsługi przepły- wiły się nowe mechanizmy, jak Timer Services w EJB
wu zdarzeń, czyli możliwości zaplanowania wywołania 2.1/3.0 lub klasy w pakiecie java.util.concurrent. Jed-
odpowiednich zadań w wyniku zakończenia innych. Po- nak rozwiązania te nie są wystarczające i każdy, kto mu-
średnio można to wykonać poprzez użycie obiektów Li- si zaplanować zadania w języku Java, z pewnością powi-
stener, które po zakończeniu danego zadania rejestrują nien zajrzeć do biblioteki Quartz. Zachęcam do zapozna-
wykonanie kolejnego. Innym rozwiązaniem jest przesy- nia się z innymi jej elementami. Jako kolejny krok proponu-
łanie w JobDataMap nazwy obiektu typu Job, które ma być ję przejść do przykładów zawartych w katalogu /QUARTZ_
uruchomione po zakończeniu działania aktualnego za- HOME/examples/. Natomiast tym, którzy wnikliwiej zain-
dania. W bardziej zaawansowanych aplikacjach polecam teresowali się rozwojem biblioteki, polecam stronę http://
integrację Quartz z inną biblioteką dostępną w projekcie wiki.opensymphony.com/display/QRTZ/Quartz oraz udział
OpenSymphony : OSWorkflow; w projektowaniu kolejnej wersji Quartz 2.0. n

S P R O S T O W A N I E

W numerze 11/2006 Software Developer’s Journal w artykule Obiektowe projektowanie relacyjnej bazy danych autorstwa
Damiana Dudka został błędnie przerysowany Rysunek 1. Diagram klas bazy danych Sklep (po lewej stronie). Po prawej stro-
nie zamieszczamy poprawny rysunek. Serdecznie przepraszamy autora za błąd. Dziękujemy za wyrozumiałość. Cały artykuł
w poprawionej wersji można znaleźć na naszej stronie www.sdjournal.org
Redakcja SDJ

������ ����������
�������������� ������
����������� ������ ���� �������������� �������
����� ��������� ������������������ �������
������� ��������� ���� ���������������� �������
����������� ��������� ��������������� ���������
������������� ���������
������������� ���������
������������� ���������
����
�������� ���������
������� ���������
��������� ��������� ����
����� ��������� �����������������
���������������������
�������������������

����
������������� ����� ����
���������� ��������� ������� ��������� �������
������ ��������� ������� ��������� ������������� ���������
������� ���������
����������� ���������
���� ����������� ��������
��������� ����������� ���������
���� ������ ���������
������������� �������� �������� ����������
���������������� ���������
������ ��������� ����
����
������������

Rysunek 1. Diagram klas bazy danych Sklep Rysunek 1. Diagram klas bazy danych Sklep
Tam

byliśmy

Java Dev Days 2006


2
1 października 2006 w Krakowie w Centrum
Sztuki i Techniki Japońskiej Manggha odbyła
się konferencja Java Dev Days zorganizowana
przez Fundację Proidea. Poświęcona była technologii
Java oraz praktykom projektowania oraz programo-
wania aplikacji na tę platformę. Gościem honorowym
był Bruce Eckhel, który promował swoją książkę Thin-
king in Java. Rozpoczął on konferencje wykładem The
World is Dynamic. Prelegentami byli również:

l Przemysław Pokrywka
l Janusz Marchewa
l Jan Mrzygłód Rysunek 1. Ekipa Software Mind z Brucem
l Waldemar Kot Eckhelem (drugi od lewej)
l Jan Pieczykolan PROIDEA została założona w 2004 roku. Powsta-
l Grzegorz Rdzany ła w odpowiedzi na rosnące zapotrzebowanie na
l Jarosław Pałka organizacje przekazujące w sposób kompetentny
l Łukasz Grabski wiedzę z zakresu teleinformatyki. Wypełnia swoje
l Marcin Kucięba cele statutowe wspierając edukację oraz promując
l Marcin Płonka inicjatywy służące popularyzowaniu informatyki w
l Paweł Rzepa szkołach. Fundacja skupia wokół siebie grono spe-
cjalistów o rozległej wiedzy informatycznej.
Warsztaty przeprowadzili Łukasz Krawczyk, Michał
Majcher, Łukasz Szandecki oraz Mariusz Kaczor. Sponsorzy główni: DRQ oraz Software Mind

Są Państwo złotym sponsorem konfe- mując taką konferencję (a pamiętajmy, że o sponsorów dla
rencji Java Dev Days 2006. Co skłoniło tego typu „mało komercyjnych” konferencji bywa ciężko i
Państwa do podjęcia takiej decyzji? nie są one popularne), napędzamy popularność tego języ-
Powody tak naprawdę są dwa główne. Je- ka. A ta popularność nie jest jeszcze aż taka oczywista. My-
den bardziej bieżący, lokalny, chcielibyśmy śleliśmy do niedawna, że wszyscy programują w Javie, tym-
w jakiś sposób zaistnieć na krakowskim czasem ogromnie zdziwiło mnie, gdy niedawno w czasie roz-
rynku jako pracodawca, który jest koja- mów ze studentami kierunków informatycznych wyszło, że
rzony nie tylko poprzez targi / konferencje duży procent spośród nich nie doceniał tej technologii i nie
skierowane do swoich Klientów (a więc w inwestowali w swoją wiedzę w tym zakresie. Dlatego mamy
ramach których prezentowana jest komer- nadzieję, że może dzięki takim konferencjom, młodzi dewe-
cyjna oferta firmy, rozdawane są broszury loperzy dużo chętniej skłonią się ku Javie. Oczywiście to nie
opisujące produkty firmy), ale także jako jest jedyny i właściwy język programowania, każdy język ma
firma, która potrafi sponsorować coś mniej swoje zastosowanie. Jednak Java – poprzez swoją popular-
komercyjnego, nie mającego bezpośred- ność na świecie (a co za tym idzie – mnogość bibliotek, na-
niego przełożenia na działania handlowe rzędzi wspierających etc.) – jest dziś „najrozsądniejszym
Łukasz Majek – DRQ Kraków (do Klientów), ale przeznaczone bardziej wyborem” przy tworzeniu aplikacji z jakimi mają do czynie-
dla środowiska deweloperów / programistów, dla ludzi, któ- nia firmy takie jak DRQ. Dlatego zależy nam na promowaniu
rzy swoją pracę traktują jako coś więcej niż tylko sposób na tej technologii. To napędza krakowskie zaplecze profesjonal-
zasilenie domowego budżetu. Chcemy się kojarzyć z firmą, nych deweloperów Javy, z którego za chwilę będziemy mogli
która w tym co robi też chce czegoś więcej, niż tylko zarabiać korzystać, dla dobra naszych Klientów.
pieniądze (co jest oczywistym celem każdej firmy). My nato- Co z kolejnymi edycjami, czy będziecie Państwo kontynu-
miast chcemy robić to dodatkowo z użyciem ciekawych tech- ować tradycję sponsorowania tej imprezy?
nologii, dając ludziom szansę realizacji pasji w ramach tego, Nie mogę tego dziś ostatecznie potwierdzić, ale na dziś
co robią, przy okazji promując pewne technologie. DRQ za dzień już rozpoczęliśmy pewne rozmowy z fundacją Proidea
taką firmę się uważa i chcemy to pokazywać środowisku de- i wyrażamy wolę równie silnego zaangażowania w roku 2007.
weloperów (a więc środowisku naszych potencjalnych przy- Wszystko dlatego, że JDD 2006 okazało się dużym sukcesem
szłych pracowników). Drugi powód sponsorowania JDD, ten i cieszy się sporą popularnością (400 gości!), widzimy więc że
bardziej strategiczny, to promowanie technologii Java. Pro- nasze działanie ma sens.

24 www.sdjournal.org Software Developer’s Journal 01/2007


Aplikacje

biznesowe

Janusz Ganczarski
e-POLTAX
W
Materiały do artykułu dniu 16 sierpnia 2006 roku Ministerstwo
zamieszczone zostały
Finansów (MF) ogłosiło, że grupa oko-
na płycie CD 1 Podstawowe akty prawne związane
ło 7.5 tysiąca największych podatników
o rocznych przychodach przekraczających 5 mln
z deklaracjami elektronicznymi
euro, obsługiwanych przez tzw. wyspecjalizowa- • Rozporządzenie Ministra Finansów z dnia 11 sierp-
ne urzędy skarbowe (US), może składać deklara- nia 2006 r. w sprawie określenia rodzajów dekla-
cje podatkowe drogą elektroniczną. Wykonaniem racji, które mogą być składane za pomocą środ-
i jednocześnie wdrożeniem systemu e-POLTAX, ków komunikacji elektronicznej (Dz.U. Nr 146, poz.
obsługującego deklaracje elektroniczne zajęła się 1060);
Państwowa Wytwórnia Papierów Wartościowych • Rozporządzenie Ministra Finansów z dnia 11 sierp-
(PWPW). nia 2006 r. w sprawie trybu składania i wzoru zawia-
W niniejszym artykule, poza przedstawieniem domienia o zamiarze składania deklaracji w formie
elektronicznej (Dz.U. Nr 146, poz. 1061);
sposobu działania systemu e-POLTAX, skupimy
• Rozporządzenie Ministra Finansów z dnia 11 sierp-
się głównie na opisie formatów deklaracji elektro-
nia 2006 r. zmieniające rozporządzenie w sprawie
nicznej. Wszystkie prezentowane przykłady po- zaświadczeń wydawanych przez organy podatkowe
wstały wyłącznie w oparciu o opublikowane przez (Dz.U. Nr 146, poz. 1062);
MF schematy dokumentów. Poprawność składnio- • Rozporządzenie Ministra Finansów z dnia 11
wą plików XML weryfikowano przy użyciu aplika- września 2006 r. w sprawie trybu składania oraz
cji off-line udostępnianej przez MF, natomiast do struktury logicznej zgłoszenia upoważnienia po-
testów poprawności strukturalnej użyto walidatora datnika lub osoby upoważnionej przez podatnika
dostępnego na stronie http://tools.decisionsoft.com/ do składania deklaracji w formie elektronicznej i
schemaValidate/. podpisywania deklaracji podpisem elektronicznym
(Dz.U. Nr 168, poz. 1196);
Budowa i zasady funkcjonowania • Rozporządzenie Ministra Finansów z dnia 11 wrze-

systemu e-POLTAX śnia 2006 r. w sprawie struktury logicznej deklara-


cji, sposobu ich przesyłania oraz rodzajów podpi-
System e-POLTAX umożliwia składanie deklaracji su elektronicznego, którymi powinny być opatrzone
podatkowych na trzy sposoby: (Dz.U. Nr 168, poz. 1197);
• Rozporządzenie Ministra Finansów z dnia 2 paź-
• bezpośrednio poprzez mechanizmy udostępnio- dziernika 2006 r. zmieniające rozporządzenie w
ne na stronie WWW umieszczonej pod adresem sprawie struktury logicznej deklaracji, sposobu ich
https://e-poltax.mf.gov.pl; do złożenia deklara- przesyłania oraz rodzajów podpisu elektroniczne-
cji wystarczy standardowa przeglądarka interne- go, którymi powinny być opatrzone (Dz.U. Nr 179,
towa obsługująca protokół szyfrowania SSL v.3 poz. 1323).
(128 bitowy);
• przy pomocy aplikacji Off-Line, udostępnione na
stronach MF; niestety aktualna wersja 1.5 do- akceptuje wszystkie certyfikaty dostępne na pol-
stępna jest tylko dla systemów z rodziny Micro- skim rynku.
soft Windows; Zanim jednak prześlemy pierwszą deklarację
• poprzez moduły wbudowane w aplikacje (np. sys- drogą elektroniczną trzeba złożyć w US zawia-
temy finansowo-księgowe) dostarczone przez fir- domienie o zamiarze składania deklaracji ZAW-
my trzecie i korzystające ze schematów doku- E1 (oczywiście w papierowej wersji – patrz Ry-
mentów udostępnionych przez MF. sunek 1), odrębnie dla każdej osoby upoważnio-
nej do składania deklaracji. Następnie osoba upo-
Każdy z powyższych sposobów wymaga posiada- ważniona przesyła drogą elektroniczną zgłosze-
nia przez podatnika bezpiecznego podpisu elek- nie w formacie ZAW-E2, w którym potwierdza
tronicznego weryfikowanego za pomocą ważne- wolę składania deklaracji drogą elektroniczną. Po
go kwalifikowanego certyfikatu. System e-POLTAX weryfikacji powyższych zawiadomień US wydaje
zaświadczenie ZAS-E potwierdzające zgodność
Autor jest matematykiem i informatykiem danych zawartych w zawiadomieniu ZAW-E1
Kontakt z autorem: JanuszG@enter.net.pl z danymi w zgłoszeniu ZAW-E2 złożonym przez
Strona domowa: www.januszg.hg.pl osobę upoważnioną, a podatnik otrzymuje moż-
liwość składania deklaracji drogą elektroniczną.

26 www.sdjournal.org Software Developer’s Journal 1/2007


e-POLTAX

Rysunek 1. Zawiadomienie ZAW-E1

Warto zauważyć, że osobą upoważnioną nie musi być na- by upoważnionej. Potwierdzenie ma postać pliku XML, któ-
wet pracownik firmy – może to być np. doradca podatkowy ry zawiera następujące informacje:
prowadzący obsługę księgową firmy.
Niezależnie od wybranego sposobu złożenia deklara- • nazwa podmiotu przyjmującego dokument elektroniczny
cji lub innego dokumentu, system e-POLTAX z założenia w (MF);
ciągu kilkudziesięciu minut generuje i przesyła potwierdze- • identyfikator złożonego dokumentu nadany przez Central-
nie przyjęcia deklaracji na adres poczty elektronicznej oso- ną Bazę Danych (CBD);

�������� ������

����������
���������
������ ������
����������� ��� ����������
���������

�������������� �������� ��������

������������������
����������������������������
���������������������

��� ������� ��������

Rysunek 2. Schemat budowy działania systemu e-POLTAX (źródło MF)

Software Developer’s Journal 1/2007 www.sdjournal.org 27


Aplikacje
biznesowe

• wartość funkcji skrótu złożonego dokumentu, która jest • data wpłynięcia dokumentu do systemu informatycznego
identyczna z wartością użytą do podpisu składanego do- administracji podatkowej (data ze stempla czasu);
kumentu; • treść stempla czasu w postaci zakodowanej algorytmem
• wartość funkcji skrótu dokumentu w postaci otrzyma- Base64;
nej przez system (łącznie z podpisem elektronicz- • numer NIP podmiotu głównego deklaracji, wniosku lub
nym); zgłoszenia;
• typ dokumentu, którego dotyczy potwierdzenie (deklara- • informacja o przyjęciu lub odrzuceniu dokumentu oraz ko-
cja, wniosek lub zgłoszenie); dy ewentualnych błędów.

Listing 1. Przykładowy plik z zawiadomieniem ZAW-E2

<?xml version="1.0" encoding="UvTF-8"?> <Faks>0221234567</Faks>


<Email>firmasa@firmasa.pl</Email>
<!-- Zgłoszenie osoby upoważnionej do składania </Kontakt>
i podpisywania deklaracji w formie elektronicznej </Podmiot1>
-->
<!-- Dane osoby fizycznej upoważnionej do podpisywania
<ZgloszenieRej xmlns:xsi= deklaracji
"http://www.w3.org/2001/XMLSchema-instance" -->
xsi:noNamespaceSchemaLocation=
"http://e-poltax.mf.gov.pl/Repozytorium/Deklaracje/ <Podmiot2>
ZAW-E2(1)_v1-0.xsd"> <OsobaFizyczna>
<NIP>1112223344</NIP>
<!-- Nagłówek deklaracji <ImiePierwsze>Jan</ImiePierwsze>
--> <Nazwisko>Kowalski</Nazwisko>
<DataUrodzenia>1980-01-01</DataUrodzenia>
<Naglowek> <PESEL>80010199999</PESEL>
<KodFormularza kodSystemowy="ZAW-E2">ZAW-E2 </OsobaFizyczna>
</KodFormularza> <AdresZamieszkania rodzajAdresu="RAD">
<WariantFormularza>1</WariantFormularza> <AdresPol>
</Naglowek> <KodKraju>PL</KodKraju>
<Wojewodztwo>mazowieckie</Wojewodztwo>
<!-- Dane podatnika lub płatnika, którego deklaracje <Powiat>warszawski</Powiat>
składane w formie elektronicznej podpisuje osoba <Gmina>Centrum</Gmina>
upoważniona <Ulica>Aleje Jerozolimskie</Ulica>
--> <NrDomu>4321</NrDomu>
<NrLokalu>1</NrLokalu>
<Podmiot1> <Miejscowosc>Warszawa</Miejscowosc>
<OsobaNiefizyczna> <KodPocztowy>00-001</KodPocztowy>
<NIP>1234567890</NIP> <Poczta>Warszawa</Poczta>
<PelnaNazwa>Firma S.A.</PelnaNazwa> </AdresPol>
<REGON>123456789</REGON> </AdresZamieszkania>
</OsobaNiefizyczna> <Kontakt>
<AdresZamieszkaniaSiedziby rodzajAdresu="RAD"> <Telefon>0221234567</Telefon>
<AdresPol> <Faks>0221234567</Faks>
<KodKraju>PL</KodKraju> <Email>jankowalski@firmasa.pl</Email>
<Wojewodztwo>mazowieckie</Wojewodztwo> </Kontakt>
<Powiat>warszawski</Powiat> </Podmiot2>
<Gmina>Centrum</Gmina>
<Ulica>Aleje Jerozolimskie</Ulica> <!-- Zakres terminu uprawnień do podpisu dekl aracji
<NrDomu>1234</NrDomu> -->
<NrLokalu>1</NrLokalu>
<Miejscowosc>Warszawa</Miejscowosc> <ZakresTerminuUprawnien>
<KodPocztowy>00-001</KodPocztowy> <WaznyOd>2006-10-01</WaznyOd>
<Poczta>Warszawa</Poczta> <WaznyDo>2006-12-31</WaznyDo>
</AdresPol> </ZakresTerminuUprawnien>
</AdresZamieszkaniaSiedziby> </ZgloszenieRej>
<Kontakt>
<Telefon>0221234567</Telefon>

28 www.sdjournal.org Software Developer’s Journal 1/2007


e-POLTAX

Z deklaracji aktualnie obsługiwanych przez system


e-POLTAX najpopularniejsze i zarazem najważniejsze są:

• PIT-4 – deklaracja na zaliczkę miesięczną na podatek do-


chodowy od łącznej kwoty dokonanych wypłat;
• PIT-8A – deklaracja o zryczałtowanym podatku dochodo-
wym;
• VAT-7 – deklaracja podatkowa dla podatku od towarów
i usług.

Przykładowo wg danych dostępnych na stronie Podlaskie-


go Urzędu Skarbowego w Białymstoku w 2005 roku do te-
go urzędu złożono 4388 deklaracji PIT-4 i 910 deklaracji
PIT-8A.

Repozytorium schematów dokumentów


Repozytorium schematów dokumentów (patrz Rysunek 3)
zostało podzielone na pięć części obejmujących: słowniki,
definicje, potwierdzenie, szablony i deklaracje. Słowniki
zawierają kody urzędów skarbowych (plik KodyUrzedow-
Rysunek 3. Repozytorium schematów dokumentów
Skarbowych_v1-0.xsd) i dwuliterowe kody krajów zgodne
Oczywiście system e-POLTAX nie weryfikuje poprawno- ze standardem ISO 3166 (plik KodyKrajow_v1-0.xsd).
ści merytorycznej deklaracji – tę może wykonać wyłącznie Aktualnie dostępne są tylko kody urzędów skarbowych
pracownik US. Cały schemat działania systemu e-POLTAX wyspecjalizowanych w obsłudze tzw. dużych podatników.
przedstawiono na Rysunku 2. W potwierdzeniach znajduje się jedynie schemat urzędo-
wego potwierdzenia odbioru dokumentu elektronicznego
Deklaracje elektroniczne (plik Potwierdzenie_v1-0.xsd), a definicje deklaracji i za-
Jako format danych na potrzeby deklaracji elektronicznych łączników do deklaracji umieszczono oczywiście w dekla-
wybrano XML, przy czym struktury poszczególnych doku- racjach.
mentów, typy danych oraz słowniki opisane zostały przy Aktualnie repozytorium nie zawiera żadnych szablonów
użyciu XML Schema. Ta stosunkowo nowa technologia dokumentów.
(specyfikacja pochodzi z 2001 roku) jest uważana za na-
stępcę DTD i posiada od tego ostatniego znacznie większe
możliwości.
Wszystkie dokumenty XSD (ang. XML Schema Defini-
tion) z definicjami dostępne są w repozytorium schema-
tów dokumentów umieszczonym na stronie WWW syste-
mu e-POLTAX (https://e-poltax.mf.gov.pl/ ). Schematy do-
kumentów elektronicznych są prawnie usankcjonowane
rozporządzeniami MF (patrz ramka).
Pierwsze akty prawne opisujące pliki XSD zostały
podpisane w dniu 11 września 2006r (od tego dnia rze-
czywiście można mówić o technicznej i prawnej możliwo-
ści składania deklaracji elektronicznych), a ostatnie do-
stępne w momencie powstawania niniejszego tekstu po-
chodzą z 2 października 2006 roku.
Także w drodze rozporządzenia MF określił termin
wprowadzania kolejnych wzorów deklaracji elektronicz-
nych (patrz ramka).
Rozporządzenia określają ponadto sposób opatrywa-
nia deklaracji i innych dokumentów bezpiecznym podpi-
sem elektronicznym weryfikowanym za pomocą ważnego
kwalifikowanego certyfikatu, algorytm bezpiecznego pod-
pisu elektronicznego, algorytm szyfrowania oraz funkcję
skrótu.
MF dopuściło opatrywanie dokumentów podpisem
elektronicznym przy użyciu jednego z dwóch formatów:
XAdES-BES (ETSI TS 101 903) oraz PKCS#7, przy czym ten
pierwszy wydaje się być znacznie lepiej przystosowany do Rysunek 4. Program e-Poltax Off-Line z wczytanym
potrzeb dokumentów w formacie XML. zawiadomieniem ZAW-E2

Software Developer’s Journal 1/2007 www.sdjournal.org 29


Aplikacje
biznesowe

W budowie dokumentów XML zawierających deklara- gramu e-Poltax Off-Line oraz gotowy do podpisania
cje, bardzo ważne są dokumenty zawarte w definicjach z wyliczoną funkcją skrótu przedstawiono na rysunkach
repozytorium. Zawierają one opis podstawowych typów nr 4 i 5.
danych (plik ElementarneTypyDanych_v1-0.xsd) i struk-
tur (plik StrukturyDanych_v1-0.xsd) używanych w dekla- PIT-4 – deklaracja na zaliczkę miesięczną na podatek
racjach. Typy i struktury danych przedstawiamy bliżej dochodowy od łącznej kwoty dokonanych wypłat
w ramce. Strukturę deklaracji PIT-4 opisuje plik PIT-4(17)_v1-0.xsd.
Na dokumenty, których schematy znajdują się w repo- Dokument zawiera cztery elementy: Nagłówek, Podmiot1,
zytorium składają się nie tylko elektroniczne odpowiedniki
papierowych formularzy z deklaracjami. Znajdują się tam
także wybrane rodzaje załączników i wniosków, które nie
Struktury danych opisane w pliku
posiadają urzędowo określonego wzoru, a które mogą być StrukturyDanych_v1-0.xsd:
elementem składowym deklaracji obsługiwanych przez • TAdres – dane adresowe, może to być adres polski (ele-
system e-POLTAX. Typowym przykładem jest formularz ment AdresPol) lub adres zagraniczny (element AdresZagr);
ORD-ZU, który zawiera uzasadnienie przyczyn składania na adres polski składają się elementy: KodKraju, Wojewódz-
korekty deklaracji. two, Powiat, Gmina, Ulica, NrDomu, NrLokalu, Miejscowosc,
Pierwszym dokumentem elektronicznym, który przed- KodPocztowy i Poczta; na adres zagraniczny składają się
stawimy nie będzie jednak żadna z deklaracji, ale omówione elementy: KodKraju, KodPocztowy, Miejscowosc, Ulica,
wcześniej zawiadomienie ZAW-E2. NrDomu, NrLokalu, Pietro, NazwaRegionu i SkrzynkaPocz-
towa;
ZAW-E2 – Zgłoszenie osoby upoważnionej do składania • TIdentyfikatorOsobyFizycznej – podstawowe dane identyfi-
kujące osobę fizyczną; są to następujące elementy: NIP, Imie-
i podpisywania deklaracji w formie elektronicznej
Pierwsze, Nazwisko, DataUrodzenia i PESEL;
Strukturę zawiadomienia ZAW-E2 zawiera plik ZAW-
• TIdentyfikatorOsobyFizycznejPelny – pełne dane iden-
E2(1)_v1-0.xsd. Dokument zawiera cztery główne elemen- tyfikujące osobę fizyczną; są to elementy: NIP, ImiePierw-
ty. Pierwszy to Nagłówek opisujący kod i wariant formu- sze, Nazwisko, DataUrodzenia, ImieOjca, ImieMatki i PE-
larza. Nagłówki stanowią standardowy element każdego SEL;
dokumentu elektronicznego w systemie e-POLTAX. Da- • TIdentyfikatorOsobyNiefizycznej – podstawowe dane identyfi-
lej formularz ZAW-E2 zawiera element Podmiot1 opisują- kujące podmioty nie będą osobami fizycznymi; składają się na
cy dane podatnika, którego deklaracje będą składane dro- elementy: NIP, PelnaNazwa i REGON;
gą elektroniczną oraz element Podmiot2 zawierający da- • TPodmiotDowolnyBezAdresu – podstawowe dane dowolne-
ne osoby upoważnionej, która w imieniu podatnika będzie go podmiotu; może to być osoba fizyczna (element Osoba-
składała deklaracje. W danych obu podmiotów elementy Fizyczna typu TIdentyfikatorOsobyFizycznej) lub pozostałe
podmioty (element OsobaNiefizyczna tylu TidentyfikatorO-
składowe Kontakt są opcjonalne. Wartość atrybutu rodza-
sobyNiefizycznej);
jAdresu w elementach AdresZamieszkaniaSiedziby i Adre-
• TIdentyfikatorOsobyNiefizycznejPelny – pełne dane iden-
sZamieszkania oznacza, że są to adresy rejestracyjne obu tyfikujące podmioty nie będące osobami fizycznymi; są to
podmiotów. Na końcu formularz ZAW-E2 zawiera okres następujące elementy: NIP, PelnaNazwa, SkroconaNazwa i
w jakim osoba upoważniona może składać deklaracje dro- REGON;
gą elektroniczną. • TOsobaFizyczna – podstawowe dane osoby fizycznej; są to
Przykładowy dokument z zawiadomieniem ZAW-E2 następujące elementy: OsobaFizyczna (typ TIdentyfikatorO-
zawiera listing 1. Ten sam dokument wczytany do pro- sobyFizycznej) oraz AdresZamieszkania (typ TAdres + atrybut
rodzajAdresu);
• TOsobaNiefizyczna – podstawowe dane podmiotu nie będą-
cego osobą fizyczną; są to elementy: OsobaNiefizyczna (typ
TIdentyfikatorOsobyNiefizycznej) oraz AdresSiedziby (typ TA-
dres + atrybut rodzajAdresu);
• TPodmiotDowolny – podstawowe dane dowolnego podmio-
tu; typ jest rozszerzeniem typu TPodmiotDowolnyBezAdresu
i posiada dodatkowy element AdresZamieszkaniaSiedziby (typ
TAdres + atrybut rodzajAdresu);
• TOsobaFizycznaPelna – pełny zestaw danych o osobie fizycz-
nej; elementy: OsobaFizyczna (typ TidentyfikatorOsobyFi-
zycznejPelny) i Adres (typ Tadres);
• TOsobaNiefizycznaPelna – pełny zestaw danych o podmio-
cie nie będącym osobą fizyczną; elementy: OsobaNiefizycz-
na (typ TidentyfikatorOsobyNiefizycznejPelny) i Adres (typ
Tadres);
• TPodmiotDowolnyPelny – pełny zestaw danych o dowol-
nym podmiocie; element OsobaFizyczna (typ TIdentyfika-
torOsobyFizycznejPelny) lub OsobaNiefizyczna (typ TIden-
tyfikatorOsobyNiefizycznejPelny) oraz element Adres (typ
Rysunek 5. Program e-Poltax Off-Line z gotowym do TAdres).
podpisania zawiadomieniem ZAW-E2

30 www.sdjournal.org Software Developer’s Journal 1/2007


e-POLTAX

Listing 2. Przykładowy plik z deklaracją PIT-4


<?xml version="1.0" encoding="utf-8"?> <P_28>0</P_28>
<Deklaracja xmlns:xsi= <!-- Suma wypłat -->
"http://www.w3.org/2001/XMLSchema-instance" <P_29>0</P_29>
xsi:noNamespaceSchemaLocation= <!-- Należne zaliczki -->
"http://e-poltax.mf.gov.pl/Repozytorium/ <P_30>0</P_30>
Deklaracje/PIT/PIT-4(17)_v1-0.xsd"> <!-- Liczba podatników -->
<Naglowek> <P_31>0</P_31>
<KodFormularza kodSystemowy="PIT-4 (17)" kodPodatku="PIT" <!-- Suma wypłat -->
rodzajZobowiazania="P">PIT-4</KodFormularza> <P_32>0</P_32>
<WariantFormularza>17</WariantFormularza> <!-- Należne zaliczki -->
<CelZlozenia>1</CelZlozenia> <P_33>0</P_33>
<Rok>2006</Rok> <!-- Liczba podatników -->
<Miesiac>10</Miesiac> <P_34>0</P_34>
<KodUrzedu>1472</KodUrzedu> <!-- Suma wypłat -->
</Naglowek> <P_35>0</P_35>
<Podmiot1 rola="Płatnik"> <!-- Należne zaliczki -->
<OsobaNiefizyczna> <P_36>0</P_36>
<NIP>1234567890</NIP> <!-- Liczba podatników -->
<PelnaNazwa>Firma S.A.</PelnaNazwa> <P_37>0</P_37>
<REGON>123456789</REGON> <!-- Suma wypłat -->
</OsobaNiefizyczna> <P_38>0</P_38>
<AdresZamieszkaniaSiedziby rodzajAdresu="RAD"> <!-- Należne zaliczki -->
<AdresPol> <P_39>0</P_39>
<KodKraju>PL</KodKraju> <!-- Liczba podatników - Inne przychody -->
<Wojewodztwo>mazowieckie</Wojewodztwo> <P_40>0</P_40>
<Powiat>warszawski</Powiat> <!-- Suma wypłat - Inne przychody -->
<Gmina>Centrum</Gmina> <P_41>0</P_41>
<Ulica>Aleje Jerozolimskie</Ulica> <!-- Należne zaliczki - Inne przychody -->
<NrDomu>1234</NrDomu> <P_42>0</P_42>
<NrLokalu>1</NrLokalu> <!-- Należne zaliczki - RAZEM -->
<Miejscowosc>Warszawa</Miejscowosc> <P_43>4000</P_43>
<KodPocztowy>00-001</KodPocztowy> <!-- Kwota zaliczek -->
<Poczta>Warszawa</Poczta> <P_44>0</P_44>
</AdresPol> <!-- Kwota przypadająca do pobrania -->
</AdresZamieszkaniaSiedziby> <P_45>0</P_45>
</Podmiot1> <P_46>0</P_46>
<!-- Dane wymiarowe deklaracji --> <P_47>0</P_47>
<PozycjeSzczegolowe> <P_48>0</P_48>
<!-- Liczba podatników --> <P_49>0</P_49>
<P_19>10</P_19> <P_50>0</P_50>
<!-- Suma wypłat --> <P_51>4000</P_51>
<P_20>20000</P_20> <P_52>0</P_52>
<!-- Należne zaliczki --> <P_53>4000</P_53>
<P_21>4000</P_21> <P_54> </P_54>
<!-- Liczba podatników --> </PozycjeSzczegolowe>
<P_22>0</P_22> <Pouczenie>W przypadku niewpłacenia w obowiązującym
<!-- Suma wypłat --> terminie kwoty z poz.53 lub wpłacenia jej
<P_23>0</P_23> w niepełnej wysokości, niniejsza deklaracja stanowi
<!-- Należne zaliczki --> podstawę do wystawienia tytułu wykonawczego,
<P_24>0</P_24> zgodnie z przepisami ustawy z dnia 17 czerwca 1966
<!-- Liczba podatników --> r. o postępowaniu egzekucyjnym w administracji
<P_25>0</P_25> (Dz.U. z 2005 r. Nr 229, poz.1954, z późn.zm)
<!-- Suma wypłat --> </Pouczenie>
<P_26>0</P_26> <Oswiadczenie>Oświadczam, że są mi znane przepisy
<!-- Należne zaliczki --> Kodeksu karnego skarbowego o odpowiedzialności za
<P_27>0</P_27> uchybienie obowiązkom płatnika.</Oswiadczenie>
<!-- Liczba podatników --> </Deklaracja>

Software Developer’s Journal 1/2007 www.sdjournal.org 31


Aplikacje
biznesowe

Listing 3. Przykładowy plik z korektą deklaracją VAT-7 oraz uzasadnieniem przyczyn korekty
<?xml version="1.0" encoding="utf-8"?> <P_34>0</P_34>
<Deklaracja xmlns:xsi= <!-- Podatek należny - Import usług -->
"http://www.w3.org/2001/XMLSchema-instance" <P_35>0</P_35>
xsi:noNamespaceSchemaLocation= <!-- Podstawa opodatkowania -->
"https://epoltax.mf.gov.pl/Repozytorium/Deklaracje/ <P_36>0</P_36>
VAT/VAT-7(9)_v1-0.xsd"> <P_37>0</P_37>
<Naglowek> <P_38>0</P_38>
<KodFormularza kodSystemowy="VAT-7 (9)" kodPodatku="VAT" <P_39>0</P_39>
rodzajZobowiazania="Z">VAT-7</KodFormularza> <P_40>1500000</P_40>
<WariantFormularza>9</WariantFormularza> <P_41>220000</P_41>
<CelZlozenia poz="P_7">2</CelZlozenia> <P_42>0</P_42>
<Rok>2006</Rok> <P_43>0</P_43>
<Miesiac>10</Miesiac> <P_44>0</P_44>
<KodUrzedu>1472</KodUrzedu> <P_45>0</P_45>
</Naglowek> <P_46>1500000</P_46>
<Podmiot1 rola="Podatnik"> <P_47>330000</P_47>
<OsobaNiefizyczna> <P_48>0</P_48>
<NIP>1234567890</NIP> <P_49>0</P_49>
<PelnaNazwa>Firma S.A.</PelnaNazwa> <P_50>330000</P_50>
<REGON>123456789</REGON> <P_51>0</P_51>
</OsobaNiefizyczna> <P_52>0</P_52>
<AdresZamieszkaniaSiedziby rodzajAdresu="RAD"> <P_53>0</P_53>
<AdresPol> <P_54>0</P_54>
<KodKraju>PL</KodKraju> <P_55>110000</P_55>
<Wojewodztwo>mazowieckie</Wojewodztwo> <P_56>110000</P_56>
<Powiat>warszawski</Powiat> <P_57>110000</P_57>
<Gmina>Centrum</Gmina> <P_58>0</P_58>
<Ulica>Aleje Jerozolimskie</Ulica> <P_59>0</P_59>
<NrDomu>1234</NrDomu> <P_64>2</P_64>
<NrLokalu>1</NrLokalu> <P_65>2</P_65>
<Miejscowosc>Warszawa</Miejscowosc> </PozycjeSzczegolowe>
<KodPocztowy>00-001</KodPocztowy> <Pouczenie>W wypadku niewpłacenia w obowiązującym
<Poczta>Warszawa</Poczta> terminie kwoty z poz.53 lub wpłacenia jej
</AdresPol> w niepełnej wysokości niniejsza deklaracja
</AdresZamieszkaniaSiedziby> stanowi podstawę do wystawienia tytułu
</Podmiot1> wykonawczego, zgodnie z przepisami ustawy z dnia
<PozycjeSzczegolowe> 17 czerwca 1966 r. o postępowaniu egzekucyjnym
<P_20>0</P_20> w administracji (Dz.U. z 2005 r. Nr 229, poz.1954,
<P_21>0</P_21> z późn.zm).</Pouczenie>
<P_22>0</P_22> <Oswiadczenie>Oświadczam, że są mi znane przepisy
<P_23>0</P_23> Kodeksu karnego skarbowego o odpowiedzialności
<P_24>0</P_24> za podanie danych niezgodnych z rzeczywistością.
<P_25>0</P_25> </Oswiadczenie>
<P_26>0</P_26> <Zalaczniki>
<P_27>0</P_27> <Zalacznik_ORD-ZU>
<P_28>1000000</P_28> <Naglowek>
<!-- Podatek należny --> <KodFormularza kodSystemowy=
<P_29>220000</P_29> "ORD-ZU (1)">ORD-ZU</KodFormularza>
<!-- Wewnątrzwspólnotowa dostawa towarów --> <WariantFormularza>1</WariantFormularza>
<P_30>500000</P_30> </Naglowek>
<!-- Eksport towarów --> <PozycjeSzczegolowe>
<P_31>0</P_31> <Tresc poz="P_10">Uzasadnienie korekty deklaracji
<!-- Podstawa opodatkowania --> za 10/2006</Tresc>
<P_32>0</P_32> </PozycjeSzczegolowe>
<!-- Podatek należny --> </Zalacznik_ORD-ZU>
<P_33>0</P_33> </Zalaczniki>
<!-- Podstawa opodatkowania - Import usług --> </Deklaracja>

32 www.sdjournal.org Software Developer’s Journal 1/2007


e-POLTAX

Listing 4. Przykładowy plik z deklaracją VAT-7K wraz z wnioskiem i przyspieszenie zwrotu podatku
<?xml version="1.0" encoding="utf-8"?> <P_39>0</P_39>
<Deklaracja xmlns:xsi= <P_40>1500000</P_40>
"http://www.w3.org/2001/XMLSchema-instance" <P_41>220000</P_41>
xsi:noNamespaceSchemaLocation="http://e-poltax.mf.gov.pl/ <P_42>0</P_42>
Repozytorium/Deklaracje/VAT/VAT-7K(3)_v1-0.xsd"> <P_43>0</P_43>
<Naglowek> <P_44>0</P_44>
<KodFormularza kodSystemowy="VAT-7K (3)" kodPodatku="VAT" <P_45>0</P_45>
rodzajZobowiazania="Z">VAT-7K</KodFormularza> <P_46>1500000</P_46>
<WariantFormularza>3</WariantFormularza> <P_47>330000</P_47>
<CelZlozenia poz="P_7">1</CelZlozenia> <P_48>0</P_48>
<Rok>2006</Rok> <P_49>0</P_49>
<Kwartal>3</Kwartal> <P_50>330000</P_50>
<KodUrzedu>1472</KodUrzedu> <P_51>0</P_51>
</Naglowek> <P_52>0</P_52>
<Podmiot1 rola="Podatnik"> <P_53>0</P_53>
<OsobaFizyczna> <P_54>0</P_54>
<NIP>1112223344</NIP> <P_55>110000</P_55>
<ImiePierwsze>Jan</ImiePierwsze> <P_56>110000</P_56>
<Nazwisko>Kowalski</Nazwisko> <P_57>110000</P_57>
<DataUrodzenia>1980-01-01</DataUrodzenia> <P_58>0</P_58>
<PESEL>80010199999</PESEL> <!-- Kwota do przeniesienia na następny okres -->
</OsobaFizyczna> <P_59>0</P_59>
<AdresZamieszkaniaSiedziby rodzajAdresu="RAD"> <!-- Podatnik wykonywał w okresie rozliczeniowym -->
<AdresPol> <P_64>2</P_64>
<KodKraju>PL</KodKraju> <P_65>1</P_65>
<Wojewodztwo>mazowieckie</Wojewodztwo> </PozycjeSzczegolowe>
<Powiat>warszawski</Powiat> <Pouczenie>W wypadku niewpłacenia w obowiązującym
<Gmina>Centrum</Gmina> terminie kwoty z poz.53 lub wpłacenia jej
<Ulica>Aleje Jerozolimskie</Ulica> w niepełnej wysokości niniejsza deklaracja
<NrDomu>4321</NrDomu> stanowi podstawę do wystawienia tytułu
<NrLokalu>1</NrLokalu> wykonawczego, zgodnie z przepisami ustawy z dnia
<Miejscowosc>Warszawa</Miejscowosc> 17 czerwca 1966 r. o postępowaniu egzekucyjnym
<KodPocztowy>00-001</KodPocztowy> w administracji (Dz.U. z 2005 r. Nr 229, poz.1954,
<Poczta>Warszawa</Poczta> z późn.zm).</Pouczenie>
</AdresPol> <Oswiadczenie>Oświadczam, że są mi znane przepisy Kodeksu
</AdresZamieszkaniaSiedziby> karnego skarbowego o odpowiedzialności za
</Podmiot1> podanie danych niezgodnych z rzeczywistością.
<PozycjeSzczegolowe> </Oswiadczenie>
<P_20>0</P_20> <Zalaczniki>
<P_21>0</P_21> <Wniosek_VAT-ZT>
<P_22>0</P_22> <Naglowek>
<P_23>0</P_23> <KodFormularza kodSystemowy="VAT-ZT (3)">VAT-ZT
<P_24>0</P_24> </KodFormularza>
<P_25>0</P_25> <WariantFormularza>3</WariantFormularza>
<P_26>0</P_26> </Naglowek>
<P_27>0</P_27> <PozycjeSzczegolowe>
<P_28>1000000</P_28> <P_20>110000</P_20>
<P_29>220000</P_29> <!-- Kwota do zwrotu w terminie 60 dni -->
<P_30>500000</P_30> <P_25>0</P_25>
<P_31>0</P_31> <!-- Kwota do zwrotu w terminie 25 dni -->
<P_32>0</P_32> <P_27>110000</P_27>
<P_33>0</P_33> <Tresc poz="P_10">Uzasadnienie przyspieszonego zwrotu
<P_34>0</P_34> podatku VAT z deklaracji VAT-7 za 3 kw. 2006</Tresc>
<P_35>0</P_35> </PozycjeSzczegolowe>
<P_36>0</P_36> </Wniosek_VAT-ZT>
<P_37>0</P_37> </Zalaczniki>
<P_38>0</P_38> </Deklaracja>

Software Developer’s Journal 1/2007 www.sdjournal.org 33


Aplikacje
biznesowe

PozycjeSzczegolowe, Pouczenie oraz Oświadczenie. Dwa


pierwsze elementy opisują deklarację i podmiot ją składa- Podstawowe typy i struktury danych
jący, element PozycjeSzczegolowe zawiera wszystkie wła-
ściwe dane deklaracji, a dwa ostatnie elementy to po-
używane w deklaracjach
uczenie o sankcjach grożących za brak terminowej wpłaty Elementarne typy danych opisane w pliku: ElementarneTypyDa-
i nierzetelność danych wykazanych w deklaracji. nych_v1-0.xsd:
Przykładowy dokument XML zawierający deklarację PIT-
4 przedstawiono na listingu nr 2. Warto zwrócić uwagę na in- • TZnakowy – typ znakowy ograniczony do jednej linii do 240 zna-

formacje zawarte w nagłówku dotyczące wersji deklaracji PIT- ków;


• TTekstowy – typ znakowy ograniczony do 2000 znaków;
4 (jest to już jak widzimy 17 wersja tego formularza) oraz atry-
• TProcentowy – wartość procentowa z dokładnością do 2
but rola zawarty w elemencie Podmiot1 (deklaracja dotyczy
miejsc po przecinku;
obowiązków płatnika).
• TCalkowity – liczba całkowita;
• TNaturalny – liczba naturalna;
PIT-8A – deklaracja na zaliczkę miesięczną na podatek • TKwota2 – wartość kwotowa wykazana w złotych i groszach;
dochodowy od łącznej kwoty dokonanych wypłat • TKwotaC – wartość kwotowa wykazana w złotych;
Drugą deklaracją, której obsługę w systemie e-POLTAX wpro- • TKwota2Nieujemna – wartość kwotowa nieujemna wykazana
wadzono razem z PIT-4, jest formularz PIT-8A opisany w pliku w złotych i groszach;
PIT-8A(13)_v1-0.xsd. Deklaracja w formie elektronicznej nie • TKwotaCNieujemna – wartość kwotowa nieujemna wykazana
różni się w swojej budowie od PIT-4, poza oczywistymi różni- w złotych;
cami w elementach Nagłówek i PozycjeSzczegolowe. • TData – data w formacie RRRR-MM-DD;
• TDataCzas – data i godzina;
• TRok – rok;
VAT-7 – miesięczna deklaracja
• TMiesiac – numeracja miesiąca;
dla podatku od towarów i usług • TKwartal – numeracja kwartału;
Schemat formularza VAT-7 (plik VAT-7(9)_v1-0.xsd) został • TAdresEmail – adres e-mail;
udostępniony na początku października 2006 roku razem • TNrNIP – numer NIP;
z deklaracjami VAT-7K, VAT-8 i VAT-9. Nową wspólną cechą • TNrPESEL – numer PESEL;
tych deklaracji jest element Załączniki, który zawiera załącz- • TNrREGON – numer REGON;
niki składane opcjonalnie razem z deklaracją. Stąd razem • TImie – pierwsze imię;
z powyższymi formularzami określone zostały schematy • TNazwisko – nazwisko;
trzech załączników: • TMiejscowosc – nazwa miejscowości;
• TJednAdmin – nazwa jednostki administracyjnej: wojewódz-
twa, powiatu lub gminy;
• VAT-ZT (wniosek o przyspieszenie terminu zwrotu podatku);
• TUlica – nazwa ulicy;
• VAT-ZZ (wniosek o zwrot podatku VAT);
• TNrBudynku – numer budynku;
• ORD-ZU (uzasadnienie przyczyn korekty deklaracji).
• TNrLokalu – numer lokalu;
• TKodPocztowy – kod pocztowy;
Załączniki te w przeciwieństwie do deklaracji nie posiadają urzę- • TCelZlozenia – ceł złożenia deklaracji: złożenie deklaracji po
dowo określonego papierowego formatu, ale ich charakter powo- raz pierwszy (1) lub korekta (2);
duje, że muszą zawierać kilka standardowych elementów repre- • TNrDokumentu – numer dokumentu;
zentowanych odpowiednio w wersji elektronicznej. Przykładowy • TWybor1 – pojedyncze pole wyboru;
plik XML z korektą deklaracji VAT-7 wraz uzasadnieniem korek- • TWybor1_2 – podwójne pole wyboru (1 lub 2);
ty przedstawiono na listingu nr 3. Poza zawartym w treści doku- • TWybor1_3 – potrójne pole wyboru (1, 2 lub 3);

mentu załącznikiem ORD-ZU warto zwrócić uwagę na wartość • TSposobOpodatkowania – wybór sposobu opodatkowania (1,
2, 3 lub 4).
atrybutu rola w elemencie Podmiot1, która w odróżnieniu od de-
klaracji PIT-4 i PIT-8A przyjmuje wartość „Podatnik ” oraz zmianę
wartości elementu CelZlozenia na 2 (korekta deklaracji).
VAT-8 i VAT-9 – deklaracje dla podatku od towarów i usług
VAT-7K – kwartalna deklaracja Dwie pozostałe deklaracje, wprowadzone razem z opisany-
dla podatku od towarów i usług mi wcześniej formularzami VAT-7 i VAT-7K, należą do grupy
Deklaracja VAT-7K (schemat zawarty w pliku VAT-7(9)_v1-0.xsd) deklaracji stosunkowo rzadko składanych przez podatników.
jest składanym kwartalnie odpowiednikiem formularza VAT-7. Ich budowa nie odbiega od przedstawionych już dokumen-
Stąd jedyną różnicą w elektronicznych wersjach obu tych dekla- tów, przy czym jedynym dopuszczalnym rodzajem załącz-
racji jest element Nagłówek, który zamiast numeru miesiąca (ele- nika, który może być składany razem z VAT-8 i VAT-9, jest
ment Miesiąc) zawiera numer kwartału (element Kwartał). uzasadnienie przyczyn korekty deklaracji (ORD-ZU).
Na listingu nr 4 przedstawiono przykładową deklara-
cję VAT-7K, tym razem jednak składaną przez osobę fizycz- Projekt e-Deklaracje
ną, czyli przez podmiot, który aktualnie nie ma takiej praw- Jak informuje MF na swojej stronie WWW jednym z celów
nej możliwości. Deklaracja zawiera w sobie wniosek VAT-ZT o systemu e-POLTAX jest aktualizacja i weryfikacja wymagań
przyspieszenie zwrotu podatku, stąd poza dodaniem elemen- funkcjonalnych, prawnych i organizacyjnych, które posłużą
tów charakterystycznych dla tego załącznika, odpowiednio do wyboru docelowych rozwiązań w ramach prowadzone-
została zmodyfikowana wartość elementu P_65. go projektu e-Deklaracje współfinansowanego z Europej-

34 www.sdjournal.org Software Developer’s Journal 1/2007


e-POLTAX

skiego Funduszu Rozwoju Regionalnego w ramach działa-


nia 1.5 Sektorowego Programu Operacyjnego Wzrost Kon- ���������
���������������������������

kurencyjności Przedsiębiorstw. Projekt e-Deklaracje ma sta- ��������


nowić docelowy system bezpośredniej komunikacji elektro- �����������������������������
nicznej pomiędzy przedsiębiorcami, a administracją podat-
��� ��������� ��� ����� ����
kową, umożliwiający wymianę drogą elektroniczną wszyst-
������
kich dokumentów przewidzianych prawem. Obecne plany ���������
zakładają uruchomienie systemu e-Deklaracje na począt- ���������
��������� ����
��� ���� �����������
ku 2008 roku.
����
Schemat systemu e-Deklaracje przedstawiono na Ry-
��������������������
sunku 6. Podatnik korzystający z portalu e-Deklaracje, sta-
nowiącego jeden z elementów portalu e-PUAP (elektronicz-
���� ���� ���� ������ ���� �� ���
na Platforma Usług Administracji Publicznej), wybiera je-
den z formularzy elektronicznych zdefiniowanych w Repo- ������ ������ ������ ������ ������
��� ���
zytorium Wzorów Dokumentów (RWD). Po jego wypełnie- ��� ��� ��� ��� ���
niu i podpisaniu przy użyciu Infrastruktury Klucza Publicz- �����������������
nego (PKI) dokument otrzymuje aplikacja e-Podatki, któ-
rej zadaniem jest jego formalna weryfikacja, porównanie Rysunek 6. Schemat systemu e-Deklaracje (źródło MF)
z danymi podatnika zawartymi w Krajowej Ewidencji Podat- łą pewnością przedstawione w artykule mechanizmy opi-
ników (KEP), a docelowo w Centralnym Rejestrze Podmio- su dokumentów elektronicznych, korzystające ze standar-
tów (CRP) oraz zapisanie w Centralnym Rejestrze Doku- du XML, zostaną utrzymane. Jest to zresztą w ocenie au-
mentów (CRD). Jednocześnie podatnik otrzymuje informa- tora trafny wybór, korzystający z otwartych standardów
cję zwrotną zawierającą m.in. unikalny numer referencyjny projektowanych m.in. do takich zastosowań. Udostępnie-
dokumentu. nie schematów elektronicznych dokumentów czyni admi-
Właściwy dla podatnika US otrzymuje dokument za nistrację podatkową bardziej otwartą (nie powielono błę-
pośrednictwem Platformy Integracji (PI) i w zależności od dów ZUS) i umożliwia odpowiednie przygotowanie apli-
rodzaju sprawy dokument, po rejestracji w aplikacji Elek- kacji FK. Warto także zauważyć, że opracowane struktu-
troniczny Obieg Dokumentów (EOD), trafia albo do lokal- ry danych umożliwiają opracowanie schematu każdego ro-
nego systemu POLTAX w US albo do realizacji zgodnie dzaju formularza podatkowego, nie tylko tych składanych
z przyjętą w US instrukcją kancelaryjną. CRD udostępnia przez przedsiębiorców.
podatnikowi informacje na temat stanu załatwiania spra- Zastosowanie bezpiecznego podpisu elektronicznego na
wy w US. Ponadto podatnik za pośrednictwem Centralnej obecnym etapie dostępności systemu tylko dla grupy naj-
Bazy Danych Operacyjnych (CBDO) będzie miał dostęp większych przedsiębiorców nie jest oczywiście żadnym pro-
m.in. do informacji o stanie swojego salda. blemem, ale już małego przedsiębiorcy lub osobę nie pro-
W systemie e-Deklaracje bazy CBDO, CRD i CRP bę- wadzącą działalności gospodarczej, konieczność zakupu
dą stanowiły podstawowe źródło informacji zarówno dla po- odpowiedniego urządzenia i opłacania abonamentu raczej
datników jak i organów podatkowych. Ułatwi to i znacz- nie zachęci do elektronicznego rozliczania się z fiskusem.
nie przyspieszy wymianę informacji pomiędzy urzędami Niewykluczone jednak, że w tematyce podpisu elektronicz-
i izbami skarbowymi oraz urzędami kontroli skarbowej. nego będą zmiany, ale to już jest temat na odrębny arty-
Z bazami tymi będą współpracować inne działające obecnie kuł. W każdym razie MF w ramach projektu e-Deklaracje nie
systemy centralne np. VIES (ang. VAT Information Exchange przewiduje udostępniania własnych certyfikatów.
System). System e-POLTAX niestety nie jest pozbawiony wad. Za-
uważyli to m.in. doradcy podatkowi, którzy spotkali się na
Podsumowanie przedstawicielami MF na początku października 2006 roku.
System e-POLTAX nie jest rozwiązaniem docelowym dla Oto postulaty wysuwane przez doradców, z którymi zgadza
polskich podatników i administracji skarbowej, ale z ca- sie także autor:

• udostępnienie systemu w wersji testowej;


Terminy wprowadzenia • możliwości podpisania i wysłania wielu deklaracji w pacz-
deklaracji elektronicznych kach, przy czym system przesyłałby potwierdzenie dla
każdej deklaracji;
• 16 sierpnia 2006: PIT-4, PIT-8A;
• znakowania czasem w momencie wysłania deklaracji,
• 1 października 2006: VAT-7, VAT-7K, VAT-8, VAT-9;
a nie w momencie otrzymania deklaracji przez system.
• 1 grudnia 2006: CIT-2, CIT-2/O, CIT-8, CIT-8/O, CIT-6, CIT-D,
VAT-23, VAT-24;
• 1 lutego 2007: VAT-10, VAT-11, VAT-12, VAT-Z, VAT-R, VAT- W czasie, gdy ukaże się niniejszy tekst dostępne już będą ko-
R/UE, VAT-UE, VAT-UE/A, VAT-UE/B, VAT-UEK, WZS-1K, lejne schematy deklaracji podatkowych. Pozostaje mieć na-
WZS-1M, WZS-1R, WZP-1K, WZP-1R, WZP-1M, ORD-U, dzieję, że cały system e-Deklaracje zostanie uruchomiony
ORD-TK, ORD-W1, POG-3A, IFT-1/IFT-1R, IFT-2/IFT-2R, IFT- w terminie, a w dalszej perspektywie wszyscy podatnicy będą
3/IFT-3R, IFT/A. mieli możliwość odwiedzenia swojego US bez konieczności wy-
chodzenia z własnego domu. n

Software Developer’s Journal 1/2007 www.sdjournal.org 35


Aplikacje

biznesowe

Business Process
Piotr Skrobisz
Execution Language
N
Materiały do artykułu ieustannie zmieniające się warunki rynkowe
zamieszczone zostały
na płycie CD 1
i wymagania klientów, wymuszają na przed- Przykłady zastosowań
siębiorstwach ciągłe udoskonalanie i zmia- Oracle BPEL Process Manager’a
nę procesów biznesowych. Powoduje to dodawanie
coraz to nowszych aplikacji i rozbudowę istniejących • State Children’s Health Insurance Program (SCHIP).
systemów. W firmach o niskiej komputeryzacji budo- Amerykańska firma Policy Studies, Inc. wykorzystała
wa nowych systemów wspierających jej działalność, technologię BPEL do budowy systemu typu workflow,
jak CRM (Customer Relationship Management), czy wspierającego przetwarzania wniosków rejestracji do
ERP (Enterprise Resource Planning), przynosi duży amerykańskiego programu ubezpieczeń SCHIP;
• Dostawca elektryczności – integracja aplikacji w od-
zwrot z inwestycji. Jednak przy dużej liczbie wdro-
działach. Firma WIPRO użyła technologii BPEL do
żonych aplikacji, zwrot z coraz to nowszych projek-
usprawnienia komunikacji pomiędzy oddziałami jed-
tów maleje. Szefowie działów IT muszą borykać się nego z dużych dostawców elektryczności. Każdy z lo-
z napiętymi planami, ograniczonymi budżetami, ro- kalnych oddziałów posiadał swoją własną aplikację do
snącą złożonością systemów informatycznych, ryzy- obsługi procesów biznesowych. Tak duża heteroge-
kiem ich rozbudowy i coraz trudniejszą replikacją da- niczność wymusiła zastosowanie architektury SOA;
nych pomiędzy niekompatybilnymi systemami. • Corrections Corporation Of America (CCA) – inte-
Odpowiedzią na te problemy jest architektura zo- gracja aplikacji dla systemu więziennictwa. BPEL
rientowana na serwisy (ang. Service Oriented Archi- został wykorzystany przez firmę BIAS do zaimple-
tecture), w skrócie SOA. Dzięki niej możliwe jest bu- mentowania wymiany danych pomiędzy systemami
dowanie nowych wielofunkcyjnych aplikacji poprzez dwóch amerykańskich firm z sektora więziennictwa
– CCA i Hamilton County Jail Systems (CJIS);
agregację funkcjonalności już istniejących systemów.
• Health Canada – kontrola wydawania i niszcze-
Odbywa się to w sposób 2-fazowy. Najpierw udostęp-
nia leków. W Kanadzie BPEL znalazł zastosowa-
niane są serwisy, które eksponują usługi już istnieją- nie przy automatyzacji procesu kontroli wydawania
cych systemów. Następnie wiele serwisów jest łączo- i niszczenia leków. Budowa systemu wymagała in-
nych i komponowanych w jeden proces biznesowy. tegracji z wieloma państwowymi wydziałami i agen-
cjami oraz instytucjami międzynarodowymi;
SOA i BPEL • Lufthansa Flight Training (LFT) – system CRM.
SOA było rozwiązaniem znanym już w ubiegłym dzie- Spółka LFT, należąca do Lufthansa AG, wykorzy-
sięcioleciu. Jednakże rynek cierpiał na brak ustanda- stała BPEL do budowy łatwo modyfikowalnego sys-
ryzowanego sposobu integracji systemów. Obecnie temu CRM zintegrowanego z SAP Financials i inny-
coraz większą popularnością cieszy się Business Pro- mi wykorzystywanymi w firmie aplikacjami;
• Washington Group International (WGI) – system
cess Execution Language for Web Services (BPEL lub
ERP. WGI dostarcza usług z najróżniejszych sek-
BPEL4WS). Jest to język, który służy do definiowania
torów przemysłu, jak budownictwo, górnictwo,
i wykonywania procesów biznesowych z wykorzysta- transport, czy energetyka. Działalność takiej firmy
niem web serwisów, za pomocą których wyekspono- wspierana jest przez ogromną liczbę najróżniejsze-
wane są serwisy podsystemów. Budowa procesu biz- go oprogramowania i serwerów. Przy tak heteroge-
nesowego polega na łączeniu i koordynowaniu wielu nicznym środowisku BPEL okazał się idealną tech-
web serwisów w jednym przepływie. nologią do budowy systemu ERP.
BPEL łączy cechy dwóch starszych języków
służących do opisu przepływów pracy (ang. work-
flow). Pierwszym z nich jest WSFL (Web Service Pierwsza wersja BPEL-a pojawiła się w sierpniu
Flow Language), stworzony przez IBM i oparty na 2002 roku. Przyciągnęła ona uwagę wielu firm, któ-
teorii grafów skierowanych. Drugim jest dziecko Mi- re przyłączyły się do współpracy. Zaowocowało to
crosoftu, XLANG, który wykorzystywał ideę sche- w marcu 2003 roku stworzeniem wersji 1.1, któ-
matów blokowych. ra miesiąc później została przekazana do organiza-
cji standaryzacyjnej OASIS (Organization for the Ad-
Autor pracuje w firmie Oracle Corporation w dziale Mobi-
vancement of Structured Information Standards).
le, Wireless and Voice Solutions, gdzie zajmuje się pro-
jektowaniem systemów informatycznych. Jest również Podstawy języka
doktorantem w Instytucie Badań Systemowych PAN. Definicja procesu biznesowego w języku BPEL pole-
Kontakt z autorem: piotr.skrobisz@oracle.com ga na określeniu porządku wywoływanych web ser-
wisów. Czy mają być one wywoływane sekwencyj-

36 www.sdjournal.org Software Developer’s Journal 1/2007


Business Process Execution Language

nie, czy też równolegle. Możliwe jest określenie operacji warun- • <pick> - umożliwia wybór jednej z wielu alternatywnych
kowych, pętli, czy też obsługa wyjątków. Język pozwala na de- ścieżek na podstawie zdefiniowanych zdarzeń;
finiowanie zmiennych, kopiowanie i przypisywanie ich wartości. • <catch> i <catchAll> - pozwalają na przechwytywanie i ob-
Dzięki temu możliwe jest przekazywanie danych pomiędzy web sługę wyjątków podobnie, jak w Javie w przypadku kon-
serwisami i gromadzenie ich w trakcie realizacji procesu. strukcji try-catch.
Składnia języka opiera się na XML-u, a z racji tego, że pro-
ces operuje na web serwisach, wykorzystywane są lub mogą Do bardzo ważnych elementów języka należą dodatkowo:
być między innymi takie standardy, jak SOAP, WSDL, UDDI,
WS-Addressing, WS-ReliableMessaging, WS-Security, WS- • <scope> - pozwala na wyodrębnianie logicznych bloków
Coordination, WS-Transaction. Należy zauważyć, że proces w całym procesie. Taki blok może posiadać lokalne zmien-
BPEL-owy sam w sobie jest web serwisem i może być wyko- ne niewidoczne poza nim, obsługę wyjątków dla czynno-
rzystywany przez inne procesy, jako podproces. Proces biz- ści w nim zawartych oraz obsługę rekompensacji w przy-
nesowy składa się z czynności. Do podstawowych należą na- padku wycofywania transakcji;
stępujące elementy: • <partnerLink> - wskaźnik na wykorzystywane web serwisy;
• <variable> - definicja zmiennej.
• <invoke> - wywołanie web serwisu;
• <receive> - oczekiwanie na wywołanie procesu przez Budowa przykładowego
klienta i odebranie od niego wiadomości; procesu biznesowego
• <reply> - zwrócenie odpowiedzi w przypadku synchronicz- Najlepszym sposobem nauki jest praktyka, dlatego w niniejszym
nego wywołania procesu; artykule zbudujemy prosty proces BPEL-owy do obsługi zamó-
• <assign> - operacje na wartościach zmiennych; wień książek. Aplikacja klienta (dalej dla uproszczenia nazywana
• <wait> - uśpienie procesu, na określony czas; klientem) przy wywołaniu procesu będzie przekazywać informa-
• <throw> - wyrzucenie wyjątku, analogicznie jak w Javie; cje takie jak: tytuł książki, autorzy, ilość egzemplarzy, numer kar-
• <terminate> - zakończenie procesu na przykład w wyniku ty kredytowej, datę jej ważności, imię i nazwisko zamawiające-
błędu lub awarii; go oraz adres, dokąd książka ma być wysłana. Zadaniem nasze-
• <compensete> - wywołanie czynności rekompensujących go systemu, będzie weryfikacja podanej karty kredytowej, odpy-
(ang. compansation) w przypadku potrzeby wycofania tanie równolegle dwóch księgarni o cenę danej książki, wybra-
transakcji. nie księgarni, gdzie cena książki jest najniższa, a następnie jej
zakup. Na końcu proces przekaże żądanie dostarczenia pacz-
Analogicznie, jak w tradycyjnych językach programowania, ki do podsystemu, zajmującego się dostawą. Będzie go symulo-
tak również w BPEL-u nie obyłoby się bez elementów od- wał inny proces BPEL-owy. Do budowy naszego systemu wyko-
powiedzialnych za kontrolę przepływu. Do dyspozycji mamy rzystamy wcześniej przygotowane web serwisy, symulujące sys-
między innymi: temy zewnętrzne, z którymi się zintegrujemy (operator kart kre-
dytowych oraz dwie księgarnie). Rysunek 1 przedstawia sche-
• <switch> - definiuje instrukcje warunkowe; mat procesu, którego budową się zajmiemy. Do konstrukcji na-
• <while> - pętla; szego procesu wykorzystamy Oracle JDeveloper 10g w wersji
• <sequence> - oznacza, że zawarty w niej zbiór czynności 10.1.3.1.0, a do jego uruchomienia Oracle BPEL Process Mana-
ma być wykonany sekwencyjnie; ger 10.1.3.1.0. Oba programy można ściągnąć za darmo z nastę-
• <flow> - pozwala na wykonywanie czynności równolegle; pującej strony: http://www.oracle.com/technology/software/tech/

�����������������������������������
��������

��������� ������
������

����������� ����������
��������� ���������
����� ������

������� ���
������������ �������
���������������

������������� �������������
��������

���������� ������� �������


������
����� ����������� ������
���������
��������� ���� ���������
����� ������
������� ���
������������ �������
������������� �������������

Rysunek 1. Schemat procesu do obsługi zamówień książek

Software Developer’s Journal 1/2007 www.sdjournal.org 37


Aplikacje
biznesowe

zwisko właściciela. W przypadku problemów z kartą wy-


rzucany jest wyjątek:
void checkCreditCard(String cardNo, Date validTo,
String name)
throws CreditCardException
• BookStore1WS – usługa pierwszej księgarni. Posiada dwie
metody. Pierwsza zwraca cenę książki. Jako parametry
wejściowe przyjmowany jest tytuł i autorzy. Druga metoda
służy do zakupu książki. Na wejściu przyjmuje tytuł, auto-
rów, numer karty, datę jej ważności, imię i nazwisko zama-
wiającego oraz ilość egzemplarzy:
double requestForQuote(String title, String authors)
int orderBook(String title, String authors,
String creditCard,
Date validTo,String name, int quantity)
Rysunek 2. Nowy asynchroniczny proces BPEL-owy
• BookStore2WS – usługa drugiej księgarni. Posiada analo-
webservices/index.html. Instalacja nie powinna nastręczyć więk- giczne metody. Różnią się one jedynie nazwami dla zróż-
szych trudności. W przypadku JDeveloper’a sprowadza się do nicowania naszego przypadku:
jego rozpakowania. BPEL PM instaluje się przez uruchomienie double RFQ(String title, String authors)
programu setup.exe. Do naszych celów wystarczy wybranie opcji int buyBook(String title, String authors, String creditCard,
deweloperskiej. W dalszej części artykułu założymy, że został on Date validTo, String name, int quantity)
zainstalowany na domyślnym porcie 9700. W pierwszej kolejno-
ści przystąpimy do zainstalowania wyżej wspomnianych web Opis tworzenia web serwisów wykracza poza ten artykuł,
serwisów, a następnie zbudujemy cały proces. dlatego wymagana jest podstawowa znajomość tej techno-
logii. Czytelnik może również skorzystać z gotowych źródeł
Przygotowanie web serwisów umieszczonych na płycie dołączonej do magazynu.
Zgodnie z wcześniejszą deklaracją przy budowie naszego Jednym ze sposobów umieszczenia web serwisów w konte-
procesu biznesowego skorzystamy z trzech web serwisów. nerze J2EE (wykorzystamy kontener OC4J dostarczany z Orac-
Do celów edukacyjnych wystarczy by były to jedynie proste le BPEL PM) jest wykorzystanie JDevelopera. W tym celu wybie-
klasy Javy symulujące systemy zewnętrzne. Będą one udo- ramy z File->New->General->Applications->Application. Po po-
stępniały następujące funkcjonalności: daniu nazwy i katalogu w oknie dialogowym klikamy na przycisk
Ok. W następnym oknie rezygnujemy ze stworzenia nowego pro-
• CreditCardCheckWS – posiada tylko jedną metodę do jektu. Do wybranego katalogu kopiujemy z płyty cały projekt za-
weryfikacji karty kredytowej. Jako parametry wejściowe wierający web serwisy – katalog ExternalWS. Dodajemy go ko-
przyjmuje numer karty, datę jej ważności oraz imię i na- rzystając z menu File->Open i wybierając plik ExternalWS.jpr.

Listing 1. Nowy asynchroniczny proces BPEL-owy

<?xml version = "1.0" encoding = "UTF-8" ?> </partnerLinks>


<process name="OrderBook" <variables>
targetNamespace="http://xmlns.oracle.com/OrderBook" <variable name="inputVariable"
xmlns="http://schemas.xmlsoap.org/ws/2003/03/ messageType="client:OrderBookRequestMessage"/>
business-process/" <variable name="outputVariable"
xmlns:client="http://xmlns.oracle.com/OrderBook" messageType="client:OrderBookResponseMessage"/>
xmlns:ora="http://schemas.oracle.com/xpath/extension" </variables>
xmlns:orcl="http://www.oracle.com/XSL/Transform/java/ <sequence name="main">
oracle.tip.pc.services.functions.ExtFunc" <receive name="receiveInput"
xmlns:xp20="http://www.oracle.com/XSL/Transform/java/ partnerLink="client"
oracle.tip.pc.services.functions.Xpath20" portType="client:OrderBook"
xmlns:ldap="http://schemas.oracle.com/xpath/ operation="initiate"
extension/ldap" variable="inputVariable"
xmlns:bpelx="http://schemas.oracle.com/bpel/extension" createInstance="yes"/>
xmlns:bpws="http://schemas.xmlsoap.org/ws/ <invoke name="callbackClient"
2003/03/business-process/"> partnerLink="client"
<partnerLinks> portType="client:OrderBookCallback"
<partnerLink name="client" operation="onResult"
partnerLinkType="client:OrderBook" inputVariable="outputVariable"/>
myRole="OrderBookProvider" </sequence>
partnerRole="OrderBookRequester"/> </process>

38 www.sdjournal.org Software Developer’s Journal 1/2007


Business Process Execution Language

W kolejnym kroku tworzymy połączenie z kontenerem


J2EE. Klikamy prawym klawiszem myszy w zakładce Connec-
tions na folderze Application Server i wybieramy New Appli-
cation Server Connection. Jako typ serwera aplikacji pozosta-
wiamy opcję Autonomiczny OC4J 10g 10.1.3.
W celu umieszczenia web serwisów należy w zakład-
ce Applications Navigator kliknąć prawym klawiszem myszy
na pliku WebServices.deploy i wybrać Deploy To oraz nazwę
wcześniej zdefiniowanego połączenia. Jeśli wszystko się po-
wiodło, to web serwisy powinny być dostępne z poziomu prze-
glądarki, a w szczególności ich opisy WSDL:

• http://localhost:9700/external/CreditCardCheckWSSoapHt-
tpPort?wsdl;
• http://localhost:9700/external/BookStore1WSSoapHttpPort
?wsdl;
• http://localhost:9700/external/BookStore2WSSoapHttpPor-
t?wsdl.
Rysunek 3. Wywołanie web serwisu z obsługą wyjątku
Oczywiście możliwe jest umieszczenie ich na dowolnym ser-
werze aplikacyjnym, jak również stworzenie własnych web wybieramy File->New->General->Projects->BPEL Process Pro-
serwisów, niekoniecznie zaimplementowanych w Javie, do ject. Podajemy nazwę procesu, np. OrderBook i jako typ proce-
czego serdecznie zachęcam. su pozostawiamy Asynchronous BPEL Process. Zatwierdzamy
wszystko naciskając przycisk Finish. Generator stworzył nowy
Stworzenie nowego projektu BPEL proces, który w zakładce Diagram powinien wyglądać tak, jak na
Mając już gotowe web serwisy możemy przystąpić do ich inte- Rysunku 2. Zwróćmy uwagę na pliki, jakie wygenerował kreator:
gracji budując asynchroniczny proces. Do tego celu użyjemy kre-
atora, który wygeneruje cały szkielet projektu BPEL-owego: plik • OrderBook.bpel – źródło procesu;
źródłowy procesu, interfejs WSDL, deskryptor oraz skrypt Ant- • OrderBook.wsdl – opis interfejsu procesu, parametry wej-
owy do kompilacji i umieszczania procesu na serwerze. Z menu ściowe i wyjściowe. Dzięki temu możliwe jest wywoływa-
nie procesu z poziomu innych procesów i aplikacji;
Listing 2. Definicja parametrów wejściowych i • OrderBook.xsd – plik XML Schema, który definiuje dane
wyjściowych procesu wejściowe i wyjściowe dla procesu. Jest on importowany
w OrderBook.wsdl;
<schema attributeFormDefault="unqualified" • build.xml i build.properties – pliki Ant-owe do kompilacji
elementFormDefault="qualified" i umieszczania procesu na serwerze.
targetNamespace="http://xmlns.oracle.com/OrderBook"
xmlns="http://www.w3.org/2001/XMLSchema"> Jeśli wybierzemy plik OrderBook.bpel i przejdziemy do zakład-
<element name="OrderBookProcessRequest"> ki Source, będziemy mieli możliwość zobaczenia źródła procesu.
<complexType> Powinien być podobny do tego z Listingu 1. Na razie proces nic
<sequence> nie robi, poza odebraniem danych wejściowych od klienta (<rece-
<element name="title" type="string"/> ive>), który go wywołuje, oraz wywołaniem klienta i przekazaniu
<element name="authors" type="string"/> mu odpowiedzi (<invoke>). Te dwa wywołania są korelowane auto-
<element name="quantity" type="int"/> matycznie dzięki wykorzystaniu standardu WS-Addressing. Klient
<element name="creditCardNo" type="string"/> zdefiniowany jest w elemencie <partnerLink> w sekcji <partner-
<element name="validTo" type="dateTime"/> Links>. Tu też będą pojawiać się połączenia do wykorzystywa-
<element name="name" type="string"/> nych web serwisów. W elemencie <variables> umieszczone są
<element name="address" type="string"/> dwie zmienne, przechowujące odpowiednio dane wejściowe i wyj-
</sequence> ściowe. Przed przystąpieniem do komponowania procesu musi-
</complexType> my określić jakie dane będzie on otrzymywał i zwracał. Dla nasze-
</element> go prostego przykładu, jako parametry wejściowe wystarczą: tytuł,
<element name="OrderBookProcessResponse"> autorzy, ilość egzemplarzy, numer karty kredytowej, data jej waż-
<complexType> ności, imię i nazwisko, adres. Po zakończeniu proces będzie zwra-
<sequence> cał string z informacją, że książka została wysłana. Informacje te
<element name="result" type="string"/> definiuje się w pliku XML Schema, w naszym przypadku w Order-
</sequence> Book.xsd. Należy go zmienić tak, jak pokazano to na Listingu 2.
</complexType>
</element> Wywołanie web serwisu
</schema> Zgodnie z Rysunkiem 1 pierwszym krokiem w naszym procesie
jest weryfikacja karty kredytowej. Sprowadza się on do wywoła-

Software Developer’s Journal 1/2007 www.sdjournal.org 39


Aplikacje
biznesowe

Te same kroki powtarzamy dla daty ważności oraz imienia


i nazwiska. W ten sposób zdefiniowaliśmy wywołanie web ser-
wisu weryfikującego kartę kredytową, a tym samym skonstru-
owaliśmy pierwszy krok naszego procesu biznesowego. Efekt
powinien być zbliżony do przedstawionego na Listingu 3.

Obsługa wyjątków
Wywoływany web serwis może wyrzucać wyjątki. Podob-
nie do języków programowania takich jak Java, BPEL umoż-
liwia ich obsługę. W naszym przypadku metoda checkCre-
ditCard, może wyrzucić wyjątek CreditCardException przy
braku pomyślnej weryfikacji karty. Gdy taka sytuacja na-
stąpi zakończymy cały proces biznesowy. Obsługę wyjąt-
ków można dodawać dla elementów Scope. W tym celu wy-
bieramy w nim ikonkę Add Catch Branch. Powoduje to poja-
Rysunek 4. Test procesu BPEL-owego w konsoli wienie się elementu <faultHandlers>. Klikamy na jego repre-
administracyjnej zentację graficzną i w oknie dialogowym naciskamy ikonkę
Browse Faults. Wybieramy Partner Links->CreditCardChec-
nia web serwisu CreditCardCheckWS. Całe wywołanie umieści- kWS->Imported WSDL->CreditCardCheckWSSoapHttpPort-
my w nowym elemencie <scope>, co pozwoli na logiczne wyod- >CreditCardException.
rębnienie tego kroku, jak również późniejszą obsługę wyjątków. Do zakończenia procesu służy komponent Terminate. Wy-
W tym celu z zakładki Component Palette przeciągamy kompo- starczy go przeciągnąć na obszar elementu <faultHandlers>.
nent Scope i umieszczamy go pomiędzy już istniejącymi czynno- Po tych operacjach nasz proces powinien przypominać ten
ściami receiveInput i callbackClient. Rozwijamy komponent Sco- przedstawiony na Rysunku 3.
pe naciskając znaczek plusa. Teraz możemy w nim umieszczać
inne elementy. Przed definiowaniem wywołania web serwisu mu- Listing 3. Wywołanie web serwisu CreditCardCheckWS
simy stworzyć dla niego wskaźnik. Robi się to przez przeciągnię-
cie komponentu PartnerLink na pole Services. W oknie dialogo- <scope name="checkingCreditCard"><variables>
wym podajemy lokalizację opisu WSDL web serwisu (np. http:// <variable name="checkCreditCard_Input"
localhost:9700/external/CreditCardCheckWSSoapHttpPort?ws messageType="ns1:CreditCardCheckWS_checkCreditCard"/>
dl) i naciskamy ikonkę Parse WSDL File. Zatwierdzamy próbę <variable name="checkCreditCard_Output"
stworzenia pliku WSDL z opisem typu Partner Link’a. Jako Part- messageType=
ner Role wybieramy z listy jedyną opcję, CreditCardCheckWS_ "ns1:CreditCardCheckWS_checkCreditCardResponse"/>
Role. Zamykamy okno naciskając przycisk Ok. </variables><sequence name="Sequence_1">
Teraz jesteśmy gotowi do zdefiniowania wywołania web ser- <assign name="Assign_CardNo"><copy>
wisu. W tym celu przeciągamy komponent Invoke i umieszczamy <from variable="inputVariable" part="payload"
go w elemencie Scope. Następnie przeciągamy ikonkę strzałki query="/client:OrderBookProcessRequest/
do uprzednio stworzonego ParnterLink’a. W oknie dialogowym client:creditCardNo"/>
zmieniamy nazwę i upewniamy się, że wybraną operacją web <to variable="checkCreditCard_Input" part="parameters"
serwisu jest ta, która służy do weryfikacji karty. Następnie two- query="/ns2:checkCreditCardElement/ns2:cardNo"/>
rzymy zmienną wejściową i wyjściową, klikając na ikonki Auto- </copy><copy>
matically Create Input Variable. Możemy zaznaczyć opcje Local <from variable="inputVariable" part="payload"
Variable, aby zmienne były widoczne jedynie w zakresie elemen- query="/client:OrderBookProcessRequest/client:validTo"/>
tu Scope. Zatwierdzamy zmiany, naciskając przycisk Ok. Do tak <to variable="checkCreditCard_Input" part="parameters"
zdefiniowanego wywołania musimy jeszcze przekazać wartości query="/ns2:checkCreditCardElement/ns2:validTo"/>
– numer karty kredytowej, datę jej ważności oraz imię i nazwi- </copy><copy>
sko. Przekopiujemy je ze zmiennej wejściowej procesu do zmien- <from variable="inputVariable" part="payload"
nej wejściowej elementu Invoke. Dokonuje się tego poprzez uży- query="/client:OrderBookProcessRequest/client:name"/>
cie komponentu Assign. Umieszczamy go przed elementem In- <to variable="checkCreditCard_Input" part="parameters"
voke. Klikamy na niego dwa razy. W oknie dialogowym wybiera- query="/ns2:checkCreditCardElement/ns2:name"/>
my opcję Create->Copy operation. W części From wybieramy ze </copy></assign>
zmiennej wejściowej procesu numer karty. Powinniśmy uzyskać <invoke name="checkCreditCard"
wyrażenie XPath (wyświetlane na dole okna) podobne do tego: partnerLink="CreditCardCheckWS"
portType="ns1:CreditCardCheckWS"
/client:OrderBookProcessRequest/client:creditCardNo operation="checkCreditCard"
inputVariable="checkCreditCard_Input"
Analogicznie w sekcji To konstruujemy wyrażenie dla zmien- outputVariable="checkCreditCard_Output"/>
nej wejściowej dla elementu Invoke: </sequence>
</scope>
/ns2:checkCreditCardElement/ns2:cardNo

40 www.sdjournal.org Software Developer’s Journal 1/2007


Business Process Execution Language

Kompilacja i uruchomienie procesu


Pomimo, że nasz proces nie jest jeszcze skończony, warto
go skompilować i przetestować. Upewnimy się, że web ser-
wis CreditCardCheckWS jest w rzeczywistości wywoływany.
Zakładając, że Oracle BPEL PM jest uruchomiony, tworzymy
w JDeveloperze połączenie do niego. Postępujemy podobnie,
jak to miało miejsce w przypadku połączenia do kontenera
J2EE, z tym, że nie wybieramy opcji Application Server, a Inte-
gration Server. Należy pamiętać, że domyślnie serwer pracuje
na porcie 9700. Po pomyślnym skonfigurowaniu połączenia,
umieszczamy aplikację na serwerze, klikając prawym klawi-
szem myszy na projekcie BPEL-owym i wybierając Deploy To-
>Nazwa naszego połączenia->Deploy to default domain. Apli-
kacja zostanie skompilowana i umieszczona na serwerze.
Teraz możemy przejść do konsoli administracyjnej Orac-
le BPEL Process Manager’a i przetestować naszą aplikację.
Rysunek 5. Graf czynności dla naszego procesu BPEL-owego
W tym celu otwieramy przeglądarkę i przechodzimy do http://
localhost:9700/BPELConsole. Logujemy się jako bpeladmin sny opis WSDL). Wypełniamy formularz z danymi wejściowymi
(domyślne hasło: welcome1). Jeśli wszystko się powiodło, to po- i naciskamy przycisk Post XML Message (patrz Rysunek 4).
winniśmy zobaczyć w konsoli administracyjnej w zakładce Da- Proces zostaje uruchomiony. Klikając na ikonkę Visual
shboard nasz proces OrderBook. Po kliknięciu na nim przecho- Flow możemy zobaczyć, jakie kolejne kroki zostały wykona-
dzimy do panelu Initiate, który pozwala na przetestowanie na- ne. Możliwe jest też podejrzenie przesyłanych danych i we-
szego procesu. Jest to wygenerowany dynamicznie klient, któ- ryfikację, czy cały proces przebieg tak, jak zakładaliśmy. Je-
ry wywołuje naszą aplikację, jak zwykły web serwis (jak zosta- śli web serwis CreditCardCheckWS został wywołany bez błę-
ło to wcześniej wspomniane, proces posiada również swój wła- dów, graf czynności powinien być taki, jak na Rysunku 5.

Listing 4. Zrównoleglenie procesu BPEL-owego

<scope name="checkPrices"> outputVariable="checkBookStore2_Output"/>


<variables> </sequence>
<variable name="checkBookStore1_Input" <sequence name="Sequence_2">
messageType="ns1:BookStore1WS_requestForQuote"/> <assign name="setBookDetails1">
<variable name="checkBookStore2_Input" <copy>
messageType="ns1:BookStore2WS_RFQ"/> <from variable="inputVariable" part="payload"
</variables> query="/client:OrderBookProcessRequest/
<flow name="Flow_1"> client:title"/>
<sequence name="Sequence_2"> <to variable="checkBookStore1_Input"
<assign name="setBookDetails2"> part="parameters"
<copy> query="/ns2:requestForQuoteElement/ns2:title"/>
<from variable="inputVariable" part="payload" </copy>
query="/client:OrderBookProcessRequest/ <copy>
client:title"/> <from variable="inputVariable" part="payload"
<to variable="checkBookStore2_Input" query="/client:OrderBookProcessRequest/
part="parameters" client:authors"/>
query="/ns2:RFQElement/ns2:title"/> <to variable="checkBookStore1_Input"
</copy> part="parameters"
<copy> query="/ns2:requestForQuoteElement/ns2:authors"/>
<from variable="inputVariable" part="payload" </copy>
query="/client:OrderBookProcessRequest/ </assign>
client:authors"/> <invoke name="checkBookStore1"
<to variable="checkBookStore2_Input" partnerLink="BookStore1WS"
part="parameters" portType="ns1:BookStore1WS"
query="/ns2:RFQElement/ns2:authors"/> operation="requestForQuote"
</copy> inputVariable="checkBookStore1_Input"
</assign> outputVariable="checkBookStore1_Output"/>
<invoke name="checkBookStore2" </sequence>
partnerLink="BookStore2WS" </flow>
portType="ns1:BookStore2WS" operation="RFQ" </scope>
inputVariable="checkBookStore2_Input"

Software Developer’s Journal 1/2007 www.sdjournal.org 41


Aplikacje
biznesowe

Rysunek 6. Zrównoleglenie procesu BPEL-owego

Zachęcam do testu dla przypadku, gdy web serwis Credit-


CardCheckWS wyrzuca wyjątek (jeśli została użyta dostarczo-
na implementacja, należy podać numer karty 123456789). Wów-
czas powinien on być obsłużony, poprzez zatrzymanie procesu.

Wywołania równoległe Rysunek 7. Wywołanie asynchroniczne


Przystąpmy teraz do dalszej budowy naszego procesu. Zgod-
nie z Rysunkiem 1 mamy odpytać dwie księgarnie o cenę książ- Po zakończeniu wymienionych kroków powinniśmy uzy-
ki. Oba te wywołania nie są ze sobą powiązane, dlatego najle- skać wynik przedstawiony na Listingu 4 i Rysunku 6.
piej wykonać obie czynności równolegle. Do rozdzielania proce-
su na dwie ścieżki służy komponent Flow. Możemy go umieścić Warunki
w nowym elemencie Scope dla logicznego wyodrębnienia te- BPEL umożliwia również operacje warunkowe, co pozwala na
go kroku. W ten sposób proces został rozdzielony na dwie rów- wybór odpowiedniej ścieżki w zależności od wyników uzyska-
noległe ścieżki. BPEL gwarantuje nam, że wszystkie operacje nych w poprzedzających operacjach. W naszym przypadku
z obu ścieżek zostaną wykonane, zanim proces przystąpi do ko- chcemy porównać ceny książki w obu księgarniach i dokonać
lejnych czynności. W pierwszej ścieżce musimy wywołać web zakupu tam, gdzie jest ona tańsza. Do tego celu posłuży nam
serwis księgarni 1, BookStore1WS, a konkretnie metodę odpytu- komponent Switch. Przypomina operację switch znaną z tra-
jącą o cenę książki. W drugiej ścieżce wywołujemy web serwis dycyjnych języków programowania. Może posiadać wiele ele-
BookStore2WS. Obie operacje konstruujemy w podobny spo- mentów <case>, do których przypisane są warunki oraz jeden
sób, jak miało to miejsce w przypadku CrediCardCheckWS. Two- blok <otherwise>, który jest wykonywany, jeśli żaden z warun-
rzymy PartnerLink’i, konfigurujemy komponenty Invoke, za pomo- ków nie zostanie spełniony. Z racji tego, że musimy porównać
cą Assign kopiujemy wartości do parametrów wejściowych (tytuł, dwie ceny, wystarczy nam jeden element <case> i <otherwise>.
autorzy oraz imię i nazwisko). Jeśli całe zrównoleglenie umieści- Warunki dodajemy po kliknięciu ikonki View Condition Expres-
liśmy w odrębnym elemencie Scope, to zmienne wyjściowe kom- sion. Możemy wpisać sami odpowiednie wyrażenie XPath
ponentów Invoke pozostawmy, jako zmienne globalne. Posłużą lub skorzystać z pomocy kreatora, klikając na ikonkę XPath
one przy operacji warunkowej, do porównania cen książki. Expression Builder. W naszym przypadku musimy porównać

Listing 5. Operacja warunkowa Switch

<switch name="LowerPrice"> </sequence>


<case condition="bpws:getVariableData( </case>
'checkBookStore1_Output','parameters','/ns2: <otherwise>
requestForQuoteResponseElement/ns2:result') <sequence name="Sequence_4">
<=bpws:getVariableData('checkBookStore2_Output',' <assign name="setOrderDetails2">
parameters','/ns2:RFQResponseElement/ns2:result')"> <!--Tutaj kopiujemy ze zmiennej wejściowej procesu
<sequence name="Sequence_3"> do zmiennej buyBook2_Input składowe: title, authors,
<assign name="setOrderDetails1"> quantity, creditCardNo, validTo, name. -->
<!--Tutaj kopiujemy ze zmiennej wejściowej procesu </assign>
do zmiennej buyBook1Input składowe: title, authors, <invoke name="buyBook2" partnerLink="BookStore2WS"
quantity, creditCardNo, validTo, name. --> portType="ns1:BookStore2WS" operation="buyBook"
</assign> inputVariable="buyBook2_Input"
<invoke name="buyBook1" partnerLink="BookStore1WS" outputVariable="buyBook2_Output"/>
portType="ns1:BookStore1WS" </sequence>
operation="orderBook" </otherwise>
inputVariable="buyBook1Input" </switch>
outputVariable="buyBook1_Output"/>

42 www.sdjournal.org Software Developer’s Journal 1/2007


Business Process Execution Language

wartości zmiennych zwróconych przez web serwisy księgarni.


Odpowiada temu poniższe wyrażenie: W Sieci
• artykuły, tutoriale, dokumentacje, porady na temat technologii
bpws:getVariableData('checkBookStore1_Output',
BPEL oraz serwera Oracle BPEL PM
'parameters',
http://www.oracle.com/technology/products/ias/bpel/index.html
'/ns2:requestForQuoteResponseElement/ns2:result')
• strona domowa organizacji standaryzacyjnej OASIS
<= bpws:getVariableData www.oasis-open.org
('checkBookStore2_Output','parameters','/ns2: • informacje na temat standardu WSIF
RFQResponseElement/ns2:result') http://ws.apache.org/wsif/

W następnym kroku odpowiednio w blokach <case> i <otherwi-


se> umieszczamy wywołania web serwisów księgarni, a kon- mie obsługa żądania wysłania paczki może wymagać manu-
kretnie ich metod do zakupu książki. Gotowy fragment proce- alnej pracy człowieka i może zająć kilka godzin lub dni. Z tego
su przedstawia Listing 5. powodu użycie wywołania synchronicznego, byłoby bardzo nie-
efektywne i odbijałoby się na wydajności całej aplikacji. W przy-
Podprocesy padku wywołania asynchronicznego cały proces jest usypiany
Ostatnim krokiem w naszym procesie jest przekazanie żąda- i budzony, dopiero gdy zostanie przysłana wiadomość zwrotna.
nia przesłania paczki do podsystemu, który zajmuje się ich ob- Podejście takie znacznie oszczędza zasoby serwera, gdy in-
sługą. Odbędzie się to w sposób asynchroniczny. Nasz pro- stancji takiego procesu są setki, czy tysiące.
ces wywoła odpowiedni web serwis, a następnie zatrzyma się Listing 6 przedstawia przykładowy proces FulFillOrder.
w oczekiwaniu na odpowiedź. Nic nie stoi na przeszkodzie by Po umieszczeniu procesu na serwerze, możemy przystą-
był to inny proces BPEL-owy, ponieważ na zewnątrz widoczne pić do stworzenia dla niego PartnerLink’a w procesie głów-
są one jako zwykłe web serwisy. Zbudujemy prosty proces Ful- nym. Adres opisu WSDL możemy znaleźć w konsoli admini-
FillOrder, który będzie symulował przetwarzanie wysłania pacz- stracyjnej, po kliknięciu na nazwie FulFillOrder, w zakładce
ki. Z tego powodu użyjemy komponentu Wait, który będzie usy- WSDL. Ponieważ proces będzie uruchamiany asynchronicz-
piał instancję procesu na 3 sekundy. Jako parametry wejścio- nie, to z listy Partner Role wybieramy opcję FulFillOrderProvi-
we będzie przyjmował id zamówienia, adres oraz imię i nazwi- der, a z My Role FulFillOrderRequester.
sko. Do głównego procesu, który jest klientem dla podprocesu, Proces wywołujemy za pomocą komponentu Invoke, podob-
będzie zwracany string „Book sent”. Użycie tutaj procesu asyn- nie, jak robiliśmy to dla wcześniejszych web serwisów. Do ode-
chronicznego ma swoje uzasadnienie. W rzeczywistym syste- brania wiadomości zwrotnej korzystamy z elementu Receive.
Po przekompilowaniu procesu i umieszczeniu go na ser-
Listing 6. Kod procesu do obsługi żądań wysłania paczki werze, możemy przetestować skończony proces BPEL-owy.
Warto zwrócić uwagę, że po wywołaniu procesu FullFillOrder,
<partnerLinks> główny proces jest usypiany w oczekiwaniu na odpowiedź.
<partnerLink name="client" Przedstawia to Rysunek 7.
partnerLinkType="client:FulfillOrder"
myRole="FulfillOrderProvider" Podsumowanie
partnerRole="FulfillOrderRequester"/> Niniejszy artykuł zapoznał czytelnika jedynie z podstawowymi
</partnerLinks><variables> i najczęściej używanymi elementami języka BPEL. Stanowi to
<variable name="inputVariable" jednak dobry początek do budowy własnych bardziej skompli-
messageType="client:FulfillOrderRequestMessage"/> kowanych procesów biznesowych.
<variable name="outputVariable" Warto zaznaczyć, że Oracle BPEL Process Manager nie
messageType="client:FulfillOrderResponseMessage"/> skazuje deweloperów jedynie na web serwisy. W celu umożliwie-
</variables><sequence name="main"> nia bardziej elastycznej integracji, wykorzystywany jest standard
<receive name="receiveInput" partnerLink="client" Web Service Invocation Framework (WSIF). Pozwala on na pod-
portType="client:FulfillOrder" operation="initiate" pinanie do procesu BPEL-owego zwykłych klas Javy, komponen-
variable="inputVariable" createInstance="yes"/> tów EJB, kolejek JMS, adapterów Java Connector Architecture
<assign name="setResult"><copy> (JCA), baz danych, itp. Poza elastycznością przy integracji moż-
<from expression="string('Book sent')"/> liwe jest znaczne zwiększenie wydajność, z racji wyeliminowania
<to variable="outputVariable" part="payload" narzutu, jaki niosą ze sobą web serwisy i SOAP.
query="/client:FulfillOrderProcessResponse/ Innym z ciekawych udogodnień, jakie oferuje Oracle BPEL
client:result"/> PM, jest wsparcie dla procesów wymagających udziału manual-
</copy></assign> nej pracy ludzi, jak na przykład zatwierdzanie wniosków. Dzięki
<wait name="Wait_1" for="'PT3S'"/> komponentowi Human Task, możliwe jest budowanie tzw. work-
<invoke name="callbackClient" partnerLink="client" flow’ów, co znacznie zwiększa możliwości opisywanej technologii.
portType="client:FulfillOrderCallback" BPEL jest coraz bardziej cenionym i popularnym standar-
operation="onResult" dem na rynku. Stanowi kolejny krok naprzód w świecie aplika-
inputVariable="outputVariable"/> cji biznesowych. Dowodem na to jest szybko rosnąca liczba
</sequence> jego zastosowań w systemach CRM, ERP, przetwarzania i re-
alizacji zamówień, czy integracji danych. n

Software Developer’s Journal 1/2007 www.sdjournal.org 43


Programowanie

Java

Aplikacje Java
Tomasz Kuprowski
w telewizji interaktywnej
N
Materiały do artykułu ie zapomnę, gdy pewnego razu mój szef
zamieszczone zostały
na płycie CD 1
na jednej z burz mózgu rzucił „Przecież
Java będzie za niedługo wszędzie, będzie-
my ją mieć nawet w naszej lodówce!”. To stwierdze-
nie wywołało na mej twarzy bardzo dyplomatyczny
uśmiech. Wyobrażałem sobie upgrade firmware-u
w lodówce za pomocą parówki drobiowej i zimową
wersję Pacman-a na zawołanie. Jednak szef jak to
szef, zawszę ma rację. Java swoją krucjatę prze-
prowadziła przez serwery, komputery stacjonarne,
telefony komórkowe i PDA. Nie wszyscy wiedzą, że
zagościła też na dobre w świecie telewizji interak-
tywnej.
Czym w zasadzie jest telewizja interaktyw-
na? Można powiedzieć… w Polsce przyszłością,
a w krajach wyżej rozwiniętych codziennością. To
telewizja, która zapewnia użytkownikowi pewien
poziom interakcji, to coś więcej niż bierne ogląda-
nie. Wyobraź sobie, że Twój telewizor potrafi śle-
dzić Twoje aukcje internetowe, że umożliwia Ci
udział w czasie rzeczywistym w ulubionym telewi-
zyjnym quizie i głosowanie w programie „Decyzja Rysunek 1. Eclipse – kreator nowej klasy
należy do Ciebie”; oglądając wieczorne wiadomo-
ści możesz na ekranie swojego telewizora odebrać Generalnie aplikacje interaktywne dzielimy na
pocztę, a nawet zapłacić rachunek za prąd. Nic nie DVB-HTML i DVB-J. Te pierwsze nie są zbyt popularne
stoi na przeszkodzie by zamówić sobie film z inte- ze względu na uciążliwą implementację. Stanowią ze-
raktywnej wypożyczalni. Nie dość, że nie będziesz stawy stron HTML opartych na standardzie HTML 1.1,
musiał po niego wychodzić z domu to obejrzysz go CSS 2.0, DOM 2.0 oraz ECMAScript i są stosowane ja-
w zasadzie natychmiast. To wszystko za pomocą ko podkomponenty. Wszyscy znamy z pewnością mi-
pilota w ręku. dlety, applety, servlety więc nadszedł czas poznać Xlet
– tym mianem określamy wspomniane aplikacje DVB-
Java na pokładzie J. Xlet jest zasadniczo podobny do appletu (programu-
Na początku lat 90-tych powstało konsorcjum jący w Javie zaraz wyłapią te podobieństwa). Ma okre-
DVB (Digital Video Broadcasting) zrzeszające ślony cykl życia i docelowo działa na najwyższym po-
nadawców telewizyjnych. Za jeden z celów obrało ziomie middlewaru w tzw. set-top boxie (w skrócie STB
sobie standaryzacje i normalizacje w obrębie tele- - nazywanym też terminalem MHP) czyli urządzeniu
wizji cyfrowej, czego efektem dziś jest obecność podobnym do dekodera cyfrowego. Każdy Xlet mo-
języka Java w aplikacjach interaktywnych. Pod- że przyjąć jeden z czterech stanów: załadowany (Lo-
stawowym API do tworzenia ich jest JavaTV firmy aded), wstrzymany (Paused), uruchomiony (Active)
Sun [TABELA1]. Definiuje ono podstawowy mo- oraz zniszczony (Destroyed). Kolejne etapy cyklu życia
del aplikacji oraz wprowadza szereg niezbędnych Xlet-a są następujące:
funkcjonalności do innych pakietów. Inne, stoso-
wane na co dzień API, z którymi warto się zapo- • Menedżer aplikacji ładuje klasę główną Xlet-u,
znać to HAVI i DAVIC, jednak tutaj nie będą one tworzy jedną instancję przez odwołanie do kon-
opisywane. struktora;
• Gdy użytkownik lub inny Xlet zażąda urucho-
Autor od lat pracuje na etacie programisty. Podobno
mienia Xlet-u, menedżer aplikacji wykonu-
nieźle zna się także na sieciach i systemach IT. W wol- je metodę initXlet(). Xlet może równie do-
nym czasie uczy się oraz chodzi po górach i robi im brze zainicjować się sam, np. by pobrać nowe
zdjęcia. Nie gardzi również sportami zimowymi. ustawienia czy też przeładować zasoby gra-
Kontakt z autorem: tomaszkuprowski@simplusnet.pl ficzne. Po takiej akcji Xlet znajduje się w stanie
„wstrzymany”;

44 www.sdjournal.org Software Developer’s Journal 1/2007


Aplikacje Java w telwizji interaktywnej

Listing 1. Game.java
package org.sdj.kuprowski.snake; tracker.waitForID(1);
import org.dvb.ui.DVBAlphaComposite; tracker.waitForID(2);
import org.dvb.ui.DVBGraphics; } catch (InterruptedException e) {
import org.havi.ui.*; e.printStackTrace();
import org.havi.ui.event.HKeyEvent; }
import org.havi.ui.event.HKeyListener; }
import javax.tv.xlet.*;
... /** Funkcja obslugi : start Xlet-u */
public void startXlet() throws XletStateChangeException {
/** Glowna klasa Xletu @author Tomasz Kuprowski / Software validate();
Developers Guide 2006 */ monit_obj = new Monitor(this);
public class Game extends Component implements HKeyListener, monit_obj.start();
Xlet { scene.setVisible(true);
/** kontext aplikacji */ scene.requestFocus();
private XletContext context; }
/** uchwyt sceny */
private HScene scene; /** Funkcja obslugi : pauza Xlet-u */
... public void pauseXlet() {
/** obrazy uzywane w aplikacji */ scene.setVisible(false);
public Image image_body, image_apple, image_background; game_state = Cons.GAME_PAUSED;
/** obiekt monitorujacy ladowanie obrazkow */ }
public MediaTracker tracker;
/** Funkcja obslugi : zatrzymanie Xlet-u, zatrzymanie
/** Initializacja Xlet-u, zapamietanie kontekstu, watku Monitor, usuniecie Listenerow */
utworzenie sceny, zaladowanie grafiki */ public void destroyXlet(boolean unconditional)
public void initXlet(XletContext ctx) throws throws javax.tv.xlet.XletStateChangeException {
XletStateChangeException { monit_obj.interrupt();
setName("SDJsnake");
this.context = ctx; if (unconditional) {
if (scene != null) {
HSceneFactory factory = HSceneFactory.getInstance(); removeKeyListener(this);
HSceneTemplate hst = new HSceneTemplate(); scene.setVisible(false);
hst.setPreference(HSceneTemplate.SCENE_SCREEN_DIMENSION, scene.remove(this);
new org.havi.ui.HScreenDimension(1, 1), HsceneFactory.getInstance().dispose(scene)
HSceneTemplate.REQUIRED); scene = null;
hst.setPreference(HSceneTemplate.SCENE_SCREEN_LOCATION, }
new org.havi.ui.HScreenPoint(0, 0),
HSceneTemplate.REQUIRED); context.notifyDestroyed();
} else {
scene = factory.getBestScene(hst); throw new XletStateChangeException(
scene.setBounds(0, 0, 720, 576); "Please don't let me die!");
scene.setLayout(null); }
scene.setBackgroundMode(HScene.NO_BACKGROUND_FILL); }
scene.add(this);
scene.addKeyListener((KeyListener) this); /** Funkcja obslugi klawiszy pilota @param key */
setSize(scene.getSize()); public void keyPressed(KeyEvent key) {
if (VK_ready) {
image_body = getToolkit().getImage("body.jpg"); switch (key.getKeyCode()) {
image_apple = getToolkit().getImage("apple.jpg"); case HKeyEvent.VK_UP: if (course != Cons.DOWN) course =
image_background = getToolkit().getImage("back.jpg"); Cons.UP; break;
case HKeyEvent.VK_LEFT: if (course != Cons.RIGHT)
tracker = new MediaTracker(this); course = Cons.LEFT; break;
tracker.addImage(image_body, 0); ...
tracker.addImage(image_apple, 1); }
tracker.addImage(image_background, 2); VK_ready = false;
try { }
tracker.waitForID(0); }

Software Developer’s Journal 1/2007 www.sdjournal.org 45


Programowanie
Java

Rysunek 4. Eclipse – argumenty VM i aplikacji

den Xlet może być aktywny i widoczny – z tego powodu


aplikacje w tle muszą być wstrzymane;
• Po wywołaniu metody destroyXlet() Xlet przechodzi
w stan ‘zniszczony’ zwalniając wszystkie swoje zasoby.

Aplikacje interaktywne mogą oferować jeden z trzech pozio-


mów interakcji:

• Rozgłoszeniowy, gdzie tylko odbieramy dane od operatora


(ślepa interakcja);
• Jednokierunkowy, gdy możemy coś wysłać poprzez za-
Rysunek 2. Eclipse – konfiguracja środowiska startowego
pewniony kanał zwrotny w postaci np. łącza ADSL (głoso-
• Wywołanie metody startXlet() powoduje zmianę stanu wanie w quizach);
Xlet-u na „uruchomiony”. Xlet wówczas wyświetla się na • Dwukierunkowy, gdy aplikacja komunikuje się w obie stro-
ekranie i zaczyna interakcję z użytkownikiem; ny (email, web services, gry online).
• W każdej chwili Xlet może zostać wstrzymany po wywo-
łaniu metody pauseXlet() i wznowiony poprzez metodę Ograniczenia
startXlet(). Może się to dziać wielokrotnie podczas pra- Zanim przystąpimy do pisania naszej pierwszej aplikacji, warto
cy Xlet-u bowiem STB i maszyna wirtualna nie zakładają dowiedzieć się, jakie czekają nas ograniczenia w maszynie wir-
multitaskingu z prawdziwego zdarzenia, a naraz tylko je- tualnej STB. Dla przykładu… pisząc applet napotkamy ograni-
czenia wynikające z zabezpieczeń, takie jak np. brak dostępu do
dysku użytkownika i możliwość komunikacji wyłącznie z ip ho-
sta, z którego applet został pobrany. W midletach natomiast, nie
skorzystamy z operacji na liczbach zmiennoprzecinkowych.
Maszyna wirtualna w STB po pierwsze ma okrojone API.
Szereg pakietów jest niedostępnych ze względu na oszczęd-
ność pamięci i fakt, że są po prostu zbędne. Odchudzono nawet
tak kluczowe pakiety jak java.lang, java.util, java.io i java.net, a to
dlatego, że STB nie zawsze mają kanał zwrotny (w postaci łącza
internetowego) czy też system plików. Nie możemy także korzy-
stać z funkcji macierzystych. Występuje również specyficzny in-
terfejs użytkownika zgodny z wymogami środowiska TV (np. ste-
rowanie aplikacji pilotem) oraz szereg zasad związanych z do-
stępem do zasobów, komunikację między Xletami i cyklem życia
aplikacji. Nie wspominając o ograniczonej liczbie obsługiwanych
formatów plików audio i video.
Dla początkujących bardzo ważne jest zrozumienie ogra-
niczeń i różnic w warstwie prezentacji. Otóż wiele klas i obiek-
tów z, nazwijmy to, „pure Java” ma swoje zastępniki i tak oto
Rysunek 3. Eclipse – konfiguracja środowiska startowego dla przykładu, komponenty z pakietu java.awt (takie jak kla-

46 www.sdjournal.org Software Developer’s Journal 1/2007


Aplikacje Java w telwizji interaktywnej

Słownik pojęć
• STB – Set-top Box, elektroniczne urządzenie podłączane do
telewizora. Umożliwia odtwarzanie video, dźwięku, przeglą-
danie stron internetowych czy granie w gry komputerowe itp.
STB wykorzystuje w tym celu łącze ethernetowe, antenę sa-
telitarną, łącze telewizji kablowej, linię telefoniczną (włącza-
jąc w to DSL) albo nawet zwykłą antenę UHF/VHF;
• EPG - Electronic Program Guide, elektroniczny przewodnik po
kanałach, grupuje wybrane kanały według ich tematyki, pozwala
szybko znaleźć interesujący nas program, prezentuje szczegóło-
we informacje o kanale, wspiera system zamówień programów
Near Video On Demand i system kontroli rodzicielskiej;
• DVB - Digital Video Broadcast, standard cyfrowej telewizji.
Charakteryzuje się jakością obrazu i dźwięku porównywalną Rysunek 6. OpenMHP – konfiguracja Xletu w emulatorze
do zapisu DVD (500i), pozwala na interaktywny odbiór, tj. włą-
czenie napisów w różnych językach oraz przełączenia języka branie dobrych, darmowych narzędzi do authoringu nie jest zbyt
ścieżki audio. W standardzie DVB obraz i dźwięk kodowane oczywiste. Dla przykładu, zakup komercyjnego środowiska pro-
są przy pomocy enkodera MPEG, tak jak w DVD; gramowego takiego jak np. MIT - xperts iDesigner to koszt rzę-
• MHP – Multimedia Home Platform, Otwarty standard opro- du 5.000 Euro za 1 licencję (dla jednostek edukacyjnych). Na-
gramowania w telewizji cyfrowej zdefiniowany przez konsor- tomiast, jeżeli chcielibyśmy testować nasze aplikacje bezpośred-
cjum DVB. Umożliwia uruchomienie aplikacji pisanych przez nio na STB, to Starter Kit, który generuje sygnał cyfrowy audio/
niezależnych dostawców na różnych urządzeniach do odbio- video wraz z pakietem informacyjnym kosztuje tyle, co… średniej
ru telewizji cyfrowej. MHP umożliwia użytkownikowi korzysta- klasy, nowy samochód. Sporo, prawda? Jednak nam, początku-
nie z aplikacji nadawanych razem z programem telewizyjnym
jącym zapaleńcom, w zupełności wystarczy darmowy emulator
w trakcie oglądania telewizji;
OpenMHP lub XletView oraz dowolne środowisko do programowa-
• Middleware – inaczej oprogramowanie / warstwa pośredniczą-
ca pomiędzy hardware-em a aplikacją.
nia w Javie dla Linuxa lub Windows. Należy jednak mocno pod-
kreślić, że te darmowe narzędzia nie pozwolą nam poznać bar-
dziej zaawansowanych możliwości MHP ze względu na to, że
wisze, listy rozwijane, checkboxy, itp.) są dla nas niedostępne. implementują one jedynie część tego standardu. W OpenMHP, któ-
W zamian używa się ich odpowiedników z API HAVI, które rego będziemy używać w dalszej części artykułu, nie ma moż-
udostępnia okna dialogowe, pola tekstowe, własne klawisze, liwości odtwarzania klipów MPEG4, nie zaimplementowano ko-
czy etykiety tekstowe oraz nawet tak podstawowe komponen- munikacji między Xlet-ami, pobierania danych z kanału informa-
ty jak HContainer i HComponent. STB posiadają również specy- cyjnego, nie wszystkie komponenty HAVI są zaimplementowane
ficzny menedżer okien, różniący się znacznie od stosowane- i przetestowane, a podpięcie zewnętrznego debugera wydaje się
go w aplikacjach na PC. Zamiast obiektów Frame używa się być niemożliwe.
Hscene, który m.in. kontroluje pozycje focusa na ekranie i to jak Nadszedł czas na praktyczny przykład. Napiszemy znaną
dana aplikacja „leży” i czy jest aktualnie widoczna. wszystkim, prostą grę Snake (niech nikogo nie przerazi jej ubo-
ga implementacja – program powstał po prostu pewnego wie-
Pierwszy Xlet czoru). Klawisze strzałek naszego pilota TV posłużą do ste-
Telewizja interaktywna jest dosyć hermetyczną dziedziną, gdzie rowania ruchem węża, klawisze Volume Up i Volume Down będą
uzyskanie darmowego wsparcia technicznego, znalezienie w sie- zmieniać prędkość gry, a klawiszami czerwony i zielony będzie-
ci kodu źródłowego przykładowych aplikacji od A do Z lub po- my odpowiednio wstrzymywać i wznawiać grę. W tym projekcie
skorzystamy ze środowiska Eclipse i emulatora OpenMHP. Musi-

Rysunek 5. OpenMHP – ścieżki do bibliotek Rysunek 7. Snake w emulatorze

Software Developer’s Journal 1/2007 www.sdjournal.org 47


Programowanie
Java

my jeszcze pobrać i zainstalować pakiety JavaTV oraz JMF (Ja-


����������
va Media Framework). Zaczynamy… tworzymy nowy projekt
i podpinamy pod niego pakiety javatv.jar oraz jmf.jar. Na- ����������
stępnie cały folder org z folderu głównego OpenMHP paku- ����������
jemy do pliku jar i tak przygotowane archiwum również podpi-
����������� �����������
namy do projektu (unikniemy w ten sposób bałaganu w widoku
Package Explorer). Powinniśmy także skopiować katalog sta- ����������
tic (również z OpenMHP) do folderu głównego naszego projek- �������������
tu. Przygotowujemy klasę główną naszego pierwszego Xlet-u.
����������
[Rysunek 1] Rozszerzy ona klasę java.awt.Component i zaim-
plementuje interfejsy org.havi.ui.event.HkeyListener oraz ja- Rysunek 8. Cykl życia Xletu
vax.tv.xlet.Xlet. Automatycznie środowisko zaimplementuje
nam następujące metody: rysowania tła i dodamy słuchacza HKeyListener. Załadujemy
również grafikę w postaci plików JPEG. Wykorzystamy przy tym
public void initXlet(XletContext arg0) throws obiekt MediaTracker, aby dopilnować by obrazki zostały załado-
XletStateChangeException {} wane do końca, nim aplikacja spróbuje je już wyświetlać.
public void startXlet() throws XletStateChange Kolejna metoda obsługi startXlet uruchomi nam osobny wą-
Exception {} tek na bazie klasy Monitor, ustawia widoczność sceny i nadaje
public void pauseXlet() {} jej focus. Z kolei w metodzie destroyXlet przerwiemy wątek uru-
public void destroyXlet(boolean arg0) throws chomiony w poprzedniej metodzie, usuniemy słuchacza HkeyLi-
XletStateChangeException {} stener, zamkniemy scenę i za pomocą zapamiętanego wcze-
public void keyTyped(KeyEvent arg0) {} śniej kontekstu powiadomimy menedżera aplikacji, że Xlet koń-
public void keyPressed(KeyEvent arg0) {} czy swoje działanie. Metoda paint, którą odziedziczyliśmy po ja-
public void keyReleased(KeyEvent arg0) {}. va.awt.Component, przerysowuje scenę. W metodzie initXlet
ustawiliśmy rozmiary sceny zgodnie ze standardem PAL na
Obsługę pilota zaszyjemy w funkcje keyPressed . Metoda get- 720x576 pixeli. Z kolei obszar roboczy gry to 640x480 pixeli, ze
KeyCode() klasy KeyEvent zwraca kod wciśniętego na pilocie kla- względu na wygodne podzielenie ekranu na 32x24 pola. Do wy-
wisza. Odpowiednich kodów należy szukać w klasie org.ha- świetlania prostych komunikatów na ekranie użyliśmy czcionkę
vi.ui.event.HKeyEvent. Dla przykładu kod czerwonego klawisza Tiresias, która jest czcionką podstawową w standardzie MHP.
występuje jako wartość statyczna VK _ COLORED _ KEY _ 0 kla- I to w zasadzie wszystko, co należało wspomnieć o metodzie pa-
sy HKeyEvent, a z kolei klawisz zwiększania głośności to VK _ VO- int. Wypada jeszcze wspomnieć o samej logice gry. Otóż, osob-
LUME _ UP. Badaniem kolizji węża, przeliczaniem współrzędnych, ny wątek na podstawie aktualnego kierunku poruszania się węża
naliczaniem punktów itp. czyli ogółem logiką ruchu zajmie się ustala jego pozycję, weryfikując czy jego głowa nie znajduje się
osobny wątek. Tego komentować nie musimy, natomiast bliżej na tej samej pozycji co jabłko lub jego ogon. Wszystkie elemen-
przyjrzymy się utworzeniu sceny i przerysowaniu ekranu, a tak- ty ogona są przechowywane w LinkedList. Losowanie nowej po-
że funkcjonowaniu Xlet-u. zycji jabłka odbywa się bez blokowania, tzn. po pierwszym loso-
Na pierwszy ogień pójdzie metoda initXlet. Zapamiętamy wym wyznaczeniu nowej pozycji, jeśli jest ona zajęta przez ogon
w niej kontekst aplikacji XletContext (posłużymy się nim później to jest przesuwana pod kątem 45 stopni po planszy aż do skutku.
zamykając aplikację), pobierzemy fabrykę, która posłuży nam do
utworzenia sceny (jedna aplikacja może mieć tylko jedną scenę). Test
Funkcja getBestScene(…) klasy HSceneFactory zwraca więc obiekt Otwieramy menedżer aplikacji OpenMHP. Podczas pierwszego
Hscene, dla którego określimy rozmiary sceny, jej układ, tryb prze- uruchomienia musimy dokonać wstępnej konfiguracji, poda-

Tabela 1. Specyfikacja JavaTV


Pakiet Opis
javax.tv.xlet Definiuje Xlet, cykl życia, klasy pomocnicze
javax.tv.locator Mechanizmy dostępu do usług rozgłoszeniowych i zasobów multimedialnych za pomocą URL-i
javax.tv.net Mechanizmy transmisji datagramów IP
javax.tv.graphics Rozszerzenie pakietu java.awt o specyficzne dla platformy TV funkcje, np. przeźroczystość
javax.tv.util Klasy narzędziowe, zarządzanie zegarami i wątkami zegarowymi
javax.tv.media Rozszerzenie Java Media Framework o specyficzne dla platformy TV funkcje
javax.tv.media.protocol Rozszerzenie JMF o protokoły transportu strumieni danych
javax.tv.service Definicja usług TV (kanały informacyjne) i mechanizmów wymiany informacji
javax.tv.service.guide Obsługa systemu EPG
javax.tv.service.navigation Nawigacja pomiędzy usługami, ich typy, zarządzanie usługami w tym np. Listy ulubionych usług
javax.tv.service.transport Mechanizmy transportu strumieni danych, informacji rozgłoszeniowych
javax.tv.service.selection Warstwa prezentacji usług (np. picture-in-picture), wyboru nowych usług

48 www.sdjournal.org Software Developer’s Journal 1/2007


Aplikacje Java w telwizji interaktywnej

nie zapominając oczywiście o classpath. Przykładowe po-


W Sieci lecenie to:

• http://java.sun.com/products/javatv/index.jsp
java -classpath .;.;\javatv_fcs\javatv.jar; \JMF\lib\jmf.jar;
Strona domowa JavaTV;
org.openmhp. system.RunXlet . HelloWorld 32 1.
• http://www.interactivetvweb.org/
Serwis InteractiveTvWeb czyli bogate źródło wiedzy na temat
programowania aplikacji interaktywnych; Z poziomu Eclipse’a w menu Run wybieramy opcję
• http://www.mhp-knowledgebase.org/ Run… i w zakładce Main w polu Main class wpisujemy
Baza wiedzy o MHP; org.openmhp.system.RunXlet . Następnie przechodzimy do
• http://www.openmhp.org/ zakładki Arguments i w polu Program arguments podaje-
Strona projektu OpenMHP; my rozdzieloną spacjami nazwę katalogu roboczego, iden-
• http://java.sun.com/products/java-media/jmf/ tyfikatory aplikacji i organizacji i na końcu ponownie nazwę
Strona domowa Java Media Framework; katalogu roboczego. Teraz w polu VM arguments podaje-
• http://www.dvb.org/ my parametr maszyny wirtualnej –classpath oraz ścieżkę do
Witryna Digital Video Broadcasting;
plików javatv.jar oraz jmf.jar. [Rysunek 3, 4] Teraz pozo-
• http://www.davic.org/
staje już tylko wpisać w polu Working directory nazwę folde-
Witryna API DAVIC;
• http://www.havi.org/
ru bazowego OpenMHP i umieszczać w nim przy każdej kom-
Witryna API HAVI; pilacji pliki class naszego Xlet-u, co łatwo wykonać stosu-
jąc Ant-a lub linki symboliczne w Linuxie. [Rysunek 2] Jeśli
w oknie Output zobaczymy komunikat Class java.awt.X is not
jąc ścieżki do bibliotek JavaTV oraz JMF. [Rysunek 5] Konfi- allowed in MHP Thread oznacza to, że classloader nie zała-
gurację możemy również zmienić ręcznie edytując pliki con- dował wskazanej klasy z pakietu AWT uznając, że nie wy-
stants.properties i openmhp.properties z folderu static . Na- stępuje ona w MHP. Niuans ten można ominąć dopisując
stępnie dodajemy nowy projekt / aplikację. nazwę wskazanej klasy w pliku allowedClasses.txt w katalo-
Wybieramy opcję Add z menu prawego klawisza myszki gu static . Jeżeli po uruchomieniu naszego Xlet-u nie poja-
i na nowo otworzonej formatce podajemy nazwę projektu, wi się nic w oknie podglądu, a w oknie Output nie raportowa-
ścieżkę bazową do projektu Eclipse’a , pełną nazwę klasy no żadnego błędu, wówczas musimy poeksperymentować
naszego Xlet -u; wprowadzamy również identyfikatory apli- ze ścieżką classpath, bo jak sami przyznają autorzy OpenMHP
kacji i organizacji. [Rysunek 6] Po zapisaniu ustawień mo- – „Classpaths are a bit tricky…”.
żemy uruchomić nasz Xlet , wybierając opcję Start ze zna-
nego nam już menu. Zakończenie
Otworzy się okno podglądu TVScreen for MHP, następnie Ten artykuł z założenia miał mieć charakter CIG (Comple-
okno pilota RemoteControl oraz najważniejsze okienko Output, te Idiot’s Guide). Nie sposób opisać w krótkim artykule na-
na którym widać wszystkie komunikaty emulatora. Jeśli nasza wet podstaw programowania aplikacji MHP. Ogrom zagad-
aplikacja spowoduje jakiś wyjątek to jego treść pojawi się rów- nień dotyczących telewizji interaktywnej - dziedziny, w którą
nież w tym oknie. Co ważne, zamiast za każdym razem mo- jest zaangażowanych ponad 270 nadawców telewizyjnych
zolnie klikać w Start, możemy uruchomić nasz Xlet bezpo- z 35 krajów – sprawia, że możnaby z powodzeniem wyda-
średnio z poziomu środowiska Eclipse. wać miesięcznik, a może i nawet tygodnik zatytułowany
Musimy tylko odpowiednio przygotować środowisko „Multimedia Home Platform Developer’s Guide”. W Polsce
startowe. OpenMHP pozwala uruchomić dowolny Xlet z linii jest już kilka firm, które tworzą software dla odbiorców z Azji
poleceń korzystając z klasy org.openmhp.system.RunXlet . i Europy Zachodniej, a wraz z rozwojem telewizji interaktyw-
Podajemy wówczas jako parametry folder roboczy, na- nej w Polsce na pewno część z nas znajdzie sobie finanso-
zwę klasy Xlet-u oraz identyfikatory aplikacji i organizacji wo atrakcyjną pracę. n

R E K L A M A
Warsztat

GWT – WEB 2.0

David de Rosier
GWT – WEB 2.0 na maksa
M
Materiały do artykułu iałem sen... w którym aplikacje webowe ścią artykułu, by zobaczyć, że GWT jest poniekąd in-
zamieszczone zostały
na płycie CD 1
zaczęły przypominać normalne programy. ne – wierzę, że wyznacza nowy standard programo-
Zawierały bogaty i funkcjonalny interfejs, wania aplikacji webowych, a JSP i ciągła komunikacja
a użytkownik nie był zmuszany do czekania po każ- HttpRequest-HttpResponse przechodzą do lamusa.
dym kliknięciu na przeładowanie strony. Programi- Główną cechą GWT jest możliwość pisania części
ści przestali rwać sobie włosy z głowy, nie musząc klienckiej aplikacji internetowej w języku Java, w spo-
się więcej martwić o utrzymanie zgodnego zacho- sób przypominający w dużym stopniu programowa-
wania i wyglądu swych programów pomiędzy róż- nie aplikacji SWING. Tak napisany program zostaje
nymi przeglądarkami internetowymi. Co więcej – przetłumaczony przez GWT do JavaScriptu i pozwala
ich praca przestała w końcu być nieustannym mie- na uruchomienie po stronie przeglądarki internetowej.
szaniem HTMLa, JavaScriptu i Javy. Wreszcie mo- Komunikacja aplikacji klienta z serwerem odbywa sie
gli odetchnąć z ulgą, programując zwarte aplikacje asynchronicznie z użyciem technologii AJAX. GWT
– w jednym języku, w jeden sposób, w jednym stan- dostarcza szeroki zbiór komponentów graficznych
dardzie dla klienta i serwera. Bez tagów, scriptletów (ang. widgets) z bardzo wygodną obsługą zdarzeń.
i javascriptowych trików. Aplikacje internetowe za- Rozbudowanie bibliotek GWT o własne komponenty
częły działać szybciej, wymieniając w trakcie pracy nie jest trudne i wprowadza dużą dowolność rozwią-
z serwerem tylko niezbędne dane (i to asynchronicz- zań. Ponadto aplikacje GWT można łatwo i szybko te-
nie), zamiast setek kilobajtów HTMLa. Miałem sen, stować w trakcie programowania, z użyciem środowi-
w którym założenia WEB 2.0 i możliwości oferowa- ska uruchomieniowego Google Web Browser. Co bar-
ne przez technologię AJAX stały się proste w użyciu, dzo ważne – GWT nie wymaga dedykowanych środo-
z wykorzystaniem zwartego, solidnego narzędzia. wisk programistycznych, programiści nie muszą zmie-
Wiosną tego roku Google spełniło marzenia, prze- niać więc swoich przyzwyczajeń.
kazało programistom dar – zestaw narzędzi i biblio- Zastanówmy się głębiej nad główną ideą GWT
tek programistycznych do tworzenia stron zgodnych – transformacji Javy do JavaScriptu. Zważywszy na
z WEB 2.0. Z ich użyciem pisanie aplikacji działających ogromną odmienność tych języków, można powie-
na takich zasadach jak Google Mail czy Google Maps, dzieć że Google dokonało niemal cudu (choć wca-
stało się zdecydowanie prostsze. Google po raz kolejny le nie było pierwsze – patrz np. projekt XML11). Jakie
udowodniło, że jego produkty cechuje przede wszyst- są najważniejsze zalety takiego rozwiązania? Przede
kim nowatorstwo i wysoka jakość. Również w podej- wszystkim łatwość programowania i debugowania
ściu do biznesu – podobnie jak inne kluczowe produk- aplikacji. Pewnie większość programistów używa śro-
ty firmy, GWT jest dystrybuowane za darmo, bez ogra- dowisk z podpowiadaniem składni i uzupełnianiem ko-
niczeń w używaniu. A przecież nie można określić Go- du Javy, co zdecydowanie przyspiesza proces pro-
ogle mianem organizacji charytatywnej... gramowania. Mocna kontrola typów języka Java czy-
ni aplikacje mniej podatnymi na błędy. Rozbudowane
Google Web Toolkit debuggery (jak np. w środowisku Eclipse) pozwalają
– Jak to działa? precyzyjnie śledzić zachowanie aplikacji. I co chyba
Domyślam się, że część Czytelników po wstępie do najważniejsze – aplikacja staje się bardzo jednorodna,
artykułu może sobie pomyśleć, że GWT to po prostu poprzez implementacyjne zbliżenie do siebie warstw
YEWF (Yet Another Web Framework) i zanegować je- serwera i klienta.
go ideę, nie chcąc zmieniać swych przyzwyczajeń, W razie konieczności, nie stanowi żadne-
nie widząc w tym znaczących korzyści. Przy zalewie go problemu łączenie aplikacji GWT z JSP, PHP
rozmaitych rozwiązań, takie podejście ma swoje uza- czy innymi technologiami. Tym nie mniej, może-
sadnienie. Zachęcam jednak do zapoznania się z tre- my stworzyć w pełni działającą aplikację interne-
tową, której część kliencka będzie reprezentowa-
na przez „czyste” pliki HTML. Programista nie mu-
Autor od wielu lat pasjonuje się językami programowania.
Centrum jego zainteresowań zawodowych stanowi techno-
si (wreszcie!) mieszać kodu HTMLa ze skrypta-
logia Java, głównie w kontekście wytwarzania aplikacji we- mi innych języków. Cała statyczna część aplikacji
bowych oraz obsługi baz danych. W wolnych chwilach autor może zostać napisana w HTMLu i odizolowana od
zajmuje się implementacją zaawansowanych algorytmów reszty, natomiast części dynamiczne (interakcja
szachowych w różnych dziwnych językach programowania. z użytkownikiem) zostaną stworzone w Javie. Pro-
Kontakt z autorem: ddrosier@gmail.com gramista może więc skupić się wyłącznie na logi-
ce aplikacji, oddając pracę nad wyglądem webma-

50 www.sdjournal.org Software Developer’s Journal 1/2007


GWT – WEB 2.0 na maksa

Po wykonaniu tej instrukcji zostanie utworzony katalog (c:\


Szybki start projects\gwttest) z podkatalogami src i test, oraz, co bardzo
przydatne, skrypt ANTa pozwalający skompilować projekt. Użyt-
Pracę z GWT najłatwiej rozpocząć od analizy istniejących przykła- kownicy środowiska Eclipse mogą skorzystać z dodatkowego
dów. Po rozpakowaniu archiwum z GWT znajdziemy wewnątrz ka- parametru -eclipse, który wygeneruje plik .project. Tak powsta-
talog samples z kilkoma aplikacjami. Polecam uruchomić przykład
ły projekt można łatwo zaimportować do Eclipsa wybierając
KitchenSink, ukazujący pełne spektrum możliwości GWT. Aby zo-
z menu File opcję import, a potem Existing projects in workspa-
baczyć aplikację w oknie środowiska uruchomieniowego GWT, wy-
starczy wykonać plik KitchenSink-shell. Jeśli chcemy obejrzeć apli-
ce. GWT dostarcza narzędzie pozwalające wygenerować testo-
kację w oknie preferowanej przeglądarki internetowej, musimy naj- wą aplikację – naszą aplikację Hello World:
pierw uruchomić plik KitchenSink-compile, celem skompilowania
aplikacji, a następnie otworzyć przykładową stronę – plik Kitchen- applicationCreator -out c:\projects\
Sink.html z katalogu www/com.google.gwt.sample.kitchensink. gwttest org.sdjournal.gwt.client.Main
KitchenSink.
Polecenie to utworzy klasę Java w zadanym pakiecie oraz kil-
ka dodatkowych plików. Zacznijmy od nazwy pakietu – appli-
sterom i grafikom. GWT składa się z czterech podstawo- cationCreator wymusza, by nasza klasa została umieszczona
wych komponentów: w pakiecie client. Jest to konwencja GWT pozwalająca w łatwy
sposób odróżnić część kliencką od serwerowej. Omówione zo-
• kompilatora kodu Java do JavaScriptu (GWT Java-to-Ja- stanie to szerzej w dalszej części artykułu. Przyjrzyjmy się do-
vaScript Compiler), kładnie wygenerowanej klasie (patrz Listing 1). Nazwijmy ją kla-
• środowiska testowego, umożliwiającego uruchamianie i de- są startową, bowiem implementuje ona interfejs EntryPoint – co
bugowanie aplikacji (GWT Hosted Web Browser), jest obowiązkowe dla przynajmniej jednej klasy w obrębie modu-
• zbioru klas JavaScript emulujących standardowe klasy ję- łu webowego. Kiedy moduł zostaje po raz pierwszy ładowany,
zyka Java (JRE Emulation Library), wszystkie klasy startowe zostają automatycznie zainicjalizowane
• biblioteki elementów interfejsu użytkownika (GWT Web UI). poprzez wykonanie metody onModuleLoad(). Możemy tę operację
określić mianem zdarzenia typu start aplikacji (ściślej – modułu).
Dochodzi do tego jeszcze zestaw narzędzi dodatkowych, Dalsza część kodu musi wydawać się bardzo znajoma Czytelni-
np. automatyzujących tworzenie projektów GWT, czy budowę kom znającym bibliotekę SWING. Utworzony zostaje tam przy-
aplikacji wpierającej wiele języków. cisk oraz nieedycyjne pole tekstowe (etykietka). Następnie za-
Gdzie leży kruczek? Właściwie go nie ma – tworzenie apli- implementowana zostaje obsługa zdarzenia – kliknięcie przyci-
kacji webowych staje się zdecydowanie szybsze i mniej podat- sku. W tym przypadku w postaci anonimowej klasy wewnętrz-
ne na błędy, a powstałe aplikacje są pozbawione problemu nie- nej. Czytelnicy mniej biegli w Javie mogą początkowo mieć kło-
kompatybilności i bardziej skalowalne. Szukając minusów moż- poty z takimi konstrukcjami, jednak jest to zapis bardzo praktycz-
na wspomnieć o dodatkowych stu kilobajtach (plik JavaScript, ny i szybko można się przyzwyczaić do takiej notacji. W tym wy-
będący jądrem GWT), które przeglądarka musi załadować przy padku kod zdarzenia sprawdza, czy etykieta jest pustym ciągiem
starcie aplikacji (tylko jednokrotnie, później plik przechowywany znaków, jeśli nie, ustawia ją na wartość Hello World, w przeciw-
jest przez cache przeglądarki). W rzeczywistości jednak trud- nym wypadku – kasuje ją. Dwie ostatnie linie kodu są bardzo
no tu mówić o ograniczeniu lub nadmiernym obciążaniu inter- ważne – łączą one kod z plikiem HTML. Nasza aplikacja w Javie
netu, bowiem przy używaniu AJAXa, aplikacja w trakcie działa- nie generuje bowiem całego wyjścia HTML, a jedynie dwa ele-
nia wymienia z serwerem znacznie mniej danych w porównaniu menty – przycisk i etykietę. Cała reszta znajduje się w statycz-
z rozwiązaniem klasycznym (każdorazowe przeładowywanie nym pliku HTML – możemy go znaleźć w pakiecie org.sdjour-
stron). Puryści JavaScriptu z pewnością zwrócą uwagę na to, nal.gwt.public. Zachęcam do zapoznania się z jego budową –
że generowany JavaScript jest niezbyt czytelny dla człowieka. nie znajdziemy tam żadnych osadzonych skryptów innych języ-
To prawda ale czy musi być? GWT zakłada, że programowanie ków. Jedyną niestandardową konstrukcją wewnątrz jest znacznik
i debugowanie odbywa się na poziome Javy, nie JavaScriptu. meta, który definiuje nazwę modułu GWT użytego na tej stronie:
Kompilator C++ może budować niezbyt optymalny kod assem-
blera ale póki wszystko działa sprawnie i bezbłędnie – komu fi- <meta name='gwt:module' content= 'pl.com.sdj.gwt.Main'>
nalnie to przeszkadza?
W jaki sposób łączymy więc kod Javy i HTML? Można
Hello GWT World! w uproszczeniu powiedzieć, że kierunek jest tutaj odwrotny niż
Jeśli mówimy o jakiejś nowości w świecie programowania w przypadku np. JSP – to kod Javy informuje aplikację, w jakim
nie może się obyć bez aplikacji typu Hello world, która po- miejscu HTMLa zostanie osadzony. Oczywiście fizycznie bę-
zwoli rzucić okiem na składnię i strukturę kodu. Zacznijmy dzie to JavaScript, wygenerowany z naszej klasy. Powróćmy do
od utworzenia nowego projektu – nazwijmy go po prostu ostatnich linii kodu Java. Konstrukcja typu:
GWTTest. W katalogu głównym GWT znajdziemy dwa na-
rzędzia automatyzujące ten proces. Pierwsze z nich tworzy RootPanel.get("slot1").add(button);
nowy projekt:
odwołuje się do elementu strony HTML, którego atrybut id jest
projectCreator -ant GWTTest ustawiony na wartość slot1. Może to być na przykład komórka
eclipse GWTTest -out c:\projects\gwttest tabeli, element DIV, itp. Prawda, że proste?

Software Developer’s Journal 1/2007 www.sdjournal.org 51


Warsztat
GWT – WEB 2.0

Każda aplikacja (podobnie jak aplikacja SWING) musi zawie- mu łatwo jest uczynić go przenośnym i budować biblioteki kom-
rać (przynajmniej jeden) RootPanel, na którym będziemy osa- ponentów na potrzeby różnych aplikacji. Moduły mogą dziedzi-
dzali inne elementy graficzne. RootPanel jest więc łącznikiem czyć po sobie, łatwo uzupełniając możliwości już istniejących.
między naszą aplikacją powstałą w Javie, a plikiem HTML. Jeśli Każdy moduł zdefiniowany jest w pliku nazwa _ modu-
nie określimy parametru w metodzie get tej klasy, domyślnie Ro- łu.gwt.xml i powinien zostać umieszczony w głównym pakie-
otPanel odniesie się do elementu BODY pliku HTML. cie, tzn. na tym samym poziomie, na którym znajdują się pa-
Czas uruchomić nasz przykład. Kiedy stworzyliśmy projekt kiety client, server i public.
z użyciem narzędzi GWT, w głównym katalogu projektu pojawi- Podstawowym modułem pochodzącym ze zbioru standar-
ły się dwa wykonywalne pliki – Main-compile i Main-shell. Pierw- dowych klas GWT jest com.google.gwt.user.User i to po nim
szy z nich pozwala na przetransformowanie klas Java do plików będą dziedziczyć wszystkie nasze aplikacje. Ponadto moduł
JavaScript. Wynik zostanie zapisany w (automatycznie utwo- powinien zawierać tzw. entry point, czyli nazwę klasy inicjali-
rzonym) katalogu web. W katalogu tym znajdzie się też plik Ma- zującej interfejs użytkownika. Przykładowo plik modułu (o na-
in.html, który możemy otworzyć z użyciem przeglądarki interne- zwie Main.gwt.xml) z opisanej wcześniej aplikacji Hello World,
towej i zacząć podziwiać efekty swojej pracy. Jeszcze łatwiej wygląda następująco:
można zobaczyć wygenerowaną stronę, uruchamiając plik Ma-
in-shell. Wystartuje on testowe środowisko GWT, które zawiera <module>
konsolę oraz przeglądarkę. Jest również niezastąpione przy te- <inherits name='com.google.gwt.user.User'/>
stowaniu komunikacji klient-serwer, zawiera bowiem wbudowa- <entry-point class='org.sdjournal.gwt.client.Main'/>
ną, uproszczoną wersję serwera Tomcat (działającą domyślnie </module>
na porcie 8888).
Poniżej opisano znaczenie poszczególnych elementów (ta-
Praca z projektami GWT gów), które mogą znaleźć się w pliku definicji modułu:
W poprzednim punkcie omówiłem pokrótce pewne aspekty
związane z budową projektu GWT, spróbujmy jednak teraz tę • inherits-name – nazwa modułu po którym dziedziczy
wiedzę usystematyzować. bieżący moduł; możliwe jest dziedziczenie po wielu mo-
dułach;
Struktura katalogów • entry-point – klasa inicjalizująca interfejs użytkownika
Pojedynczy projekt GWT może łączyć ze sobą kod aplikacji w obrębie modułu; jej metoda onModuleLoad zostanie wy-
klienta i serwera. Mimo wszystko logicznym błędem byłoby konana w trakcie ładowania modułu;
zbytnie mieszanie takiego kodu. Google zaleca podział aplika- • source – tag pozwalający zdefiniować pakiety z plikami Ja-
cji na przynajmniej trzy pakiety różniące się nazwą ostatniego va, które zostaną w trakcie kompilacji przetransformowane
członu w ścieżce pakietów: Pakiet client – zawierający cały do JavaScriptu (nie jesteśmy więc ograniczeni wyłącznie
kod przeznaczony do transformacji do JavaScriptu. Będą się do pakietu client);
tu znajdowały klasy odpowiedzialne za wygląd i logikę aplika- • public – definiuje katalogi których zawartość (zwykle pliki
cji po stronie klienta, własne komponenty, a także interfejsy graficzne i HTML) zostanie skopiowana do katalogu web
serwisów odpowiedzialnych za komunikację z serwerem. Na- w trakcie kompilacji projektu;
leży pamiętać, że niektóre mechanizmy języka Java nie mo- • servlet – definiuje klasę i ścieżkę servletów do komunikacji
gą być używane wewnątrz tego pakietu, bowiem nie zawsze klient-serwer; wartość ta używana jest tylko na potrzeby śro-
możliwa jest transformacja do JavaScript (więcej szczegółów dowiska uruchomieniowego GWT – w środowisku produkcyj-
w punkcie dedykowanym kompatybilności). nym wszystkie servlety będą musiały być zdefiniowane w de-
Pakiet server – to przede wszystkim miejsce dla servletów skryptorze aplikacji internetowej (pliku web.xml);
obsługujących komunikację z klientem. Może się tu znajdo- • script – pozwala na umieszczenie zewnętrznego skryptu
wać też cała niekliencka logika aplikacji, jak na przykład klasy JavaScript w module;
odpowiedzialne za komunikację z bazą danych. • stylesheet – umieszcza zewnętrzny plik CSS na potrzeby
Pakiet public – tutaj będziemy umieszczać wszystkie pliki modułu;
nie będące plikami Java, jak dodatkowe skrypty JavaScript, pli- • extend-property – pozwala na zdefiniowanie dodatkowych
ki HTML, CSS oraz pliki graficzne. Nie wszystkim może przy- parametrów konfiguracyjnych; zwykle używane do określe-
paść do gustu koncepcja mieszania tych plików ze źródłami Ja- nia obsługiwanych przez aplikację wersji językowych.
va – zapewne część Czytelników przyzwyczajona jest do od-
dzielania warstwy webowej i Javowej od siebie. W GWT podział Hosted-mode
ten jednak nie jest aż tak oczywisty i to raczej kwestia przyzwy- W poprzednich punktach wspominałem już o środowisku uru-
czajenia się do nowej koncepcji. W trakcie kompilacji projektu chomieniowym GWT, przyjrzyjmy się jednak zważniej jakie ko-
GWT, pliki z pakietu client zostaną przetransformowane na Ja- rzyści płyną z jego używania. Standardowo, by przetestować
vaScript i skopiowane do katalogu web, natomiast pliki z katalo- webaplikację musimy ją opublikować na serwerze aplikacji i wte-
gu public zostaną tam po prostu skopiowane. dy uruchomić. Często czyni to debugowanie aplikacji dość uciąż-
liwym. W przypadku GWT również nie jest to proste – po stro-
Koncepcja modułów GWT nie klienta operujemy bowiem na wygenerowanych plikach Ja-
Aplikacja GWT może zostać podzielona na zbiory logicznych vaScript. w przypadku błędu nie zawsze łatwo będzie odnaleźć
komponentów i funkcjonalności, tzn. modułów. Każdy moduł po- który fragment kodu Java odpowiada za nieprawidłowe działa-
winien odpowiadać pewnej niezależnej części aplikacji, dzięki te- nie JavaScriptu. Tryb hosted-mode pozwala ominąć te problemy.

52 www.sdjournal.org Software Developer’s Journal 1/2007


GWT – WEB 2.0 na maksa

To środowisko z wbudowaną przeglądarką internetową oraz ser- ką jest destrukcja (finalizacja) obiektów. Klasy aplikacji klienta nie
werem aplikacji, który w trakcie pracy korzysta z klas Javy, a nie powinny więc używać słowa kluczowego finalize.
z generowanego JavaScriptu. Dzięki temu możemy debugować Ostatnim elementem wartym omówienia są wyrażenia regu-
naszą aplikację tak jak klasyczną aplikację Java. Również sa- larne. Oba języki umożliwiają ich używanie, jednak składnia wy-
mo uruchamianie aplikacji do testów staje się znacznie szybsze rażeń regularnych nieznacznie różni się pomiędzy Javą a Java-
i prostsze niż w przypadku pracy z serwerem aplikacji. Scriptem, a kompilator GWT nie jest w stanie dokonać transfor-
Gdy tworzymy nową aplikację z użyciem narzędzia ap- macji. Należy więc zachować tu pewną ostrożność i najlepiej ko-
plicationCreator, zostaje automatycznie wygenerowany plik rzystać z wyrażeń interpretowanych identycznie przez oba języki.
(o nazwie nazwa_aplikacja-shell), który uruchamia nasz mo-
duł w środowisku GWT. W przypadku środowiska Eclipse, ist- Interfejs użytkownika à la GWT
nieje możliwość takiego skonfigurowania go, by aplikacja uru- Z punktu widzenia programisty, Google Web Toolkt to
chamiała się w trybie Hosted-mode automatycznie po wybra- przede wszystkim biblioteka klas interfejsu użytkownika,
niu przycisku Run z poziomu Eclipse. tylko że dedykowana na potrzeby internetu. Jak już było to
wspomniane, programowanie przypomina używanie biblio-
Z Javy do JavaScriptu tek AWT albo SWING. Przyjrzyjmy się jakie możliwości da-
– rozprawka o kompatybilności je nam GWT w świecie aplikacji webowych, ograniczonym
Programując moduł webowy aplikacji musimy mieć świadomość, przecież w porównaniu do rozwiązań okienkowych.
że kod źródłowy zostanie finalnie przetłumaczony przez kompi-
lator GWT na JavaScript. Zastanówmy się głębiej nad ideą ta- Praca z panelami
kiej transformacji. W części klienckiej aplikacji używać będziemy Panele służą do wygodnego rozmieszczania elementów interfej-
nie tylko elementów graficznych dostarczonych przez GWT ale su użytkownika (np. przycisków czy pól edycyjnych) w zdefiniowa-
także standardowych klas Javy, jak choćby kolekcji. Czy rzeczy- nym przez programistę układzie. Głównym panelem aplikacji po-
wiście możemy to robić i czy programiści Google podjęli próbę winien zawsze być RootPanel, który definiuje w jakim miejscu stro-
przeportowania Javy do JavaScriptu? W znacznej części – tak! ny HTML powinien zostać osadzony (poprzez zadany parametr
Są jednak pewne różnice, o których należy pamiętać. Rozwa- ID elementu HTML). Do panelu RootPanel możemy dodać bez-
żymy poniżej cechy i elementy języka Java, które nie występują pośrednio elementy GUI, ale lepiej jest umiejscowić tutaj najpierw
w JavaScripcie, jednak zostały zasymulowane przez GWT. Po- któryś z paneli, definiujących kolejność rozłożenia elementów
wiemy też o mechanizmach, które mogą sprawiać trudności lub w swoim obrębie. Do wyboru mamy niemały zbiór możliwości:
w ogóle nie powinny występować w części aplikacji klienta.
Zacznijmy od typów danych – wszystkie podstawowe typy • HorizontalPanel – rozmieszcza elementy w poziomie, od
(np. int oraz klasa Integer) mogą być z powodzeniem używane lewej do prawej strony;
(czyt. konwertowane do JavaScriptu). Dotyczy to również ca- • VerticalPanel – rozmieszcza elementy w pionie;
łych klas, których składowymi są proste typy danych lub klasy • FlowPanel – działa podobnie jak HorizontalPanel, jed-
dziedziczące po nich. Jedynym wyjątkiem jest typ long, który nak jeśli sumaryczna szerokość wszystkich elemen-
nie ma swojego bezpośredniego odpowiednika w JavaScrip- tów w rzędzie przekracza rozmiar okna przeglądarki,
cie. Będzie on reprezentowany poprzez typ zmiennoprzecin- zaczyna wyświetlanie kolejnych elementów w nowym
kowy (double-precision). wierszu;
Java i JavaScript to języki o bardzo odmiennej naturze, • DockPanel – wyróżnia centralny, duży obszar na główny ele-
fizycznie nie jest więc możliwe, by zezwolić na używanie ment panelu oraz miejsce na dodatkowe elementy po bo-
wszystkich cech języka Java w implementacji części klienc- kach oraz ponad i poniżej obszaru centralnego. Dla przy-
kiej. Przykładowo JavaScript nie ma wbudowanej koncepcji kładu zobaczmy kod dodający przycisk u dołu panelu: new
wielowątkowości i raczej nie byłaby ona łatwa do zasymulo- DockPanel().add(new Button(), DockPanel.SOUTH);
wania. Takie konstrukcje języka Java jak Object.wait() czy • HTMLPanel – praktyczny panel, którego zwartość jest po
Object.notify() nie powinny być wiec stosowane w modu- prostu kodem HTML; możliwe jest jednak wstawianie do
le webowym aplikacji. Kompilator GWT nie zgłosi co praw- wnętrza tego panelu elementów interfejsu GWT. Zobacz-
da błędu, jednak zignoruje taki kod. my to na przykładzie:
Również Reflection jest mechanizmem, którego nie da się HTMLPanel p = new HTMLPanel
przenieść bezpośrednio na JavaScript. Kompilator GWT gene- ("<div width='250'>Komentarz:<span id='txt'></span></div>");
ruje raczej statyczny skrypt, więc dynamiczne ładowanie klas nie p.add(new Label("Test"),"txt");
jest możliwe do zrealizowania. GWT wprowadza co prawda pew- • ScrollPanel – panel do wykorzystania raczej wewnątrz in-
ne klasy pomocnicze pozwalające częściowo zrekompensować nych paneli; ma zdefiniowaną stałą wielkość – jeśli jego
ten brak, jednak w tym wypadku będziemy musieli używać dedy- zawartość przekroczy rozmiar panelu, zostaną wyświetlo-
kowanych rozwiązań, zamiast standardowych. Przykładowo po- ne paski przewijania;
branie nazwy klasy obiektu jest możliwe z użyciem statycznej • TabPanel – umożliwia łatwe tworzenie zakładek; przykła-
metody GWT.getTypeName(Object). dowo poniżej utworzymy panel z dwiema zakładkami,
Rozbudowany mechanizm serializacji obiektów Javy nie jest gdzie jedna wyświetla przycisk, a druga tekst:
możliwy do zaimplementowania po stronie JavaScriptu, dlatego TabPanel p = new TabPanel();
też GWT, na potrzeby komunikacji aplikacji klienckiej z serwe- p.add( new Button("Tab1"), "TAB 1");
rem, dostarcza własny mechanizm serializacji. Inną, raczej nie- p.add( new Label("Tab2"), "TAB 2");
możliwą do zaimplementowania po stronie JavaScriptu techni- • FormPanel – tworzy formularz HTML.

Software Developer’s Journal 1/2007 www.sdjournal.org 53


Warsztat
GWT – WEB 2.0

Elementy interfejsu użytkownika standardowym w webaplikacjach komponentem graficznym jest


Google Web Toolkit dostarcza zestaw podstawowych kontrolek, drzewo – reprezentowane tu przez obiekt klasy Tree. Pojedynczy
będących bezpośrednimi odpowiednikami elementów formularzy element drzewa, reprezentowany jest przez obiekt TreeItem. Zo-
HTML oraz kilka rozbudowanych komponentów, na bazie których baczmy przykład tworzący dwupoziomowe, rozwijalne drzewo:
można budować złożone interfejsy użytkownika. Do podstawo-
wych elementów należeć będą: pole tekstowe (klasa TextBox), li- TreeItem t1 = new TreeItem("Poziom 1");
sta (ListBox), przycisk (Button ), pole wyboru (CheckBox) i duże po- TreeItem t2 = new TreeItem("Poziom 2");
le tekstowe (TextArea). Ponadto znajdziemy klasę reprezentującą t1.addItem( t2 );
link (Hyperlink), element graficzny (Image ) oraz dowolny fragment Tree tree = new Tree();
kodu HTML (HTML). Używanie podstawowych elementów inter- tree.addItem( t1 );
fejsu użytkownika jest raczej intuicyjne. Skupmy się więc bardziej
na złożonych kontrolkach, których bezpośrednia implementacja Pisząc o rozbudowanych komponentach GWT nie sposób nie
w HTMLu i JavaScripcie byłaby zapewne niemałym wyzwaniem. wspomnieć o możliwości tworzenia wielopoziomowego me-
Jedną z takich kontrolek jest niewątpliwie DialogBox. Wyświe- nu aplikacji internetowej, przypominającego standardowe menu
tlanie okienek dialogowych spędza sen z powiek niejedne- okienkowych programów. Podobnie jak w poprzednich przykła-
mu programiście aplikacji webowych – nikt nie lubi wyskaku- dach – programista nie ma zbyt wiele pracy, by utworzyć dzia-
jących okienek, przeglądarki starają się je blokować, a w rze- łającą kontrolkę – wystarczy zainicjować obiekt typu MenuBar
czywistości i tak nie możemy zasymulować pełnej funkcjonal- i umieścić go w jakimś panelu. Elementy menu dodajemy za po-
ności okna dialogowego, bowiem takie okienko nie może być mocą metody addItem.
modalne. Okno dialogowe z GWT to jedynie warstwa w obrę-
bie okna głównego, ale zachowująca się jak niezależne, mo- Obsługa zdarzeń
dalne okienko. Możemy je nawet przesuwać w obrębie okna Aby umożliwić operowanie na elementach interfejsu użytkow-
przeglądarki! Zobaczmy przykład takiego okna, zawierające- nika należy zaimplementować mechanizm obsługi zdarzeń.
go listwę tytułową, komunikat i przycisk Close: Są to proste interfejsy, których implementację często zawie-
rać będziemy bezpośrednio w wywołaniu metody:
DialogBox db = new DialogBox();
db.setText("Dialog Box"); Button b = new Button( "Alert" );
DockPanel panel=new DockPanel(); b.addClickListener(new ClickListener() {
panel.add( new Button("Close"), DockPanel.SOUTH); public void onClick(Widget sender) {
HTML msg = new HTML("To jest DialogBox"); Window.alert( "Alarm!" );
panel.add(msg,DockPanel.CENTER); }
db.setWidget(panel); });
db.show();
Pisanie osobnych klas obsługi zdarzenia może mieć uzasad-
Przykład okna dialogowego z aplikacji KitchenSink został zapre- nienie w przypadku, kiedy więcej niż jedna kontrolka wykonu-
zentowany na Rysunku 1. Innym bardzo ciekawym i dość nie- je dokładnie tę samą operację. Przykładowo element menu
i przycisk mogą mieć identyczną obsługę zdarzenia. W nie-
Listing 1. Aplikacja Hello world wygenerowana przez których przypadkach można też napisać jedną metodę obsłu-
narzędzie applicationCreator gi zdarzenia dla wielu kontrolek i rozpoznawać wewnątrz, któ-
ra z nich metodę wywołała:
package org.sdjournal.gwttest.client;
import com.google.gwt.core.client.EntryPoint; public class EventTest implements ClickListener {
import com.google.gwt.user.client.ui.*; Button a = new Button("A");
public class Main implements EntryPoint { Button b = new Button("B");
public void onModuleLoad() { public EventTest() {
final Button button = new Button("Click me"); a.addClickListener ( this );
final Label label = new Label(); b.addClickListener ( this );
button.addClickListener(new ClickListener() { }
public void onClick(Widget sender) { public void onClick(Widget sender) {
if (label.getText().equals("")) if( sender == a ) { /* obsluga zdarzenia */ }
label.setText("Hello World!"); }
else }
label.setText("");
} Każdemu zdarzeniu może towarzyszyć więcej niż jeden li-
}); stener je obsługujący. W takich sytuacjach funkcje obsługi
RootPanel.get("slot1").add(button); zdarzeń zostaną uruchomione w kolejności ich dodania do
RootPanel.get("slot2").add(label); kontrolki. Można również usunąć dodany uprzednio obiekt
} za pomocą metody removeNazwaListenera, np.
}
myButton.removeClickListener( listener );

54 www.sdjournal.org Software Developer’s Journal 1/2007


GWT – WEB 2.0 na maksa

Metoda getCountries to nasze faktyczne żądanie. Klasa ob-


sługująca je po stronie serwera musi implementować ten in-
terfejs oraz dziedziczyć po klasie RemoteServiceServlet :

public class CountryServiceImpl


extends RemoteServiceServlet implements CountryService {
public Collection getCountries(String continent) {
return /* kolekcja państw */;
}
}

Pozostało jeszcze utworzyć interfejs reprezentujący odpo-


wiedź ze strony serwera. Musi on mieć taką samą nazwę
jak interfejs żądania ale z końcówką Async. Interfejs również
Rysunek 1. Zbudowane na warstwie HTML modalne okno musi zawierać metodę o tej samej nazwie co interfejs żąda-
dialogowe, które można swobodnie przesuwać w obrębie okna
nia, ale z jednym dodatkowym parametrem na końcu – Async-
przeglądarki. Implementacja takiego rozwiązania to zaledwie
Callback wskazuje on na klasę aplikacji klienta, która obsłuży
kilka linii kodu
odpowiedź.
Niektóre interfejsy obsługi zdarzeń deklarują kilka metod. Je- W tym układzie nie ma więc uzasadnienia, by metoda in-
śli nie chcemy każdorazowo implementować wszystkich me- terfejsu zwracała jakąś wartość (jak w interfejsie żądania) –
tod, możemy skorzystać z wygodnego mechanizmu adapte- typ zwracanego przez metodę parametru musi więc być usta-
rów. Adapter to prosta klasa implementująca dany interfejs, wiony na void:
zawierająca puste metody (nie wykonujące żadnych akcji).
Przykładowo interfejs KeyboardListener zawiera kilka metod. public inteface CountryServiceAsynch {
Chcąc zaimplementować tylko jedną z nich ( onKeyPress ), mo- public void getCountries(String continent,
żemy łatwo skorzystać z adaptera: AsyncCallback callback); }

KeyboardListener list = new KeyboardListenerAdapter() { Na koniec pozostało połączyć wszystko w całość. Zobaczmy
public void onKeyPress(Widget sender, char keyCode, jak wysłać żądanie i obsłużyć je ze strony klienta. W pierw-
int modifiers) { sze kolejności należy utworzyć obiekt reprezentujący inter-
// implementacja metody fejs – obiekt ten w nomenklaturze GWT określany jest mia-
} nem client proxy:
}
CountryServiceAsynch hservice =
Komunikacja z serwerem (CountryServiceAsynch)GWT.create(CountryService.class);
Dotychczas skupialiśmy się na części klienckiej aplikacji, czas
opisać sposób użycia GWT po stronie serwera oraz komunika- Uważny Czytelnik może odnieść wrażenie, że w kodzie powy-
cję pomiędzy obiema stronami. Mechanizm komunikacji określa- żej jest błąd – metodzie create przekazujemy bowiem interfejs
ny jest mianem RPC (Remote Procedure Calling). żądania, jednak otrzymujemy instancję interfejsu odpowiedzi.
Stwórzmy przykładową aplikację, by zobaczyć w jaki sposób To jednak jak najbardziej poprawny zapis.
dynamicznie podmienić zwartość listy rozwijanej danymi pocho- W kolejnym kroku musimy określić adres URL, pod którym
dzącymi z serwera. Niech interfejs użytkownika zawiera dwie li- znajduje się servlet, z którym zamierzamy się komunikować.
sty rozwijane – pierwsza z nazwami kontynentów, druga – z na- Należy pamiętać, iż adres może wskazywać wyłącznie na tę
zwami państw. Kiedy użytkownik wybierze wartość z pierwszej samą domenę i port z których uruchomiliśmy stronę.
listy (kontynent), aplikacja pobierze z serwera powiązaną kolek-
cję nazw państw i wyświetli ją na drugiej liście. ServiceDefTarget endpoint = (ServiceDefTarget)hservice;
Proces komunikacji z serwerem początkowo może wydawać endpoint.setServiceEntryPoint("/country.srv");
się nieco zawiły, musimy bowiem w tym celu stworzyć dwa in-
terfejsy i jedną klasę. Pierwszy z interfejsów reprezentuje żąda- Przed nami najważniejsze zadanie – musimy utworzyć klasę,
nie do serwera, a drugi – odpowiedź. Konieczność posiadania która otrzyma odpowiedź od serwera i zinterpretuje ją. Klasa
dwóch różnych interfejsów bierze się z asynchronicznej natury ta musi implementować interfejs AsyncCallback . Dobrym roz-
komunikacji z serwerem. Wspomniane interfejsy znajdują się po wiązaniem jest jej bezpośrednia implementacja, np tak:
stronie klienta, natomiast klasa, będąca defacto servletem, zo-
stanie umieszczone po części serwera. Zacznijmy od interfej- AsyncCallback callback = new AsyncCallback() {
su żądania – musi on dziedziczyć po interfejsie RemoteService public void onFailure(Throwable caught) {
i w naszej przykładowej aplikacji będzie wyglądał następująco: Window.alert( "Error: " + caught.getMessage() );
}
public inteface CountryService extends RemoteService { public void onSuccess(Object result) {
public Collection getCountries(String continent); // obsługa odpowiedzi
} } };

Software Developer’s Journal 1/2007 www.sdjournal.org 55


Warsztat
GWT – WEB 2.0

Klasa implementuje dwie metody – onFailure, która jest urucha- Gdybyśmy przekazywali kolekcję jako parametr wejściowy
miana w przypadku błędu i standardowo będzie wyświetlać ko- metody interfejsu, w komentarzu musielibyśmy jeszcze podać
munikat o niepowodzeniu operacji, oraz metodę onSuccess, która nazwę parametru, np. tak:
obsłuży odpowiedź serwera. Parametr tej drugiej metoda (obiekt
typu Object), to rzeczywista odpowiedź od serwera, a jej typ jest @gwt.typeArgs mojParametr <java.lang.Integer>
zgodny z typem zwracanym przez metodę interfejsu żądania
(w naszym przypadku będzie to Collection ). Wewnątrz me- Implementacja własnych komponentów
tody należy więc dokonać odpowiedniego rzutowania typów. Jedną z największych zalet GWT jest łatwość pisania własnych
W naszej przykładowej aplikacji metoda onSuccess powinna zaktu- komponentów. To właśnie ten mechanizm pozwala na upodob-
alizować dane w liście rozwijanej z państwami, np. w taki sposób: nienie naszej strony internetowej do normalnej, okienkowej apli-
kacji. Wyobraźmy sobie formularz, który w zależności od wpro-
Collection c = (Collection)result; wadzanych danych ukrywa lub wyświetla niektóre pola, zmienia
countries.clear(); ich typ, albo doładowuje dynamicznie zawartości list. Wszystko
for( Iterator i=c.iterator(); i.hasNext(); ) to możliwe jest do zaprogramowania z poziomu JavaScriptu, jed-
countries.addItem( (String)i.next() ); nak nie jest to operacja łatwa, a na dodatek troszczyć się będzie-
my musieli o kompatybilność kodu między przeglądarkami. Napi-
Utworzyliśmy powyżej wszystkie niezbędne obiekty, pozostało sanie podobnego rozwiązania z użyciem GWT nie powinno być
już tylko wykonać żądanie. W naszym przykładzie interfejs żą- zbyt czasochłonne. Nietrywialne poruszanie się po obiektach
dania oczekuje parametru typu String, wskazującego na nazwę drzewa DOM, zachowanie zgodności kodu itp, zostało bowiem w
kontynentu – pobierzemy go z listy rozwijanej o nazwie htype: GWT obudowane przez wygodne w użyciu obiekty Javy. Ponad-
to możliwość tworzenia własnych komponentów tworzy bardziej
String selectedType = htype.getValue czytelny, a przede wszystkim przenośny, kod.
( htype.getSelectedIndex() ); Zwykle nowe komponenty pisane przez programistów bę-
hservice.getCountry( selectedType, callback ); dą kombinacjami lub rozszerzeniami komponentów podstawo-
wych. Klasycznym przykładem prostego komponentu może
Finalnie wywołaliśmy metodę asynchronicznego interfejsu. być panel z kilkoma powiązanymi logicznie elementami, trak-
Aplikacja nie będzie więc czekać na odpowiedź serwera, tylko towany jako całość. Niestandardowe rozwiązania będą jed-
będziemy mogli kontynuować pracę. Aby uruchomić i przete- nak wymagały większego nakładu pracy oraz częściowej im-
stować nasz kod na serwerze aplikacji, musimy jeszcze zmo- plementacji bezpośrednio w JavaScripcie. Jednak i tutaj GWT
dyfikować plik web.xml, deklarując w nim utworzony servlet: przychodzi z pomocą udostępniając nam mechanizm JSNI
(JavaScript Native Interface ).
<servlet><servlet-name>countryService</servlet-name> Stwórzmy dla przykładu prosty komponent. Wyobraźmy so-
<servlet-class>org.sdjournal.gwt.server. bie sytuację, w której użytkownik ma możliwość wyboru w formu-
CountryServiceImpl</servlet-class></servlet> larzu wartości z listy rozwijanej (combo box), jednak w przypadku
<servlet-mapping><servlet-name>countryService</servlet-name> braku poszukiwanej wartości powinien mieć możliwość wpisania
<url-pattern>/country.srv</url-pattern> własnej. W tym celu na końcu listy umieścimy wartość specjal-
</servlet-mapping> ną, np. o nazwie „>> zdefiniuj <<”. Kiedy użytkownik wybierze ta-
ką wartość, wyświetlone zostanie normalne pole edycyjne. Jeśli
Pozostaje jeszcze omówić jedną kwestię, którą dla uproszcze- całość zamkniemy w jednym komponencie, będziemy mogli zde-
nia pominąłem. Obiekty, na których operujemy podczas komu- finiować dla niego metodę getValue(), która, w zależności od sy-
nikacji klient-serwer, muszą być serializowalne. Wszystkie ty- tuacji, zwróci wartość z listy rozwijanej lub pola edycyjnego. Taki
py proste i ich tablice spełniają ten warunek. Klasy utworzone komponent możemy stworzyć na bazie standardowych obiektów
przez programistę powinny w tym celu implementować interfejs GWT. Będziemy tu potrzebowali listę (komponent ListBox), po-
com.google.gwt.user.client.rpc.IsSerializable (jak wspomnie- le tekstowe (TextBox) oraz panel, na którym umieścimy oba ele-
liśmy w rozdziale o kompatybilności – nie możemy tu używać menty (w tym przypadku użyjemy HorizontalPanel). Prostym roz-
java.io.Serializable ). Problemem pozostają kolekcje, które do- wiązaniem byłoby stworzenie klasy rozszerzającej klasę repre-
myślnie operują na niezserlializowanych obiektach typu Object. zentująca panel i dodanie do niej elementów formularza. Takie
Aby umożliwić przesyłanie kolekcji między serwerem i klientem rozwiązanie ma jednak istotną wadę – nasz komponent będzie
(jak w naszej przykładowej aplikacji), musimy poinformować apli- udostępniał wszystkie metody panelu, jak np. możliwość usunię-
kację kliencką, jakiego typu są elementy kolekcji. Siłą rzeczy ko- cia elementu, a na to nie chcielibyśmy pozwolić. Rozwiązaniem
lekcja będzie musiała być monolityczna i zawierać obiekty seria- jest stworzenie własnej klasy, która zawiera wewnątrz kompo-
lizowalne. Przekazanie informacji o typie elementów kolekcji od- nenty GWT i deleguje na zewnątrz tylko te metody, które chcemy
bywa się z użyciem odpowiedniego przypisu w komentarzu inter- udostępnić. Pojawia się jednak tutaj jeden specyficzny dla GWT
fejsu żądania. W naszym przypadku finalna wersja interfejsu po- problem – nasz komponent do poprawnego działania po stronie
winna więc wyglądać następująco: klienta musi wywołać w konstruktorze metodę initWidget(). Aby
mięć taką możliwość, będziemy musieli odziedziczyć naszą kla-
public inteface CountryService extends RemoteService { sę po klasie com.google.gwt.user.client.ui.Composite, która de-
/** @gwt.typeArgs <java.lang.String> */ dykowana jest tworzeniu komponentów użytkownika.
public Collection getCountries(String continent); Na Listingu 2 zamieszczony został kod opisanego kom-
} ponentu. Przyjmuje on w konstruktorze dwa parametry –

56 www.sdjournal.org Software Developer’s Journal 1/2007


Warsztat
GWT – WEB 2.0

etykietę i wartość elementu specjalnego, odpowiedzialne- Środowisko programistyczne IntelliJ Idea daje pełne wsparcie dla
go za wyświetlenie pola tekstowego. Klasa deleguje meto- programistów JSNI, udostępniając funkcję podkreślania składni,
dę addItem z klasy ListBox , byśmy mogli dodawać nowe ele- a nawet uzupełniania kodu wewnątrz osadzonego JavaScriptu.
menty do listy. Wartym uwagi fragmentem kodu jest meto-
da onChange, wykonywana w przypadku zmiany wartości na i18n
liście rozwijanej. To właśnie tutaj znajduje się kod odpowie- W obecnych czasach raczej trudno wyobrazić sobie poprawnie
dzialny za wyświetlenie lub ukrycie pola tekstowego. Nale- zbudowaną aplikację internetową nie wspierającą wielu wersji
ży zwrócić uwagę, że metoda onChange pochodzi z interfejsu językowych. Na szczęście GWT dostarcza wygodne narzędzia
ChangeListener, który nasz komponent implementuje. Aby ułatwiające zarządzanie wersjami językowymi i tworzenie tłuma-
zdarzenie zmiany wartości na liście mogło być obsłużone, czeń. Początkowo cały proces może wydawać się nieco pokręt-
musimy zarejestrować nasz komponent, jako listener listy ny, jednak GWT pozwala go w znacznej części zautomatyzować
rozwijanej (patrz konstruktor): combo.addChangeListener( this ); z użyciem własnych narzędzi. Z punktu widzenia kodu Java, tłu-
Pozostaje przetestować utworzony komponent, np tak: maczenia będą reprezentowane przez dedykowane ku temu in-
terfejsy. W przykładzie poniżej przedstawiono taki interfejs tłu-
EditableComboBox ecb = new EditableComboBox maczący nazwy dwóch podstawowych przycisków – Ok i Anuluj:
(">>zdefiniuj<<","-1");
ecb.addItem("Wartosc 1", "1"); public interface Translations extends Constants {
ecb.addItem("Wartosc 2", "2"); String ok();
String cancel(); }
JavaScript Native Interface
Transformacja kodu Javy do JavaScriptu może być w nie- Listing 2. Implementacja własnego komponentu – lista
których przypadkach niewystarczająca – czasem przydat- rozwijana, która w przypadku wybrania (zdefiniowanej
nym może okazać się bezpośrednia implementacja fragmen- w konstruktorze) wartości specjalnej, wyświetla pole
tów kodu w JavaScripcie. Nic nie stoi na przeszkodzie, by do- edycyjne, w którym użytkownik może wprowadzić własną
łączyć do aplikacji zewnętrzne pliki JavaScript, jednak w ta- wartość (spoza listy)
kiej sytuacji zostaniemy pozbawieni możliwości odwoływania public class EditableComboBox extends Composite implements
się do struktur zawartych w takim pliku z poziomu aplikacji Ja- ChangeListener {
va. GWT rozwiązuje tę kwestię poprzez JSNI (JavaScript Na- protected ListBox combo;
tive Interface), oparty koncepcyjnie na standardowym mecha- protected TextBox newElement;
nizmie Javy – JNI (Java Native Interface). Mechanizm ten po- protected String newElementValue;
zwala na łączenie kodu Java z funkcjami napisanymi bezpo- public EditableComboBox(String newElementLabel, String
średnio w JavaScripcie. Zobaczmy przykład: newElementValue) {
this.newElementValue = newElementValue;
public static native void jsalert(String msg) /*-{ combo = new ListBox();
$wnd.alert(msg); combo.setVisibleItemCount( 1 );
}-*/; combo.addItem(newElementLabel, newElementValue);
combo.addChangeListener( this );
Różnica między klasycznym JNI a JSNI polega na tym, że newElement = new TextBox();
w przypadku tego ostatniego możemy zawrzeć implementa- newElement.setVisible( true );
cję metody bezpośrednio w klasie Java. Musi ona jednak zo- HorizontalPanel panel = new HorizontalPanel();
stać otoczona komentarzem. Google wprowadziło następują- panel.add( combo );
cą notację dla oznaczenia osadzonego JavaScriptu: deklarac- panel.add( newElement );
ja metody(parametry) /*-{ treść metody JavaScript }-*/; przy czym initWidget( panel );
deklaracja metody musi zawierać słowo kluczowe native. Me- }
chanizm JSNI pozwala na pełną interakcję kodu JavaScriptu public void onChange(Widget sender) {
z kodem Javy i vice versa. Oczywiście faktycznie będzie miało if( sender == combo && combo.getSelectedIndex() >= 0 ) {
to miejsce po stronie wygenerowanego JavaScriptu. Uruchamia- newElement.setVisible( combo.getValue(combo.getSelectedI
nie metod Javy po stronie JavaScriptu wymaga użycia dość nie- ndex()).equals(newElementValue) );
wygodnej składni. Na przykładzie poniżej przedstawiono sposób }
wywołania metody void test(String str) z klasy org.sdjournal. }
gwt.Example: public String getValue() {
String val = combo.getValue(combo.getSelectedIndex());
this.@org.sdjournal.gwt.Example: return val.equals( newElementValue ) ?
:test(Ljava/lang/String;)("test"); newElement.getText() : val;
}
Zamiast this możemy w powyższej konstrukcji używać nazwy public void addItem(String item, String value) {
zmiennej wskazującej na obiekt klasy Example. Natomiast me- combo.addItem( item, value );
todę statyczną będziemy uruchamiać bez wskazania na żaden }
obiekt, rozpoczynając zapis od znaku @ . Dostęp do pól klas Javy }
jest nieco prostszy: var val=obj.@org.sdjournal.gwt.Example::field.

58 www.sdjournal.org Software Developer’s Journal 1/2007


GWT – WEB 2.0 na maksa

giwanych przez naszą aplikację języków powinna zostać za-


W Sieci deklarowana w pliku definicji modułu:

• główna strona projektu GWT – http://code.google.com/webtoolkit/


<extend-property name="locale" values="fr"/>
• forum programistów GWT
<extend-property name="locale" values="en_US"/>
http://groups.google.com/group/Google-Web-Toolkit
• strona domowa wtyczki Googlipse, usprawniającej pracę
z GWT w środowisku Ecipse – http://www.googlipse.com/ Ponadto nasz moduł musi dziedziczyć po dostarczanym przez
• strona konkurencyjnego narzędzia – XML11, które również Google module I18N: <inherits name="com.google.gwt.i18n.I18N"/>.
umożliwia transformację kodu Javy do JavaScriptu Na koniec powinniśmy jeszcze zdefiniować wybrany język na stro-
http://www.xml11.org/ nie HTML. Możemy to zrobić w dwojaki sposób – używając dedy-
kowanego meta taga w nagłówku HTMLa: <meta name="gwt:proper-
ty" content="locale=en_NZ"> albo poprzez parametr w adresie URL
Aby móc używać takiego interfejsu w naszej klasie, musimy go strony, np: http://sdjournal.org/przyklad.htm?locale=en_NZ. To dru-
zainstancjonować za pomocą metody GWT.create(). Tak powsta- gie rozwiązanie pozwala na łatwe przełączanie się między wer-
ły obiekt będzie reprezentował aktualnie wybrany język. Oczywi- sjami językowymi. Opisany powyżej sposób tłumaczenia tekstów
ście można mieć wiele różnych interfejsów dla jednego języka, może okazać się niewystarczający w przypadku bardziej złożo-
np. jeden będzie reprezentował elementy interfejsu, drugi komu- nych fraz, jak na przykład komunikaty o błędach. Nierzadko bę-
nikaty. Zobaczmy przykład utworzenia przycisku Anuluj: dziemy bowiem musieli zamieszczać tam informacje dynamiczne,
jak np. kod błędu, nazwę użytkownika itd. W tym celu mamy do
Translations trans=(Translations)GWT. dyspozycji mechanizm sparametryzowanych tłumaczeń, obsługi-
create(Translations .class); wany przez interfejs Message. Przypomina on mocno opisany wy-
Button cancel=new Button(trans .cancel()); żej mechanizm statycznego tłumaczenia (interfejs Constants), z tą
różnicą, iż metody interfejsu mogą posiadać parametry. Z pozio-
Pozostaje jeszcze rozwiązać zagadkę, gdzie znajdują się mu plików .properties będziemy odwoływać się do parametrów
faktyczne tłumaczenia? Oczywiście w pliku .properties. poprzez znaczniki {nr_parametru}, przy czym numeracja para-
Prawdopodobnie większość Czytelników ma obecnie wra- metrów rozpoczyna się od zera, np: Błąd nr {0}, użytkownik {1} nie
żenie, że jest zbyt dużo do oprogramowania, aby uzyskać fi- jest zdefiniowany w systemie. Chcąc utworzyć plik ze sparametry-
nalny efekt – pliki .properties oraz konieczność implemen- zowanymi tłumaczeniami należy uruchomić opisane wcześniej na-
tacji interfejsu. Na szczęście ten ostatni może zostać wy- rzędzie i18nCreator z dodatkową opcją -createMessages.
generowany automatycznie na bazie pliku z tłumaczenia-
mi. Prześledźmy cały proces. W pierwszej kolejności wyge- Podsumowanie
nerujmy plik .properties z naszymi tłumaczeniami za pomo- Tak jak przeminęła era assemblera, wyparta przez języki wyż-
cą narzędzia GWT: szego poziomu, tak samo nadejdzie kres czystego HTMLa. Apli-
kacje internetowe w epoce Web 2.0, mogą przypominać klasycz-
i18nCreator -out c:\projects\gwttest org. ne programy i tego właśnie będą oczekiwać użytkownicy. Z tech-
sdjournal.gwt.client.Translator nicznego punktu widzenia, kod takich aplikacji będzie składał się
w większości z JavaScriptu – nie z HTMLa. GWT, będąc defac-
Pierwszy parametr komendy wskazuje na lokalizację na- to generatorem JavaScriptu, idzie dokładnie z tym postępem,
szego projektu a drugi określa nazwę interfejsu z tłumacze- a może bardziej – tworzy go. Użytkownicy Lynxa i Internet Explo-
niami (wraz z pakietem). Narzędzie wygeneruje dwa pliki – rera 4.0 będą musieli dać za wygraną... Na koniec warto za-
Translator.properties (w zadanym pakiecie) oraz Translator- dać sobie pytanie czy należy unikać JavaScriptu? Oczywiście,
i18n.cmd – w katalogu głównym projektu. Możemy teraz wy- że nie! JavaScript to piękny i pełen możliwości język, a niechęć
edytować plik z tłumaczeniami, dodając tam nasze przyci- do niego bierze się raczej z pobieżnej znajomości, niż rzeczy-
ski, np: wistych wad języka. Niewątpliwym minusem jest niekompatybil-
ność podstawowego JavaScriptu miedzy przeglądarkami. W in-
ok = Ok ternecie nie brak jednak rozwiązań obudowujących niskopozio-
cancel = Anuluj mowe operacje na drzewie DOM i dających przenośny interfejs.
Niektóre z bibliotek javascriptowych, jak np. DOJO lub Prototype,
Następnie uruchommy narzędzie Translator-i18n – wygene- pozwalają na uzyskanie takich samych efektów, jakie daje nam
ruje ono automatycznie interfejs z niezbędnymi metodami. GWT, a kod ich kod będzie zdecydowanie czytelniejszy i krótszy,
I to wszystko! W niektórych środowiskach programistycz- niż ten generowany. GWT, jak każde inne rozwiązanie, nie jest
nych (np. Eclipse lub IntelliJ IDEA) łatwo można dodać plik idealne dla wszystkich. Po prostu - każdemu według potrzeb.
generatora do procesu kompilacji projektu, by zautomatyzo- Z pewnością webmasterzy, czujący się swobodnie w świecie Ja-
wać cały proces. To samo można zrobić z użyciem skryp- vaScriptu, lecz niekoniecznie w Javie – wybiorą rozwiązanie opar-
tu ANTa. Jeśli chcemy by nasza aplikacja obsługiwała wie- te na bezpośrednim kodowaniu skryptów. Programiści Java zaś
le języków, musimy zdefiniować osobny plik .properties dla postąpią na odwrót, a zwolennicy Ruby on Rails pójdą jeszcze in-
każdego z nich (ale tylko jeden interfejs!). Przykładowo plik ną ścieżką. Ta programistyczna wieża Babel tylko pozornie sieje
Translations _ fr.properties będzie zawierał tłumaczenia na zamęt i chaos. W rzeczywistości umiejscawia nas w najbardziej
język francuski a Translations _ en _ US.properties – tłuma- demokratycznym ze światów, w którym zawsze możemy wybrać,
czenia na amerykańską odmianę angielskiego. Lista obsłu- a jeśli nie mamy z czego – możemy zbudować coś od podstaw... n

Software Developer’s Journal 1/2007 www.sdjournal.org 59


Bazy

danych

Rozszerzenia środowiska
Jarosław Staniek
bazodanowego Kexi
K
exi jest środowiskiem dla tzw. desktopowych
baz danych (ang. desktop/workgroup databa-
ses), to jest narzędziem przedkładającym ła-
twość tworzenia i rozwijania aplikacji bazodanowych,
nad bogactwo zaawansowanych opcji. Ciężar prze-
twarzania danych jest przeniesiony na serwer SQL,
którym obecnie może być MySQL, PostgreSQL lub
SQLite. Korzystanie z tego ostatniego – wbudowa-
nego w Kexi – umożliwia zredukowanie konieczności
konfiguracji serwera baz danych praktycznie do ze-
ra. Naturalną konkurencją dla Kexi jest Microsoft Ac- Rysunek 1. Dane tabeli pomiary
cess oraz FileMaker.
Program Kexi, rozwijany na zasadach Open So- wnętrznych. W niniejszym artykule będą przedsta-
urce, jest obecnie dostępny w postaci kodu źródło- wione dwa rozszerzenia:
wego oraz binariów dla większości popularnych dys-
trybucji Linuksa, dla BSD oraz Solarisa. Jest też do- • narzędzie służące do eksportowania tabel da-
stępny w wersji dla MS Windows. W produkcji pro- nych do nieobsługiwanego przez Kexi formatu
gramu uczestniczą profesjonalni programiści, użyt- Fixed-Width Text;
kownicy oraz firmy a całość jest zarządzana pod • dodanie nowego elementu interfejsu użytkownika na
skrzydłami organizacji KDE. przykładzie widżetu suwaka (ang. slider), pozwalają-
Z uwagi na mnogość popularnych silników baz cego na nowy sposób wprowadzania danych.
danych oraz języków skryptowych, aplikacja Ke-
xi jest w dużej mierze zbudowana z wtyczek (ang. Potrzebne narzędzia i składniki
plugins), dzięki czemu użytkownicy nie są zmuszani Do zbudowania planowanych rozszerzeń będzie po-
do spełniania zbyt wielu zależności w czasie insta- trzebne środowisko umożliwiające kompilowanie apli-
lacji programu. W szczególności, do uzyskania peł- kacji Kexi. Dla uproszczenia, założenie jest takie, że
nej funkcjonalności nie jest wymagane instalowanie korzysta się z gcc 3.x lub 4.x na Linuksie. Zwykle nie
bibliotek klienckich MySQL lub PostreSQL, czy też byłoby konieczne posiadanie kodu źródłowego całe-
konfigurowanie serwerów tychże silników – w więk- go program, a jedynie plików nagłówkowych dla API
szości przypadków wystarcza efektywna baza pli- rozszerzeń. W tym przypadku konieczne jest jednak
kowa SQLite. korzystanie z (w momencie pisanie tego artykułu)
jeszcze nie wydanej publicznie Kexi w wersji 1.1. Jest
Rozszerzenia aplikacji to część KOffice 1.6, planowanego na październik
Dzięki modularyzacji z użyciem wtyczek zyskuje się 2006 – czytelnik może nie być w stanie zdobyć nie-
jeszcze dwie rzeczy. Aplikacja nie ładuje do pamię- zbędnych pakietów deweloperskich Kexi dla swojej
ci nieużywanych komponentów, przez co jej start jest dystrybucji. Należy wykonać następujące czynności:
o wiele szybszy niż programu o architekturze mono-
litycznej. Drugą korzyścią jest łatwość rozszerzania • Upewnić się co do posiadania zainstalowanych pa-
aplikacji – wykorzystując ściśle zdefiniowane API, kietów z bibliotekami Qt oraz KDE, jak też pakietów
programista może dodać niestandardową funkcjonal- z nagłówkami dla tych bibliotek; zwykle nazywają-
ność bez ingerencji w samo jądro programu. O tym cych się, odpowiednio: qt3-devel oraz kdelibs3-de-
ostatnim aspekcie mówi niniejszy artykuł. vel. Nie jest konieczne korzystanie ze środowiska
Głównymi czynnościami wykonywanymi w aplika- KDE – potrzebne funkcje będą uruchamiane w tle
cjach bazodanowych jest wprowadzanie danych oraz niezależnie od uruchomionego pulpitu;
ich przetwarzanie i wyprowadzanie do systemów ze- • Pobrać kod źródłowy Kexi. Znajduje się on na stro-
nie poświęconej artykułowi (link podany na koń-
Jarosław Staniek jest z wykształcenia informatykiem,
cu artykułu). Aktualną wersję można też pobrać
pracuje w firmie OpenOffice Polska w Warszawie. Jest z repozytorium Subversion KDE – sposób pobrania
założycielem projektu KDElibs for Windows oraz zarzą- oraz instrukcje kompilacji znajdują się na http://kexi-
dza projektem Kexi w ramach organizacji KDE. project.org/w/?UsingSubversion (zalecana wer-
Kontakt z autorem: js@iidea.pl sja zawsze aktualnego kodu) lub pobrać paczkę
z kodem źródłowym (dla naszych potrzeb wymaga-

60 www.sdjournal.org Software Developer’s Journal 1/2007


Rozszerzenia środowiska bazodanowego Kexi

na jest wersja co najmniej 1.6 rc1) – http://download.kde.org/ dem źródłowym, gdyż uniemożliwiłoby to ewentualne
download.php?url=unstable/koffice-1.6-rc1/ ; testy.
• Skompilować Kexi. Wystarczy przeprowadzić kompilację • Sprawdzić poprawność zbudowania i zainstalowania Kexi, na
w katalogach koffice/lib/ oraz koffice/kexi/, omijając inne przykład przez uruchomienie programu i otwarcie przykłado-
programy pakietu KOffice. Dokonuje się tego poleceniami: wej bazy danych Simple_Database.kexi znajdującej się w ka-
cd koffice; ./configure –prefix=`kde-config –prefix` talogu koffice/kexi/examples/ – należy ją wygenerować uru-
cd lib; make; make install; cd ../ chamiając znajdujący się tam skrypt build_kexi_files.sh;
kexi; make; make install • Szczegółowa wiedza na temat kompilacji wykracza po-
(w przypadku pobierania źródeł w postaci archiwum) oraz: za zakres niniejszego artykułu. W razie problemów moż-
cd koffice/; make -f Makefile.cvs; ./ na skorzystać z pomocy oferowanej na stronie http://kexi-
configure –prefix=`kde-config –prefix` project.org/w/?Support. W dalszej lekturze artykułu przy-
cd lib; make; make install; cd ../ da się znajomość biblioteki Qt, jednak przykłady będą
kexi; make; make install dość zrozumiałe dla każdego znającego język C++.
• Potrzebne będą autoconf oraz automake, ten ostat-
ni można zastąpić szybszym unsermake. Po kompila- Pliki z omawianym kodem źródłowym znajdują się na stronie
cji nie należy usuwać katalogu ze skompilowanym ko- dedykowanej niniejszemu artykułowi. Na końcu artykułu znaj-

Listing 1. Główny program eksportu do formatu Fixed-Width Text (main.cpp)

#include <stdio.h> if (!app.openDatabase( dbName )) {


#include <qfile.h> app.debugError();
#include <kdebug.h> return 1;
#include <kcmdlineargs.h> }
#include <kapplication.h> KexiDB::Connection *conn = app.connection();
#include <kinstance.h> KexiDB::TableSchema *table = conn->tableSchema(
#include <kaboutdata.h> dataSourceName );
#include <kexidb/connection.h> KexiDB::QuerySchema *query = table ? table->query()
#include <kexidb/tableschema.h> : conn->querySchema( dataSourceName );
#include <kexidb/queryschema.h> if (!query) {
#include <kexidb/cursor.h> kdWarning() << "Data source '" << dataSourceName <<
#include <kexidb/simplecommandlineapp.h> "' not found" << endl;
static KCmdLineOptions options[] = { return 1;
{ "+db_name", I18N_NOOP("Database name"), 0}, }
{ "+table_or_query", I18N_NOOP("Table or query name QFile outputFile(outputFName);
(as data source)"), 0}, { "+output_file", bool ok;
I18N_NOOP("Output filename in Fixed-Width Text format\n" if (outputFName=="-")
"(use \"-\" for standard output)"), 0}, ok = outputFile.open(IO_WriteOnly, stderr);
KCmdLineLastOption else
}; ok = outputFile.open(IO_WriteOnly);
int main(int argc, char** argv) { if (!ok) {
KexiDB::SimpleCommandLineApp app( kdWarning() << "Could not open '" << outputFName <<
argc, argv, options, "ExportToFixedWidth", "' output file: "
"0.1", "", KAboutData::License_LGPL, << outputFile.errorString() << endl;
"(C) 2006, Jaroslaw Staniek\n", "", return 1;
"http://www.koffice.org/kexi"); }
KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); QTextStream outputStream(&outputFile);
if (args->count()<3) { if (!exportToFixedWidthText(query, outputStream)) {
KCmdLineArgs::usage(); kdWarning() << "Error exporting '" << dataSourceName
return 1; << "' to '" << outputFName << "'" << endl;
} app.closeDatabase();
const QString dbName( args->arg(0) ), return 1;
dataSourceName( args->arg(1) ), }
outputFName( args->arg(2) ); outputFile.close();
if (!app.connectionData()->fileName().isEmpty() if (!app.closeDatabase()) {
&& dbName==outputFName) { app.debugError();
kdWarning() << "Output filename cannot be the same return 1;
as database filename" << endl; }
return 1; return 0;
} }

Software Developer’s Journal 1/2007 www.sdjournal.org 61


Bazy
danych

duje się opis kompilacji obu rozszerzeń przy wykorzystaniu Narzędzie eksportu będzie dla uproszczenia stanowić osob-
tych plików. ny program wywoływany z linii poleceń. Programy tego typu są
przydatne w integracji różnych systemów przetwarzania informa-
Narzędzie eksportu cji. Przy okazji uniknie się nieistotnych dla poruszanego tematu
do formatu Fixed-Width Text spraw związanych np. z integracją w interfejsie użytkownika.
Mając przygotowane środowisko z potrzebnymi funkcjami Pierwszą rzeczą do napisania jest łączenie się z bazą da-
API, najpierw napiszemy program służący do eksportowania nych według parametrów podanych przez użytkownika. Na Li-
tabel danych do formatu Fixed-Width Text. Pomoże to przy stingu 1 znajduje kod programu głównego. Nie korzystamy z
okazji poznać API dostępu do baz danych używane w Kexi – okien startowych Kexi, więc są przyda się klasa KCmdLineArgs
warstwę abstrakcji zaimplementowaną w bibliotece KexiDB. z biblioteki kdecore i argumenty opisane strukturą KCmdLineOp-
W czasie pisania programów korzystających z tej biblio- tions. Obiekt klasy KexiDB::SimpleCommandLineApp obsłuży in-
teki przydatna może być dokumentacja http://www.kexi- stancję programu bez GUI, dodając obsługę argumentów –
project.org/docs/svn-api/html/namespaceKexiDB.html. driver <nazwa _ sterownika _ baz _ danych> (lub - drv, domyśl-

Listing 2. Funkcja eksportująca dane (pozostała część main.cpp)

bool exportToFixedWidthText(KexiDB::QuerySchema // wyjsciowego


*query, QTextStream& outputStream) { KexiDB::Cursor *cursor = conn->executeQuery( *query );
KexiDB::Connection *conn = query->connection(); if (!cursor) {
KexiDB::Driver *drv = conn->driver(); conn->debugError();
// policz szerokosci kolumn (zaleznie od typu danych) return false;
KexiDB::QueryColumnInfo::Vector vector = }
query->fieldsExpanded(); cursor->moveFirst();
QValueVector<uint> columnSizes(vector.size()); if (cursor->error()) {
for (uint i = 0; i<vector.count(); i++) { cursor->debugError();
KexiDB::QueryColumnInfo *info = vector[i]; conn->deleteCursor(cursor);
switch (info->field->type()) { return false;
case KexiDB::Field::Text: }
case KexiDB::Field::LongText: { bool printColumnNames = true;
QString len; while (!cursor->eof()) {
if ( true != conn->querySingleString( const uint fields = QMIN(cursor->fieldCount(),
QString("SELECT MAX(LENGTH(%1)) FROM %2") vector.count());
.arg(drv->escapeIdentifier(info->aliasOrName())) for (uint i = 0; i<fields; i++) {
.arg(drv->escapeIdentifier(info->field->table()->name())), KexiDB::QueryColumnInfo *info = vector[i];
len) ) { QString str( printColumnNames ?
conn->debugError(); info->captionOrAliasOrName()
return false; : cursor->value(i).toString() );
} if (info->field->isNumericType()) {
columnSizes[i] = len.isEmpty() ? 5 : len.toInt(); outputStream << str.rightJustify( columnSizes[i] );
break; outputStream << " ";
} }
case KexiDB::Field::Byte: columnSizes[i]=4; break; else
case KexiDB::Field::ShortInteger: columnSizes[i]=6;break; outputStream << str.leftJustify( columnSizes[i] );
case KexiDB::Field::Integer: columnSizes[i]=12; break; }
case KexiDB::Field::BigInteger: columnSizes[i]=21; break; outputStream << "\n";
case KexiDB::Field::Boolean: columnSizes[i]=2; break; // nazwy kolumn pokazane, teraz pokaz pierwszy wiersz
case KexiDB::Field::Date: columnSizes[i]=11; break; if (printColumnNames) {
case KexiDB::Field::DateTime: columnSizes[i]=20; break; printColumnNames = false;
case KexiDB::Field::Time: columnSizes[i]=8; break; continue;
case KexiDB::Field::Float: columnSizes[i]=16; break; }
case KexiDB::Field::Double: columnSizes[i]=20; break; if (!cursor->moveNext() && cursor->error()) {
case KexiDB::Field::BLOB: columnSizes[i]=5; break; cursor->debugError();
default: columnSizes[i]=2; break; conn->deleteCursor(cursor);
} return false;
columnSizes[i] = QMAX( columnSizes[i], }
info->captionOrAliasOrName().length() ); }
columnSizes[i]++; query->connection()->deleteCursor( cursor );
} return true;
// otworz kursor bazodanowy i wypisz dane do strumienia }

62 www.sdjournal.org Software Developer’s Journal 1/2007


Rozszerzenia środowiska bazodanowego Kexi

Listing 3. Klasa widżetu suwaka obsługującego dane z bazy


// kexidbslider.h protected:
#include <plugins/forms/kexiformdataiteminterface.h> // reakcja na otrzymane dane z bazy
#include <knuminput.h> virtual void setValueInternal(const QVariant& add,
class KexiDBSlider : public KIntNumInput, bool removeOld);
public KexiFormDataItemInterface { Q_OBJECT private:
// wlasciwosci potrzebne w trybie projektowania bool m_invalidState : 1;
// formularza bool m_valueIsNull : 1;
Q_PROPERTY(QString dataSource READ dataSource };
WRITE setDataSource DESIGNABLE true) // kexidbslider.cpp
Q_PROPERTY(QCString dataSourceMimeType #include <qlineedit.h>
READ dataSourceMimeType WRITE #include "kexidbslider.h"
setDataSourceMimeType DESIGNABLE true) public: #include <kexiutils/utils.h>
KexiDBSlider(QWidget *parent, const char *name=0); #include <kexidb/queryschema.h>
virtual ~KexiDBSlider(); KexiDBSlider::KexiDBSlider(QWidget *parent, const char
// nazwa zrodla danych *name)
inline QString dataSource() const { : KIntNumInput(parent, name), KexiFormDataItemInterface()
return KexiFormDataItemInterface::dataSource(); } , m_invalidState(false), m_valueIsNull(true)
// typ zrodla danych (obecnie kexi/table lub kexi/query) {
// - potrzebne do rozroznienia tabeli od zapytania, gdy setRange(0, 100, 1/*step*/, true/*slider*/);
// nie roznia sie nazwa setFocusPolicy(QWidget::StrongFocus);
inline QCString dataSourceMimeType() const // we want to react on text changes, not only on clicking
{return KexiFormDataItemInterface::dataSourceMimeType();} QLineEdit *editor = KexiUtils::findFirstChild<QLineEdit>(
// biezaca wartosc widzetu m_spin, "QLineEdit");
virtual QVariant value(); if (editor)
// uzywane, gdy zrodlo danych jest niepoprawne connect( editor, SIGNAL(textChanged(const QString&)),
virtual void setInvalidState(const QString& displayText); SLOT(slotValueChanged()) );
// zwraca true jesli wartosc edytora jest NULL - musi byc }
// ona trzymana w osobnej zmiennej, bo oryginalny widzet KexiDBSlider::~KexiDBSlider() {}
// przechowuje tylko wartosci typu int void KexiDBSlider::setInvalidState(
virtual bool valueIsNull() { return m_valueIsNull; } const QString& displayText ) {
// zwraca true jesli wartosc edytora jest pusta setEnabled(false);
virtual bool valueIsEmpty() { return valueIsNull(); } KexiFormDataItemInterface::setValue(minValue());
// zwraca wartosc flagi 'tylko do odczytu' m_invalidState = true;
virtual bool isReadOnly() const { return !isEnabled(); } if (focusPolicy() & TabFocus)
// wskazuje na wlasciwy widzet, ktory powinien otrzymac setFocusPolicy(QWidget::ClickFocus); }
// focus (tutaj jest nim ten sam widzet) void KexiDBSlider::setEnabled(bool enabled) {
virtual QWidget* widget() { return this; } if(enabled && m_invalidState)
// obsluga klawiszu strzalek - zawsze zezwalaj na return;
virtual bool cursorAtStart() { return true; } KIntNumInput::setEnabled(enabled); }
virtual bool cursorAtEnd() { return true; } void KexiDBSlider::setValueInternal(
// czyszczenie wewnetrznej wartosci widzetu, powrot const QVariant &add, bool removeOld) {
// do wartosci oryginalnej Q_UNUSED(add);
virtual void clear(); Q_UNUSED(removeOld);
virtual void setEnabled(bool enabled); KIntNumInput::setValue( m_origValue.toInt() );
public slots: m_valueIsNull = m_origValue.isNull(); }
// obsluga wlasciwosci 'zrodlo danych' Qvariant KexiDBSlider::value() {
void setDataSource(const QString &ds) return m_valueIsNull ? QVariant() : KIntNumInput::
{ KexiFormDataItemInterface::setDataSource(ds); } value(); }
// obsluga wlasciwosci 'typ zrodla danych' void KexiDBSlider::slotValueChanged() {
inline void setDataSourceMimeType(const QCString &ds) m_valueIsNull = false;
{ KexiFormDataItemInterface::setDataSourceMimeType(ds); } signalValueChanged(); }
// obsluga zablokowania mozliwosci edycji void KexiDBSlider::clear() {
virtual void setReadOnly( bool readOnly ) { KIntNumInput::setValue( m_origValue.toInt() );
setEnabled(!readOnly); } m_valueIsNull = true;
protected slots: }
// reakcja na zmiane wartosci ze strony uzytkownika // metadefinicje Qt dla klasy KexiDBSlider
void slotValueChanged(); #include "kexidbslider.moc"

Software Developer’s Journal 1/2007 www.sdjournal.org 63


Bazy
danych

policzyć szerokości kolumn i zapamiętać je. Można tego doko-


nać metodą KexiDB::QuerySchema::fieldsExpanded() obiektu zapy-
tania, co zwróci wektor w którym elementami są struktury Query-
ColumnInfo niosące informacje o kolumnie zapytania. Używając
KexiDB::QueryColumnInfo::field->type() uzyskuje się informację
o typie danych (uogólnionym, niezależnym od silnika bazy da-
nych). W zależności od typu danych, przewidujemy maksymal-
ną szerokość kolumny, np. 8-bitowa liczba zajmie do 4 znaków
(z ewentualnym znakiem „-”), a typ data/czas 20 znaków. Szcze-
gólnym przypadkiem są typy KexiDB::Field::Text i KexiDB::
Field::LongText – dla nich przydatne jest wykonanie zapytania li-
czącego długość maksymalnego tekstu – SELECT MAX(LENGTH(na-
zwaKolumny)) FROM tabelaLubZapytanie.

Rysunek 2. Projekt formularza (na pasku narządzi widoczny Drugi etap eksportu to wypisanie w pętli dla każdego re-
nowy przycisk) kordu odpowiednio sformatowanej linii tekstu. Dotychczas
operowaliśmy na samym schemacie zapytania. Odczyt da-
nym jest obsługa plików .kexi), –user <nazwa _ uzytkownika> nych rekord po rekordzie wymaga zaalokowania obiektu kur-
(lub -u ), –password (lub -p, opcjonalnie), –host <nazwa _ kom- sora KexiDB::Cursor poprzez wywołanie metody KexiDB::Con-
putera> (domyślnie jest localhost), –port <numer _ portu> (do- nection::executeQuery(const &KexiDB::QuerySchema). Najpierw
myślna wartość zależna od bazy) oraz –local-socket <nazwa _ wypisywane są nazwy każdej z kolumn, ponownie wykorzy-
pliku _ gniazda _ lokalnego> (opcjonalnie). Czyni to przygoto- stując do tego wektor informacji o kolumnach KexiDB::Query-
wywany program prostszym do napisania. ColumnInfo::Vector. Metoda QueryColumnInfo::captionOrA-
Pozostaje dodać własne obowiązkowe argumenty. Po- liasOrName() pozwoli wypisać bardziej zrozumiałą dla użyt-
trzebne są trzy – kolejno – nazwa bazy danych, nazwa tabe- kownika etykietę kolumny lub jej alias zamiast zwykłej nazwy.
li lub zapytania oraz nazwa pliku do zapisania wyniku ekspor- Dopełniania wierszy spacjami najłatwiej dokonać metodami
tu. Te argumenty odczytuje się przy pomocy metody KcmdLi- QString::leftJustify(liczbaSpacji) oraz QString::rightJusti-
neArgs::arg(int). Klasa SimpleCommandLineApp zapewnia zbu- fy(liczbaSpacji), liczby spacji to szerokości kolumn uzyska-
dowanie struktury danych przechowującej dane potrzebne do ne w pierwszym kroku eksportu. Wartości liczbowe mogą być
połączenia. Można uzyskać do niej dostęp poprzez KexiDB:: wyrównywane do prawej, a pozostałe do lewej. Aby to spraw-
ConnectionData KexiDB::SimpleCommandLineApp::connectionDa- dzić typ, korzystamy z pomocnej metody KexiDB::Field::isNu-
ta() – korzystamy z tej możliwość aby na wszelki wypadek mericType() dla składowej KexiDB::QueryColumnInfo::field .
upewnić się, że nazwa pliku bazy (o ile baza jest w pliku) nie Po wykonanym eksporcie pozostaje usunąć kursor bazy
jest identyczna z nazwą pliku wyjściowego. danych (KexiDB::Connection::deleteCursor(kursor)), zamknąć
Bazę otwiera się wywołaniem KexiDB::SimpleCommandLine- bazę danych (KexiDB::SimpleCommandLineApp::closeDatabase())
App::openDatabase(nazwa), po czym można już korzystać z po- oraz zamknąć plik wyjściowy ( QFile::close()).
łączenia wykorzystując obiekt KexiDB::Connection, dostępny po-
przez KexiDB::SimpleCommandLineApp::connection(). Obiekt Ke- Testy eksportu
xiDB::Connection zawiera m.in. informacje o tabelach i zapyta- Program jest gotowy do użycia. Obsługiwane są bazy plikowe
niach, więc korzystamy z metody KexiDB::Connection::tableSche- .kexi oraz bazy na serwerach SQL. Przykładowe wywołanie eks-
ma(nazwaTabeli) a w przypadku gdy nie znaleziono tabeli o zada- portu tabeli adresy z bazy firmy.kexi na standardowe wyjście:
nej nazwie, także z KexiDB::Connection::querySchema(nazwaTabe-
li). Wart uwagi jest fakt, że ostatecznie i tak zawsze korzysta się ./fixed_width_export firmy.kexi -
z zapytania – obiekt tabeli oferuje bowiem metodę KexiDB::Table-
Schema::query() zwracającą zapytanie tożsame z SELECT * FROM
nazwaTabeli, dzięki czemu dalsze działania będą jednolite nieza-
leżnie od źródła danych przeznaczonych do eksportu. Przed wła-
ściwym eksportem należy przygotować plik wyjściowy otwierając
go w trybie do zapisu przy pomocy obiektu klasy QFile. Sam eks-
port wykonuje się poprzez obiekt klasy QTextStream , strumienia
dbającego o właściwe zakodowanie ewentualnych znaków na-
rodowych. Warto uwzględnić przydatny szczególny przypadek –
nazwa „-” oznacza standardowe wyjście – jest do niego dostęp
poprzez systemowy wskaźnik FILE *stdout. Funkcja exportToFi-
xedWidthText() będzie odpowiedzialna za wykonanie właściwego
eksportu. Jej kod wpiszemy przed funkcją main().
Właściwy eksport do formatu tekstowego należy przeprowa-
dzić w dwóch etapach. Format Fixed-Width wymaga znajomości
preferowanej szerokości każdej z kolumn, tak aby pomieściła da-
ne z każdego rekordu. Danych może być wiele, więc aby uniknąć Rysunek 3. Widżety suwaka w formularzu wyświetlające dane
potrzeby ponownego otwierania źródła danych, najpierw należy z tabeli pomiary

64 www.sdjournal.org Software Developer’s Journal 1/2007


Rozszerzenia środowiska bazodanowego Kexi

Przykładowe wywołanie eksportu tabeli adresy do pliku ad- 10916 94-241 Łódź Cieplarniana 60
resy.txt z bazy firmy na serwerze MySQL znajdującym się 23113 51-616 Wrocław Parkowa 2A
pod adresem data.base.org, korzystając z konta użytkowni-
ka scott: Nowy element GUI: widżet suwaka
Program Kexi zawiera zestaw widżetów do wyświetlania i wpro-
./fixed_width_export -p –drv mysql -h data.base.org wadzania danych bądź do sterowania (np. przycisk). W konkret-
-u scott firmy adresy - nych zastosowaniach zdarzają się specyficzne typy danych dla
których lepiej mogą się sprawdzać niestandardowe metody ich
Otrzymany wynik jest następującej postaci: wprowadzania czy wyświetlania. Jednym z takich typów jest licz-
ba całkowita ograniczona przedziałem (np. 0..100). Kiedy wpro-
Id Kod Miejscowość Ulica wadzanie wartości ma być szybkie i niekoniecznie precyzyjne –
3 16-300 Augustów Rynek 3 za to przy użyciu myszy – warto pokusić się o użycie widżetu su-
3034 80-029 Gdańsk Nakielska 15 waka zamiast zwykłego pola do wprowadzania liczby.

Listing 4. Klasa fabryki widżetów udostępniająca widżet suwaka

// customfactory.h wi->addAlternateClassName("QSlider", true/*override*/);


#include <formeditor/widgetfactory.h> wi->setNamePrefix(
#include <kgenericfactory.h> i18n("Widget name", "slider"));
class KexiCustomFactory : public wi->setDescription(i18n(
KFormDesigner::WidgetFactory { "A slider widget for editing integer values"));
Q_OBJECT public: wi->setPixmap("slider");
KexiCustomFactory(QObject *parent, const char *name, addClass(wi);
const QStringList &args); m_propDesc["label"] = i18n("Label Text");
virtual ~KexiCustomFactory(); m_propDesc["value"] = i18n("Value");
virtual QWidget *createWidget(const QCString &classname, m_propDesc["minValue"] = i18n("Minimum Value");
QWidget *parent, m_propDesc["maxValue"] = i18n("Maximum Value");
const char *name, KFormDesigner::Container *container, m_propDesc["suffix"] = i18n("Suffix Text");
int options = DefaultOptions ); m_propDesc["prefix"] = i18n("Prefix Text");
virtual void createCustomActions(KActionCollection* m_propDesc["specialValueText"] = i18n(
col) {}; "property name", "Special\nValue Text"); }
virtual bool createMenuActions(const QCString &classname, KexiCustomFactory::~KexiCustomFactory() {}
QWidget *w, QPopupMenu *menu, KFormDesigner:: QWidget* KexiCustomFactory::createWidget(
Container *container) { return false; } const QCString &c, QWidget *p, const char *n,
virtual bool startEditing(const QCString &classname, KFormDesigner::Container *container, int options) {
QWidget *w, QWidget *w = 0;
KFormDesigner::Container *container) { return false; } if (c == "KexiDBSlider")
virtual bool previewWidget(const QCString &, QWidget *, w = new KexiDBSlider(p, n);
KFormDesigner::Container *) { return false; } return w; }
virtual QValueList<QCString> autoSaveProperties( bool KexiCustomFactory::isPropertyVisibleInternal(
const QCString &classname) const QCString& classname,
return QvalueList<QCString>(); } QWidget *w, const QCString& property, bool isTopLevel) {
protected: bool ok = true;
virtual bool isPropertyVisibleInternal(const if (property=="dataSource" || property==
QCString& classname, QWidget *w, "dataSourceMimeType")
const QCString& property, bool isTopLevel); }; return false; //force hide
// customfactory.cpp if(classname == "KexiDBSlider") { //hide properties
#include "customfactory.h" if (property=="relativeValue" || property==
#include <klocale.h> "referencePoint")
#include <plugins/forms/kexidataawarewidgetinfo.h> return false;
#include "kexidbslider.h" }
KexiCustomFactory::KexiCustomFactory( return ok && WidgetFactory::isPropertyVisibleInternal(
QObject *parent, const char *name, const QStringList &) classname, w, property, isTopLevel); }
: KFormDesigner::WidgetFactory(parent, name) { // deklaracja punktu dostepu do biblioteki dynamicznej
KexiDataAwareWidgetInfo *wi = // (wtyczki)
new KexiDataAwareWidgetInfo( KFORMDESIGNER_WIDGET_FACTORY(
this, "stdwidgets", "QSlider" /*override*/); KexiCustomFactory, kexicustomwidgets)
wi->setName(i18n("Slider")); //metadefinicje Qt dla klasy KexiCustomFactory
wi->setClassName("KexiDBSlider"); #include "customfactory.moc"

Software Developer’s Journal 1/2007 www.sdjournal.org 65


Bazy
danych

zastosować prosty zabieg: wyszukać pole przy pomocy kon-


Listing 5. Plik do budowania wtyczki strukcji QLineEdit *editor = KexiUtils::findFirstChild<QLine-
// custom_widget/Makefile.am Edit>(m _ spin, "QLineEdit"), wiedząc że w hierarchii widże-
include $(top_srcdir)/kexi/Makefile.global tów podrzędnych suwaka jest tylko jeden obiekt QLineEdit. Po
kde_module_LTLIBRARIES = kformdesigner_kexicustomwidgets.la znalezieniu pola, łączymy jego sygnał QLineEdit::textChange-
d(const QString&) do slotu KexiDBSlider::slotValueChanged().
kformdesigner_kexicustomwidgets_la_LDFLAGS = $( Implementacja metody QVariant KexiDBSlider::value() ma
all_libraries) $(KDE_PLUGIN) \ zapewnić zwracanie poprawnej wartości bieżącej suwaka. Ja-
$(VER_INFO) -module -no-undefined ko, że bazy danych obsługują także wartość NULL , a KIntNu-
kformdesigner_kexicustomwidgets_la_SOURCES = mInput::value() operuje na typie int, potrzebna jest dodatko-
kexidbslider.cpp customfactory.cpp wa flaga bool m _ valueIsNull. Ustawienie jej na true będzie
kformdesigner_kexicustomwidgets_la_LIBADD = \ oznaczało, że value() ma zwrócić wartość NULL , czyli QVa-
$(top_builddir)/kexi/formeditor/libkformdesigner.la \ riant(). Implementacja metod bool valueIsNull() oraz bo-
$(top_builddir)/kexi/plugins/forms/libkexiformutils.la ol valueIsEmpty(), jest oczywista i opiera się na wspomnia-
nej fladze. Flaga m _ valueIsNull jest uaktualniana w metodzie
servicesdir=$(kde_servicesdir)/kformdesigner setValueInternal(), która odpowiada za zainicjowanie widże-
services_DATA=kformdesigner_kexicustomfactory.desktop ta oryginalną wartością m _ origValue pobraną z bazy danych
rcdir = $(kde_datadir)/kexi (jest ona zdefiniowana w nad-nadklasie KexiDataItemInterfa-
rc_DATA = kformdesigner_kexicustomwidgets.rc ce ). Metoda clear() po prostu przywraca przy pomocy metody
SUBDIRS = . KIntNumInput::setValue() wartość do domyślnej m _ origValue.
INCLUDES = -I$(top_srcdir)/kexi -I$(top_srcdir)/kexi/ Dla uproszczenia nie zajmujemy się sposobem wyświetlania
core $(all_includes) wartości NULL , co wykraczałoby poza zakres artykułu.
METASOURCES = AUTO Widżet suwaka jest gotowy, jednak to nie wystarczy by
można było go użyć w aplikacji Kexi, gdyż program musi wie-
dzieć o jego istnieniu. Aby spełnić ten warunek należy zbu-
Suwak zostanie zbudowany przy użyciu klasy KIntNumIn- dować odpowiednie rozszerzenie akceptowane przez Kexi.
put dostępnej w bibliotece kdeui. Jest ona bardziej rozbudo- Działa ono na zasadzie wtyczki, co oznacza, że aby dodać
wana niż QSlider z biblioteki Qt – zawiera dodatkowo pole do rozszerzenie nie jest wymagana żadna modyfikacja oryginal-
wpisywania wartości liczbowej, co jest przydatne gdy jednak nego programu Kexi lub jego reinstalacja. Wtyczka taka sta-
nadarzy się potrzeba skorzystania z klawiatury. Wygląd wi- nowi tzw. fabrykę widżetów – bibliotekę dynamicznie ładowa-
dżetu KIntNumInput jest przedstawiony na Rysunku 2. ną zdolną to tworzenia obiektów widżetów na żądanie macie-
Zgodnie z nieformalną zasadą używaną dla widżetów for- rzystego programu Kexi.
mularzy w Kexi, widżet suwaka będzie miał nazwę KexiDBSli- Fabryka widżetów (której deklaracja i implementacja znajdu-
der. Powinien on dziedziczyć nie tylko z klasy KIntNumInput ale ją się na Listingu 4) na potrzeby pisanego rozszerzenia otrzyma
też z KexiFormDataItemInterface, czyli z interfejsu programi- nazwę KexiCustomFactory, a dziedziczyć będzie z klasy KFormDe-
stycznego przeznaczonego do deklarowania widżetów obsłu- signer::WidgetFactory, dostępnej w bibliotece kformdesigner –
gujących dane z bazy danych. Deklaracja oraz implementacja składnika Kexi. Będzie to prosty przypadek fabryki oferującej tyl-
klasy KexiDBSlider znajdują się na Listingu 3. ko jedną klasę widżetu – zaimplementowanego wcześniej suwa-
Podstawową sprawą w „podłączeniu” widżetu do bazy da- ka. W konstruktorze fabryki KexiCustomFactory wymagane jest
nych jest zdefiniowanie właściwości dataSource oraz dataSour- zadeklarowanie istnienia oferowanych widżetów. Jest tak, gdyż
ceMimeType. Jest to proste, gdyż należy w implementacji wywo- informacje te są wykorzystywane przez macierzysty program
łać odpowiednią metodę nadklasy KexiFormDataItemInterface. także zanim zostanie utworzony pierwszy obiekt widżeta. Przy
Nie da się tego uniknąć ze względu na sposób działania mecha- pomocy klasy KexiDataAwareWidgetInfo należy zadeklarować ta-
nizmu właściwości w Qt, gdzie użyte we właściwościach (Q _ PRO- kie cechy jak nazwę klasy widżetu (metoda setClassName()), na-
PERTY) metody muszą być jawnie zadeklarowane jako KexiDBSli- zwę dostępną do przetłumaczenia (metoda setName()), ikonę wi-
der::dataSource(), KexiDBSlider::setDataSource(), itd.
W konstruktorze klasy KexiDBSlider można zainicjować Listing 6. Plik deklarujący wtyczkę dla nowej fabryki
pewne ustawienia domyślne. Wywołanie KIntNumInput::se- widżetów w środowisku KDE
tRange(0, 100, 1, true) ustawi domyślny zakres suwaka na
0..100, krok na 1 oraz włączy pokazywanie suwaka obok pola [Desktop Entry]
z liczbą. Konieczne jest wywołanie metody signalValueChan- Encoding=UTF-8
ged() z nadklasy w momencie zmiany wartości. Można by zro- Type=Service
bić to przez połączenie sygnału valueChanged(int value) wła- ServiceTypes=KFormDesigner/WidgetFactory
ściwego suwaka QSlider* KIntNumInput::m _ slider. Problem Name=Custom Kexi Widgets
jednak w tym, że formularz powinien otrzymać od suwaka X-KDE-Library=kformdesigner_kexicustomwidgets
informację o zmianie wartości od razu po rozpoczęciu edy- X-KFormDesigner-FactoryGroup=kexi
cji, czyli także po wpisaniu lub usunięciu pierwszego znaku X-KFormDesigner-WidgetFactoryVersion=2
w polu obok suwaka. Niestety pole to nie jest dostępne w pu- X-KFormDesigner-XMLGUIFileName=
blicznym API klasy KIntSpinBox , z której korzysta KIntNumIn- kformdesigner_kexicustomwidgets.rc
put. Aby zapewnić obsłużenie także tego przypadku, można

66 www.sdjournal.org Software Developer’s Journal 1/2007


Rozszerzenia środowiska bazodanowego Kexi

dżetu na pasku narzędzi (metoda setPixmap()), prefiks nazwy


używany do utworzenia domyślnej nazwy obiektu („suwak1”, W Sieci
„suwak2”, itp. – metoda setNamePrefix()), krótki opis przeznacze-
nia widżetu (metoda setDescription()). Dodatkowo dodaje się • Strona niniejszego artykułu z potrzebnymi zasobami:
http://www.kexi.pl/wiki/index.php/Artykuł:Pisanie_rozszerzeń_
też zwroty, które mają być później dostępne do tłumaczenia, np.
dla_Kexi
właściwość „minValue” suwaka może być wyświetlana w Panelu
• Główna strona projektu Kexi:
właściwości Kexi jako „Wartość minimalna”, zamiast mniej jasnej http://kexi-project.org
i nie przetłumaczonej „minValue”. • Polska strona projektu Kexi:
Za właściwe tworzenie obiektów klasy KexiDBSlider od- http://www.kexi.pl
powiada metoda KexiCustomFactory::createWidget(). Należy • Strona internetowa firmy OpenOffice Polska:
ją zaimplementować, sprawdzając żądaną nazwę klasy (pa- http://openoffice.com.pl
rametr c ) i tworząc nowy widżet z żądanymi parametrami: p
(widżet nadrzędny) oraz n (nazwa). Metoda isPropertyVisi-
bleInternal() ma zwracać false, jeśli dana właściwość ma być rozpoczęciu projektowania formularza (także o nazwie pomia-
ukryta na liście właściwości. Jest to używane w przypadku ry) można się zorientować, że w Kexi stał się dostępny nowy
właściwości dataSource, dataSourceMimeType, które są raczej przycisk paska narzędzi – „Suwak” (Rysunek 2). Formularz
wyświetlane na karcie danych panelu właściwości w projek- czerpie dane z tabeli pomiary i ma wstawione dwa widżety
tancie formularzy. Warto też ukryć właściwości relative Value suwaka, przy czym pierwszy suwak ma źródło danych w po-
i referencePoint niesprawdzające się w obecnym przypadku. lu temperatura, drugi – w polu wilgotność. Suwaki umożliwia-
Pozostałe metody, jak createCustomActions(), pozostaną pu- ją w tym przypadku szybką modyfikację obu wartości, jak też
ste, gdyż w przypadku suwaka nie mają one zastosowania. zwiększają czytelność danych (Rysunek 3).
Gotową implementację fabryki deklarujemy jako bibliotekę
dostępną dla ładowania dynamicznego (mechanizmem KDE), Kompilacja rozszerzeń
dopisując na końcu linię KFORMDESIGNER _ WIDGET _ FACTORY(Ke- Należy wykonać następujące czynności:
xiCustomFactory, kexicustomwidgets).
Na listingu 5 znajduje plik Makefile.am, służący do zbu- • Rozpakować pliki fixed_width_text_src.tar.bz2 oraz cu-
dowania biblioteki z fabryką. Biblioteka jest ładowana na stom_widgets_src.tar.bz2 w katalogu koffice/kexi/tests/,
zasadzie wtyczki (modułu) o nazwie kformdesigner_kexi- co utworzy podkatalogi fixed_width oraz custom_widgets ;
customwidgets. Ważna jest tu deklaracja katalogów doce- • Do linii SUBDIRS w pliku koffice/kexi/tests/Makefile.am
lowych gdzie będą trafiały zbudowane pliki – zmiana tych dopisz nazwę katalogów fixed_width oraz custom_widget;
ścieżek uniemożliwiłaby odnalezienie wtyczki przez środo- • Powtórnie przeprowadzić konfigurację, aby powstały pli-
wisko KDE. ki Makefile w nowo dodanych katalogach (cd ../koffice;
Do działania wtyczki potrzebne są ponadto dwa dodat- ./configure –prefix=`kde-config –prefix`), kompilację i insta-
kowe pliki konfiguracyjne. Jednym jest plik usługi środowi- lację obu rozszerzeń (cd kexi/tests/fixed_width; make; ma-
ska KDE – kformdesigner_kexicustomfactory.desktop (Listing ke install; cd ../custom_widgets; make; make install). Na
6), poszukiwany podczas próby ładowania wtyczki przez Ke- wszelki wypadek można odświeżyć cache konfiguracji
xi. Drugim jest kformdesigner_kexicustomwidgets.rc, deklaru- KDE, aby upewnić się, że wtyczka jest wykrywana przez
jący akcje paska narzędzi w aplikacji Kexi. Jedyną akcją do- system uruchamiając kbuildsycoca –noincremental.
starczaną przez wtyczkę jest library _ widget _ KexiDBSlider
(prefiks nazwy jest obowiązkowy), umożliwiająca wstawienie Wnioski
nowego widżetu do formularza. Oba pliki są dostępne razem W omówionych rozwiązaniach przyjęto pewne konieczne
z kodem źródłowym do tego rozszerzenia. uproszczenia. Format Fixed-Width Text będzie obsługiwany
w przyszłych wersjach Kexi z poziomu GUI, na zasadzie po-
Testy widżetu suwaka dobnej jak ma to obecnie miejsce z formatem CSV. Obsłu-
Do przetestowania widżetu suwaka można użyć prostej ba- ga formatu Fixed-Width Text będzie uzupełniona też funk-
zy danych test.kexi. Jest ona dostępna na stronie niniejsze- cją importu, powstaną funkcje udostępnione dla innych apli-
go artykułu. Tabela o nazwie pomiary zawiera pola tempera- kacji, w tym programów biurowych. Widżet suwaka prawdo-
tura i wilgotność , oba typu liczba całkowita (Rysunek 1). Przy podobnie znajdzie się w standardowej bibliotece widżetów
wbudowanych w aplikację i zostanie rozszerzony obsługę
Listing 7. Plik deklarujący akcje paska narzędzi dla liczb z cyframi po przecinku.
rozszerzenia suwaka w aplikacji Kexi Interfejsy programistyczne pozwoliły na skupienie się na za-
daniu – większość potrzebnych funkcji jest od razu wbudowana,
<!DOCTYPE kpartgui> np. klasa KexiDB::SimpleCommandLineApp pozwoliła na szybkie
<kpartgui name="kexiformpartinst" version="1"> zbudowanie programu działającego z linii poleceń z niezbędnymi
<ToolBar name="widgets" fullWidth="false"> opcjami. Z kolei API widżetów pozwoliło łatwo dodać obsługę ba-
<text>Widgets</text> zy danych do istniejącego widżetu powszechnego użycia (KInt-
<Action name="library_widget_KexiDBSlider"/> SpinBox). W obu rozszerzeniach nie użyto ani jednej linii kodu za-
</ToolBar> leżnej od konkretnego serwera SQL, dzięki czemu dodanie ob-
</kpartgui> sługi nowego typu źródła danych na ogół nie wymagałoby doko-
nywania zmian w niniejszych programach. n

Software Developer’s Journal 1/2007 www.sdjournal.org 67


Wywiad

SDJ

Rozmowa
Sylwia Pogroszewska
z Davem Chappelem
D
ave Chappell, Vice President and Chief
Technilogy Evenagelist Prograss Softwa-
re. Wywiad przeprowadzono na konferen-
cji dotyczącej SOA.
Sylwia Pogroszewska: Jest Pan autorem artykułów
na temat Javy...
Dave Chappel: Tak, napisałem wiele artykułów o Ja-
vie, wiele z moich artykułów dotyczyło również aplika-
cji migracyjnych, oprogramowania typu MOM (Mes-
sage-Oriented Middleware) i korporacyjnej magistra-
li usług (Enterprise Service Bus) jako środków do bu-
dowania architektury zorientowanej na usługi (Service
Oriented Architecture). Nie chodzi więc tylko o Javę,
ale o łączenie różnorodnych platform i aplikacji w bar-
dziej interoperacyjną SOA przy użyciu usług siecio-
wych, protokołów, oraz technologii takich jak ESB.
SDJ: I właśnie o korporacyjnej magistrali usług chcia-
łeś nam dzisiaj opowiedzieć?
DC: Cóż, to nie ja wpadłem na ten pomysł, to wynik
pracy wielu naprawdę inteligentnych ludzi w Progress
Software, którzy razem z naszymi klientami przez la-
ta wspólnie określali wymagania oraz rozwiązania dla
kompleksowej integracji systemów przy użyciu architek-
tury zorientowanej na usługi, dla komunikacji za pomo-
Zdjęcie 1. Dave Chappel
cą różnorodnych technologii, jednak skupiając się głów-
nie na uzyskaniu niezawodności, dostępności i skalo- dziej na konfiguracji, niż programowaniu, jednak wciąż
walności korporacyjnych systemów opartych na aplika- istnieje wystarczająco duża ilość kodu, który trzeba na-
cjach usługowych komunikujących się między sobą we pisać gdzie indziej, w formie rdzenia logiki biznesowej.
wspólnej magistrali usługowej. Mówiąc w skrócie, tech- W ten sposób deweloperzy wnoszą wartość do bizne-
nologia ESB jest wykorzystywana do łączenia, pośred- su - nie musi to koniecznie polegać na pisaniu kodu łą-
niczenia, oraz zarządzania interakcją pomiędzy różno- czącego aplikacje. ESB uwalnia programistę od zmar-
rodnymi aplikacjami świadczącymi usługi w sieci. twień związanych z tworzeniem infrastruktury zabez-
Cała historia zaczęła się, kiedy na początku 2000 pieczeń, pisania niskopoziomowego kodu obsługują-
roku firma Sonic Software weszła na rynek ze swo- cego protokoły sieciowe, czy zapewnienia niezawodno-
im produktem, który oferował rozwiązania enterprise ści każdej aplikacji, dzięki czemu może się on skupić na
messaging i spełniał wymogi specyfikacji Java Mes- logice biznesowej i rzeczywistej implementacji samych
sage Service. Od początku zgłaszało się do nas bar- usług, może budować bardziej wszechstronną SOA w
dzo wielu klientów, takich jak Commerce One i GE Glo- dowolny sposób, który uzna za odpowiedni.
bal eXchange Services (GE GXS), którzy próbowa- SDJ: …w takim razie, czy mógłbyś opowiedzieć, jak
li tworzyć rynki elektroniczne w oparciu o nasze opro- budować architekturę oprogramowania opartą na SOA?
gramowanie oraz globalne korporacje, jak Philips Elec- DC: Naturalnie. Tak naprawdę SOA jest modelem
tronics, gdzie próbowano zintegrować rozsiane po ca- projektowania, poprzez który deweloperzy i projek-
łym świecie oddziały firmy w scentralizowanym syste- tanci z branży IT tworzą usługi wykorzystując w tym
mie przesyłu płatności. Spodobały się im nasze rozwią- celu istniejące komponenty aplikacji i źródła danych,
zania, ale powiedzieli, że JMS to za mało, bo nie chcą łącząc je następnie ze sobą przy pomocy standardo-
angażować programistów za każdym razem, kiedy bę- wych interfejsów. Dzięki temu można podnosić war-
dzie trzeba połączyć jeden system z innym. Potrzebo- tość już rozpoczętych inwestycji i istniejących zaso-
wali struktury usługowej na wyższym poziomie, za po- bów oprogramowania, możliwe jest współdzielenie
mocą której mogliby opisać wzajemne interakcje tych zasobów systemowych pomiędzy zespołami dewelo-
systemów bardziej poprzez konfigurację, niż kodowa- perów, pomiędzy działami.
nie. Wiem, że wasi czytelnicy, którzy zawodowo zajmu- SDJ: …co jest najważniejsze przy budowaniu aplika-
ją się kodowaniem, pomyślą teraz, że ESB polega bar- cji opartych na SOA?

68 www.sdjournal.org Software Developer’s Journal 1/2007


Wywiad SDJ

DC: Najważniejszą rzeczą jest to, że możesz budować syste- ra stworzone specjalnie dla usług rozproszonych. Koncentru-
my umożliwiające automatyzację funkcji w dziedzinach bizne- je się ono na zachodzących procesach, dzięki czemu możesz
su, w których nie było to dotąd możliwe. Tworząc SOA budujesz ustawiać punkty przerwań dla poszczególnych usług, śledzić
o wiele bardziej elastyczną architekturę, która potrafi reagować krok po kroku całe procesy i debugować wywołania usług,
na zmienne wymagania pojawiające się w biznesie. Największa kiedy każda z nich otrzymuje i wysyła żądania do innych. Co
presja, z jaką obecnie mają do czynienia deweloperzy polega na więcej, można to robić zdalnie, dlatego nawet jeśli usługi dzia-
tym, że nieustannie żąda się od nich tworzenia nowych funkcji i łają na wielu maszynach, debuger automatycznie przejdzie
wprowadzania zmian w istniejących systemach tak, aby zaspo- tam, gdzie są one uruchomione. Możesz zajrzeć do wnętrza
kajać potrzeby ludzi związanych z biznesem. SOA dostarcza no- usługi, prześledzić przepływ danych, możesz ją debugować i
wą, o wiele bardziej elastyczną architekturę, która pozwala pro- przekonać się, gdzie leży problem… To wyjątkowa możliwość.
gramistom o wiele lepiej reagować na potrzeby ludzi biznesu SDJ: … tu w Polsce?
związane z implementowaniem nowych funkcji i wprowadzaniem DC: Na razie nie. Koncentrujemy się na zdobywaniu rynku.
zmian w istniejących systemach oprogramowania. Sonic istnieje, jak już wspominałem, od sześciu lat. Zaczynali-
SDJ: Jak udało się wasze dzisiejsze seminarium? śmy w Ameryce Północnej i kilku krajach Europy, a dopiero w
DC: Jak się udało? Bardzo - przyszło wielu ludzi. Mieliśmy dwie zeszłym roku zaczęliśmy rozszerzać naszą obecność w całej
pełne sale… Myślę, że wzięło w nim udział sześćdziesiąt, mo- Europie. Skupiamy się na rozwoju firmy i nabieramy rozpędu.
że siedemdziesiąt osób. Odbiór był bardzo dobry, wykształceni Umacniamy relacje z naszą macierzystą korporacją, którą jest
ludzie z wielu różnych środowisk. Spotkaliśmy się z ludźmi, któ- Progress, i która ma już przedstawicielstwa w Polsce oraz in-
rzy już tworzą swoje własne architektury zorientowane usługo- nych krajach; w większości krajów europejskich. Dzięki temu
wo korzystając z własnych technik i kodu… i oni naprawdę po- możemy wejść na polski rynek i pozyskiwać nowych klientów.
znali, jak wiele korzyści może dać ESB, kiedy nie trzeba zajmo- Przed nami ekscytujące możliwości…
wać się całą tą dodatkową pracą. Mieliśmy dużo ciekawych py- SDJ: Więc poprzez tą konferencję prezentujecie te narzędzia, tak?
tań, które potwierdziły dobre zrozumienie problemu… Jakie to DC: Tak, dzisiaj pokazywaliśmy narzędzia, rozmawialiśmy
były pytania? Cóż, przede wszystkim ludzie chcieli się dowie- głównie o architekturze, ESB, również o kwestiach związanych
dzieć, na jakim etapie są ich koledzy w innych częściach świa- z kulturą korporacyjną, które towarzyszą wdrażaniu SOA. Ele-
ta, bo wielu z nich miało wrażenie, że zostają trochę w tyle i mentem wdrażania SOA jest to, że deweloperzy muszą po-
próbują nadrabiać zaległości w wiedzy. Patrząc na wyniki son- przez organizację szeroko komunikować się z innymi działami
daży, które regularnie prowadzę z podobnymi grupami w innych informując, co robią, i dlaczego to robią, muszą też budować
krajach mogę powiedzieć, że jeśli chodzi o rozumienie tego, współpracę międzyludzką na nowych poziomach. W przeszło-
czym jest SOA, znajdują się mniej więcej na tym samym pozio- ści wielu deweloperów zajmowało się tworzeniem jednej bądź
mie, co reszta świata. Powiedziałbym, że około 20 procent już kilku aplikacji, skupiając się przede wszystkim na własnym
bierze udział w jakimś projekcie związanym z SOA, wielu jesz- dziale i własnych zadaniach, ale teraz, razem z pojawieniem się
cze nie zaczęło, ale wiedzą, że będą musieli; zdają sobie spra- architektury zorientowanej na usługi, każdy, kto posiada kawa-
wę z korzyści, jakie to ze sobą niesie, ale dopiero zaczynają łek logiki aplikacji lub danych musi myśleć, jak zamierza opako-
poznawać, na czym polega. Tak wygląda typowy przekrój pu- wać ten kawałek logiki w interfejs usługi i udostępnić go innym
bliczności, która pojawia się na tych forach… Ale gdybym miał zespołom deweloperskim, tak żeby mogły one skorzystać po-
przeprowadzić sondaż na grupie klientów Sonic Software, wy- nownie z twojego kawałka logiki biznesowej. Dodatkowo, na-
niki bardzo by się różniły. To dlatego, że oni posiadają już infra- stępnym razem, kiedy trzeba będzie stworzyć nowe oprogra-
strukturę umożliwiającą integrację SOA w ramach ESB, korzy- mowanie musisz też wiedzieć, w jaki sposób wyszukiwać inne
stają z SOA w o wiele większym zakresie. Nie muszą poświę- już istniejące usługi, które mogą spełniać wymagania tworzonej
cać tak dużo czasu na tworzenie niezawodnego modelu prze- przez ciebie aplikacji. Wtedy następne zadanie będzie polegało
syłania komunikatów, nie muszą się przejmować sposobem ko- na tym, żeby wykorzystać ponownie jak największą ilość tych
ordynacji usług, czy tworzeniem zabezpieczeń, bo wszystko to usług łącząc je w jeden program; i tak właśnie będzie wyglądał
jest już częścią ESB. Jedną z rzeczy, która może zaintereso- nowy sposób tworzenia oprogramowania. To oznacza, że zmia-
wać twoich czytelników jest wersja 7.0 Sonic ESB, która zawie- ny zachodzące w kulturze korporacyjnej wykraczają daleko po-
ra zrealizowany w środowisku Eclipse zestaw narzędzi do bu- za technologię, kiedy musisz nauczyć się współpracować z in-
dowy rozwiązań w architekturze SOA. nymi zespołami, żeby wykonać jakieś zadanie.
SDJ: Dlaczego Eclipse? SDJ: Na polskim rynku można zauważyć trzy firmy, są to
DC: Dlaczego Eclipse? Bo naszym zdaniem jest to narzędzie, BEA, IBM i Sonic. Czym różni się oferta Sonic Software od te-
po które deweloperzy sięgają najchętniej. go, co proponują IBM i BEA? Jest wiele innych firm, ale te trzy
SDJ: A co z NetBeans? Czy zamierzacie … są najbardziej popularne, są tutaj zauważane.
DC: Nie, nie mamy w planach wsparcia dla NetBeans, wybra- DC: No cóż… idea ESB polega na tym, że masz do dyspozycji
liśmy Eclipse. Stworzyliśmy nasz zestaw narzędzi do budo- elastyczną architekturę zapewniającą wsparcie dla rozproszonej
wania rozwiązań w architekturze SOA (SOA Workbench) wo- architektury SOA, którą próbujesz zbudować. Jeśli patrzeć na to
kół Eclipse, które obsługuje cały cykl tworzenia usług, konfi- w ten sposób, Sonic ESB dostarcza szkieletu, na którym możesz
gurowania usług, testowania usług, koordynacji wzajemne- zbudować wysoce skalowalną, lepszą rozproszoną architektu-
go oddziaływania usług, oraz uruchamiania usług. Zasadni- rę, która pozwala ci instalować i korzystać z poszczególnych ele-
czo oznacza to zarządzanie całym cyklem życia SOA, co jest mentów infrastruktury w dowolnej chwili i miejscu. Poza tym, So-
nigdy nie kończącym się procesem. Jednym z unikalnych ele- nic ESB jest jedynym produktem, który oferuje architekturę stałej
mentów zestawu narzędzi Eclipse jest środowisko debuge- dostępności (Continuous Availability Architecture). Architektura

Software Developer’s Journal 1/2007 www.sdjournal.org 69


Wywiad
SDJ

stałej dostępności pozwala infrastrukturze SOA przetrwać awa- sta i okolicznych terenów w sieć obsługującą telefony alarmowe i
rie, umożliwia jej dalsze funkcjonowanie w razie awarii i zakłóceń identyfikującą schematy mogące sygnalizować większy problem.
w sieci. Działa to w ten sposób, że nie wymaga żadnego specja- Jeśli więc ktoś łączy się z numerem 911, który służy do zgłosze-
listycznego sprzętu, współdzielonych zasobów dyskowych i te- nia pożaru, eksplozji i podobnych wypadków, ten system auto-
go typu rzeczy. W przypadku innych rozwiązań zapewniających matycznie połączy się z innymi, które zgłaszają takie zdarzenie i
wysoki stopień dostępności musisz polegać na łączeniu sprzę- automatycznie zidentyfikuje odpowiedni schemat, który może na
towym (hardware clustering), współdzielonych zasobach dysko- przykład oznaczać atak terrorystyczny.
wych, cofnięciu do ostatniej zapisanej transakcji, i ręcznym roll- SDJ: Jeszcze tylko dwa pytania. Pierwsze dotyczy głównej
forward recovery. Sonic ESB jest o wiele dojrzalszym produktem. technologii wykorzystywanej w waszych produktach, a dru-
Nasz pierwszy produkt ESB wszedł na rynek w marcu 2002 ro- gie… jako czytelnik, jak odbierasz „Software Developer’s”?
ku. Sprzedajemy go od ponad czterech lat i mamy ponad 350 DC: Rozumiem. Cóż, w czasie ostatnich kilku lat skupialiśmy się
klientów, z czego 250 już z niego korzysta i wiele się dzięki temu głównie na projektantach systemów, docieraliśmy do nich dzięki
nauczyliśmy, ulepszyliśmy też nasze oprogramowanie. Z drugiej konferencjom, takim jak ta, którą poprowadziłem dzisiaj. Odwie-
strony, IBM i BEA późno dołączyły do gry i dopiero zaczynają. dzaliśmy wiele miast na całym świecie, w Europie, Stanach Zjed-
Próbują unowocześniać swoje systemy tak, by zbudować coś na noczonych i Azji, zapraszaliśmy deweloperów do dyskusji o tech-
kształt ESB, ale w obu przypadkach przeszkodą jest przestarza- nologii, i okazało się to bardzo dobrym pomysłem. Jeśli chodzi o
ła infrastruktura, dlatego stworzenie dobrego produktu będzie dla technologie, które ma do zaoferowania Sonic, to tak naprawdę
nich bardzo trudnym wyzwaniem. są to dwa główne produkty, Sonic ESB, o którym już mówiłem i
SDJ: Oferta Sonic jest tańsza? Actional, który jest platformą do zarządzania systemami wykona-
DC: Zdecydowanie tak. Sonic opiera się na filozofii, która mó- nymi w architekturze zorientowanej na usługi (SOA management
wi, że integracja powinna dotyczyć całego przedsiębiorstwa. platform). Actional to infrastruktura umożliwiająca stosowanie za-
Jest tańsza, jeśli chodzi o licencjonowanie, ale ważniejsze od sad bezpieczeństwa, kontrolę i zarządzanie całą siecią SOA bez
tego są jeszcze koszt nabycia (cost of ownership) oraz prosto- względu na technologię, w której została zbudowana. Jeśli pod-
ta zdalnej instalacji, zarządzania i utrzymania. Mamy na przy- stawą twojej sieci SOA jest logika sieciowa, lub serwer aplikacji,
kład klientów, którzy zaimplementowali opcje zdalnego urucha- lub broker EAI, Sonic ESB, lub ESB innego dostawcy, platfor-
miania niewymagające żadnych działań ze strony człowieka… ma zarządzania SOA będzie w stanie automatycznie monitoro-
udostępniające kompletną infrastrukturę SOA razem z instala- wać sieć usług, będzie w stanie wyświetlić użytkownikowi infor-
cją wszystkich elementów Sonic ESB, kontenerem usług, ser- macje o parametrach jakości połączeń i automatycznie zastosuje
werami komunikacyjnymi, definicjami usług, wszystkimi ele- zasady poprzez całościowy proces biznesowy. Na przykład, jeśli
mentami uruchomieniowymi wymaganymi przez usługi, jak ustalasz politykę, według której wszystkie usługi muszą posiadać
arkusz stylów XSLT dla usług przekształcających dane, oraz możliwość szyfrowania, audytu i logowania, platforma zarządza-
wszystkimi zabezpieczeniami. Dzięki opcjom zdalnego uru- nia SOA będzie w stanie zastosować tę politykę dla wszystkich
chamiania wszystko może zostać zrobione w przeciągu minut. usług, które są częścią jakiegoś procesu biznesowego. To są
W przypadku dowolnej innej infrastruktury opartej na serwe- dwa główne produkty w ofercie Sonic Software.
rze aplikacji J2EE wymaga to obecności człowieka, który mu- Jeśli chodzi o waszych czytelników, którzy są dewelope-
si pracować na miejscu przez kilka tygodni, zanim wszystko za- rami, którzy mogą być zainteresowani tworzeniem architek-
cznie działać. To samo odnosi się do Websphere, mają podob- tur zorientowanych na usługi, najczęściej zadawane pyta-
ną architekturę i nawet bardziej skomplikowane oprogramowa- nia brzmią w ten sposób - jakie są technologie, które powinni
nie, które musi obsługiwać armia konsultantów. Taka jest głów- znać korzystający z ESB i jak nauczyć się korzystać z ESB?
na różnica między nami. Co więcej, w kwestii dostępności oni Sonic ESB w całości opiera się na standardach, co oznacza,
nie mają nawet w przybliżeniu tak dobrych rozwiązań, jakie So- że każdy aspekt, z którym się zetkniesz w ramach ESB wy-
nic oferuje dzięki swojej architekturze stałej dostępności. korzystuje jakiś standard. Na przykład, jeśli tworzysz usługi
SDJ: A co z klientami? Jakie sektory was interesują? Sektor przekształcania danych XML, głównym standardem, który ma
rządowy, ubezpieczeniowy, bankowy? tu zastosowanie jest XSLT, dlatego deweloperzy powinni za-
DC: Tak, to są rzeczywiście typowe dziedziny zastosowań. Wie- poznać się z tą technologią. Jeśli tworzysz usługi content ba-
lu z naszych klientów na całym świecie zajmuje się finansami, te- sed routing do badania zawartości usług, żeby określić, gdzie
lekomunikacją, obrotem detalicznym, o którym już wspomnia- przekierować dany proces biznesowy, wtedy w użyciu będzie
łem, zarządzaniem łańcuchem dostaw, a ostatnio obserwujemy XPath, JavaScript lub nawet Java. Tak więc deweloperzy po-
duży popyt ze strony władz lokalnych i federalnych. Spotkaliśmy winni się zapoznać z tymi technologami. Budując architekturę
się z tym w Stanach, spotkaliśmy się z tym w Europie, w Holan- SOA przy użyciu ESB bardzo ważnym aspektem są też usłu-
dii. Mamy kilka przypadków zastosowania w wymiarze sprawie- gi sieciowe, takie jak WSDL i SOAP, oraz nowsze, bardziej za-
dliwości, gdzie łączone są bazy danych przechowujące informa- awansowane usługi sieciowe, jak WS-ReliableMessaging,
cje o przestępcach… więc jeśli masz do czynienia z wymiarem WS-Security, WS-Policy, i WS-Addressing. Wersja 7.0 Sonic
sprawiedliwości, albo jeśli masz konflikt z prawem, to daleko nie ESB, o której opowiadałem, jako pierwsza dostarcza imple-
uciekniesz, bo Sonic poprzez ulepszenie procesu integracji baz mentacji tych zaawansowanych protokołów usług sieciowych.
danych zamierza sprawić, że informacje będą dostępne w czasie Deweloperzy powinni poznać te technologie, bo są to umie-
rzeczywistym. Inną dziedziną zastosowań są systemy reagowa- jętności, dzięki którym łatwiej będzie im znaleźć pracę. Przy-
nia kryzysowego. W Stanach Zjednoczonych mamy to na przy- szłość należy do technologii pochodnych XML oraz do inter-
kładzie Dystryktu Kolumbii w Waszyngtonie, gdzie używa się na- fejsów i protokołów budowanych w oparciu o standardy.
szego oprogramowania do połączenia wszystkich dzielnic mia- SP: Dziękuję za wywiad.

70 www.sdjournal.org Software Developer’s Journal 1/2007


R E K L A M A
Kasa dla

programisty

Rozmowa
Magdalena Filip
z Marcinem Kuciębą
M
arcin Kucięba, Software Development Mana-
ger Centrum Rozwoju Oprogramowania Sa-
bre w Krakowie
Magdalena Filip: Czy może mi Pan powiedzieć czym
zajmuję sie Centrum Rozwoju Oprogramowania Sabre
w Polsce?
Marcin Kucięba: Centrum Rozwoju Oprogramowania
Sabre zajmuje się tworzeniem rozwiązań dla sektora
turystycznego i lotniczego. Centrum istnieje już sześć
lat. Jednak dopiero dwa ostatnie lata to okres szczegól-
nie dynamicznego rozwoju. Działalność w Polsce po-
dzielona jest głównie na dwa obszary: Travel Network
i Airlines Solutions. Grupa Travel Network zajmuje się
tworzeniem i utrzymywaniem oprogramowania, któ-
re związane jest między innymi z procesem rezerwa-
cji biletów i połączeń lotniczych. Sabre jest właścicie-
lem jednego z czterech GDS na świecie, czyli syste-
mu do wyszukiwania i rezerwacji połączeń lotniczych,
hoteli, wycieczek. Firma ma szczególnie mocną pozy-
cję na rynku amerykańskim, gdzie większość transak-
cji bookingowych dotyczących biletów lotniczych prze- Zdjęcie 1. Marcin Kucięba
chodzi właśnie przez system Sabre. Drugim obszarem ski w poszukiwaniu ciekawej pracy. Bardzo dużo osób
działalności jest tworzenie rozwiązań i systemów infor- przyjeżdża również ze Stanów. Są to robocze wizyty na
matycznych dla przemysłu lotniczego, czyli Airline So- tydzień czy dwa, ale są i takie osoby, które przyjechały
lutons. Są to głównie aplikacje wspomagające obsługę do Krakowa na rok i dłużej. To, że decydują się na takie
lotnisk, cargo, boardingu, a także umożliwiające zarzą- dłuższe pobyty to także zasługa uroku miasta. Te dłuż-
dzanie rezerwacją miejsc w samolotach. sze kontakty są bardzo ważne. Szczególnie teraz, kiedy
SDJ: Czy Centrum Rozwoju Oprogramowania Sabre firma rozrasta się w takim tempie, potrzebujemy wspar-
tworzy, czy tylko wdraża oprogramowanie? cia w sprawach organizacji, zarządzania oraz kształce-
MK: W Krakowie zajmujemy się tworzeniem, modyfika- nia liderów w Polsce. Tak więc można powiedzieć, że
cją oraz utrzymaniem oprogramowania. W wielu przy- mamy zespół międzynarodowy. Poza tym, bardzo czę-
padkach systemy i serwisy stworzone jakiś czas temu sto zespoły, w których pracujemy, złożone są nie tylko
w USA, są przez nas przenoszone na nowe technolo- z deweloperów z Krakowa, ale również z deweloperów
gie czy platformy. Dobrym przykładem może być jeden pracujących w Stanach czy Indiach w Bangalore, gdzie
z projektów prowadzonych przez mój zespół. Prace do- Sabre posiada ośrodek deweloperski.
tyczyły migracji systemu służącego do definiowania SDJ: Ilu pracowników zatrudnia Centrum Rozwoju
cen połączeń lotniczych. Architektura całego tego sys- Oprogramowania Sabre?
temu charakteryzowała się obecnością dużej ilości roż- MK: Jeszcze 2,5 roku temu zatrudnialiśmy zaledwie
nych technologii: Java, JSP, C++, CORBA, Platforma 30-40 osób. Obecnie jest to ponad 300 pracowników.
NSK, MQSeries. Nasze zadanie polegało na uprosz- Jak widać dynamika wzrostu zatrudnienia jest ogrom-
czeniu architektury oraz przeniesieniu systemu w cało- na. Amerykanie cenią krakowski rynek pracy, chcą dalej
ści na Javę, używając frameworków Spring, Hibernate w niego inwestować. Angażują się bardzo mocno w to,
oraz bazy Oracle, a w warstwie systemowej rozwiązań co się tutaj tworzy, zarówno w obszarze technologii, za-
typu Open Systems. Tak więc podsumowując, w Krako- rządzania zespołami i projektami, lidershipem oraz moty-
wie zajmujemy się: utrzymywaniem systemów, ich mo- wacją pracowników. Bardzo wysoko cenią naszą wiedzę
dernizacją oraz implementacją wszelkiego rodzaju no- technologiczną i fachowość. Pomagają nam natomiast
wych funkcji, produktów, usług. w dziedzinach, w których mamy mniejsze doświadczenie.
SDJ: Czy zespół pracujący u Państwa jest stricte Polski SDJ: Jakie kryteria stawia firma przed kandydatem na
czy zagraniczny? pracownika?
MK: Większość zatrudnionych w Krakowie to Polacy, MK: Osoba, która chce pracować w Sabre, musi być
chociaż nie tylko. Pracują u nas również obywatele in- przede wszystkim otwarta. Szukamy ludzi, którzy chcą
nych krajów Unii Europejskiej, którzy przyjechali do Pol- pracować przy rozwoju software'u w dynamicznie roz-

72 www.sdjournal.org Software Developer’s Journal 1/2007


Kasa dla programisty

wijającej się firmie, którzy chcą i nie boją się kwestionować sta- gólnie cenimy chęć poznawania nowych technologii, nie ucieka-
tus quo, są w staniu aktywnie uczestniczyć we wprowadzaniu nia w jedną wąską dziedzinę, gdyż informatyka zmienia się bar-
nowych technologii, kreowaniu nowych pomysłów, wdrażaniu dzo dynamicznie. To, co dziś jest aktualne, jutro może być juz
nowych rozwiązań. Sabre stawia na osoby umiejące pracować przestarzałe. Ludzie, którzy są w stanie przeskoczyć z jednej
w zespole, nieobawiające się nowych wyzwań, chętne do nauki. technologii na drugą, z jednego projektu na inny, to osoby, które
To są pracownicy, których szukamy. mają największe szanse w Sabre.
SDJ: Jakich specjalistów poszukuje Sabre? SDJ: Czy zamierzają Państwo powiększyć zespół pracowników?
MK: W tym momencie poszukujemy doświadczonych dewelo- MK: Rekrutacja jest prowadzona właściwie na bieżąco. W momen-
perów, którzy mają już dłuższy staż pracy i odpowiednią wie- cie, gdy zbierzemy odpowiednią ilość kandydatów organizowane
dzę. Takich osób jest dość mało na rynku, i można powiedzieć, są tzw. „Assestment Days” czyli dni poświęcone rekrutacji. W fir-
że znalezienie i zatrudnienie takich ludzi stanowi wyzwanie dla mie wyznacza się zespoły, które prowadzą proces rekrutacyjny.
firm informatycznych. Sabre zatrudnia również ambitnych, mło- Kandydat zawsze przechodzi przez rozmowy z dwoma zespołami.
dych pracowników, dla których nasza firma jest bardzo często Pozwala to na konsultacje w większej liczbie osób i na lepszą oce-
pierwszym miejscem pracy. Jeśli chodzi o rodzaj doświadczenia nę potencjalnych pracowników. Decyzja o ewentualnym zatrudnie-
zawodowego, to nasze oczekiwania są dość szerokie. W Sabre niu podejmowana jest kolektywnie w gronie minimum 4 osób.
pracujemy z wieloma technologiami. Poczynając od tych, których SDJ: Jakie są warunki finansowe proponowane pracownikom?
my w kraju już raczej nie obsługujemy, a które głównie obecne MK: Uważam, że firma zapewnia dobre warunki finansowe,
są w Stanach, poprzez standardowe technologie: C, C++, Java, a także dodatkowo system premiowania, opiekę medyczną i wie-
RDBMS, kończąc na technologicznych nowościach. Poszukuje- le ciekawych opcji kulturalno – socjalnych. Fakt, że zdecydowana
my wiec specjalistów w niemal wszystkich dziedzinach. większość ofert jest przyjmowanych przez kandydatów świadczy
SDJ: Jaką ścieżkę kariery oferuje Sabre swoim pracownikom? o dostosowaniu naszej oferty do oczekiwań rynku. Uważam, że
MK: Ścieżka kariery zależy od tego, w jaki sposób zespół rekruta- jest to bardzo dobry wynik, szczególnie biorąc pod uwagę dość
cyjny oceni kandydata. Pracownik następnie ma możliwość awan- wysoką konkurencję na rynku pracy IT w Krakowie. Duży odse-
su z pozycji np. „junior developer” na pozycję „developer” bądź tek podpisywanych umów świadczy o tym, że to, co proponuje-
„senior developer”. Dalsza kariera może rozwijać się w jednym my kandydatom, jest powyżej średniej na rynku.
z dwóch kierunków. Pierwsza opcja to ścieżka menadżerska, która SDJ: Jakiej rady udzieliłby Pan osobom ubiegającym się o pracę
zaczyna się od „Software Developer Supervisor”, a wyżej są sta- w Sabre? Co musiałaby zrobić taka osoba?
nowiska menadżerskie. Druga możliwość związana jest bardziej MK: Taki idealny kandydat, musiałby przekonać nas, że jest
z technologią i są to stanowiska o profilu techniczno – architekto- w nim inicjatywa do tego żeby się uczyć i zgłębiać wiedzę. Braki
nicznym. Niemniej również i takie osoby muszą wykazywać pew- w wiedzy, jeżeli nawet są, mogą zostać zniwelowane, nadrobione.
ne cechy menażerskie. Na awans szansę mają osoby wyjątkowe, Jeżeli ktoś mnie o tym przekona, to ja jestem skłonny taką osobę
które będą potrafiły poprowadzić i motywować zespół. zatrudnić. Sabre pracuje dla takiego sektora, że w Polsce trudno
SDJ: Jakie kryterium decyduje o przyjęciu do pracy? jest znaleźć specjalistów znających problematykę przemysłu lot-
MK: Bardzo ważne jest to, jak przebiega rozmowa z kandy- niczego i turystycznego - po prostu ich nie ma. Co nie znaczy, że
datem. Jeżeli przeprowadzam rozmowę kwalifikacyjną jestem w firmie nie ma doskonałych specjalistów, którzy juz się na tym
skłonny do zatrudnienia osoby, która może ma mniejszą wiedzę, znają. To właśnie są osoby, które były w stanie się tego szybko na-
ale widać, że ma potencjał, chęć do pogłębiania wiedzy. Szcze- uczyć. Takie osoby zawsze będą miały pierwszeństwo. n

R E K L A M A
Algorytmy

zadanie

Monika Franczak
Licytacja
B
ył pochmurny listopadowy dzień. Zza okna
dochodziły odgłosy kropel deszczu uderza- Listing 1. Rozwiązywanie intuicyjne
jących w parapet a ja właśnie skończyłam var lz,ilz:longint; a,b:int64; n,m,i:longint;
czytać ostatni rozdział mojej ulubionej książki. Praw- begin
dę mówiąc, nie miałam pomysłu na ciekawe spędze- readln(lz);
nie tego dnia, ale w pewnej chwili przypomniałam so- for ilz:=1 to lz do
bie o czym w ostatnich dniach prowadzili intensyw- BEGIN
ne rozmowy moi koledzy z pracy. Dyskutowali za- readln(a,b,n,m); a:=a mod m; b:=b mod m;
wzięcie o jakichś internetowych zawodach w progra- for i:=1 to n do
mowaniu… zaraz, zaraz, jak one dokładnie się nazy- begin
wały? Internetowe Mistrzostwa Polski w Programo- if (i mod 2)=1 then a:=a+b
waniu? Tak, to była właśnie ta nazwa, tylko gdzie te- else b:=b+a; a:=a mod m; b:=b mod m;
go szukać w sieci? Kilka prostych zapytań i po pro- end;
blemie: http://opss.safo.biz i… wybrałam zadanie na writeln((a+b) mod m);
chybił-trafił. Oho, mam już chyba zajęcie na dzisiaj, END;
pomyślałam po przeczytaniu treści. Zadanie wydało end.
mi się ciekawe, a sposób rozwiązania przyszedł mi
do głowy stosunkowo szybko, choć przypuszczałam
że z pewnością nie będzie tak łatwo i gdzieś będzie się z jednego wiersza zawierającego liczby całkowite
tkwił haczyk. „Licytacja”, bo na ten właśnie problem a, b, n, m, oddzielone pojedynczą spacją
algorytmiczny trafiłam, miała następującą treść:
„Dwóch matematyków Pi i Sigma spotkało się wie- (0 ≤ a, b < 2 31
, 0 ≤ n < 231 , 2 ≤ m < 231 )
czorem na partyjce pokera. Ponieważ nie mieli pienię-
dzy, postanowili grać „na zapałki”. Pi miał przy sobie Liczby a, b określają kolejno liczbę niebieskich zapa-
tylko niebieskie zapałki, a Sigma tylko zielone. Przed łek Pi oraz zielonych Sigmy znajdujących się w pu-
przystąpieniem do licytacji Pi wyłożył a swoich niebie- li przed rozpoczęciem licytacji. Liczba n określa licz-
skich zapałek, zaś Sigma dołożył b swoich zielonych. bę kroków licytacji. Liczba m to ustalona przez gra-
Pi zaczyna licytację. Licytują na zmianę. W każdym czy „magiczna” liczba.
kroku licytacji zawodnik dorzuca tyle swoich zapałek,
ile aktualnie jest zapałek przeciwnika w puli. Licytacja WYJŚCIE
trwała dość długo i gracze nie mogli się doliczyć aktual- Dla każdego zestawu danych, wynikiem jest linia za-
nej liczby zapałek w puli. Wiedzieli jednak, ile razy każ- wierająca jedną liczbę - resztę z dzielenia przez m licz-
dy z nich dorzucał zapałki podczas licytacji.” by zapałek po n krokach licytacji, przy założeniu, że
przed przystąpieniem do licytacji w puli znajduje się a
ZADANIE niebieskich zapałek Pi oraz b zielonych zapałek Sigmy.
Pomóż matematykom określić, ile zapałek jest w pu-
li po n krokach licytacji. Ponieważ to matematycy, PRZYKŁAD
zadowoli ich znajomość reszty z dzielenia tej liczby Dla danych wejściowych:
(liczby zapałek po n krokach) przez ustaloną przez
nich „magiczną” liczbę m. 3
1 1 4 1000
WEJŚCIE 5 6 7 1000
Pierwsza linia wejścia zawiera liczbę zestawów da- 4 101 23 999
nych W kolejnych wierszach wejścia znajdują się
C (1 ≤ C ≤ 1000)

zestawy danych. Każdy z C zestawów danych składa poprawną odpowiedzią jest:

13
Autorka jest pracownikiem Działu Business Intelligence
w firmie SAFO, odpowiedzialnym za projektowanie oraz 309

wdrażanie systemów informatycznych opartych na hur- 767


towni danych i narzędziach OLAP.
Kontakt z autorką: monika.franczak@safo.biz Pierwsza metoda była tak oczywista, że bez większe-
go namysłu napisałam program rozwiązujący problem.

74 www.sdjournal.org Software Developer’s Journal 01/2007


Licytacja

Listing 2. Wyznaczenie n-tej liczby Fibonacciego, Listing 3. Binarne mnożenie macierzy kwadratowej stopnia 2
złożoność liniowa
type _mac=array[1..2,1..2] of int64;
function Fib(n:longint):int64; var MAC_A: _mac=((1,1),(1,0));
var F,F1,F2:int64; i:longint; T: array[1..32] of _mac; M: int64;
begin function mnoz(m1,m2:_mac):_mac;
if n=0 then Fib:=0 var wyn:_mac;
else begin
begin wyn[1,1]:=(m1[1,1]*m2[1,1]+m1[1,2]*m2[2,1]) mod M;
F1:=0; F:=1; wyn[1,2]:=(m1[1,1]*m2[1,2]+m1[1,2]*m2[2,2]) mod M;
for i:=2 to n do wyn[2,1]:=(m1[2,1]*m2[1,1]+m1[2,2]*m2[2,1]) mod M;
begin wyn[2,2]:=(m1[2,1]*m2[1,2]+m1[2,2]*m2[2,2]) mod M;
F2:=F1; F1:=F; F:=F2+F1; mnoz:=wyn;
end; end;
Fib:=F; procedure init;
end; var i:longint;
end; begin
T[1]:=MAC_A;
for i:=2 to 32 do
Wystarczyło napisać zwykłą pętlę i pamiętać, że operacja mo- begin
dulo (znajdowania reszty z dzielenia) jest rozdzielna względem T[i]:=mnoz(T[i-1],T[i-1]);
dodawania i mnożenia – to po to, aby już na początku procesu end;
wartości zmiennych nie wykroczyły poza zakres. Trochę mnie to end;
zaniepokoiło, ponieważ do tej pory problemy na OPSS wyma-
gały zdecydowanie większej wiedzy z dziedziny algorytmizacji,
ale postanowiłam spróbować. Moje pierwsze podejście do „Li- oraz analogicznie:
cytacji” wyglądało następująco (Listing 1). Dla obliczenia liczby lb ( n ) = lb ( n − 1) + lb ( n − 2)
zapałek po n krokach licytacji, refren pętli musiał wykonać się
l b ( 0) = 1
n razy, inaczej mówiąc: mój program miał złożoność liniową, co
dla dużych n powodowało, że zaczynał działać długo i nie zwra- lb (1) = 1
cał wyników w ustalonym limicie czasowym. Trzeba więc jednak To spostrzeżenie spowodowało, że na „Licytację” od tej
podejść do tego problemu z innej strony, pomyślałam. Przeczy- chwili mogłam patrzeć zupełnie inaczej. Problem przybrał
tałam raz jeszcze treść zadania. Zaczęłam zapisywać i liczyć postać wyznaczenia wyrazu ciągu S(n) określonego wzo-
„na piechotę” ile zapałek jest w grze w kolejnych krokach licyta- rem: S ( n ) = a ⋅ F ( n + 1) + b ⋅ F ( n + 2) gdzie F(n) oznacza n-ty wy-
cji.Na podstawie powyższej tabeli oraz warunków zadania do- raz ciągu Fibonacciego zdefiniowanego następująco:
tyczących przebiegu licytacji, zauważyłam, że mają miejsce na- F ( 0) = 0
stępujące równości:
F (1) = 1

l dla n nieparzystych: F ( n ) = F ( n − 1) + F ( n − 2) , n > 1


S ( n ) = Pi ( n ) + Sig ( n ) = Pi ( n ) + Sig ( n − 1) = S ( n − 1) + S ( n − 2) , n > 1 Widać zatem, że zadanie można sprowadzić do problemu ob-
l dla n parzystych: liczenia zadanych wyrazów ciągu Fibonacciego. Jeden z pod-
S ( n ) = Pi ( n ) + Sig ( n ) = Pi ( n − 1) + Sig ( n ) = S ( n − 2) + S ( n − 1) , n > 1 stawowych i najprostszych algorytmów obliczania wyrazów cią-
gu Fibonacciego ma również złożoność liniową, a zatem niewiele
To już było coś, pomyślałam, ponieważ dzięki tym własno- wnosi pod kątem wydajności do wcześniejszych prób rozwiąza-
ściom ogólny wzór na S(n) przyjął postać: Po chwili namy- S ( n ) = S ( n − 1) + S ( n − 2) , n > 1
S ( 0) = a + b
S (1) = a + 2b
nia problemu (Listing 2). Jednak spojrzenie na „Licytację” jak na
słu stwierdziłam dalej, że każdy wyraz ciągu S(n) jest kom- problem ciągu Fibonacciego pozwoliło mi podejrzewać, że jed-
binacją liniową liczb a i b, czyli można go zapisać w postaci: nak znajomość szybkich i być może nawet skomplikowanych al-
S ( n ) = a ⋅ la ( n ) + b ⋅ lb ( n ) . Ponieważ kolejne wyrazy tego ciągu po- gorytmów znajdzie tutaj zastosowanie. Poszukiwania optymal-
wstają przez zsumowanie dwóch poprzednich wyrazów, to: nego rozwiązania skierowałam w stronę sposobów wyznacza-
nia liczb Fibonacciego. Odświeżyłam swoja wiedzę matematycz-
la ( n ) = la ( n − 1) + la ( n − 2)
ną z dziedziny algebry i teorii liczb. To, co sobie przypomniałam,
la ( 0) = 1 zapisałam w następującej postaci: Przeczuwałam, że to będzie
1 1  F2
 =
1 0  F1
1 1
n
 Fn +1
F1 
F0 
Fn 

la (1) = 1
  =F Fn −1 
,n ≥1
1 0  n

klucz do sukcesu, ale będzie trzeba jeszcze nad nim popraco-

Tabela 1. Kroki w licytacji


Krok (n) 0 1 2 3 4
Zapałek Pi (Pi(n)) a a+b a+b 2a+3b 2a+3b
Zapałek Sigmy (Sig(n)) b b a+2b a+2b 3a+5b
Razem zapałek (S(n)) a+b a+2b 2a+3b 3a+5b 5a+8b

Software Developer’s Journal 01/2007 www.sdjournal.org 75


Algorytmy
zadanie

wać. Standardowy algorytm potęgowania macierzy ma bowiem


złożoność liniową, więc znowu nie jest to żadna korzyść w po- Listing 5. Program główny dla rozwiązania
równaniu do poprzednich metod rozwiązania „Licytacji”. Szuka- var lz,ilz:longint; a,b,n:int64;
łam jednak dalej, tym razem sięgając pamięcią do wykładów begin
z metod numerycznych poświęconych obliczeniom macierzo- readln(lz); / wczytanie liczby zestawow
wym. Jakie były efektywne sposoby potęgowania macierzy? Na- for ilz:=1 to lz do
gle mnie olśniło. Przecież to oczywiste, że w tym przypadku na- begin
leży wykorzystać algorytm binarny, który ma złożoność logaryt- readln(a,b,n,M); init; a:=a mod M; b:=b mod M;
miczną. Algorytm binarny potęgowania macierzy jako swoje a:=(a*Fib(n+1)) mod M; b:=(b*Fib(n+2)) mod M;
główne założenia przyjmuje fakt, że każdą liczbę naturalną K, writeln((a+b) mod M); // liczba zapalek po n krokach
K ≥ 1 można przedstawić jako sumę potęg liczby 2 (co do tego end;
nie ma chyba większych wątpliwości, wszak każda liczba na- end.
turalna może być zapisana w systemie binarnym), czyli istnie-
je ciąg z(i) o wyrazach 0 lub 1, taki że:
j Ale ale… chyba zbyt daleko odbiegłam od pierwotnego tema-
K = ∑ z ( i ) ⋅ 2i tu, powrócę zatem do problemu „Licytacji”. Przedstawiony po-
i=0
wyżej algorytm binarny mnożenia macierzy wykorzystam do
Pojawić się może pytanie, w jaki sposób znaleźć te potęgi licz- obliczenia liczby Fibonacciego. Aby dokonać dodatkowej opty-
by 2, które „generują” zadaną liczbę K. Tutaj odpowiedź wy- malizacji, wykorzystam fakt, że potęgować będę nie dowolną
daje się być, powiem nawet więcej: jest, prosta. Wystarczy macierz, lecz konkretną znaną mi macierz kwadratową.
znaleźć zapis binarny liczby K (nie będę tutaj zanudzać niko-
1 1
go opowieściami jak to należy zrobić, bowiem akurat ten pro- A= 
blem nie należy do zadań mocno skomplikowanych – jest ra- 1 0
czej trywialny….). Miejsca (pozycje), na których w zapisie W tym celu, na początku procesu obliczeniowego obliczę
występuje cyfra 1 wskazują szukane potęgi. Dla przykładu: i zapiszę w tablicy T kolejne binarne (1, 2, 4, 8, 16, …) potęgi
209(dec) = 11010001(b) , stąd 209 = 27 + 26 + 24 + 20 . Drugim zało- A tak, aby móc je potem wykorzystać w trakcie obliczeń. Pa-
żeniem tego algorytmu są prawa działań na potęgach, czy- miętać tutaj należy, że warunkiem zadania jest podanie wyni-
li wzory znane chyba wszystkim ze szkoły podstawowej lub ku jako reszty z dzielenia przez magiczną liczbę M. Aby mieć
średniej: a R +S = a R ⋅ a S . Łącząc te dwa fakty i stosując je dla ob- pewność, że wszystkie pośrednie wyniki obliczeń nie wyjdą
liczeń macierzowych otrzymujemy: poza zakres typu danych całkowitych int64, operację modulo
j
będę wykonywać na każdym tymczasowym wyniku występu-
A K ∏ A z(i)⋅2 jącym podczas działania algorytmu (Listing 3).
i

i=0
Jak widać z powyższego kodu, wygenerowanie tablicy po-
gdzie A jest w dowolną macierzą kwadratową. mocniczej T jest nieskomplikowaną czynnością, stanowiącą
Dla zobrazowania powyższych zasad podam przykład: niewielki koszt, wykonaną jednorazowo dla pojedynczego ze-
7 6 4 0
A 209 = A128+ 64+16+1 = A 2 ⋅ A 2 ⋅ A 2 ⋅ A 2 . Siła binarnego algorytmu stawu danych. Dla uproszczenia zapisów i elegancji rozwiąza-
mnożenia macierzy nie polega jednak na wykorzystaniu zwy- nia zastosowałam funkcję pomocniczą mnóż, realizującą mno-
kłych praw matematyki (przecież większość algorytmów mniej żenie dwóch macierzy. W tym przypadku nie było konieczne
lub bardziej korzysta z zasad matematycznych) lecz na tym, wykorzystanie ogólnego algorytmu mnożenia macierzy, ponie-
że dla obliczenia 2i-tej potęgi korzysta się z uprzednio obli- waż, z założenia, macierz jest kwadratowa stopnia 2.
czonej wartości potęgi 2i-1, czyli wykorzystana jest prosta za- W tym momencie poczułam, że naprawdę jestem blisko roz-
leżność rekurencyjna: wiązania problemu. Mając przygotowane właściwie wszystkie
fragmenty rozwiązania, pozostało tylko zebrać je w całość aby
A1 = A
2i i −1 i −1 otrzymać końcowy efekt. Niemalże bez kłopotów przygotowałam
A = A2 ⋅ A2 , i > 0
funkcję Fib obliczającą n-ty wyraz ciągu Fibonacciego (Listing 4).
Szybkie sprawdzenie czy dobrze działa i dalej do roboty. Pozo-
Listing 4. Wyznaczanie n-tej liczby Fibonacciego, stał tylko finał, czyli napisanie głównego programu, który będzie
złożoność logarytmiczna wczytywał dane wejściowe i dla każdego zestawu danych prze-
prowadzał niezbędne obliczenia. Cały czas pamiętać trzeba tyl-
function Fib(n:longint):int64; ko o tym, że wynik końcowy ma być modulo M (Listing 5).
var W: _mac; b: longint; J: _mac=((1,0),(0,1)); Uff, udało mi się napisać niezły kawałek kodu… I po-
begin myśleć tylko że po przeczytaniu treści zadania wydawa-
W:=J; b:=1; ło mi się, że wystarczy napisać zwykłą pętlę. A tu, proszę,
while (n<>0) do przydała się i algebra, i teoria liczb, i metody numeryczne.
begin Chyba mi się spodobało. Ale co to? Za oknem już nie pada,
if (n mod 2=1) then W:=mnoz(W,T[b]); inc(b); n:=n div 2; czyżby rozpoczęła się złota polska jesień? W takim razie
end; skorzystam z okazji i wyjdę z domu trochę się przewietrzyć.
Fib:=W[1,2]; Ale już wiem, czym się zajmę gdy następnym razem będzie
end; słota i deszcz. Zapisałam sobie adres tej strony w Zakład-
kach, ot tak, na wszelki wypadek. n

76 www.sdjournal.org Software Developer’s Journal 01/2007


KLUB TECHNICZNY PROGRESS SOFTWARE

Progress Sonic ESB


Tworzenie usługi w środowisku Progress Sonic Workbench

W poprzednim klubie technicznym, przedstawili- wartość, dodając nowe informacje). Może tak-
śmy przegląd narzędzi, z których składa się śro- że zmienić kontekst wiadomości; ���
��������
dowisko Sonic Workbench. Zaprezentowaliśmy, jak • Usługa umieszcza wiadomość na wyjściu,
stworzyć swój własny projekt ESB oraz w jaki spo- ewentualnie przesyła ją do specjalnego wyj- ���
���������
sób skorzystać z dostarczanych przez producenta ścia sygnalizującego błąd w przetwarzaniu;
przykładów. Posiadajmy więc wiedzę potrzebną, • Dispatcher sprawdza zawartość wiadomości na
aby przejść do kolejnego bardzo ważnego zadania wyjściu i przesyła ją do następnego punktu;
związanego z budowaniem infrastruktury ESB. • Punkt końcowy konwertuje wiadomość XQMes-
W niniejszym numerze skoncentrujemy się na sage do odpowiedniego formatu natywnego;
tworzeniu usług ESB. • I przesyła wiadomość do kolejnego punktu podłą-
czonego do korporacyjnej magistrali usług. ��������������
USŁUGI ESB �������������
������
Usługa w ESB to modularny, wielokrotnie wykorzy- A zatem w kontekście Sonic ESB usługi są zarzą-
stywany element funkcjonalności. Realizowane dzanymi elementami – klientami magistrali ko- Rysunek 1. Schemat relacji pomiędzy usługą ESB, konte-
nerem i magistralą komunikatów
przez usługę zadania, takie jak np. wbudowane ope- munikatów, które mogą być wykorzystywane po-
racje transformacji, mogą być związane z zapew- jedynczo lub łączone w procesy ESB (o których platformę i specyficzne operacje realizowane przez
nianiem pracy infrastruktury ESB lub bezpośrednio więcej w kolejnym odcinku). Właściwie cała logika daną usługę. Po przetworzeniu nowa lub tylko zmo-
z wykonaniem logiki aplikacji np. obliczeniem war- aplikacji mieści się wewnątrz usług, a wiadomości dyfikowana wiadomość jest wysyłana do kolejnego
tości podatku. Usługi ESB są uruchamiane w konte- i kontekst ich przetwarzania jest przekazywany do punktu w magistrali. Jednakże usługi ESB nie są klien-
nerach, które zapewniają zarządzenie cyklem życia usługi. Na poziomie usługi można zrealizować ob- tami JMS w pełnym tego słowa znaczeniu. Ich cykl ży-
danej funkcjonalności (np. uruchamianiem i wyłą- sługę błędów, a samymi usługami można zarzą- cia jest sterowany zewnętrznie przy pomocy kon-
czaniem usługi) oraz odpowiadają za połączenie dzać (konfigurować je i monitorować) z poziomu tenerów, bezpośrednio nie biorą one udziału w two-
usługi z magistralą komunikatów, co zaprezentowa- menadżera domeny. Ich interfejsy są zdefiniowane rzeniu połączeń JMS, sesji, ani instancji MessageLi-
no na Rysunku 1. przy pomocy technologii XML i WSDL. W Sonic ESB stener. Konfigurację oraz tego typu operacje zapew-
Aby lepiej zrozumieć, w jaki sposób zachodzi inte- każda działająca usługa jest instancją pewnego nia kontener. Wiadomości w korporacyjnej magistra-
rakcja z wykorzystaniem usługi, prześledźmy poniż- typu usługi. W celu stworzenia usługi należały za- li usług posiadają identyfikator i kontekst, który jest
szy scenariusz. Dane wejściowe danej usługi zostają implementować interfejs XQService, używając pro- przesyłany wraz z wiadomością. W JMS nie ma takich
do niej dostarczone w postaci wiadomości, tzw. XQMes- stego API, a następnie dodając odpowiednie klasy i atrybutów jak nagłówek, QoS czy kontekst zawarto-
sage i w takiej też formie prezentowane są wyniki dzia- parametry konfiguracyjne stworzyć klasy oczeku- ści, który jest automatycznie przekazywany. Imple-
łania usługi. Każda z wiadomości jest przetwarzana jące na poszczególnych punktach końcowych. mentacja obsługi przychodzącej wiadomości (za po-
sekwencyjnie wewnątrz logiki usługi realizowanej we- Gdy tak stworzony fragment kodu otrzyma wia- mocą MessageListener) jest dużo bogatsza niż w
wnątrz metody service(). Rysunek 2 jest ilustracją domość, zostanie ona odpowiednio zwalidowana, a przypadku JMS. Przykładowy kod prostej metody se-
procesu przetwarzania wiadomości wewnątrz każdej później przesłana do wspomnianej metody servi- rvice() zaprezentowano na Listingu 1. Wszystkie
z usług (i odpowiadających im kontenerów). Zgodnie z ce(). Po wykonaniu operacji wiadomość jest wysy- usługi ESB muszą implementować także metody in-
przedstawionym rysunkiem kolejne etapy procesu łana za pomocą JMS. Wiadomości JMS dostarczane z it() i destroy() interfejsu XQService. Jak już wspo-
przetwarzania wiadomości są następujące: kolejki komunikatów (SonicMQ) są odpowiednio prze- mniano, każda usługa działająca w ESB to instancja
twarzane przez instancję MessageListener, która za- pewnego typu, a jej konfiguracja jest przechowywana
• Wiadomość w normatywnym formacie dociera pewnia wewnętrzne przetwarzanie wymagane przez w postaci pliku XML w Directory Service.
do kontenera ESB;
• Nasłuchujący punkt końcowy konwertuje ją do Listing 1. Kod prostej metody service()
formatu wewnętrznego Sonic ESB XQMessage;
• Wiadomość jest dostarczana do dispatchera; public void service (XQServiceContext ctx)
• Wiadomość zostaje umieszczona na wejściu od- throws XQServiceException {
powiedniej usługi, a do jej treści dodawany jest // Otrzymanie informacji o wiadomości i pobranie wiadomości z wejścia
nowy domyślny adresat – wyjście z usługi; XQEnvelope letter = ctx.getFirstIncoming();
• Usługa otrzymuje wiadomość, wykonuje ope- XQMessage inMsg = letter.getMessage();
racje na wiadomości (np. przekształca jej za- // Proste przetwarzanie i nadpisanie treści informacji o wiadomości
XQMessage outMsg = myAction.performMyCode(in);
letter.setMessage(outMsg);
Progress Software Corporation jest dostawcą
// Wysłanie wiadomości do standardowego (domyślnego) wyjścia
infrastruktury do rozwoju, wdrażania, integra-
cji i zarządzania aplikacjami biznesowymi. ctx.addOutgoing(letter);
Więcej informacji – http://www.progress.com }

78 www.sdjournal.org Software Developer’s Journal 01/2007


KLUB TECHNICZNY PROGRESS SOFTWARE

������� ������������������ �������


������ ������������� ������������� ������
���������� ����������

���

�� ��� ������ ��

���

� � � � � � � � �

Rysunek 2. Diagram przetwarzania wiadomości przez usługę wewnątrz kontenera

TWORZENIE WŁASNEGO TYPU USŁUG sza usługa. Instalacja jest bardzo prosta, wystarczy tego celu służy narzędzie Sonic Management Conso-
W celu stworzenia nowego typu usługi i powiązanego z menu kontekstowego pliku .esbstyp wybrać opcję le, które opiszemy w jednym z kolejnych odcinków.
z nią szablonu konfiguracji należy wykonać kilka kro- Upload Service Type. W oknie należy zwrócić uwa- Można także zastosować tzw. scenariusze, które słu-
ków. W środowisku Sonic Workbench należy stworzyć gę na nazwę usługi, wartości wszystkich parametrów żą do testowania konfiguracji magistrali przy pomo-
nowy projekt, co można wykonać, wybierając opcję Fi- inicjalizacyjnych dla instancji usługi oraz w szczegól- cy zestawu wiadomości. Wreszcie można rozpocząć
le->New->Other, opcję Source Folder w węźle Java i po- ności na punkty końcowe usługi zaprezentowane w pracę z narzędziami, takimi jak debuger i okno śle-
dając nazwę nowego folderu. Następnie wybieramy Fi- polu Advanced. Można samodzielnie modyfikować dzenia, które omówimy dokładniej już w następnym
le->New->Java Service Type, a w oknie dialogowym na- wspomniane wartości w celu dostosowania usługi do klubie technicznym.
leży wskazać właśnie stworzony folder i podać unikalną własnych potrzeb, a następnie, wybierając przycisk
nazwę usługi. Na kolejnym ekranie można zdefiniować OK, zatwierdzić operację. W wyniku uruchomienia usłu- PODSUMOWANIE
parametry pracy usługi, na razie pozostawiamy je bez gi środowisko poinformuje nas, że trzeba zrestartować W tym odcinku przybliżyliśmy pojęcia związane z
zmian, przechodząc do kolejnego ekranu pozwalające- kontener - co też należy uczynić. Po instalacji możemy usługami ESB oraz zaprezentowaliśmy, jak stworzyć
go określić nazwę klasy, która będzie zawierała imple- modyfikować podane wcześniej wartości za pomo- nową klasę usług przy użyciu Sonic Workbench. W
mentację usługi. Klikając Finish, spowodujemy utworze- cą menu kontekstowego pliku .esbstyp definiującego kolejnym odcinku zaprezentujemy, jak stworzyć wła-
nie szkieletu usługi. Efekt powinien przypominać zrzut usługę i opcji Configure Service Instance. sny proces ESB, który będzie składał się operacji wy-
ekranu z Rysunku 3. Teraz możemy przystąpić do mo- konywanych przez instancje przedstawionych w ni-
dyfikacji działania usługi. W tym celu zrealizujemy ope- DALSZE KROKI niejszym klubie usług ESB. Przyjrzymy się bliżej defi-
rację wypisania komunikatu „Hello world” wewnątrz Aby wykorzystać wynik przeprowadzenia powyż- niowaniu i śledzeniu wykonania takiego procesu oraz
usługi. W metodzie service() dodajmy linię kodu: szych operacji, można stworzyć instancje odpowia- możliwościom, jakie oferuje w tym zakresie produkt
dające właśnie zainstalowanemu typowi usługi. Do Progress Sonic ESB.
msg.SetStringHeader
("MyService","Hello world")

zaraz po pobraniu treści wiadomości i wejściu w sekcję


try. Usługę możemy już dowolnie rozszerzać. Niestety
scenariusze, takie jak opakowanie istniejącej klasy w
celu wykorzystania jej logiki w usłudze, bezpośrednie
komunikowanie się pomiędzy usługą a JMS, odczyty-
wanie parametrów konfiguracyjnych i inne, wykracza-
ją poza zakres tego krótkiego przeglądu.

INSTALOWANIE
USŁUGI W REPOZYTORIUM
Po modyfikacji kodu, usługę instalujemy w kontekście
Sonic Domain. W tym celu można wykorzystać testo-
wy kontener dev.ESBTest i sprawdzić, jak działa na-

30-dniową wersję testową produktu Sonic


Workbench można pobrać ze strony firmy So-
nic Progress Software
http://www.sonicsoftware.com/products/
sonic_esb_family/index.ssp
Rysunek 3. Sonic Workbench po stworzeniu usługi

Software Developer’s Journal 01/2007 www.sdjournal.org 79


KLUB TECHNICZNY MAGIC

Klub Magic’a
Magic eDeveloper - zdarzeniowe podejście do programowania

Seria ostatnich artykułów stanowiła wstęp do progra- sora do kolejnego rekordu, dzięki czemu do bufora zo- sora do kolejnego dostępnego na formularzu po-
mowania w środowisku Magic eDeveloper. Materiał w stanie załadowany kolejny rekord i wykona się dla la. Definicja tych domyślnych zdarzeń klawiaturo-
nich zaprezentowany pozwala na tworzenie aplikacji w niego faza Record Prefix oraz Record Main. wych jest zapisana w specjalnej tabeli w menu Set-
tym narzędziu. Opisane dotychczas zostały zasady pra- Jednak w przypadku edycji danych za pomo- tings opcji Keyboard Mapping. Dzięki temu progra-
cy środowiska, jego komponenty, własności oraz pod- cą formularza nie wyposażonego w formant tabe- mista ma możliwość dowolnego przedefiniowania
stawowe metody wizualizacji danych. W tym odcinku li, wciśnięcie tego przycisku spowoduje wywołanie zachowania systemu bazując na skrótach klawia-
zostanie zaprezentowana metoda tworzenia aplikacji, w akcji Next Field, a w rezultacie przeniesienie kur- turowych.
której wykorzystuje się mechanizm zdarzeń.
Jak zwykle wszystkie elementy środowiska,
umożliwiające uruchomienie systemu są do po-
brania ze strony internetowej: http://komtech.pl/
software/

DEFINICJA ZDARZENIA
W ŚRODOWISKU MAGIC EDEVELOPER
Zdarzeniem nazywamy każdą aktywność środowi-
ska, która zostanie wykonana w rezultacie zaistnienia
przypisanego dla niej tzw. wyzwalacza. W praktyce,
większość czynności wykonywanych zarówno przez
programistę jak i końcowego użytkownika jest pewne-
go rodzaju zdarzeniami zaimplementowanymi w śro-
dowisku lub zaprogramowanymi w aplikacji.
Środowisko Magic eDeveloper posiada domyśl-
nie zdefiniowane podstawowe zdarzenia, czyli po-
wiązanie tzw. akcji, których zaistnienie powodu-
je wywołanie określonych zachowań środowiska.
W dalszej części tego artykułu będzie dla nich sto-
sowana nazwa – zdarzenia wewnętrzne (Internal
Event), gdyż ich definicja i zachowanie jest opisa-
ne wewnątrz środowiska Magic. Są to wszystkie Rysunek 1. Formatka programu użytego do dalszych prac
możliwe predefiniowane zachowania systemu, jak
choćby przeskok z pola, kliknięcie, zmiana rekordu,
zamknięcie zadania i wiele innych.
By zachować jednorodność środowiska, część
predefiniowanych zdarzeń wewnętrznych jest do-
myślnie powiązana ze skrótami klawiaturowymi,
tworząc tzw. zdarzenia klawiaturowe, które są w
środowisku Magic eDeveloper nazywane systemo-
wymi (System Event). Przykładem tej definicji jest
wciśnięcie klawisza ESC, które spowoduje wywoła-
nie zdarzenia wewnętrznego Close, które to spowo-
duje zamknięcie aktywnego zadania.
Inny przykład to wciśnięcie klawisza Down. Zda-
rzeń opartych na tym wyzwalaczu jest wiele. W edy-
cji danych w układzie tabeli, wciśnięcie tego przyci-
sku spowoduje wywołanie zdarzenia wewnętrznego
Next Row, a to domyślnie wymusi przeniesienie kur-

Dystrybutor: Komtech Sp. z o.o.


Rynek 10, 26-600 Radom
tel. (048)3688300
http://www.komtech.pl/software/
Rysunek 2. Definicja zmiennej – przycisk

80 www.sdjournal.org Software Developer’s Journal 01/2007


KLUB TECHNICZNY MAGIC

Programista otrzymuje jeszcze jeden potężny czy (również zdarzeń wewnętrznych, systemowych, mi w aplikacji. Dzięki temu istnieje możliwość zmiany
mechanizm – programowanie zdarzeń – dzięki któ- czy nowych opisanych przez programistę) oraz two- domyślnego zachowania systemu choćby w przypad-
remu może dowolnie zmieniać zachowanie systemu rzyć nowe zdarzenia – poprzez przypisanie własnych ku zaistnienia akcji „Close”, czy zdefiniowania zupeł-
w następstwie zaistnienia zdefiniowanych wyzwala- wyzwalaczy i wiązanie ich z określonymi zachowania- nie nowych definicji, które zostaną użyte w algoryt-
mie aplikacji.

PRZYCISK
– PROSTY PRZYKŁAD WYKORZYSTANIA
ZDARZENIA WEWNĘTRZNEGO
Jak już zostało wspomniane, każda aktywność po-
woduje wywołanie jakiegoś zdarzenia. Najpraw-
dopodobniej najczęściej stosowanym wyzwala-
czem jest skrót klawiaturowy ESC, który wywołu-
je akcję wewnętrzną Close. Bardzo często w aplika-
cjach stosuje się element graficzny – przycisk, któ-
ry również służy do wywołania określonego działa-
nia, np. zamknięcia zadania. By zaznajomić się z
mechanizmem przypisania przyciskowi określonej
akcji, zostanie w wybranym programie użyta kon-
trolka Push Buton i przypisana mu akcja wewnętrz-
na Close. Wciśnięcie tego przycisku spowoduje wy-
wołanie akcji i zamknięcie aktywnego zadania, tak
samo jak wciśnięcie klawisza ESC.
Bazą dla dalszych prac będzie program wy-
świetlający dane Klient – Zamówienia, utworzony
w poprzednim odcinku. Trzeba zmodyfikować wy-
gląd tego programu, by umożliwić umieszczenie
Rysunek 3. Definicja własności przycisku
na formatce jeszcze kilku przycisków. W tym ce-
lu formatkę podzadania wyświetlającą zamówie-
nia dla wybranego klienta należy zmniejszyć, by
po prawej stronie okna głównego znalazło się wię-
cej miejsca na ewentualne przyciski (Rysunek. 1.).
Element ekranowy Przycisk (Push Button) może
funkcjonować jako samodzielny obiekt zdefiniowany
jedynie na formatce, ale zalecane jest by obiekt ten był
powiązany ze zmienną opisaną w zadaniu w jego fazie
Record Main. Taka konstrukcja ułatwia określenie spo-
sobu poruszania się po formatce.
W tym celu należy przejść do edycji zada-
nia nadrzędnego programu Klient – Zamówienia i
utworzyć w jego fazie Record Main, na końcu defi-
nicję zmiennej wirtualnej (Select Virtual).
Polecenie to powołuje do istnienia zmienną,
która nie ma bezpośredniego powiązania z bazą
danych, może służyć do przechowania wyników
tymczasowych określonych przeliczeń lub, jak w
tym przypadku, pozwolić na zdefiniowanie aktyw-
nego elementu formularza jakim jest przycisk.
Po wstawieniu operacji Select Virtual dostęp-
na jest opcja umożliwiająca określenie jakiego typu
zmienna będzie dostępna (natychmiast po utwo-
rzeniu zamiast nazwy pojawiają się dwa znaki za-
pytania). Dwukrotne kliknięcie powoduje otwarcie
okna umożliwiającego opisanie tej zmiennej. Na-
leży najpierw podać nazwę zmiennej, w tym przy-
padku zostanie użyta nazwa: BT_Zamknij, która
dość jednoznacznie określa co to będzie za zmien-
na. Kolejny krok to wybór modelu, jeśli taki byłby
Rysunek 4. Określenie etykiety dla przycisku zdefiniowany (np. globalny model do określania

Software Developer’s Journal 01/2007 www.sdjournal.org 81


KLUB TECHNICZNY MAGIC

przycisków). Ponieważ w tym przypadku nie ist-


nieje taki model, niezbędne jest opisanie tej zmien-
nej indywidualnie. Do obsługi przycisków wybie-
ra się atrybut znakowy (Alpha), zaś opcja Pictu-
re określa maksymalną długość łańcucha znaków,
który może zostać użyty jako etykieta przycisku.
W tym przykładzie użyto 12 znaków. Do tego mo-
mentu zmienna może pełnić funkcję umożliwiają-
cą wyświetlenie czy przechowanie łańcucha zna-
ków. Dopiero zmiana sposobu wyświetlania z do-
myślnego trybu Edit na Push button (we własno-
ściach w opcji Style / GUI Display) ustala sposób
działanie tej zmiennej (Rysunek. 2.)
Każdy przycisk powinien mieć przypisaną ak-
cję, czyli określenie co się stanie, jeśli zostanie wci-
śnięty. W tym celu należy podświetlić wybór try-
bu wyświetlania, a to spowoduje pojawienie się do-
datkowego przycisku z trzeba kropkami, umożli-
wiającego ustalenie dodatkowych parametrów tej
zmiennej (krok 1). Po wciśnięciu pojawi się okno
własności, w którym należy określić parametr Ra-
ise Event czyli rodzaj zdarzenia, które nastąpi po
jego wciśnięciu (Rysunek. 3.)
Wywołanie tej opcji (krok 2) spowoduje wy- Rysunek 5. Wstawienie zmiennej – przycisku na formatkę.
świetlenie okna umożliwiającego wybór typu zda-
rzenia powiązanego z przyciskiem. Na liście znaj-
duje się znajduje się kilka typów (Event type), z
których należy wybrać Internal (Krok 3), gdyż wci-
śnięcie tego przycisku ma wywołać zdarzenie we-
wnętrzne środowiska Magic. Przejście do kolejnej
opcji (Event) powoduje wywołanie słownika – li-
sty dostępnych zdarzeń (Krok 4), z których nale-
ży wybrać Close – zamknięcie zadania. Po wybra-
niu należy zatwierdzić klawiszem Enter wszystkie
ekrany, aż do ekranu z fazami zadania.
Od tego momentu w zadaniu będzie funkcjonować
zmienna wirtualna o nazwie BT_Zamknij, która jest przy-
ciskiem, którego wciśnięcie spowoduje wywołanie akcji
Close, czyli zamknięcie zadania. Być może wydaje się
być to skomplikowane, lecz w praktyce taka definicja
jest zazwyczaj określona w repozytorium modeli i po-
tem używana w ramach potrzeb w zadaniach.
Przy definicji zmiennej tego typu konieczne jest
określenie jeszcze jednego atrybutu – etykiety przy-
cisku umieszczonego na formatce. Stosuje się do te-
go zazwyczaj opcję Init przy definicji zmiennej. Wią-
że się ją z wyrażeniem zawierającym ciąg znaków,
będący wyświetlaną etykietą, np. „&Zamknij” (Ry-
sunek. 4.). Umieszczenie w ciągu znaków znaku „&”
oznacza wprowadzenie dodatkowego skrótu klawia-
turowego aktywującego przycisk (np. ALT+Z),
Ostatni etap to umieszczenie zmiennej na for-
matce w wyznaczonym miejscu. Przy prawidłowej
definicji wstawienie na formatce zmiennej, spowo-
duje umieszczenie przycisku z opisanymi wcze-
śniej własnościami (Rysunek. 5.)
Pozostaje zapisanie wszystkich zmian, spraw-
dzenie programu pod względem poprawności i uru-
chomienie programu. Rysunek 6. Umieszczenie i własności przycisku „Szczegóły”

82 www.sdjournal.org Software Developer’s Journal 01/2007


KLUB TECHNICZNY MAGIC

Po uruchomieniu, by zakończyć pracę, można Proste powiązanie akcji i przycisku jest w wielu By zaprezentować ten mechanizm warto przy-
wcisnąć klawisz ESC, kliknąć na przycisk „x” w pra- przypadkach niewystarczające do zbudowania algo- gotować kilka programów, które mogą się wzajem-
wym górnym rogu okna (zdarzenia predefiniowane), rytmu. Dlatego często stosuje mechanizm, w którym nie wywołać w wyniku zaistnienia zdefiniowanego
kliknąć przycisk „Zamknij”, albo wcisnąć skrót ALT+Z przycisk wywołuje akcję (najczęściej jest to akcja we- zdarzenia. Dotychczas zostały stworzone dwie ta-
(zdarzenia zdefiniowane przez programistę). wnętrzna ZOOM lub w przypadku starszych wersji śro- bele umożliwiające przechowywanie informacji o
Ten sposób definiowania zdarzeń stosuje się dowiska User Action), a w logice aplikacji opisany jest nagłówkach zamówień i powiązanych z nimi kon-
w aplikacjach bardzo szeroko, zazwyczaj do opi- algorytm reakcji systemu, który zostanie wykonany w trahentami. Kolejnym krokiem będzie zdefiniowa-
sania podstawowych zdarzeń jak Zamknij, Wybierz przypadku zaistnienia tej akcji. nie tabeli przechowującej informacje o produktach
(akcja Select), czyli wywołania zdarzeń wewnętrz- Dlaczego używana jest tu akcja Zoom albo User związanych z zamówieniami.
nych. Do opisania bardziej skomplikowanych al- Action? Spowodowały to względy historyczne, gdyż Zostanie wykorzystany program Klient – Zamó-
gorytmów stosuje się mechanizm redefiniowania zdarzenie Zoom od początku powstania środowiska wienia, w którym umieszczony zostanie jeszcze je-
zdarzeń wewnętrznych lub definiowanie tzw. zda- Magic było używane do wywołania logiki skojarzonej den przycisk, uruchomiający oddzielny program (za-
rzeń użytkownika. z kontrolką (Zoom – Rozwiń). W przypadku User Ac- danie), pozwalający na modyfikację listy produktów
tion, w starszych wersjach środowiska Magic było do- skojarzonych z wybranym zamówieniem. Niezbędne
REDEFINICJA stępnych 20 takich akcji, które nie miały wprost przy- jest więc zdefiniowanie tabeli Zamowienia_Linie
ZDARZENIA WEWNĘTRZNEGO pisanego wewnętrznego działania i służyły do wyko- o następującej strukturze:
Opisany powyżej mechanizm powiązania wybra- rzystania przez programistę (User Action 1, User Ac-
nej akcji z przyciskiem jest szeroko wykorzysty- tion 2, itd.). Metoda ta jest bardzo uniwersalna gdyż • ID_Zamówienia – identyfikator zamówienia do
wany podczas tworzenia aplikacji w środowisku daje programiście szerokie możliwości w budowie lo- zachowania relacji z tabelą Zamowienia_Nagl;
Magic. Sposób ten będzie również wykorzystywa- giki, zapewniając jednocześnie kompatybilność z roz- • Nr_linii – pole numeryczne, przechowujące
ny w kolejnych metodach wykorzystania zdarzeń wiązaniami tworzonymi w poprzednich wersjach śro- dane z zakresu 1 – 99;
w aplikacjach. dowiska Magic eDeveloper. • Nazwa_produktu – pole 30 znakowe;
• Cena_jednostkowa – pole numeryczne o for-
macie „3.2”;
• Ilosc_zamawiana – pole numeryczne o for-
macie „3”.

Należy też zdefiniować dla tej tabeli jeden indeks


unikalny składający się z dwóch segmentów: ID_
Zamówienia i Nr_Linii Mechanizm zakładania
tabel i powiązanych z nimi modeli został szczegóło-
wo opisany w odcinku 3 i 4 tego cyklu. By przyspie-
szyć dalsze prace można wygenerować program o
nazwie Zamówienia – Linie, który troszczy się o ob-
sługę tej tabeli, co zostało opisane w odcinku 6.
Mając przygotowaną tabelę i wygenerowany
program można przystąpić do realizacji zdarzenia
opartego na przedefiniowaniu wewnętrznej akcji.
Podobnie jak w przypadku opisanym w poprzed-
nim punkcie, również i tu wyzwalaczem będzie
wciśnięcie przycisku umieszczonego na formula-
rzu wyświetlającym zamówienia.
W tym celu należy ponownie przejść do edycji pro-
gramu Klient – Zamówienia, lecz tym razem modyfiko-
wane będzie zadanie Zamówienia. To w nim należy za-
łożyć zmienną wirtualną, będącą przyciskiem, który
tym razem jest powiązany z akcją Zoom. Metoda two-
rzenia jest dokładnie taka sama jak przy definicji przy-
Rysunek 7. Definicja zdarzenia na obsługującego akcję Zoom na kontrolce BT_Szczegóły
cisku z akcją Close – różni się tylko powiązaną akcją
oraz etykietą na przycisku (w tym przypadku: „Szcze-
góły”). Tak zdefiniowaną zmienną trzeba umieścić na
formularzu w obrębie formatki podzadania Zamówie-
nia (Rysunek. 6.) Od tego momentu kontrolka ta mo-
że zostać użyta do opisania zdarzenia.
Po powrocie do tablicy wykonawczej zadania
Zamówienia należy ustawić kursor na ostatniej
pozycji w oknie z fazami (na fazie Record Suffix) i
utworzyć nową linię, w której trzeba wybrać opera-
Rysunek 8. Deklaracja zmiennej typu parametr. cję Handler – służącą do definicji zdarzenia.

Software Developer’s Journal 01/2007 www.sdjournal.org 83


KLUB TECHNICZNY MAGIC

Definicja ta w uproszczeniu wygląda nastę- dzy wymienionymi programami konieczne jest prze- zdarzenia jak i powiązanie pomiędzy danymi. Oczywi-
pująco: jeśli w zadaniu system zarejestruje użycie kazanie jedynie identyfikatora zamówienia, dlatego ście nad samą formą wizualizacji należy jeszcze popra-
wyzwalacza opisanego w kolumnie Event, dodatko- wystarczająca jest jedna operacja Select Parameter. cować, lecz opisana funkcjonalność pracuje poprawnie.
wo pod warunkiem zaparkowania kursora w okre- Podobnie jak w przypadku deklaracji zmiennej wirtu- W tej części zostało wykorzystane zdarzenie ba-
ślonym polu, na określonej kontrolce (opcjonalny alnej i tu należy określić typ zmiennej – przekazywa- zujące na przycisku związanym z akcją wewnętrzną
parametr CTRL), należy wykonać operacje zapisa- nego parametru, przy czym można skorzystać z de- Zoom. Równie dobrze mogłoby tu być użyta akcja User
ne w oknie Operation: Handler On … finicji modeli. Warto nazwać zmienną: Id_Zamówie- Action 1, wymieniona wcześniej. Analogicznie można
W tym przypadku szczegółowa definicja sa- nia_PAR, co jednoznacznie ją określi (Rysunek. 8.). W by również zdefiniować zdarzenie bazujące na akcji
mego zdarzenia ma postać: Handler na akcję we- przypadku większej liczby, każdy parametr musi być Close (opisanej w poprzedniej części). Spowodowało-
wnętrzną Zoom, na kontrolce BT_Szczegóły (Ry- zadeklarowany oddzielną operacją Select Parametr. by to zablokowanie możliwości wyjścia z zadania, gdyż
sunek. 7.) ma spowodować uruchomienie poleceń Gdy w tej zmiennej znajdzie się wartość identyfika- zamiast wewnętrznego znaczenia akcji Close (czyli
opisanych w oknie Operation: Handler On Zoom. Te- tora przetwarzanego zamówienia, należy użyć ją do de- zamknięcia aktywnego zadania) nastąpiłoby urucho-
raz można zająć się opisaniem zachowania syste- finicji zakresu (Range) na polu ID_Zamowienia (by wy- mienie podprogramu. Byłby to rezultat błędnego rede-
mu po zaistnieniu tego zdarzenia, czyli ma nastą- świetlić z tej tabeli rekordy powiązane z wybranym za- finiowania wewnętrznego znaczenia akcji. Jednak roz-
pić uruchomienie programu Zamówienia – Linie. mówieniem), oraz w opcji Init, by zapewnić powiązanie wiązanie to często się spotyka, włączając nawet prze-
By to zrealizować wystarczy umieścić na liście ope- przy tworzeniu nowych rekordów (Rysunek. 9) co stwo- chwytywanie akcji Close, czy Exit, by zabezpieczyć się
racji polecenie Call Program i wybrać z listy wymieniony rzy relację pomiędzy tabelami. przez możliwością zamknięcia okna przerwania dzia-
powyżej program. Już na tym etapie mechanizm obsłu- Ostatni krok to przekazanie właściwej warto- łania w trakcie algorytmu. Lecz wykorzystuje się tu do-
gi zdarzenia zadziała poprawnie, choć ze względu na re- ści identyfikatora zamówienia w obsłudze zdarze- datkową własność zdarzenia – Enable, która określa w
lacje pomiędzy tabelami dane będą wprowadzanie i wy- nia. W zdarzeniu zdefiniowanym w zadaniu Klient jakim przypadku ma nastąpić obsługa opisanego zda-
świetlane błędnie. Po uruchomieniu nie ma przekazania – Zamówienia.Zamówienia (często stosuje się ta- rzenia. Pozwala to na indywidualne sterowanie działa-
do nowego okna informacji o edytowanym zamówieniu, ką notację, gdyż jednoznacznie określa ścieżkę w niem poszczególnych zdarzeń.
co w tym przypadku jest krytyczne. drzewie: Program „Klient – Zamówienia”, podzada-
Ponieważ mamy tu powiązanie dwóch oddziel- nie „Zamówienia”) występuje polecenie Call Prog. ZDARZENIE UŻYTKOWNIKA
nych drzew programów musi nastąpić jawne przeka- Polecenie to ma opcję Arg (Parametry), która służy – KOLEJNY KROK W ZDARZENIOWYM
zanie parametru pomiędzy nimi. W tym celu koniecz- do powiązania lokalnych zmiennych lub wyrażeń PODEJŚCIU DO PROGRAMOWANIA
ne jest zadeklarowanie parametrów w programie wy- z parametrami oczekiwanymi w programie wywo- Opisane wcześniej techniczne sposoby definiowania
woływanym. Po otwarciu do edycji programu (a do- ływanym. Należy tu wymienić zmienną ID_Zamo- zdarzeń można wykorzystać przy całkowicie zdarzenio-
kładnie zadania) Zamówienia Linie w fazie Record Main wienia z tabeli Zamowienia_Nagl.(Rysunek. 10). wym podejściu do tworzenia aplikacji w środowisku Ma-
trzeba na początku utworzyć jeszcze jedną linie do de- Po sprawdzeniu składni program nadaje się już do gic eDeveloper. Dotychczas wyzwalaczem dla zdarze-
klaracji parametru z operacją Select Parametr. Pomię- uruchomienia. Jak widać działa w nim zarówno obsługa nia było wciśnięcie (kliknięcie) przycisku, choć w rze-
czywistości było to zaistnienie zdarzenia powiązanego
z tym przyciskiem. W takim rozwiązaniu w kodzie apli-
kacji znajdzie się wiele zdarzeń powiązanych z akcją
ZOOM (lub inną – wewnętrzną) w korelacji z wybranymi
zmiennymi (kontrolkami przycisków na ekranie). Przy
rozbudowanych programach i skomplikowanej logice
ważne jest, by nazwy kontrolek przycisków choć w czę-
ści oddawały sens zdarzenia, gdyż w innym przypadku
kod aplikacji staje się mało czytelny.
Alternatywą jest wiązanie zdarzeń z akcjami, któ-
re są powoływane do istnienia również przez progra-
Rysunek 9. Wykorzystanie zmiennej typu parametr w celu uzyskania relacji pomiędzy tabelami.
mistę i nie bazują na akcjach wewnętrznych ani syste-
mowych. Tak zwane zdarzenia użytkownika (nie my-
lić ze zdarzeniami wewnętrznymi User Action), są de-
finiowane w specjalnym repozytorium User Events na
poziomie zadania. Mogą określać dowolną aktywność
przewidywaną przez programistę, która zostanie opro-
gramowana później (Rysunek. 11.). Zdarzenie to mo-
że być dalej powiązane z przyciskiem, czy wywołane
w logice aplikacji za pomocą operacji Raise Events.
Bazując na programie Klient – Zamówienia, w
zadaniu Zamówienia możliwe jest zdefiniowanie
kilku typów zdarzeń:

• Wydruk dokumentu to zdarzenie, które zostanie


użyte do uruchomienia programu drukującego
dokument. Dodatkowo dla tego zdarzenia zdefi-
Rysunek 10. Wykorzystanie parametrów przy wywoływaniu podprogramów. niowany jest wyzwalacz – skrót klawiaturowy

84 www.sdjournal.org Software Developer’s Journal 01/2007


KLUB TECHNICZNY MAGIC

CTLR+P. Oznacza to, iż niezależnie od programo-


wego wywołania tego zdarzenia, zostanie zaini- DODATKOWE INFORMACJE
cjowane po uruchomieniu tego skrótu; W cyklu Klub Magic’a do tej pory ukazały się następujące artykuły:
• Odświeżenie okna to zdarzenie, które docelowo zo-
stanie użyte do ponownego odczytania danych wy- • Magic eDeveloper – wysoko produktywna technologia ponad 4GL do tworzenia aplikacji C/S i Web;
świetlanych na ekranie. Będzie mogło być użyte w • Magic eDeveloper – instalacja pakietu;
logice aplikacji, lecz dodatkowo przyporządkowano • Magic eDeveloper – Wstęp do programowania: repozytoria i modele;
• Magic eDeveloper – Wstęp do programowania: Tabela – znaczenie, cechy i definicja;
mu wyzwalacz bazujący na czasie. Zdarzenie to zo-
• Magic eDeveloper – Wstęp do programowania: Program – budowa i cechy funkcjonalne;
stanie wywołane automatycznie co 30 sekund;
• Magic eDeveloper – Wstęp do programowania: Program – tworzenie pierwszego programu
• Nieprawidłowe ID Zamówienia to zdarzenie • Magic eDeveloper – Wstęp do programowania: Program – dostęp do danych w trybie końcowego
które zostanie zainicjowane gdy wartość pola użytkownika ;
ID_Zamowienia będzie miało wartość 0. Może • Magic eDeveloper – Wstęp do programowania: Program – łączenie danych z wielu tabel – relacja 1:1;
być przydatne do obsługi sytuacji niepożąda- • Magic eDeveloper – Wstęp do programowania: Program – łączenie danych z wielu tabel – relacja 1:1,
nej przy edycji danych; opcje połączenia;
• Edycja linii to typowe zdarzenie, które nie ma • Magic eDeveloper – Wstęp do programowania: Program – łączenie danych z wielu tabel – relacja 1:n.
zdefiniowanego żadnego wyzwalacza i będzie
wywołane tylko z logiki aplikacji (z zadania) za
pomocą polecenia Raise Events, lub poprzez szczególności np. Edycja linii (Rysunek. 12.). Takie opi- teria w algorytmie itd. Ważne jest to, iż kod samego
wciśnięcie powiązanego z nim przycisku. sanie zdarzeń pozwala na stworzenie przejrzyste- zdarzenia (czyli zbiór operacji w ramach niego wy-
go kodu, gdyż każda aktywność jest tu jednoznacz- konywanych) istnieje tylko w jednym miejscu i nie
We wszystkich przypadkach jest to tylko definicja akcji, nie nazwana i obsłużona. Poza tym, zdarzenie np. musi być powielany w zadaniu.
która może zaistnieć w danym zadaniu. Sama obsługa Edycja Linii opisane na poziomie zadania może być Logika zdarzenia może zawierać dowolne kon-
zdarzenia, czyli powiązanie akcji z konkretnym działa- wywołane w wielu miejscach aplikacji i za pomocą strukcje bazujące na zmiennych pochodzących z
niem jest definiowane w logice aplikacji, analogicznie do wielu wyzwalaczy. Może być powiązanie z przyci- faz Record Main, zmiennych lokalnych zdefinio-
przykładu ilustrującego redefiniowanie zdarzenia opisa- skiem na ekranie, może to być rezultat zadziałania wanych w ramach zdarzenia, operacji wywołania
nego w poprzednim rozdziale. Tym razem parametrem skrótu klawiszowego, możliwe jest wywołanie au- innych zdarzeń czy innych programów. Warto za-
operacji Handler będzie jednak zdarzenie typu User a w tomatycznie gdy zostaną spełnione określone kry- uważyć, że wszystkie polecenia są wykonywane w
trybie nie interakcyjnym w kolejności zgodnej z ich
definicją. Zdarzenie jest więc jakby fazą wtrąconą
w podstawowy model działania zadania.

PODSUMOWANIE
Niedoceniane przez wielu programistów środowi-
ska Magic zdarzenia, umożliwiają tworzenie przej-
rzystych i wydajnych aplikacji, w których każda
aktywność jest jednoznacznie określona i opro-
gramowana. Artykuł ten przybliżył ideę stosowa-
nia tego typu metody programowania, lecz nie wy-
czerpał całego materiału. Dodatkowe informacje na
ten temat można znaleźć w dokumentacji środo-
wiska Magic eDeveloper. Bardziej zaawansowane
przykłady zastosowanie tej metody projektowa-
Rysunek 11. Przykłady definicji zdarzeń użytkownika nia zostały przedstawione w udostępnionym kur-
sie programowania w środowisku Magic eDevelo-
per. Kurs ten jak też dodatkowe komponenty i in-
formacje można odnaleźć na stronie internetowej
http://komtech.pl/software/.
W następnym artykule zostanie opisany jesz-
cze jeden element tworzenia zadań interaktyw-
nych, mianowicie mechanizm kontrolowania war-
tości zmiennych oraz sposób tworzenia tzw. pro-
gramów wyboru czyli słowników. Kolejny arty-
kuł zostanie natomiast poświęcony idei tworzenia
programów wsadowych i ich przykładowych za-
stosowań.
Mamy nadzieję, że informacje te pozwolą czy-
telnikom na samodzielną pracę ze środowiskiem
Magic oraz odkrywaniem nowych możliwości te-
Rysunek 12. Definicja zdarzenia użytkownika – Edycja linii go narzędzia.

Software Developer’s Journal 01/2007 www.sdjournal.org 85


Postmodernistyczne
Rafał Kocisz
języki programowania
M
oja przygoda z tzw. postmodernistycznymi językami kich języków jak Ada, C++, CLU, Lisp, Java, Perl, Python, PHP,
programowania zaczęła się jakoś pod koniec studiów. oraz Smalltalk. Tyle jeśli chodzi o dygresję. Kontynuując głów-
Mniej więcej w tamtym okresie trafiłem na wspania- ny wątek: jakiś czas po przeczytaniu Pragmatycznego Pro-
łą książkę Andrew Hunta i Davida Thomasa pt. „The Pragma- gramisty znalazłem wreszcie czas na naukę Perla. Dość szyb-
tic Programmer: From Journeyman to Master”. Jako żądny wie- ko przerobiłem klasyczną pozycję Learning Perl z wydawnic-
dzy student połknąłem to dzieło w okamgnieniu. Właśnie wtedy twa OReilly i zacząłem stosować ten „egzotyczny język skryp-
pierwszy raz uderzył mnie fakt, iż moja wiedza o językach pro- towy” w praktyce. Pierwszym szokiem było wyjście poza do-
gramowania jest mocno ograniczona. W tamtym okresie tkwi- brze znany, bezpieczny teren statycznej kontroli typów. Mocno
łem po czubek głowy w świecie C++. Wydawało mi się, że zna- zaintrygowany tematem zacząłem drążyć dalej i dalej. Przeło-
jąc dobrze STL i potrafiąc cytować fragmenty standardu ISO/ mem była książka Higher Order Perl: „Transforming Programs
IEC 14882 złapałem Pana Boga za nogi i nic więcej już mi nie with Programs” autorstwa Marka Jasona Dominusa. Autor po-
potrzeba do osiągnięcia programistycznej Nirvany. Książka An- kazał tu prawdziwą moc drzemiącą w Perlu – szczerze zachę-
drew i Davida ostudziła mnie nieco i dała wiele do myślenia. cam każdego programistę do przeczytania tej pozycji, potrafi
W szczególny sposób uderzyła mnie pewna rada umieszczo- dobrze namieszać w głowie. Idąc dalej tropem Perla trafiłem na
na w rozdziale traktującym o budowaniu portfolio wiedzy. Ra- Ruby – język programowania rodem z Japonii. I zgadnijcie ko-
da ta brzmiała: naucz się co najmniej jednego nowego języka go spotkałem przy tej okazji? Okazało się, że są tu moi starzy
programowania w ciągu roku. Co więcej, autorzy Pragmatycz- pragmatyczni znajomi – Andrew Hunt i David Thomas. Panowie
nego Programisty udowodnili mi na stronicach swojej książki, Ci błyskawicznie dostrzegli potencjał tego języka i stali się je-
że nauka taka może być bardzo pożyteczna. Czytając tę książ- go oddanymi propagatorami. Zachęcony ich entuzjazmem, po-
kę, pierwszy raz zetknąłem się bliżej z Perlem – ulubionym (w stanowiłem wziąć się do nauki. Dla zabawy zacząłem pisać so-
momencie pisania książki) postmodernistycznym językiem pro- bie w Ruby... raytracera. Jakież było moje zdziwienie, kiedy po
gramowania Andrew i Davida. Powziąłem sobie wtedy silne po- trzech wieczorach – nie znając wcześniej składni języka i ucząc
stanowienie, że zastosuję się do zalecenia i co rok nauczę się się wszystkiego „w locie”, napisałem w pełni działający (oczywi-
nowego języka. Ale, ale – korzystam z przymiotnika „postmo- ście w pewnym bardzo podstawowym zakresie) program. Gdy-
dernistyczny” w odniesieniu do języków programowania – mo- bym chciał zrobić coś podobnego w C++, to (zakładając, że nie
że warto w końcu wyjaśnić o co chodzi? Terminu „postmoder- znałbym tego języka i musiałbym uczyć się go w trakcie pra-
nistyczny język programowania” po raz pierwszy użył Larry cy) zajęłoby mi to o wiele, wiele więcej czasu. W Ruby wszyst-
Wall, twórca Perla. Gdyby zapytać filozofa bądź historyka sztu- ko jest takie... domyślne. Koncepcje i mechanizmy wyrwane
ki na czym polega postmodernizm to zapewne w potoku uczo- z innych języków są tutaj pięknie złączone w jedną, logiczną
nej wypowiedzi moglibyśmy wyłowić zapewne dominujące sło- całość. Trudno to krótko i zwięźle opisać – trzeba to poczuć –
wo kluczowe: dekonstrukcja. I tu właśnie leży sedno sprawy – najlepiej kodując w tym języku (osobom, które chciałyby szyb-
otóż języki postmodernistyczne zostały zbudowane na bazie ko zapoznać się z podstawami Ruby polecam darmową książ-
dekonstrukcji i rekombinacji cech innych języków programowa- kę Why’s (Poignant) Guide to Ruby; można ją znaleźć pod adre-
nia. Tak właśnie powstały Perl, Python, Ruby, Tcl i wiele innych. sem http://poignantguide.net). Według mnie najpiękniejsze przy
Oczywiście niemalże każdy język programowania w taki czy in- nauce postmodernistycznych języków programowania jest nie-
ny sposób czerpie z dorobku swoich poprzedników – jednakże samowite rozszerzanie się horyzontów myślowych. Znajdziemy
w niektórych przypadkach mamy do czynienia z dekonstrukcją tu mieszankę właściwości, o których w ogóle się nam nie śni-
na bardzo szeroką skalę. Mamy tu podobną sytuację jak z post- ło – zakładając, że znaliśmy jedynie C++, C# czy Javę. Patrząc
modernizmem w sztuce – potrzebna jest bardzo solidna baza, z tej perspektywy uczenie się Ruby (bądź innego postmoderni-
z której można by czerpać. Trudno przeprowadzać dekonstruk- stycznego języka programowania) jest przedsięwzięciem ryzy-
cję jeśli... nie ma czego dekonstruować. A przykładowo Ruby kownym – łatwo się uzależnić i trudno przestawić się ponow-
– mój ulubiony dialekt postmodernistyczny, według zapewnień nie na kodowanie w „zwyczajnych” dialektach. Jednakże, mo-
swojego twórcy – Yukihiro Matsumoto – powstał na bazie ta- im zdaniem nawet sama nauka daje bardzo dużo. Przykładowo,
ja w sensie zawodowym cały czas pracuję z językiem C++, lecz
od kiedy zacząłem poznawać i analizować alternatywne rozwią-
Autor pracuje na stanowisku Starszego Specjalisty ds. Oprogra-
zania, potrafię zdobyć się na pewien dystans i o wiele wyraźniej
mowania w firmie BLStream (www.blstream.com) oraz odbywa
studia doktoranckie na Wydziale Informatyki Politechniki Szcze- dostrzegać zarówno mocne jak i słabe strony C++. Konkludując,
cińskiej (www.wi.ps.pl). Centrum zainteresowań zawodowych au- jeśli jesteś programistą któregoś z wiodących (w sensie prze-
tora stanowią technologie mobilne, przetwarzanie równoległe mysłowym) języków i poza nim nie interesuje Cię nic innego, to
oraz języki programowania w ujęciu ogólnym. gorąco Cię namawiam: jeszcze dziś zacznij uczyć się jednego
Kontakt z autorem: rafal.kocisz@gmail.com z postmodernistycznych języków programowania. Gwarantuję
Ci, że sprawi to, iż staniesz się lepszym programistą! n

86 www.sdjournal.org Software Developer’s Journal 01/2007


Księgozbiór

Więcej niż architektura oprogramowania


Autor: Luke Hohmann
Wydawnictwo: Helion
ISBN: 83-246-0110-4
Ocena: 4,5

Los, przyszłość i droga życia oprogramowania nie zawsze jest prosta. W wielu przypadkach iden-
tyczne postępowanie w stosunku do tworzonych czy rozpowszechnianych narzędzi może przy-
nieść odwrotne skutki. Dlatego w tej kwestii nie możemy opierać się na sztywnych wzorcach i opi-
sach co mamy zrobić. To od wniosków pochodzących z analizy czynników, które wpływają na opro-
gramowanie, zależy nasze działanie, a nie od grafiku postępowania. Biorąc do ręki tę książkę spo-
dziewałem kolejnego, teoretycznego wykładu o tworzeniu diagramów jak i relacjach klient – opro-
gramowanie. Jednak nie znajdziemy w tej książce, poza miejscami gdzie jest to konieczne, su-
chych, tematycznych definicji i porad działania, które nie sprawdzają się w realnym świecie. Autor
opisuje problemy z jakimi możemy się spotkać podczas projektowania. Luke Hohmann poruszył wiele kwestii tak normalnych dla ryn-
ku IT ale nie opisywanych w innych książkach. Książka nakreśla czytelnikowi procesy produkcyjne, rozbudowy, funkcjonalne, wdro-
żeniowe oprogramowania. Przeczytamy tu nie tylko o problemach związanych z software’m, ale też o czynniku ludzkim, jak np. rozu-
mowanie programisty, ich przyzwyczajenia i skłonności oraz relacje programistów do innych członków zespołu. Wszystko to jest po-
parte licznymi przykładami wziętymi z wieloletniej pracy Hohmann’a jako programisty czy też szefa zespołu projektu. Mało jest pozy-
cji na rynku, których charakter byłby bardziej praktyczny. Ciekawym pomysłem jest też umieszczenie po każdym rozdziale podsumo-
wania oraz rad dotyczących co warto sprawdzić i co warto spróbować. Minusem pozycji jest zatrzymywanie się i rozprawianie na te-
maty marketingowe co nie oznacza, że te kwestie są mniej znaczące, jednak wielu programistów ten fakt może denerwować. Nieste-
ty spis treści nie do końca spełnia swoje role. Czego dowiemy się z haseł np: Tak, to jest potrzebne czy Chcę wiedzieć co jest grane?
Nie za wiele. Czy jest to książka z której nauczymy się architektury oprogramowania? Z pewnością nie do końca, gdyż będziemy mu-
sieli sięgnąć do pozycji bardziej technicznych. Czy zrozumiemy i nauczymy się analizować procesy i problemy związane z oprogra-
mowaniem, o których mielibyśmy się dowiedzieć podczas naszej pracy w tej tematyce? Z pewnością tak.
Zrecenzował: Mariusz Ostapowicz

C# i .NET
Tytuł oryginalny: Core C# and .NET
Autor: Stephen C. Perry
Wydawnictwo: Wydawnictwo Helion, czerwiec 2006
ISBN: 83-246-0320-4
Ocena: 5-

Po dość długim okresie posuchy na polskim rynku wydawniczym, jak grzyby po deszczu, zaczęły
pojawiać się pozycje opisujące możliwości platformy .NET. I o ile jeszcze przed niespełna rokiem nie
mieliśmy praktycznie wyboru, szukając pozycji, z pomocą której zdobywalibyśmy szlify w najnow-
szej technologii firmy Microsoft, dziś możemy dość swobodnie przebierać wśród książek omawiają-
cych tę tematykę. Trudno znaleźć na polskim rynku książkę, która bez zbędnego wprowadzenia w
podstawy programowania omawia podstawowe konstrukcje języka, elementy biblioteki standardo-
wej .NET, kontrolki Windows Forms, GDI+, .NET Remoting, pracę z dokumentami XML, techniki zabezpieczania kodu i wiele innych
aspektów, dość dobrze znanych każdemu, kto miał okazję spędzić trochę czasu w projektach realizowanych przy wykorzystaniu plat-
formy .NET i języka C#. Chociaż nagromadzenie tak wielu tematów spowodowało, że kilka z nich jest omówionych zbyt pobieżnie,
to programiście, który chce tylko zajrzeć za drugą stronę barykady, takie przekrojowe omówienie może przypaść do gustu. Mimo to,
programista .NET skuszony numerem „2.0” na okładce, odnajdując w publikacji zaledwie wprowadzające informacje o możliwości
niesionych przez nową wersję, może poczuć lekki niedosyt. Podsumowując, książkę „C# i .NET” z czystym sumieniem mogę pole-
cić każdemu, kto ma zamiar poznać możliwości platformy .NET. Choć ostrzegam, że trzeba się uzbroić w odrobinę cierpliwości, aby
nie usnąć nad tą publikacją. Wiedza w niej zawarta z pewnością wystarczy, aby samodzielnie wykorzystać tę technologię i sprawnie
podjąć poszukiwania szczegółowych informacji o interesujących nas elementach platformy .NET. Programista, który ma już za sobą
przygodę z tą technologią, niestety nie znajdzie tu wiele nowych informacji, a książka ta co najwyżej pomoże mu uporządkować już
zdobytą wiedzę. Niemniej jednak na uznanie zasługuje wysiłek autora, aby przedstawić w ramach jednej publikacji tak szerokie spek-
trum zastosowania „C# i .NET”, co niewątpliwie mu się udało. Głównie dzięki temu jest to aktualnie najlepsza, moim zdaniem, publi-
kacja omawiająca możliwości platformy .NET na polskim rynku wydawniczym.
Zrecenzował: Stefan Turalski

Software Developer’s Journal 01/2007 www.sdjournal.org 87


www.buyitpress.com

Zaprenumeruj swoje ulubione magazyny


i zamów archiwalne numery!

Już teraz w kilka minut możesz zaprenumerować swoje ulubione pismo.


Gwarantujemy:
- preferencyjne ceny
- bezpieczną płatność on-line
- szybką realizację Twojego zamówienia
Bezpieczna prenumerata on-line wszystkich tytułów Wydawnictwa Software!
zamówienie prenumeraty

Prosimy wypełnić czytelnie i przesłać faksem na numer: (22) 887 10 11 lub listownie na adres: Software-Wydawnictwo Sp. z o.o.,
Bokserska 1, 02-682 Warszawa, e-mail: pren@software.com.pl. Przyjmujemy też zamówienia telefoniczne: (22) 887 14 44

Imię i nazwisko............................................................................................ ID kontrahenta..........................................................................................

Nazwa firmy................................................................................................. Numer NIP firmy.......................................................................................

Dokładny adres....................................................................................................................................................................................................................

Telefon (wraz z numerem kierunkowym)................................................... Faks (wraz z numerem kierunkowym) ....................................................

E-mail (niezbędny do wysłania faktury)............................................................................................................................................................................


automatyczne przedłużenie prenumeraty

Tytuł
Ilość Od numeru Opłata
Ilość
zamawianych pisma lub w zł
numerów
prenumerat miesiąca z VAT
Software Developer’s Journal (1 płyta CD)
– dawniej Software 2.0 12 250/1801
Miesięcznik profesjonalnych programistów
SDJ Extra (od 1 do 4 płyt CD lub DVD)
– dawniej Software 2.0 Extra! 6 150/1352
Numery tematyczne dla programistów

Linux+DVD (2 płyty DVD)


Miesięcznik o systemie Linux
12 199/1791

Linux+Extra! (od 1 do 7 płyt CD lub DVD)


Numery specjalne z najpopularniejszymi dystrybucjami Linuksa
8 232/1982

PHP Solutions (1 płyta CD)


Dwumiesięcznik o zastosowaniach języka PHP
6 135

Hakin9, jak się obronić (1 płyta CD)


Miesięcznik o bezpieczeństwie i hakingu
12 1991/219

.psd (1 płyta CD + film instruktażowy)


Dwumiesięcznik użytkowników programu Adobe Photoshop
6 140

.psd numery specjalne


(.psd Extra + .psd Starter Kit)
6 140

Suma

Jeżeli chcesz zapłacić kartą kredytową, wejdź na


stronę naszego sklepu internetowego:
1
Cena prenumeraty rocznej dla osób prywatnych
2
Cena prenumeraty rocznej dla osób prenumerujących już Software Developer’s Journal lub Linux+
3
Cena prenumeraty dwuletniej Aurox Linux
www.buyitpress.com
nr 2/2007 (146)

Numer w sprzedaży już od 18-stego stycznia 2007r.

Programowanie dla internetu


w następnym numerze między innymi:

Biblioteka
miesiąca
CLucene
CLucene to biblioteka C++ oferująca wysoko wydajne, bogate, przenośne i rozszerzalne API
wspomagające proces indeksowania oraz przeszukiwania danych tekstowych. CLucene to port
Lucene, popularnego silnika do przeszukiwania tekstu, stworzonego w języka Java. W odnie-
sieniu od swojego pierwowzoru CLucene cechuje się bardzo dużą szybkością działania, co czy-
ni ją idealnym kandydatem przy tworzeniu aplikacji o wysokich wymaganiach wydajnościowych.
W następnym numerze, w ramach kolumny Biblioteka Miesiąca autor CLucene przedstawi możli-
wości swojego rozwiązania i pokaże jak najłatwiej rozpocząć pracę z tą biblioteką.

Warsztat
XHTML
Pierwsza strona w XHTML
XHTML jest następcą nierozwijanego już oficjalnie języka HTML4 będąc równocześnie zgodny z zasa-
dami XML. Powstał z myślą o rozwinięciu możliwości stron internetowych, których brakowało w HTML.
Jako dokument (aplikacja) XML pozwala na korzystanie ze wszystkich jego możliwości. Oficjalny FAQ
konsorcjum W3C opisuje podstawowe różnice między XHTML a HTML, zaznaczając przy tym, że różni-
ce w korzyści z przejścia na XHTML mogą okazać się niewielkie dla początkujących projektantów stron
lub w przypadku stron nieskomplikowanych.

Inżynieria
oprogramowania
Biblioteka POSH
Biblioteka POSH ułatwia tworzenie przenośnego kodu pomiędzy różnymi kompilatora-
mi, systemami operacyjnymi i platformami sprzętowymi. Artykuł przedstawi zastosowanie
POSH na prostym przykładzie biblioteki analizującej nagłówek pliku WAV (dźwiękowego).

Na CD:
Na dołączonej do pisma płycie znajdziecie komplet materiałów do artykułów.
Zapraszamy do lektury!

Aktualne informacje o najbliższym numerze: http://www.sdjournal.org/pl/


Redakcja zastrzega sobie prawo do zmiany zawartości pisma.

You might also like