2 * Copyright (C) 2016, 2017 Roland Häder
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (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 Affero General Public License for more details.
14 * You should have received a copy of the GNU Affero General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.jjobs.beans.country;
19 import java.text.MessageFormat;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.MissingResourceException;
24 import java.util.Objects;
25 import java.util.ResourceBundle;
26 import javax.annotation.PostConstruct;
27 import javax.enterprise.context.RequestScoped;
28 import javax.enterprise.event.Event;
29 import javax.enterprise.inject.Any;
30 import javax.faces.application.FacesMessage;
31 import javax.faces.context.FacesContext;
32 import javax.faces.view.facelets.FaceletException;
33 import javax.inject.Inject;
34 import javax.inject.Named;
35 import javax.naming.Context;
36 import javax.naming.InitialContext;
37 import javax.naming.NamingException;
38 import org.mxchange.jcountry.data.Country;
39 import org.mxchange.jcountry.data.CountryData;
40 import org.mxchange.jcountry.data.CountrySingletonBeanRemote;
41 import org.mxchange.jcountry.events.AdminAddedCountryEvent;
42 import org.mxchange.jcountry.events.ObservableAdminAddedCountryEvent;
43 import org.mxchange.jcountry.exceptions.CountryAlreadyAddedException;
44 import org.mxchange.jjobs.beans.BaseJobsController;
47 * An administrative country bean
49 * @author Roland Häder<roland@mxchange.org>
51 @Named ("adminCountryController")
53 public abstract class JobsAdminCountryWebRequestBean extends BaseJobsController implements JobsAdminCountryWebRequestController {
58 private static final long serialVersionUID = 18_598_175_719_603L;
61 * An event triggered when the administrator has added a country
65 private Event<ObservableAdminAddedCountryEvent> addedCountryEvent;
70 private String countryAbroadDialPrefix;
75 private CountrySingletonBeanRemote countryBean;
78 * 2-letter country code
80 private String countryCode;
83 * Regular country controller
86 private JobsCountryWebApplicationController countryController;
91 private String countryExternalDialPrefix;
96 private String countryI18nKey;
99 * Whether the local dial prefix is required to use
101 private Boolean countryIsLocalPrefixRequired;
106 private Short countryPhoneCode;
109 * Default constructor
111 public JobsAdminCountryWebRequestBean () {
112 // Call super constructor
117 public String addCountry () {
118 // Create new country object
119 Country country = new CountryData();
122 country.setCountryAbroadDialPrefix(this.getCountryAbroadDialPrefix());
123 country.setCountryCode(this.getCountryCode());
124 country.setCountryExternalDialPrefix(this.getCountryExternalDialPrefix());
125 country.setCountryI18nKey(this.getCountryI18nKey());
126 country.setCountryIsLocalPrefixRequired(this.getCountryIsLocalPrefixRequired());
127 country.setCountryPhoneCode(this.getCountryPhoneCode());
129 // Does it already exist?
130 if (this.isCountryAdded(country)) {
131 // Yes, then abort here
132 throw new FaceletException(new CountryAlreadyAddedException(country));
136 Country updatedCountry = null;
139 // Send country to bean
140 updatedCountry = this.countryBean.addCountry(country);
141 } catch (final CountryAlreadyAddedException ex) {
143 throw new FaceletException(ex);
147 this.addedCountryEvent.fire(new AdminAddedCountryEvent(updatedCountry));
153 return "admin_list_country"; //NOI18N
157 public List<Country> allCountries () {
158 // Return "cached" version
159 return this.countryController.allCountries();
163 public String getCountryAbroadDialPrefix () {
164 return this.countryAbroadDialPrefix;
168 public void setCountryAbroadDialPrefix (final String countryAbroadDialPrefix) {
169 this.countryAbroadDialPrefix = countryAbroadDialPrefix;
173 public String getCountryCode () {
174 return this.countryCode;
178 public void setCountryCode (final String countryCode) {
179 this.countryCode = countryCode;
183 public String getCountryExternalDialPrefix () {
184 return this.countryExternalDialPrefix;
188 public void setCountryExternalDialPrefix (final String countryExternalDialPrefix) {
189 this.countryExternalDialPrefix = countryExternalDialPrefix;
193 public String getCountryI18nKey () {
194 return this.countryI18nKey;
198 public void setCountryI18nKey (final String countryI18nKey) {
199 this.countryI18nKey = countryI18nKey;
203 public Boolean getCountryIsLocalPrefixRequired () {
204 return this.countryIsLocalPrefixRequired;
208 public void setCountryIsLocalPrefixRequired (final Boolean countryIsLocalPrefixRequired) {
209 this.countryIsLocalPrefixRequired = countryIsLocalPrefixRequired;
213 public Short getCountryPhoneCode () {
214 return this.countryPhoneCode;
218 public void setCountryPhoneCode (final Short countryPhoneCode) {
219 this.countryPhoneCode = countryPhoneCode;
223 public boolean hasCountries () {
224 return (!this.allCountries().isEmpty());
228 * Post-construction method
231 public void init () {
234 // Get initial context
235 Context context = new InitialContext();
237 // Try to lookup the bean
238 this.countryBean = (CountrySingletonBeanRemote) context.lookup("java:global/jjobs-ejb/country!org.mxchange.jcountry.data.CountrySingletonBeanRemote"); //NOI18N
239 } catch (final NamingException ex) {
241 throw new FaceletException(ex);
246 * Clears this bean's data. This should be called after a form has been
247 * submitted and the processing of the form was successful.
249 private void clear () {
251 this.setCountryAbroadDialPrefix(null);
252 this.setCountryCode(null);
253 this.setCountryExternalDialPrefix(null);
254 this.setCountryI18nKey(null);
255 this.setCountryIsLocalPrefixRequired(null);
256 this.setCountryPhoneCode(null);
260 * Checks if given country is already added by iterating over the whole list
261 * and try to find it.
263 * @param country Country instance to look for
265 * @return Whether the country was already found
267 private boolean isCountryAdded (final Country country) {
268 // Default is not found
269 boolean isAdded = false;
272 List<Country> countries = this.countryController.allCountries();
274 // Get iterator from it
275 Iterator<Country> iterator = countries.iterator();
278 while (iterator.hasNext()) {
280 Country next = iterator.next();
282 // Is country code or i18n the same?
283 if ((Objects.equals(country.getCountryCode(), next.getCountryCode())) || (Objects.equals(country.getCountryI18nKey(), next.getCountryI18nKey()))) {
284 // Yes, then abort search
295 * Returns given property key or throws an exception if not found.
297 * @param parameterKey Property key
299 * @return Property value
301 * @throws NullPointerException If given key is not found
302 * @throws NumberFormatException If no number is given in context parameter
304 protected int getIntegerContextParameter (final String parameterKey) throws NullPointerException, NumberFormatException {
305 // Get context parameter
306 Integer contextValue = Integer.parseInt(this.getStringContextParameter(parameterKey));
312 * Returns given property key or throws an exception if not found.
314 * @param parameterKey Property key
316 * @return Property value
318 * @throws NullPointerException If given key is not found
320 protected String getStringContextParameter (final String parameterKey) throws NullPointerException {
321 // Get context parameter
322 String contextValue = FacesContext.getCurrentInstance().getExternalContext().getInitParameter(parameterKey);
324 if (null == contextValue) {
326 throw new NullPointerException(MessageFormat.format("parameterKey={0} is not set.", parameterKey)); //NOI18N
333 * Checks whether debug mode is enabled for given controller
335 * @param controllerName Name of controller
337 * @return Whether debug mode is enabled
339 protected boolean isDebugModeEnabled (final String controllerName) {
340 // Parameters should be valid
341 if (null == controllerName) {
343 throw new NullPointerException("controllerName is null"); //NOI18N
344 } else if (controllerName.isEmpty()) {
346 throw new IllegalArgumentException("controllerName is empty"); //NOI18N
348 // Try to get context parameter
349 String contextParameter = this.getStringContextParameter(String.format("is_debug_%s_enabled", controllerName)); //NOI18N
350 // Is it set and true?
351 boolean isEnabled = Boolean.parseBoolean(contextParameter) == Boolean.TRUE;
357 * Loads resource bundle for given locale. This must be implemented per
358 * project so all projects can still customize their methods. Calling
359 * ResourceBundleloadBundle() in this class means that also the bundle files
360 * must be present here.
362 * @param locale Locale from e.g. FacesContext
364 * @return Initialized and loaded resource bundle
366 protected abstract ResourceBundle loadResourceBundle (final Locale locale);
369 * Shows a faces message for given causing exception. The message from the
370 * exception is being inserted into the message.
372 * @param clientId Client id to send message to
373 * @param cause Causing exception
375 protected void showFacesMessage (final String clientId, final Throwable cause) {
376 // Get context and add message
377 this.showFacesMessage(clientId, cause.getMessage());
381 * Shows a faces message with given message (i18n) key.
383 * @param clientId Client id to send message to
384 * @param i18nKey Message key
386 * @throws NullPointerException If clientId or i18nKey is null
387 * @throws IllegalArgumentException If clientId or i18nKey is empty
389 protected void showFacesMessage (final String clientId, final String i18nKey) throws NullPointerException, IllegalArgumentException {
390 // Both parameter must be valid
391 if (null == clientId) {
393 throw new NullPointerException("clientId is null"); //NOI18N
394 } else if (clientId.isEmpty()) {
396 throw new IllegalArgumentException("clientId is null"); //NOI18N
397 } else if (null == i18nKey) {
399 throw new NullPointerException("i18nKey is null"); //NOI18N
400 } else if (i18nKey.isEmpty()) {
402 throw new IllegalArgumentException("i18nKey is null"); //NOI18N
404 // Get current locale
405 Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
407 ResourceBundle bundle = this.loadResourceBundle(locale);
408 // Default is i18nKey
409 String message = MessageFormat.format("!{0}!", i18nKey); //NOI18N
413 message = bundle.getString(i18nKey);
414 } catch (final MissingResourceException ex) {
415 // Did not find it, ignored
417 // Get context and add message
418 FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(message));