Home » Mojarra-2.0.1 » javax » faces » component » [javadoc | source]

    1   /*
    2    * $Id: MessageFactory.java,v 1.15.4.1 2008/06/10 18:00:16 rlubke Exp $
    3    */
    4   
    5   /*
    6    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    7    * 
    8    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   package javax.faces.component;
   42   
   43   import javax.el.ValueExpression;
   44   import javax.faces.FactoryFinder;
   45   import javax.faces.application.Application;
   46   import javax.faces.application.ApplicationFactory;
   47   import javax.faces.application.FacesMessage;
   48   import javax.faces.component.UIComponent;
   49   import javax.faces.context.FacesContext;
   50   import javax.faces.el.ValueBinding;
   51   
   52   import java.text.MessageFormat;
   53   import java.util.Locale;
   54   import java.util.MissingResourceException;
   55   import java.util.ResourceBundle;
   56   
   57   /**
   58    * 
   59    * <p>supported filters: <code>package</code> and
   60    * <code>protection</code>.</p>
   61    */
   62   
   63    class MessageFactory {
   64   
   65       private static final String MOJARRA_RESOURCE_BASENAME =
   66           "com.sun.faces.resources.Messages";
   67   
   68       private MessageFactory() {
   69       }
   70   
   71       /**
   72        * @see #getMessage(String, Object...)
   73        * @param FacesMessage.Serverity set a custom severity
   74        */
   75        static FacesMessage getMessage(String messageId,
   76                                                   FacesMessage.Severity severity,
   77                                                   Object... params) {
   78           FacesMessage message = getMessage(messageId, params);
   79           message.setSeverity(severity);
   80           return message;
   81       }
   82   
   83   
   84       /**
   85        * @see #getMessage(Locale, String, Object...)
   86        * @param FacesMessage.Serverity set a custom severity
   87        */
   88        static FacesMessage getMessage(Locale locale,
   89                                                   String messageId,
   90                                                   FacesMessage.Severity severity,
   91                                                   Object... params) {
   92           FacesMessage message = getMessage(locale, messageId, params);
   93           message.setSeverity(severity);
   94           return message;
   95       }
   96   
   97   
   98       /**
   99        * @see #getMessage(FacesContext, String, Object...)
  100        * @param FacesMessage.Serverity set a custom severity
  101        */
  102        static FacesMessage getMessage(FacesContext context,
  103                                                   String messageId,
  104                                                   FacesMessage.Severity severity,
  105                                                   Object... params) {
  106           FacesMessage message = getMessage(context, messageId, params);
  107           message.setSeverity(severity);
  108           return message;
  109       }
  110   
  111      
  112       /**
  113        * <p>This version of getMessage() is used for localizing implementation
  114        * specific messages.</p>
  115        *
  116        * @param messageId - the key of the message in the resource bundle
  117        * @param params    - substittion parameters
  118        *
  119        * @return a localized <code>FacesMessage</code> with the severity
  120        *  of FacesMessage.SEVERITY_ERROR
  121        */
  122         static FacesMessage getMessage(String messageId, 
  123                                                    Object... params) {
  124           Locale locale = null;
  125           FacesContext context = FacesContext.getCurrentInstance();
  126           // context.getViewRoot() may not have been initialized at this point.
  127           if (context != null && context.getViewRoot() != null) {
  128               locale = context.getViewRoot().getLocale();
  129               if (locale == null) {
  130                   locale = Locale.getDefault();
  131               }
  132           } else {
  133               locale = Locale.getDefault();
  134           }
  135           
  136           return getMessage(locale, messageId, params);
  137       }
  138   
  139        /**
  140         * <p>Creates and returns a FacesMessage for the specified Locale.</p>
  141         *
  142         * @param locale    - the target <code>Locale</code>
  143         * @param messageId - the key of the message in the resource bundle
  144         * @param params    - substittion parameters
  145         *
  146         * @return a localized <code>FacesMessage</code> with the severity
  147         *  of FacesMessage.SEVERITY_ERROR
  148         */
  149         static FacesMessage getMessage(Locale locale, 
  150                                                    String messageId, 
  151                                                    Object... params) {       
  152           String summary = null;
  153           String detail = null;       
  154           ResourceBundle bundle;
  155           String bundleName;
  156   
  157           // see if we have a user-provided bundle
  158           if (null != (bundleName = getApplication().getMessageBundle())) {
  159               if (null != 
  160                   (bundle = 
  161                       ResourceBundle.getBundle(bundleName, locale,
  162                         getCurrentLoader(bundleName)))) {
  163                   // see if we have a hit
  164                   try {
  165                       summary = bundle.getString(messageId);
  166                       detail = bundle.getString(messageId + "_detail");
  167                   }
  168                   catch (MissingResourceException e) {
  169                       // ignore
  170                   }
  171               }
  172           }
  173       
  174           // we couldn't find a summary in the user-provided bundle
  175           if (null == summary) {
  176               // see if we have a summary in the app provided bundle
  177               bundle = ResourceBundle.getBundle(FacesMessage.FACES_MESSAGES, 
  178                                                 locale,
  179                                                 getCurrentLoader(bundleName));
  180               if (null == bundle) {
  181                   throw new NullPointerException();
  182               }
  183               // see if we have a hit
  184               try {
  185                   summary = bundle.getString(messageId);
  186                   detail = bundle.getString(messageId + "_detail");
  187               } catch (MissingResourceException e) {
  188                   // ignore
  189               }
  190           }
  191   
  192           // no hit found in the standard javax.faces.Messages bundle.
  193           // check the Mojarra resources
  194           if (summary == null) {
  195               // see if we have a summary in the app provided bundle
  196               bundle = ResourceBundle.getBundle(MOJARRA_RESOURCE_BASENAME,
  197                                                 locale,
  198                                                 getCurrentLoader(bundleName));
  199               if (null == bundle) {
  200                   throw new NullPointerException();
  201               }
  202               // see if we have a hit
  203               try {
  204                   summary = bundle.getString(messageId);
  205               } catch (MissingResourceException e) {
  206                   return null;
  207               }
  208           }
  209   
  210           // At this point, we have a summary and a bundle.     
  211           FacesMessage ret = new BindingFacesMessage(locale, summary, detail, params);
  212           ret.setSeverity(FacesMessage.SEVERITY_ERROR);
  213           return (ret);
  214       }
  215   
  216   
  217       /**
  218        * <p>Creates and returns a FacesMessage for the specified Locale.</p>
  219        *
  220        * @param context   - the <code>FacesContext</code> for the current request
  221        * @param messageId - the key of the message in the resource bundle
  222        * @param params    - substittion parameters
  223        *
  224        * @return a localized <code>FacesMessage</code> with the severity
  225        *  of FacesMessage.SEVERITY_ERROR
  226        */
  227        static FacesMessage getMessage(FacesContext context, 
  228                                                   String messageId,
  229                                                   Object... params) {
  230                                                   
  231           if (context == null || messageId == null ) {
  232               throw new NullPointerException(" context " 
  233                   + context 
  234                   + " messageId " 
  235                   + messageId);
  236           }
  237           Locale locale;
  238           // viewRoot may not have been initialized at this point.
  239           if (context.getViewRoot() != null) {
  240               locale = context.getViewRoot().getLocale();
  241           } else {
  242               locale = Locale.getDefault();
  243           }
  244           
  245           if (null == locale) {
  246               throw new NullPointerException(" locale is null ");
  247           }
  248           
  249           FacesMessage message = getMessage(locale, messageId, params);
  250           if (message != null) {
  251               return message;
  252           }
  253           locale = Locale.getDefault();
  254           return (getMessage(locale, messageId, params));
  255       }  
  256                          
  257   
  258       /**
  259        * <p>Returns the <code>label</code> property from the specified
  260        * component.</p>
  261        *
  262        * @param context   - the <code>FacesContext</code> for the current request
  263        * @param component - the component of interest
  264        *
  265        * @return the label, if any, of the component
  266        */
  267        static Object getLabel(FacesContext context, 
  268                                           UIComponent component) {
  269                                           
  270           Object o = component.getAttributes().get("label");
  271           if (o == null || (o instanceof String && ((String) o).length() == 0)) {
  272               o = component.getValueExpression("label");
  273           }
  274           // Use the "clientId" if there was no label specified.
  275           if (o == null) {
  276               o = component.getClientId(context);
  277           }
  278           return o;
  279       }
  280   
  281       protected static Application getApplication() {
  282           FacesContext context = FacesContext.getCurrentInstance();
  283           if (context != null) {
  284               return (FacesContext.getCurrentInstance().getApplication());
  285           }
  286           ApplicationFactory afactory = (ApplicationFactory)
  287               FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
  288           return (afactory.getApplication());
  289       }
  290   
  291       protected static ClassLoader getCurrentLoader(Object fallbackClass) {
  292           ClassLoader loader =
  293               Thread.currentThread().getContextClassLoader();
  294           if (loader == null) {
  295               loader = fallbackClass.getClass().getClassLoader();
  296           }
  297           return loader;
  298       }
  299   
  300       /**
  301        * This class overrides FacesMessage to provide the evaluation
  302        * of binding expressions in addition to Strings.
  303        * It is often the case, that a binding expression may reference
  304        * a localized property value that would be used as a 
  305        * substitution parameter in the message.  For example:
  306        *  <code>#{bundle.userLabel}</code>
  307        * "bundle" may not be available until the page is rendered.
  308        * The "late" binding evaluation in <code>getSummary</code> and 
  309        * <code>getDetail</code> allow the expression to be evaluated
  310        * when that property is available.
  311        */
  312       static class BindingFacesMessage extends FacesMessage {
  313           BindingFacesMessage(
  314               Locale locale,
  315               String messageFormat,
  316               String detailMessageFormat,
  317               // array of parameters, both Strings and ValueBindings
  318               Object[] parameters) {
  319   
  320               super(messageFormat, detailMessageFormat);
  321               this.locale = locale;
  322               this.parameters = parameters;
  323               if (parameters != null) {
  324                   resolvedParameters = new Object[parameters.length];
  325               }
  326           }
  327   
  328           public String getSummary() {
  329               String pattern = super.getSummary();
  330               resolveBindings();
  331               return getFormattedString(pattern, resolvedParameters);
  332           }
  333   
  334           public String getDetail() {
  335               String pattern = super.getDetail();
  336               resolveBindings();
  337               return getFormattedString(pattern, resolvedParameters);
  338           }
  339   
  340           private void resolveBindings() {
  341               FacesContext context = null;
  342               if (parameters != null) {
  343                   for (int i = 0; i < parameters.length; i++) {
  344                       Object o = parameters[i];
  345                       if (o instanceof ValueBinding) {
  346                           if (context == null) {
  347                               context = FacesContext.getCurrentInstance();
  348                           }
  349                           o = ((ValueBinding) o).getValue(context);
  350                       }
  351                       if (o instanceof ValueExpression) {
  352                           if (context == null) {
  353                               context = FacesContext.getCurrentInstance();
  354                           }
  355                           o = ((ValueExpression) o).getValue(context.getELContext());
  356                       }
  357                       // to avoid 'null' appearing in message
  358                       if (o == null) {
  359                           o = "";
  360                       }
  361                       resolvedParameters[i] = o;
  362                   }
  363               }
  364           }
  365   
  366           private String getFormattedString(String msgtext, Object[] params) {
  367               String localizedStr = null;
  368                                                                                   
  369               if (params == null || msgtext == null ) {
  370                   return msgtext;
  371               }
  372               StringBuffer b = new StringBuffer(100);
  373               MessageFormat mf = new MessageFormat(msgtext);
  374               if (locale != null) {
  375                   mf.setLocale(locale);
  376                   b.append(mf.format(params));
  377                   localizedStr = b.toString();
  378               }
  379               return localizedStr;
  380           }
  381   
  382           private Locale locale;
  383           private Object[] parameters;
  384           private Object[] resolvedParameters;
  385       }
  386       
  387   } // end of class MessageFactory

Home » Mojarra-2.0.1 » javax » faces » component » [javadoc | source]