Save This Page
Home » mojarra-1.2_09-b02-FCS-source » com.sun.faces.util » [javadoc | source]
    1   /*
    2    * $Id: Util.java,v 1.216.4.4 2008/04/30 01:14:00 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   // Util.java
   42   
   43   package com.sun.faces.util;
   44   
   45   import com.sun.faces.RIConstants;
   46   
   47   import javax.el.ELResolver;
   48   import javax.el.ValueExpression;
   49   import javax.faces.FacesException;
   50   import javax.faces.application.Application;
   51   import javax.faces.application.StateManager;
   52   import javax.faces.application.ViewHandler;
   53   import javax.faces.component.UIComponent;
   54   import javax.faces.component.UIViewRoot;
   55   import javax.faces.context.ExternalContext;
   56   import javax.faces.context.FacesContext;
   57   import javax.faces.convert.Converter;
   58   import javax.faces.event.AbortProcessingException;
   59   import java.beans.FeatureDescriptor;
   60   import java.lang.reflect.Method;
   61   import java.util.Iterator;
   62   import java.util.Locale;
   63   import java.util.Map;
   64   import java.util.logging.Level;
   65   import java.util.logging.Logger;
   66   import java.util.regex.Pattern;
   67   
   68   /**
   69    * <B>Util</B> is a class ...
   70    * <p/>
   71    * <B>Lifetime And Scope</B> <P>
   72    *
   73    * @version $Id: Util.java,v 1.216.4.4 2008/04/30 01:14:00 rlubke Exp $
   74    */
   75   
   76   public class Util {
   77   
   78       
   79       // Log instance for this class
   80       private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger();
   81   
   82       // README - make sure to add the message identifier constant
   83       // (ex: Util.CONVERSION_ERROR_MESSAGE_ID) and the number of substitution
   84       // parameters to test/com/sun/faces/util/TestUtil_messages (see comment there).
   85    
   86       // Loggers
   87       public static final String RENDERKIT_LOGGER = ".renderkit";
   88       public static final String TAGLIB_LOGGER = ".taglib";
   89       public static final String APPLICATION_LOGGER = ".application";
   90       public static final String CONTEXT_LOGGER = ".context";
   91       public static final String CONFIG_LOGGER = ".config";
   92       public static final String LIFECYCLE_LOGGER = ".lifecycle";
   93       public static final String TIMING_LOGGER = ".timing";
   94   
   95       /**
   96        * Flag that, when true, enables special behavior in the RI to enable
   97        * unit testing.
   98        */
   99       private static boolean unitTestModeEnabled = false;
  100   
  101       /**
  102        * Flag that enables/disables the core TLV.
  103        */
  104       private static boolean coreTLVEnabled = true;
  105   
  106       /**
  107        * Flag that enables/disables the html TLV.
  108        */
  109       private static boolean htmlTLVEnabled = true;
  110       
  111       private static final Map<String,Pattern> patternCache = 
  112             new LRUMap<String,Pattern>(15);
  113   
  114   //
  115   // Instance Variables
  116   //
  117   
  118   // Attribute Instance Variables
  119   
  120   // Relationship Instance Variables
  121   
  122   //
  123   // Constructors and Initializers    
  124   //
  125   
  126       private Util() {
  127           throw new IllegalStateException();
  128       }
  129   
  130   //
  131   // Class methods
  132   //
  133   
  134       /**
  135        * <p>Factory method for creating the varius JSF listener
  136        *  instances that may be referenced by <code>type</code>
  137        *  or <code>binding</code>.</p>
  138        * <p>If <code>binding</code> is not <code>null</code>
  139        * and the evaluation result is not <code>null</code> return
  140        * that instance.  Otherwise try to instantiate an instances
  141        * based on <code>type</code>.</p>
  142        * 
  143        * @param type the <code>Listener</code> type
  144        * @param binding a <code>ValueExpression</code> which resolves
  145        *  to a <code>Listener</code> instance
  146        * @return a <code>Listener</code> instance based off the provided
  147        *  <code>type</code> and <binding>
  148        */
  149       public static Object getListenerInstance(ValueExpression type,
  150                                                ValueExpression binding) {
  151   
  152           FacesContext faces = FacesContext.getCurrentInstance();
  153           Object instance = null;
  154           if (faces == null) {
  155               return null;
  156           }
  157           if (binding != null) {
  158               instance = binding.getValue(faces.getELContext());
  159           }
  160           if (instance == null && type != null) {
  161               try {
  162                   instance = ReflectionUtils.newInstance(((String) type.getValue(faces.getELContext())));
  163               } catch (Exception e) {
  164                   throw new AbortProcessingException(e.getMessage(), e);
  165               }
  166   
  167               if (binding != null) {
  168                   binding.setValue(faces.getELContext(), instance);
  169               }
  170           }
  171   
  172           return instance;
  173   
  174       }
  175   
  176       public static void setUnitTestModeEnabled(boolean enabled) {
  177           unitTestModeEnabled = enabled;
  178       }
  179   
  180       public static boolean isUnitTestModeEnabled() {
  181           return unitTestModeEnabled;
  182       }
  183   
  184       public static void setCoreTLVActive(boolean active) {
  185           coreTLVEnabled = active;
  186       }
  187   
  188       public static boolean isCoreTLVActive() {
  189           return coreTLVEnabled;
  190       }
  191   
  192       public static void setHtmlTLVActive(boolean active) {
  193           htmlTLVEnabled = active;
  194       }
  195   
  196       public static boolean isHtmlTLVActive() {
  197           return htmlTLVEnabled;
  198       }
  199   
  200   
  201       public static Class loadClass(String name,
  202                                     Object fallbackClass)
  203           throws ClassNotFoundException {
  204           ClassLoader loader = Util.getCurrentLoader(fallbackClass);
  205           // Where to begin...
  206           // JDK 6 introduced CR 6434149 where one couldn't pass
  207           // in a literal for an array type ([Ljava.lang.String) and
  208           // get the Class representation using ClassLoader.loadClass().
  209           // It was recommended to use Class.forName(String, boolean, ClassLoader)
  210           // for all ClassLoading requests.
  211           // HOWEVER, when trying to eliminate the need for .groovy extensions
  212           // being specified in the faces-config.xml for Groovy-based artifacts,
  213           // by using a an adapter to the GroovyScriptEngine, I found that the class
  214           // instance was cached somewhere, so that no matter what change I made,
  215           // Class.forName() always returned the same instance.  I haven't been
  216           // able to determine why this happens in the appserver environment
  217           // as the same adapter in a standalone program works as one might expect.
  218           // So, for now, if the classname starts with '[', then use Class.forName()
  219           // to avoid CR 643419 and for all other cases, use ClassLoader.loadClass().
  220           if (name.charAt(0) == '[') {
  221               return Class.forName(name, true, loader);
  222           } else {
  223               return loader.loadClass(name);
  224           }
  225       }
  226   
  227   
  228       public static ClassLoader getCurrentLoader(Object fallbackClass) {
  229           ClassLoader loader =
  230               Thread.currentThread().getContextClassLoader();
  231           if (loader == null) {
  232               loader = fallbackClass.getClass().getClassLoader();
  233           }
  234           return loader;
  235       }
  236   
  237   
  238       public static void notNull(String varname, Object var) {
  239   
  240           if (var == null) {
  241               throw new NullPointerException(
  242                     MessageUtils.getExceptionMessageString(
  243                         MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, varname));
  244           }
  245           
  246       }
  247   
  248   
  249       /**
  250        * @param context the <code>FacesContext</code> for the current request
  251        * @return the Locale from the UIViewRoot, the the value of Locale.getDefault()
  252        */
  253       public static Locale getLocaleFromContextOrSystem(FacesContext context) {
  254           Locale result, temp = Locale.getDefault();
  255           UIViewRoot root;
  256           result = temp;
  257           if (null != context) {
  258               if (null != (root = context.getViewRoot())) {
  259                   if (null == (result = root.getLocale())) {
  260                       result = temp;
  261                   }
  262               }
  263           }
  264           return result;
  265       }
  266   
  267   
  268       public static Converter getConverterForClass(Class converterClass,
  269                                                    FacesContext context) {
  270           if (converterClass == null) {
  271               return null;
  272           }
  273           try {            
  274               Application application = context.getApplication();
  275               return (application.createConverter(converterClass));
  276           } catch (Exception e) {
  277               return (null);
  278           }
  279       }
  280   
  281   
  282       public static Converter getConverterForIdentifer(String converterId,
  283                                                        FacesContext context) {
  284           if (converterId == null) {
  285               return null;
  286           }
  287           try {            
  288               Application application = context.getApplication();
  289               return (application.createConverter(converterId));
  290           } catch (Exception e) {
  291               return (null);
  292           }
  293       }
  294   
  295   
  296       public static StateManager getStateManager(FacesContext context)
  297           throws FacesException {
  298           return (context.getApplication().getStateManager());
  299       }
  300   
  301   
  302       public static ViewHandler getViewHandler(FacesContext context)
  303           throws FacesException {
  304           // Get Application instance
  305           Application application = context.getApplication();
  306           assert (application != null);
  307   
  308           // Get the ViewHandler
  309           ViewHandler viewHandler = application.getViewHandler();
  310           assert (viewHandler != null);
  311   
  312           return viewHandler;
  313       }
  314   
  315   
  316       public static boolean componentIsDisabled(UIComponent component) {
  317   
  318           return (Boolean.valueOf(String.valueOf(component.getAttributes().get("disabled"))));
  319   
  320       }
  321   
  322   
  323       public static boolean componentIsDisabledOrReadonly(UIComponent component) {
  324           return Boolean.valueOf(String.valueOf(component.getAttributes().get("disabled"))) || Boolean.valueOf(String.valueOf(component.getAttributes().get("readonly")));
  325       }
  326   
  327   
  328       
  329   
  330       // W3C XML specification refers to IETF RFC 1766 for language code
  331       // structure, therefore the value for the xml:lang attribute should
  332       // be in the form of language or language-country or
  333       // language-country-variant.
  334   
  335       public static Locale getLocaleFromString(String localeStr)
  336           throws IllegalArgumentException {
  337           // length must be at least 2.
  338           if (null == localeStr || localeStr.length() < 2) {
  339               throw new IllegalArgumentException("Illegal locale String: " +
  340                                                  localeStr);
  341           }
  342   
  343           Locale result = null;
  344           String lang = null;
  345           String country = null;
  346           String variant = null;
  347           char[] seps = {
  348               '-',
  349               '_'
  350           };
  351           int i = 0;
  352           int j = 0;
  353           int inputLength = localeStr.length();
  354   
  355           // to have a language, the length must be >= 2
  356           if ((inputLength >= 2) &&
  357               ((i = indexOfSet(localeStr, seps, 0)) == -1)) {
  358               // we have only Language, no country or variant
  359               if (inputLength != 2) {
  360                   throw new
  361                       IllegalArgumentException("Illegal locale String: " +
  362                                                localeStr);
  363               }
  364               lang = localeStr.toLowerCase();
  365           }
  366   
  367           // we have a separator, it must be either '-' or '_'
  368           if (i != -1) {
  369               lang = localeStr.substring(0, i);
  370               // look for the country sep.
  371               // to have a country, the length must be >= 5
  372               if ((inputLength >= 5) &&
  373                   ((j = indexOfSet(localeStr, seps, i + 1)) == -1)) {
  374                   // no further separators, length must be 5
  375                   if (inputLength != 5) {
  376                       throw new
  377                           IllegalArgumentException("Illegal locale String: " +
  378                                                    localeStr);
  379                   }
  380                   country = localeStr.substring(i + 1);
  381               }
  382               if (j != -1) {
  383                   country = localeStr.substring(i + 1, j);
  384                   // if we have enough separators for language, locale,
  385                   // and variant, the length must be >= 8.
  386                   if (inputLength >= 8) {
  387                       variant = localeStr.substring(j + 1);
  388                   } else {
  389                       throw new
  390                           IllegalArgumentException("Illegal locale String: " +
  391                                                    localeStr);
  392                   }
  393               }
  394           }
  395           if (variant != null && country != null && lang != null) {
  396               result = new Locale(lang, country, variant);
  397           } else if (lang != null && country != null) {
  398               result = new Locale(lang, country);
  399           } else if (lang != null) {
  400               result = new Locale(lang, "");
  401           }
  402           return result;
  403       }
  404   
  405   
  406       /**
  407        * @param str local string
  408        * @param set the substring
  409        * @param fromIndex starting index
  410        * @return starting at <code>fromIndex</code>, the index of the
  411        *         first occurrence of any substring from <code>set</code> in
  412        *         <code>toSearch</code>, or -1 if no such match is found
  413        */
  414       public static int indexOfSet(String str, char[] set, int fromIndex) {
  415           int result = -1;
  416           for (int i = fromIndex, len = str.length(); i < len; i++) {
  417               for (int j = 0, innerLen = set.length; j < innerLen; j++) {
  418                   if (str.charAt(i) == set[j]) {
  419                       result = i;
  420                       break;
  421                   }
  422               }
  423               if (result != -1) {
  424                   break;
  425               }
  426           }
  427           return result;
  428       }
  429   
  430   
  431       public static void parameterNonNull(Object param) throws FacesException {
  432           if (null == param) {
  433               throw new FacesException(
  434                   MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "param"));
  435           }
  436       }
  437   
  438   
  439       public static void parameterNonEmpty(String param) throws FacesException {
  440           if (null == param || 0 == param.length()) {
  441               throw new FacesException(MessageUtils.getExceptionMessageString(MessageUtils.EMPTY_PARAMETER_ID));
  442           }
  443       }
  444   
  445       /**
  446        * <p>Leverage the Throwable.getStackTrace() method to produce a String
  447        * version of the stack trace, with a "\n" before each line.</p>
  448        *
  449        * @param e the Throwable to obtain the stacktrace from
  450        *
  451        * @return the String representation ofthe stack trace obtained by calling
  452        *         getStackTrace() on the passed in exception.  If null is passed
  453        *         in, we return the empty String.
  454        */
  455       public static String getStackTraceString(Throwable e) {
  456           if (null == e) {
  457               return "";
  458           }
  459   
  460           StackTraceElement[] stacks = e.getStackTrace();
  461           StringBuffer sb = new StringBuffer();
  462           for (int i = 0; i < stacks.length; i++) {
  463               sb.append(stacks[i].toString()).append('\n');
  464           }
  465           return sb.toString();
  466       }
  467   
  468       /**
  469        * <p>PRECONDITION: argument <code>response</code> is non-null and
  470        * has a method called <code>getContentType</code> that takes no
  471        * arguments and returns a String, with no side-effects.</p>
  472        *
  473        * <p>This method allows us to get the contentType in both the
  474        * servlet and portlet cases, without introducing a compile-time
  475        * dependency on the portlet api.</p>
  476        *
  477        * @param response the current response
  478        * @return the content type of the response
  479        */
  480       public static String getContentTypeFromResponse(Object response) {
  481           String result = null;
  482           if (null != response) {           
  483   
  484               try {
  485                   Method method = ReflectionUtils.lookupMethod(
  486                         response.getClass(),
  487                         "getContentType",
  488                         RIConstants.EMPTY_CLASS_ARGS
  489                   );
  490                   if (null != method) {
  491                       Object obj =
  492                             method.invoke(response, RIConstants.EMPTY_METH_ARGS);
  493                       if (null != obj) {
  494                           result = obj.toString();
  495                       }
  496                   }
  497               } catch (Exception e) {
  498                   throw new FacesException(e);
  499               }
  500           }
  501           return result;
  502       }
  503   
  504       public static boolean prefixViewTraversal(FacesContext context,
  505                                                 UIComponent root,
  506                                                 TreeTraversalCallback action)
  507       throws FacesException {
  508           boolean keepGoing;
  509           if (keepGoing = action.takeActionOnNode(context, root)) {
  510               Iterator<UIComponent> kids = root.getFacetsAndChildren();
  511               while (kids.hasNext() && keepGoing) {
  512                   keepGoing = prefixViewTraversal(context,
  513                                                   kids.next(),
  514                                                   action);
  515               }
  516           }
  517           return keepGoing;
  518       }
  519   
  520       public static interface TreeTraversalCallback {
  521   	public boolean takeActionOnNode(FacesContext context, 
  522   					UIComponent curNode) throws FacesException;
  523       }
  524       
  525       public static FeatureDescriptor getFeatureDescriptor(String name, String
  526           displayName, String desc, boolean expert, boolean hidden, 
  527           boolean preferred, Object type, Boolean designTime) {
  528               
  529           FeatureDescriptor fd = new FeatureDescriptor();
  530           fd.setName(name);
  531           fd.setDisplayName(displayName);
  532           fd.setShortDescription(desc);
  533           fd.setExpert(expert);
  534           fd.setHidden(hidden);
  535           fd.setPreferred(preferred);
  536           fd.setValue(ELResolver.TYPE, type);
  537           fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, designTime);
  538           return fd;
  539       }
  540      
  541   
  542       /**
  543        * <p>A slightly more efficient version of 
  544        * <code>String.split()</code> which caches
  545        * the <code>Pattern</code>s in an LRUMap instead of
  546        * creating a new <code>Pattern</code> on each
  547        * invocation.</p>
  548        * @param toSplit the string to split
  549        * @param regex the regex used for splitting
  550        * @return the result of <code>Pattern.spit(String, int)</code>
  551        */
  552       public synchronized static String[] split(String toSplit, String regex) {
  553           Pattern pattern = patternCache.get(regex);
  554           if (pattern == null) {
  555               pattern = Pattern.compile(regex);
  556               patternCache.put(regex, pattern);
  557           }
  558           return pattern.split(toSplit, 0);
  559       }
  560   
  561   
  562       /**
  563        * <p>Returns the URL pattern of the
  564        * {@link javax.faces.webapp.FacesServlet} that
  565        * is executing the current request.  If there are multiple
  566        * URL patterns, the value returned by
  567        * <code>HttpServletRequest.getServletPath()</code> and
  568        * <code>HttpServletRequest.getPathInfo()</code> is
  569        * used to determine which mapping to return.</p>
  570        * If no mapping can be determined, it most likely means
  571        * that this particular request wasn't dispatched through
  572        * the {@link javax.faces.webapp.FacesServlet}.
  573        *
  574        * @param context the {@link FacesContext} of the current request
  575        *
  576        * @return the URL pattern of the {@link javax.faces.webapp.FacesServlet}
  577        *         or <code>null</code> if no mapping can be determined
  578        *
  579        * @throws NullPointerException if <code>context</code> is null
  580        */
  581       public static String getFacesMapping(FacesContext context) {
  582   
  583           if (context == null) {
  584               String message = MessageUtils.getExceptionMessageString
  585                     (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "context");
  586               throw new NullPointerException(message);
  587           }
  588   
  589           // Check for a previously stored mapping   
  590           ExternalContext extContext = context.getExternalContext();
  591           String mapping =
  592                 (String) RequestStateManager.get(context, RequestStateManager.INVOCATION_PATH);
  593   
  594           if (mapping == null) {
  595            
  596               // first check for javax.servlet.forward.servlet_path
  597               // and javax.servlet.forward.path_info for non-null
  598               // values.  if either is non-null, use this
  599               // information to generate determine the mapping.
  600   
  601               String servletPath = extContext.getRequestServletPath();
  602               String pathInfo = extContext.getRequestPathInfo();
  603   
  604               mapping = getMappingForRequest(servletPath, pathInfo);
  605               if (mapping == null) {
  606                   if (LOGGER.isLoggable(Level.FINE)) {
  607                       LOGGER.log(Level.FINE,
  608                                  "jsf.faces_servlet_mapping_cannot_be_determined_error",
  609                                  new Object[]{servletPath});
  610                   }
  611               }
  612           }
  613           
  614           // if the FacesServlet is mapped to /* throw an 
  615           // Exception in order to prevent an endless 
  616           // RequestDispatcher loop
  617           //if ("/*".equals(mapping)) {
  618           //    throw new FacesException(MessageUtils.getExceptionMessageString(
  619           //          MessageUtils.FACES_SERVLET_MAPPING_INCORRECT_ID));
  620           //}
  621   
  622           if (mapping != null) {
  623               RequestStateManager.set(context,
  624                                       RequestStateManager.INVOCATION_PATH,
  625                                       mapping);
  626           }
  627           if (LOGGER.isLoggable(Level.FINE)) {
  628               LOGGER.log(Level.FINE,
  629                          "URL pattern of the FacesServlet executing the current request "
  630                          + mapping);
  631           }
  632           return mapping;
  633       }
  634   
  635       /**
  636        * <p>Return the appropriate {@link javax.faces.webapp.FacesServlet} mapping
  637        * based on the servlet path of the current request.</p>
  638        *
  639        * @param servletPath the servlet path of the request
  640        * @param pathInfo    the path info of the request
  641        *
  642        * @return the appropriate mapping based on the current request
  643        *
  644        * @see javax.servlet.http.HttpServletRequest#getServletPath()
  645        */
  646       private static String getMappingForRequest(String servletPath, String pathInfo) {
  647   
  648           if (servletPath == null) {
  649               return null;
  650           }
  651           if (LOGGER.isLoggable(Level.FINE)) {
  652               LOGGER.log(Level.FINE, "servletPath " + servletPath);
  653               LOGGER.log(Level.FINE, "pathInfo " + pathInfo);
  654           }
  655           // If the path returned by HttpServletRequest.getServletPath()
  656           // returns a zero-length String, then the FacesServlet has
  657           // been mapped to '/*'.
  658           if (servletPath.length() == 0) {
  659               return "/*";
  660           }
  661   
  662           // presence of path info means we were invoked
  663           // using a prefix path mapping
  664           if (pathInfo != null) {
  665               return servletPath;
  666           } else if (servletPath.indexOf('.') < 0) {
  667               // if pathInfo is null and no '.' is present, assume the
  668               // FacesServlet was invoked using prefix path but without
  669               // any pathInfo - i.e. GET /contextroot/faces or
  670               // GET /contextroot/faces/
  671               return servletPath;
  672           } else {
  673               // Servlet invoked using extension mapping
  674               return servletPath.substring(servletPath.lastIndexOf('.'));
  675           }
  676       }
  677       
  678       
  679       /**
  680        * <p>Returns true if the provided <code>url-mapping</code> is
  681        * a prefix path mapping (starts with <code>/</code>).</p>
  682        *
  683        * @param mapping a <code>url-pattern</code>
  684        * @return true if the mapping starts with <code>/</code>
  685        */
  686       public static boolean isPrefixMapped(String mapping) {
  687           return (mapping.charAt(0) == '/');
  688       }
  689   
  690   
  691   } // end of class Util

Save This Page
Home » mojarra-1.2_09-b02-FCS-source » com.sun.faces.util » [javadoc | source]