package hirondelle.fish.all.preferences; import hirondelle.web4j.Controller; import hirondelle.web4j.database.DAOException; import hirondelle.web4j.model.AppException; import hirondelle.web4j.security.LoginTasks; import hirondelle.web4j.security.SafeText; import hirondelle.web4j.util.Util; import java.util.logging.Logger; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** Ensures the user preferences are present in session scope. <P>Upon login, it is often desirable to place user preferences in the session. However, in applications which use the servlet <tt>security-constraint</tt> mechanism, user login is controlled mostly by the container. So, the issue arises of how to place user preferences into a session after successful login. <P>There does not seem to be any suitable items in the existing Servlet API for this task. The {@link javax.servlet.http.HttpSessionListener} allows inspection of sessions that have just been created, but does not allow inspection of <em>who</em> has logged in. */ public final class Login implements LoginTasks { /** Returns <tt>true</tt> only if an attribute named {@link Controller#LOCALE} is in session scope. */ public boolean hasAlreadyReacted(HttpSession aSession) { return aSession.getAttribute(Controller.LOCALE) != null; } /** Ensure the user preferences are in session scope. <P>In this implementation, there is only one user preference - the language (English or French). This method adds a {@link java.util.Locale} object to session scope under a key defined by {@link hirondelle.web4j.Controller#LOCALE}. <P>If there are many user preferences, and not just one, then it might make sense to place a single object into session scope, which gathers together all such preferences into a single object. Note, however, that the <em>default</em> implementations of {@link hirondelle.web4j.request.LocaleSource} and {@link hirondelle.web4j.request.TimeZoneSource} are not consistent with such a style, since they expect their data to be stored under separate keys defined in {@link Controller}. */ public void reactToUserLogin(HttpSession aSession, HttpServletRequest aRequest) throws AppException { fLogger.fine("Adding user preferences to session."); String userName = aRequest.getUserPrincipal().getName(); PreferencesDAO dao = new PreferencesDAO(); try { Preferences prefs = dao.fetch(SafeText.from(userName)); fLogger.fine("Adding language/locale preference to session: " + prefs.getLocale()); aSession.setAttribute(Controller.LOCALE, prefs.getLocale()); } catch (DAOException ex){ throw new AppException("Cannot fetch language preference from database.", ex); } } // PRIVATE private static final Logger fLogger = Util.getLogger(Login.class); }