org.fryske_akademy.jsf.SessionBean Maven / Gradle / Ivy
The newest version!
package org.fryske_akademy.jsf;
/*-
* #%L
* guiCrudApi
* %%
* Copyright (C) 2018 Fryske Akademy
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.io.IOException;
import java.io.Serializable;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.inject.Inject;
import javax.security.enterprise.SecurityContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.fryske_akademy.ejb.AbstractCrudService;
import org.fryske_akademy.jsf.util.CookieHelper;
import org.fryske_akademy.jsf.util.JsfUtil;
/**
* manages logout, internationalization and theming, configure this as a
* managed-bean with name "sessionBean" in faces-config.xml, this way overriding
* is more clear.
*
*
*
* @author eduard
*/
@SessionScoped
public class SessionBean implements Serializable {
public static final String LANGUAGE_COOKIE = "language";
public static final String THEME_COOKIE = "theme";
private String language;
private Locale locale;
private static final Map languageLocales = new HashMap<>(3);
private static final List languages = new ArrayList<>(3);
private final List themes = new ArrayList<>(40);
private String currentTheme;
{
addTheme("aristo").addTheme("omega");
currentTheme = themes.get(1);
}
protected SessionBean addTheme(String theme) {
if (!themes.contains(theme)) {
themes.add(theme);
}
return this;
}
@Inject
private SecurityContext securityContext;
@PostConstruct
private void init() {
initLanguages();
initFromCookies();
}
/**
* list available themes. By default the built-in themes aristo and omega
* are present. You can add themes you bought by calling
* {@link #addTheme(java.lang.String) } from for example the constructor of
* a subclass.
*
* @return
*/
public final List getThemes() {
return themes;
}
public String getCurrentTheme() {
return currentTheme;
}
public final void setCurrentTheme(String currentTheme) {
if (!themes.contains(currentTheme)) {
throw new IllegalArgumentException(currentTheme + " not supported");
}
this.currentTheme = currentTheme;
}
public void themeChanged(ValueChangeEvent event) {
setCurrentTheme((String) event.getNewValue());
setCookie(THEME_COOKIE, currentTheme);
}
protected final void addLanguage(String name, String code, String region) {
languageLocales.put(name, new Locale(code, region));
if (!languages.contains(name)) {
languages.add(name);
}
}
private static void setCookie(String name, String value) {
FacesContext context = FacesContext.getCurrentInstance();
CookieHelper.replaceCookie(name, value, 60*60*24*365,
(HttpServletRequest)context.getExternalContext().getRequest(),
(HttpServletResponse)context.getExternalContext().getResponse());
}
private static Cookie getCookie(String name) {
FacesContext context = FacesContext.getCurrentInstance();
return CookieHelper.getCookie(name, (HttpServletRequest) context.getExternalContext().getRequest());
}
/**
* Called from @Postconstruct, sets current language and theme from a cookie
* or to a default
*
* @see CookieHelper
*/
protected void initFromCookies() {
Cookie cookie = getCookie(LANGUAGE_COOKIE);
setLanguage(cookie != null ? cookie.getValue() : "Frisian");
cookie = getCookie(THEME_COOKIE);
setCurrentTheme(cookie != null ? cookie.getValue() : "aristo");
}
/**
* Called from @Postconstruct, initializes frisian, ducth and english.
* Override this to support more / other languages
*/
protected void initLanguages() {
synchronized (languageLocales) {
if (languageLocales.isEmpty()) {
addLanguage("Frisian", "fy", "NL");
addLanguage("Dutch", "nl", "NL");
addLanguage("English", "en", "EN");
}
}
}
/**
* use this for user choice (dropdown)
*
* @return
*/
public List getLanguages() {
return languages;
}
/**
* The current choice
*
* @return
*/
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
if (languageLocales.containsKey(language)) {
locale = languageLocales.get(language);
FacesContext.getCurrentInstance()
.getViewRoot().setLocale(locale);
this.language = language;
} else {
throw new IllegalArgumentException(language + " not supported");
}
}
/**
* the current locale, use this in @locale in f:view
*
* @return
*/
public Locale getLocale() {
return locale;
}
public boolean mayEdit(String role) {
return securityContext.isCallerInRole(role);
}
/**
* Calls {@link #mayEdit(java.lang.String) } with {@link AbstractCrudService#EDITORROLE}.
* @return
*/
public boolean mayEdit() {
return mayEdit(AbstractCrudService.EDITORROLE);
}
/**
* Call this when user chooses other language
*
* @param e
*/
public void languageChanged(ValueChangeEvent e) {
setLanguage((String) e.getNewValue());
setCookie(LANGUAGE_COOKIE, language);
}
public String getUser() {
Principal p = securityContext.getCallerPrincipal();
return (p == null) ? "not logged in" : p.getName();
}
/**
* ises {@link #getLogoutPath() }
*/
public void logout() {
try {
JsfUtil.logout();
FacesContext.getCurrentInstance().getExternalContext().redirect(getLogoutPath());
} catch (ServletException | IOException ex) {
Logger.getLogger(SessionBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
*
* @return contextPath + "/login.xhtml"
*/
protected static String getLogoutPath() {
return JsfUtil.contextPath() + "/login.xhtml";
}
}