2 * Copyright (C) 2017, 2018 Free Software Foundation
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.jcoreee.bean.faces;
19 import java.io.Serializable;
20 import java.math.BigDecimal;
21 import java.security.Principal;
22 import java.text.MessageFormat;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Locale;
26 import java.util.MissingResourceException;
27 import java.util.ResourceBundle;
28 import javax.faces.application.FacesMessage;
29 import javax.faces.context.FacesContext;
32 * An abstract bean for faces (web) projects.
34 * @author Roland Häder<roland@mxchange.org>
36 public abstract class BaseFacesBean implements Serializable {
39 * Loaded resource bundles ("cached")
41 private static final List<ResourceBundle> RESOURCE_BUNDLES;
46 private static final long serialVersionUID = 18_605_498_672_261L;
52 // Init resource bundle list
53 RESOURCE_BUNDLES = new ArrayList<>(3);
57 * Removes all bundles from web application. Typically you want to invoke
58 * this method in a ServletContextListener implementation on the
59 * contextDestroyed() method.
61 public static void removeBundles () {
63 RESOURCE_BUNDLES.clear();
67 * Getter for resource bundle list
69 * @return Resource bundle list
71 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
72 protected static List<ResourceBundle> getBundles () {
73 return RESOURCE_BUNDLES;
77 * Protected constructor
79 protected BaseFacesBean () {
80 // Call super constructor
87 * @param value Actual value to check
88 * @param filter Filter value to check against {@code value}
89 * @param locale Locale
91 * @return Whether price ({@code value}) is at least {@code filter}
93 * @see https://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml
95 @SuppressWarnings ("unchecked")
96 public boolean filterByPrice (final Object value, final Object filter, final Locale locale) {
97 // Get trimmed string or NULL
98 final String filterText = (filter == null) ? null : filter.toString().trim();
101 if (filterText == null || filterText.isEmpty()) {
106 // Is value NULL or not castable?
110 } else if (!(value instanceof Comparable)) {
112 throw new ClassCastException("value is not instance of Comparable");
115 // Do the cast and compare
116 return ((Comparable<BigDecimal>) value).compareTo(BigDecimal.valueOf(Double.valueOf(filterText))) > 0;
120 * Determines principal's name or returns null if no principal (security) is
123 * @return Principal's name or null
125 protected String determinePrincipalName () {
127 final Principal userPrincipal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
130 String principalName = null;
132 // Is the principal set?
133 if (userPrincipal instanceof Principal) {
134 // Get principal's name
135 principalName = userPrincipal.getName();
139 return principalName;
143 * Returns given property key or throws an exception if not found.
145 * @param parameterKey Property key
147 * @return Property value
149 protected int getIntegerContextParameter (final String parameterKey) throws NullPointerException, NumberFormatException {
150 // Get context parameter
151 final Integer contextValue = Integer.parseInt(this.getStringContextParameter(parameterKey));
158 * Returns a message based on given i18nKey or puts it into three question
159 * marks each side when not found.
161 * @param i18nKey I18n key
163 * @return Localized message
165 * @throws NullPointerException If the parameter is null
166 * @throws IllegalArgumentException If the parameter is empty
168 protected String getMessageFromBundle (final String i18nKey) {
169 // Validate parameter
170 if (null == i18nKey) {
172 throw new NullPointerException("i18nKey is null"); //NOI18N
173 } else if (i18nKey.isEmpty()) {
175 throw new IllegalArgumentException("i18nKey is empty"); //NOI18N
178 // Get current locale
179 final Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
182 this.loadResourceBundles(locale);
184 // Default is i18nKey
185 String message = MessageFormat.format("???{0}???", i18nKey); //NOI18N
188 for (final ResourceBundle bundle : getBundles()) {
193 message = bundle.getString(i18nKey);
195 } catch (final MissingResourceException ex) {
196 // Did not find it, ignored
205 * Returns given property key or throws an exception if not found.
207 * @param parameterKey Property key
209 * @return Property value
211 * @throws NullPointerException If given key is not found
213 protected String getStringContextParameter (final String parameterKey) throws NullPointerException {
214 // Get context parameter
215 final String contextValue = FacesContext.getCurrentInstance().getExternalContext().getInitParameter(parameterKey);
218 if (null == contextValue) {
220 throw new NullPointerException(MessageFormat.format("parameterKey={0} is not set.", parameterKey)); //NOI18N
228 * Checks whether debug mode is enabled for given controller
230 * @param controllerName Name of controller
232 * @return Whether debug mode is enabled
234 protected boolean isDebugModeEnabled (final String controllerName) {
235 // Parameters should be valid
236 if (null == controllerName) {
238 throw new NullPointerException("controllerName is null"); //NOI18N
239 } else if (controllerName.isEmpty()) {
241 throw new IllegalArgumentException("controllerName is empty"); //NOI18N
244 // Try to get context parameter
245 final String contextParameter = this.getStringContextParameter(String.format("is_debug_%s_enabled", controllerName)); //NOI18N
247 // Is it set and true?
248 final boolean isEnabled = Boolean.parseBoolean(contextParameter) == Boolean.TRUE;
255 * Loads resource bundles for given locale. This must be implemented per
256 * project so all projects can still customize their methods. Calling
257 * ResourceBundleloadBundle() in this class means that also the bundle files
258 * must be present here.
260 * @param locale Locale from e.g. FacesContext
262 protected abstract void loadResourceBundles (final Locale locale);
265 * Shows a faces message for given causing exception. The message from the
266 * exception is being inserted into the message.
268 * @param clientId Client id to send message to
269 * @param cause Causing exception
271 protected void showFacesMessage (final String clientId, final Throwable cause) {
272 // Get context and add message
273 this.showFacesMessage(clientId, cause.getMessage());
277 * Shows a faces message with given message (i18n) key.
279 * @param clientId Client id to send message to
280 * @param i18nKey Message key
282 * @throws NullPointerException If clientId or i18nKey is null
283 * @throws IllegalArgumentException If clientId or i18nKey is empty
285 protected void showFacesMessage (final String clientId, final String i18nKey) throws NullPointerException, IllegalArgumentException {
286 // Both parameter must be valid
287 if (null == clientId) {
289 throw new NullPointerException("clientId is null"); //NOI18N
290 } else if (clientId.isEmpty()) {
292 throw new IllegalArgumentException("clientId is null"); //NOI18N
293 } else if (null == i18nKey) {
295 throw new NullPointerException("i18nKey is null"); //NOI18N
296 } else if (i18nKey.isEmpty()) {
298 throw new IllegalArgumentException("i18nKey is null"); //NOI18N
301 // Get message from bundle
302 final String message = this.getMessageFromBundle(i18nKey);
304 // Get context and add message
305 FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(message));