Home > Polish > Pierwsze kroki w konfiguracji aplikacji w Tapestry5

Pierwsze kroki w konfiguracji aplikacji w Tapestry5

Dzisiejszy wpis będzie tylko wstępem do konfiguracji, jako że muszę uzupełnić w tym względzie własne braki :).
No to dziś będzie nudno, bo będzie dużo xmla… hmm no może jednak nie. Tapestry należy do tych szkieletów aplikacyjnych, w których nie musimy pisać ni linijki w xmlu (pomijając web.xml i templaty, które są dokumentami XHTML czyli XMLami).
Niektórzy stwierdzą w tym momencie, że bez sensu, nie da się programować w notatniku i na żywo podmieniać na produkcji kodu zmieniając wszystko. A ja powiem, że dzięki temu można dbać o jakość, testować, popełniać mniej błędów, korzystać z wsparcia IDE, refaktoryzować, etc.
To co warto nadmienić przed przejściem dalej, to że T5 jest zbudowane na module IOC więc cała nasza konfiguracja będzie interakcją z modułem wstrzyknięć. Nadmieniam to tutaj, gdyż mówiąc na co dzień o IOC mam na myśli nasze klasy wstrzykiwane do innych naszych klas. Gdy piszę o konfiguracji, to mam na myśli interakcję z klasami dostarczanymi z Tapestry. Wiem, zagmatwałem :(

No ale do kodu (z którego komentarze pozwalam sobie wycinać).
Specyfikacja JEE wymaga od nas byśmy zajrzeli na początek do web.xml, gdzie ponad standardową deklarację XMLa i web app (wymagane przez kontener servletów) znajdziemy następujący fragment

    <context-param>
        <param-name>tapestry.app-package</param-name>
        <param-value>pl.rits.blog.projektBlogowy</param-value>
    </context-param>
    <filter>
        <filter-name>app</filter-name>
        <filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>app</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Mam nadzieję, że na dziś się już XMLa naoglądaliście, bo więcej go w tym wpisie nie znajdziecie. Dewianci niech otworzą jakiś projekt Springowy/facowy/strursowy i wrócą za miesiąc, bo w najbliższej przyszłości nie przewiduję więcej XMLa na blogu (no .tml-e się pewnie pojawią, ale niewiele!).

Słowo wyjaśnienia się teraz należy co widać w zamieszczonym kodzie. Zdefiniowaliśmy root projektu, dzięki temu T5 będzie się w stanie znaleźć w naszej aplikacji (od podanego tu pakietu, szukane są pakiety pages, components, etc).

Druga istotna informacja to rejestracja filtra tapestry i określenie jego nazwy na app. Definiuje ona nazwę klasy w której będziemy dokonywali konfiguracji naszej aplikacji. Dla przykładu: jeśli pozostanie ona zdefiniowana jako app, to tapestry będzie szukać klasy ${rootProjektu}.services.AppModule.java. Brak tej klasy nie jest błędem, ale uniemożliwia nadpisanie jakichkolwiek domyślnych ustawień tapestry. Wyłączy nam też możliwość definiowania nowych services więc de facto poza pół statycznymi aplikacjami, ta klasa będzie zawsze obecna.

Przejdźmy więc do niej i sprawdźmy co w niej znajdziemy. Niestety jest tego niewiele. Nie ma interfejsu, dziedziczenia ani, co gorsza, XMLa! :( Hańba!

Jest za to kilka metod. Przypomnę, że tapestry to Convention over Configuration więc korzysta z konwencji nazw by umożliwić nam konfigurację. Niestety zmiany w tej klasie będą wymagały restartu aplikacji, live class reloading tu nie działa, z doświadczenia za to wiem, że to nie jest uciążliwy problem. Po pierwszej konfiguracji jedyną zmianą jest dokładanie kolejnych services. Spójrzmy na 2 z metod znajdujących się domyślnie w klasie (tj znajdujących się w mavenowym archetypie):

public static void bind(ServiceBinder binder) {
// binder.bind(MyServiceInterface.class, MyServiceImpl.class);
}
public static void contributeApplicationDefaults(MappedConfiguration configuration) {
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
configuration.add(SymbolConstants.APPLICATION_VERSION, "0.0.1-SNAPSHOT");
}

Pierwsza metoda służy do powiadomienia kontenera IOC tapestry o istnieniu naszego service (w springu zwanego beanem, co BTW jest dla mnie najbardziej denerwującą rzeczą w całym springu).
Serwisy w tapestry standardowo składają się z interfejsu oraz jego implementacji, choć pierwsze może zostać pominięte (niezalecane). Nazwa powinna być znana użytkownikom HiveMind (który był stworzony na potrzeby poprzedniego tapestry).
Powiązanie pomiędzy implementacją a interfejsem tworzone jest po .class, dzięki czemu możemy refaktoryzować nasz kod w dowolnym IDE, a i tak będzie nas ono wspierało. Powiązania są również wyszukiwalne, choć oba punkty stają się coraz mniej aktualne wraz z wzrastającym wsparciem  wszystkich IDE dla Springa. Wspominam o tym jednak, gdyż w dawnych czasach, zdarzyło mi się pomagać koledze utrzymującemu naszą aplikację, znaleźć błąd w mojej klasie. Po dłuższej chwili okazało się, że nastąpiły zmiany w klasach, które nie zostały odzwierciedlone w plikach XML.

Druga metoda dokłada się do domyślnych ustawień aplikacji, co to dokładnie oznacza wyjaśnię w jednym z przyszłych wpisów. Do metody tapestry dostarczy nam obiektu, który jest taką a’la mapą do której można tylko wkładać. Klucz odpowiada za nazwę opcji a wszystkie opcje można znaleźć w obiekcie SymbolConstatns. Opisy poszczególnych ustawień można znaleźć na stronach tapestry.
My dodamy jedno od siebie configuration.add(SymbolConstants.COMPRESS_WHITESPACE, “false”);
Dzięki temu łatwiej się developuje (przynajmniej mi) bo więcej widać. Co to zmienia? Przed zmianą podejrzyjcie dowolną stronę wygenerowaną przez T5, a następnie tę samą stronę po zmianie (w przeglądarce korzystamy z opcji source/pokaż źródła ctrl+u).

I wszystko jasne.  Tapestry kompresuje mnóstwo rzeczy by do klienta szło jak najmniej danych. Domyślnie tapestry Gzipuje niektóre dane (o czym za chwilę poniżej) oraz wycina zbędne białe znaki (co właśnie zmieniliśmy). Domyślny rozmiar danych by zostały skompresowane to 100 bajtów, ale da się limit ten zmienić w sposób analogiczny do kompresji białych znaków.

Ciekawostka. Opcja Application_Version jest przydatna :) Na czas developmentu opcję tę kasujemy, przywrócimy ją dopiero jak aplikacja pójdzie live. Dlaczego? Odpowiada ona za przygotowywanie tzw. Assetów (czyli wszystkiego co może zostać wysłane do przeglądarki). Przygotowanie polega na wkomponowaniu w adres URI zasobów numeru wersji. Dzięki temu przeglądarka może cachować po stronie klienta zasoby i pobierać je ponownie dopiero gdy zmieni się numer wersji. Gdy nie podamy tej opcji w ogóle to za każdym uruchomieniem generowany jest losowy numer, co pozwala nam uniknąć ręcznego czyszczenia cachu by zobaczyć wyniki naszych zmian.

To na dziś tyle. Może krótko, ale jak wspominałem sam mam braki w temacie. Jednak pomimo tego czułem potrzebę omówienia zagadnienia konfiguracji. Przepraszam również, że wpis ukazuje się tak późno. Był gotów w zeszłą niedzielę, ale po windows updatcie i pewnej dozie nerwów z tym związanych, postanowiłem go opublikować w poniedziałek. Naiwny, nie widziałem wtedy jeszcze, że czeka mnie piekielny tydzień.
Postaram się nadrobić tekstem jutro :)
Do przeczytania

Advertisements
Categories: Polish Tags:
  1. 05/12/2010 at 07:02

    Fajnie, że podajesz takie niuanse jak na przykład Application_Version. Czytając kolejne wpisy czuje się jakbym znów był na Twojej prelekcji JUG’owej, tylko o poszerzonej treści :)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: