2 * Copyright (C) 2017 - 2024 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 () {
85 * @param value Actual value to check
86 * @param filter Filter value to check against {@code value}
87 * @param locale Locale
89 * @return Whether price ({@code value}) is at least {@code filter}
91 * @see https://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml
93 @SuppressWarnings ("unchecked")
94 public boolean filterByPrice (final Object value, final Object filter, final Locale locale) {
95 // Get trimmed string or NULL
96 final String filterText = (filter == null) ? null : filter.toString().trim();
99 if (filterText == null || filterText.isEmpty()) {
104 // Is value NULL or not castable?
108 } else if (!(value instanceof Comparable)) {
110 throw new ClassCastException("value is not instance of Comparable"); //NOI18N
113 // Do the cast and compare
114 return ((Comparable<BigDecimal>) value).compareTo(BigDecimal.valueOf(Double.parseDouble(filterText))) >= 0;
118 * Determines principal's name or returns null if no principal (security) is
121 * @return Principal's name or null
123 protected String determinePrincipalName () {
125 final Principal userPrincipal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
128 String principalName = null;
130 // Is the principal set?
131 if (userPrincipal instanceof Principal) {
132 // Get principal's name
133 principalName = userPrincipal.getName();
137 return principalName;
141 * Returns given property key or throws an exception if not found.
143 * @param parameterKey Property key
145 * @return Property value
147 protected int getIntegerContextParameter (final String parameterKey) throws NullPointerException, NumberFormatException {
148 // Validate parameter
149 if (null == parameterKey) {
151 throw new NullPointerException("parameterKey is null"); //NOI18N
152 } else if (parameterKey.isEmpty()) {
154 throw new IllegalArgumentException("parameterKey is empty"); //NOI18N
157 // Get context parameter
158 final Integer contextValue = Integer.valueOf(this.getStringContextParameter(parameterKey));
165 * Returns a message based on given i18nKey or puts it into three question
166 * marks each side when not found.
168 * @param i18nKey I18n key
170 * @return Localized message
172 * @throws NullPointerException If the parameter is null
173 * @throws IllegalArgumentException If the parameter is empty
175 protected String getMessageFromBundle (final String i18nKey) {
176 // Validate parameter
177 if (null == i18nKey) {
179 throw new NullPointerException("i18nKey is null"); //NOI18N
180 } else if (i18nKey.isEmpty()) {
182 throw new IllegalArgumentException("i18nKey is empty"); //NOI18N
185 // Get current locale
186 final Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
189 this.loadResourceBundles(locale);
191 // Default is i18nKey
192 String message = MessageFormat.format("???{0}???", i18nKey); //NOI18N
195 for (final ResourceBundle bundle : getBundles()) {
199 message = bundle.getString(i18nKey);
201 // Skip further iterations
203 } catch (final MissingResourceException ex) {
204 // Did not find it, ignored
213 * Returns given property key or throws an exception if not found.
215 * @param parameterKey Property key
217 * @return Property value
219 * @throws NullPointerException If given key is NULL or not found
220 * @throws IllegalArgumentException If given key is empty
222 protected String getStringContextParameter (final String parameterKey) throws NullPointerException, IllegalArgumentException {
223 // Is the parameter valid?
224 if (null == parameterKey) {
226 throw new NullPointerException("parameterKey is null"); //NOI18N
227 } else if (parameterKey.isEmpty()) {
229 throw new IllegalArgumentException("parameterKey is empty"); //NOI18N
232 // Get context parameter
233 final String contextValue = FacesContext.getCurrentInstance().getExternalContext().getInitParameter(parameterKey);
236 if (null == contextValue) {
238 throw new NullPointerException(MessageFormat.format("parameterKey={0} is not set.", parameterKey)); //NOI18N
246 * Checks whether debug mode is enabled for given controller
248 * @param controllerName Name of controller
250 * @return Whether debug mode is enabled
252 protected boolean isDebugModeEnabled (final String controllerName) {
253 // Parameters should be valid
254 if (null == controllerName) {
256 throw new NullPointerException("controllerName is null"); //NOI18N
257 } else if (controllerName.isEmpty()) {
259 throw new IllegalArgumentException("controllerName is empty"); //NOI18N
262 // Try to get context parameter
263 final String contextParameter = this.getStringContextParameter(String.format("is_debug_%s_enabled", controllerName)); //NOI18N
266 return Boolean.parseBoolean(contextParameter);
270 * Loads resource bundles for given locale. This must be implemented per
271 * project so all projects can still customize their methods. Calling
272 * ResourceBundleloadBundle() in this class means that also the bundle files
273 * must be present here.
275 * @param locale Locale from e.g. FacesContext
277 protected abstract void loadResourceBundles (final Locale locale);
280 * Shows a faces message for given causing exception. The message from the
281 * exception is being inserted into the message.
283 * @param clientId Client id to send message to
284 * @param cause Causing exception
285 * @param severity Severity
287 protected void showFacesException (final String clientId, final Throwable cause, final FacesMessage.Severity severity) {
288 // Both parameter must be valid
289 if (null == clientId) {
291 throw new NullPointerException("clientId is null"); //NOI18N
292 } else if (clientId.isEmpty()) {
294 throw new IllegalArgumentException("clientId is null"); //NOI18N
295 } else if (null == cause) {
297 throw new NullPointerException("cause is null"); //NOI18N
298 } else if (null == severity) {
300 throw new NullPointerException("severity is null"); //NOI18N
303 // Get context and add message
304 this.showFacesMessage(clientId, cause.getMessage(), severity);
308 * Shows a faces message with given message (i18n) key.
310 * @param clientId Client id to send message to
311 * @param i18nKey Message key
312 * @param severity Severity
314 * @throws NullPointerException If clientId or i18nKey is null
315 * @throws IllegalArgumentException If clientId or i18nKey is empty
317 protected void showFacesMessage (final String clientId, final String i18nKey, final FacesMessage.Severity severity) throws NullPointerException, IllegalArgumentException {
318 // Both parameter must be valid
319 if (null == clientId) {
321 throw new NullPointerException("clientId is null"); //NOI18N
322 } else if (clientId.isEmpty()) {
324 throw new IllegalArgumentException("clientId is null"); //NOI18N
325 } else if (null == i18nKey) {
327 throw new NullPointerException("i18nKey is null"); //NOI18N
328 } else if (i18nKey.isEmpty()) {
330 throw new IllegalArgumentException("i18nKey is null"); //NOI18N
331 } else if (null == severity) {
333 throw new NullPointerException("severity is null"); //NOI18N
336 // Get message from bundle
337 final String message = this.getMessageFromBundle(i18nKey);
339 // Get context and add message
340 FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(severity, message, message));