Maj
06
2010

Seam: Pobieranie konfiguracji poczty z bazy

Słowa kluczowe: , , , , | Kategorie: Seam Framework
No Gravatar

Gdy już udało mi się wysłać wiadomość email z poziomu aplikacji Seam, postanowiłem przenieść konfigurację serwera poczty wychodzącej do bazy danych – tak aby użytkownik (administrator) systemu mógł ją zmieniać w dowolnym momencie.

Realizacja tego zadania wymagała rozszerzenia funkcjonalności komponentu org.jboss.seam.mail.mailSession. Na początek tworzę nową klasę, dziedziczącą po MailSession:

@Name("org.jboss.seam.mail.mailSession")
@Install(
        precedence = Install.APPLICATION,
        classDependencies = "javax.mail.Session")
@Scope(ScopeType.APPLICATION)
public class JpaMailSession extends org.jboss.seam.mail.MailSession {
    @In
    private EntityManager entityManager;
}

Pobieranie danych serwera poczty z bazy wymaga przeciążenia kilku metod. Na początku zajmę się tworzeniem właściwego obiektu sesji:

@Override
@Unwrap
public javax.mail.Session getSession() throws NamingException {
    setSessionJndiName(null);
    create();
    return super.getSession();
}

Ustawienie nazwy sesji na null (linia 4) spowoduje, że metoda create() (linia 5) faktycznie utworzy nową sesję. Domyślnie dane serwera poczty są stałe (pochodzą z pliku components.xml), więc wystarczy jednorazowe utworzenie sesji. W wypadku konfiguracji zapisanej w bazie wszelkie niezbędne dane mogą ulec zmianie w trakcie działania aplikacji, co powoduje konieczność przeładowania sesji.

Powyższe operacje można wykonywać w odpowiednio przygotowanej metodzie obserwatora zdarzenia związanego ze zmianą danych serwera pocztowego… może w następnym artykule.

Kolejną przeciążaną metodą będzie getHost() – odpowiedzialna za pobieranie nazwy serwera pocztowego:

@Override
public String getHost() {
    if (entityManager != null) {
        super.setHost(loadHostFromDB());
    }
    return super.getHost();
}

Implementację prywatnej metody loadHostFromDB() pozostawiam czytelnikom, ponieważ dane serwera pocztowego można przechowywać w bazie na wiele sposobów – wszystko zależy od konkretnej sytuacji i kontekstu.

Przed pobraniem nazwy hosta z bazy sprawdzam, czy istnieje entityManager (linia 3). Nie chodzi o to, że komponent może nie istnieć w kontekście – on mógł nie zostać wstrzyknięty. Powodem takiej sytuacji jest adnotacja @BypassInterceptors przy klasie org.jboss.seam.mail.MailSession – bez interceptorów nie ma wstrzykiwania zależności.

Analogicznie przeciążam metody pobierające pozostałe dane serwera pocztowego:

@Override
public Integer getPort() {
    if (entityManager != null) {
        super.setPort(loadPortFromDB());
    }
    return super.getPort();
}

@Override
public String getUsername() {
    if (entityManager != null) {
        super.setUsername(loadUsernameFromDB());
    }
    return super.getUsername();
}

@Override
public String getPassword() {
    if (entityManager != null) {
        super.setPassword(loadPasswordFromDB());
    }
    return super.getPassword();
}

Teraz już można usunąć znacznik mail:mail-session z pliku components.xml. Wysyłanie wiadomości będzie się odbywać w oparciu o konfigurację zapisaną w bazie danych.

Opisany wyżej mechanizm można poddać wielu dalszym ulepszeniom. Być może opiszę swoje propozycje w przyszłości.

Napisz Komentarz

*