Seam: Pobieranie konfiguracji poczty z bazy
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.



