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);
}