/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You 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. */ package com.esri.gpt.framework.jsf; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.faces.application.FacesMessage; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import com.esri.gpt.framework.util.Val; /** * Retrieves messages based upon the resource bundle associated with the locale * of the Faces view root. */ public class MessageBroker { // class variables ============================================================= /** Navigation outcome - home page with no redirection, "homeDirect" */ private static final String RESOURCEKEY_PREFIX= "catalog."; /** Default resource bundle that should be looked at **/ public static final String DEFAULT_BUNDLE_BASE_NAME = "gpt.resources.gpt"; // instance variables ========================================================== private ResourceBundle _bundle = null; private String _bundleBaseName = ""; private final FacesContextBroker _contextBroker = new FacesContextBroker(); // constructors ================================================================ /** Default constructor. */ public MessageBroker() {} // properties ================================================================== /** * Gets the associated ResourceBundle * @return the ResourceBundle */ private ResourceBundle getBundle() { if (_bundle == null) { _bundle = makeResourceBundle(getBundleBaseName()); } return _bundle; } /** * Gets the base name for the resource bundle. * @return the ResourceBundle base name */ public String getBundleBaseName() { return _bundleBaseName; } /** * Sets the base name for the resource bundle. * @param baseName the resource bundle base name */ public void setBundleBaseName(String baseName) { baseName = Val.chkStr(baseName); if (!baseName.equalsIgnoreCase(_bundleBaseName)) { _bundle = null; } _bundleBaseName = baseName; } /** * Gets the Faces context broker. * @return the Faces context broker */ private FacesContextBroker getContextBroker() { return _contextBroker; } /** * Gets the resource key prefix. * @return the resource key prefix */ public String getResourceKeyPrefix() { return RESOURCEKEY_PREFIX; } // methods ===================================================================== /** * Adds a message to the Faces context. * @param message the message to add */ public void addMessage(FacesMessage message) { FacesContext fc = getContextBroker().getFacesContext(); if ((fc != null) && (message != null)) { fc.addMessage(null,message); } } /** * Adds an error message to the Faces context. * @param resourceKey the resource key for the message */ public void addErrorMessage(String resourceKey) { addErrorMessage(resourceKey,null); } /** * Adds an error message message to the Faces context. * @param resourceKey the resource key for the message * @param parameters optional formating parameters */ public void addErrorMessage(String resourceKey, Object[] parameters) { String sMsg = retrieveMessage(resourceKey,parameters); addMessage(new FacesMessage(FacesMessage.SEVERITY_ERROR,sMsg,null)); } /** * Adds an error message to the Faces context based upon a thrown exception. * <p> * The full class name (including path) of the exception is used a key * to look up an associated message within the resource bundle. If no * associated resource is found, the exception's toString method is * used to generate the message. * @param t the thrown exception */ public void addErrorMessage(Throwable t) { String sMsg = retrieveString(t.getClass().getName(),false); if (sMsg.length() == 0) sMsg = Val.chkStr(t.getMessage()); if (sMsg.length() == 0) sMsg = Val.chkStr(t.toString()); FacesMessage msg = new FacesMessage(sMsg); msg.setSeverity(FacesMessage.SEVERITY_ERROR); addMessage(msg); } /** * Adds a success message to the Faces context. * @param resourceKey the resource key for the message */ public void addSuccessMessage(String resourceKey) { addSuccessMessage(resourceKey,null); } /** * Adds a success message to the Faces context. * @param resourceKey the resource key for the message * @param parameters optional formating parameters */ public void addSuccessMessage(String resourceKey, Object[] parameters) { String sMsg = retrieveMessage(resourceKey,parameters); addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO,sMsg,null)); } /** * Gets a message from a resource bundle. * @param resourceKey the resource key for the message * @return the message */ public FacesMessage getMessage(String resourceKey) { return getMessage(resourceKey,null); } /** * Gets a message from a resource bundle. * @param resourceKey the resource key for the message * @param parameters optional formating parameters * @return the message */ public FacesMessage getMessage(String resourceKey, Object[] parameters) { String sMsg = retrieveMessage(resourceKey,parameters); return new FacesMessage(sMsg); } /** * Gets locale. If locale is null, it will attempt to get it from the * jsf viewRoot * * @return locale */ public Locale getLocale() { Locale locale = null; UIViewRoot viewRoot = getContextBroker().extractViewRoot(); if (viewRoot != null) { locale = viewRoot.getLocale(); } if (locale == null) { locale = Locale.getDefault(); } return locale; } /** * Makes a resource bundle. Uses {@link #getLocale()} * @param bundleBasename the resource bundle base name * @return the resource bundle */ private ResourceBundle makeResourceBundle(String bundleBasename) { // determine the class loader ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader == null) { loader = ClassLoader.getSystemClassLoader(); } // determine the locale Locale locale = getLocale(); ResourceBundle bundle = ResourceBundle.getBundle(bundleBasename,locale,loader); return bundle; } /** * Makes an unfound UI resource string. * @param resourceKey the key for the resource * @return a string indicating an unfound UI resource ("???"+resourceKey) */ private String makeUnfoundResource(String resourceKey) { return "???"+Val.chkStr(resourceKey); } /** * Retrieves a message from a resource bundle. * @param resourceKey the resource key for the message * @return the message */ public String retrieveMessage(String resourceKey) { return retrieveMessage(resourceKey,null); } /** * Retrieves a message from a resource bundle. * @param resourceKey the resource key for the message * @param parameters optional formating parameters * @return the message */ public String retrieveMessage(String resourceKey, Object[] parameters) { String sResource = retrieveString(resourceKey,true); if (sResource.length() == 0) { sResource = makeUnfoundResource(resourceKey); } else if ((parameters != null) && (parameters.length > 0)) { //MessageFormat formatter = new MessageFormat(resource,locale); sResource = MessageFormat.format(sResource,parameters); } return sResource; } /** * Retrieves a resource string from a resource bundle. * @param resourceKey the resource key * @param checkPrefix if true, check to ensure that the key is properly prefixed * @return the resource string (zero-length if no match) */ private String retrieveString(String resourceKey, boolean checkPrefix) { String sResource = ""; try { resourceKey = Val.chkStr(resourceKey); if (checkPrefix && (resourceKey.length() > 0)) { if (!resourceKey.startsWith(getResourceKeyPrefix())) { if (!resourceKey.startsWith("fgdc.")) { resourceKey = getResourceKeyPrefix()+resourceKey; } } } ResourceBundle bundle = getBundle(); sResource = Val.chkStr(bundle.getString(resourceKey)); } catch (MissingResourceException mre) { sResource = ""; } catch (Exception e) { sResource = ""; } return sResource; } }