com.sun.faces.util.Util Maven / Gradle / Ivy
Show all versions of javax.faces Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Util.java
package com.sun.faces.util;
import static com.sun.faces.util.RequestStateManager.INVOCATION_PATH;
import static java.util.Collections.emptyList;
import static java.util.logging.Level.FINE;
import java.beans.FeatureDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.el.ELResolver;
import javax.el.ValueExpression;
import javax.enterprise.inject.spi.BeanManager;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.ProjectStage;
import javax.faces.application.StateManager;
import javax.faces.application.ViewHandler;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.event.AbortProcessingException;
import javax.faces.render.ResponseStateManager;
import javax.faces.webapp.FacesServlet;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.validation.SchemaFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
import com.sun.faces.RIConstants;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.io.FastStringWriter;
/**
* Util is a class ...
*
* Lifetime And Scope
*
*/
public class Util {
// Log instance for this class
private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger();
// README - make sure to add the message identifier constant
// (ex: Util.CONVERSION_ERROR_MESSAGE_ID) and the number of substitution
// parameters to test/com/sun/faces/util/TestUtil_messages (see comment there).
/**
* Flag that, when true, enables special behavior in the RI to enable
* unit testing.
*/
private static boolean unitTestModeEnabled = false;
/**
* RegEx patterns
*/
private static final String patternCacheKey = RIConstants.FACES_PREFIX + "patternCache";
private static final String FACES_SERVLET_CLASS = FacesServlet.class.getName();
private Util() {
throw new IllegalStateException();
}
private static Map getPatternCache(Map appMap) {
@SuppressWarnings("unchecked")
Map result = (Map) appMap.get(patternCacheKey);
if (result == null) {
result = new LRUMap<>(15);
appMap.put(patternCacheKey, result);
}
return result;
}
private static Map getPatternCache(ServletContext sc) {
@SuppressWarnings("unchecked")
Map result = (Map) sc.getAttribute(patternCacheKey);
if (result == null) {
result = new LRUMap<>(15);
sc.setAttribute(patternCacheKey, result);
}
return result;
}
private static Collection getFacesServletMappings(ServletContext servletContext) {
ServletRegistration facesRegistration = getExistingFacesServletRegistration(servletContext);
if (facesRegistration != null) {
return facesRegistration.getMappings();
}
return emptyList();
}
private static ServletRegistration getExistingFacesServletRegistration(ServletContext servletContext) {
Map existing = servletContext.getServletRegistrations();
for (ServletRegistration registration : existing.values()) {
if (FACES_SERVLET_CLASS.equals(registration.getClassName())) {
return registration;
}
}
return null;
}
/**
*
* Convenience method for determining if the request associated
* with the specified FacesContext
is a PortletRequest
* submitted by the JSR-301 bridge.
*
* @param context the FacesContext
associated with
* the request.
*/
public static boolean isPortletRequest (FacesContext context) {
return context.getExternalContext().getRequestMap().get("javax.portlet.faces.phase") != null;
}
/**
* Factory method for creating the varius JSF listener
* instances that may be referenced by type
* or binding
.
* If binding
is not null
* and the evaluation result is not null
return
* that instance. Otherwise try to instantiate an instances
* based on type
.
*
* @param type the Listener
type
* @param binding a ValueExpression
which resolves
* to a Listener
instance
* @return a Listener
instance based off the provided
* type
and
*/
public static Object getListenerInstance(ValueExpression type,
ValueExpression binding) {
FacesContext faces = FacesContext.getCurrentInstance();
Object instance = null;
if (faces == null) {
return null;
}
if (binding != null) {
instance = binding.getValue(faces.getELContext());
}
if (instance == null && type != null) {
try {
instance = ReflectionUtils.newInstance(((String) type.getValue(faces.getELContext())));
} catch (InstantiationException | IllegalAccessException e) {
throw new AbortProcessingException(e.getMessage(), e);
}
if (binding != null) {
binding.setValue(faces.getELContext(), instance);
}
}
return instance;
}
public static void setUnitTestModeEnabled(boolean enabled) {
unitTestModeEnabled = enabled;
}
public static boolean isUnitTestModeEnabled() {
return unitTestModeEnabled;
}
public static TransformerFactory createTransformerFactory() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
TransformerFactory factory;
try {
Thread.currentThread().setContextClassLoader(Util.class.getClassLoader());
factory = TransformerFactory.newInstance();
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
return factory;
}
public static SAXParserFactory createSAXParserFactory() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
SAXParserFactory factory;
try {
Thread.currentThread().setContextClassLoader(Util.class.getClassLoader());
factory = SAXParserFactory.newInstance();
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
return factory;
}
public static DocumentBuilderFactory createDocumentBuilderFactory() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
DocumentBuilderFactory factory;
try {
Thread.currentThread().setContextClassLoader(Util.class.getClassLoader());
factory = DocumentBuilderFactory.newInstance();
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
return factory;
}
public static SchemaFactory createSchemaFactory(String uri) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
SchemaFactory factory;
try {
Thread.currentThread().setContextClassLoader(Util.class.getClassLoader());
factory = SchemaFactory.newInstance(uri);
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
return factory;
}
public static Class loadClass(String name,
Object fallbackClass)
throws ClassNotFoundException {
ClassLoader loader = Util.getCurrentLoader(fallbackClass);
String[] primitiveNames = { "byte", "short", "int", "long", "float", "double", "boolean", "char" };
Class[] primitiveClasses = { byte.class, short.class, int.class, long.class, float.class, double.class, boolean.class, char.class };
for(int i=0; i List reverse(List list) {
int length = list.size();
List result = new ArrayList<>(length);
for (int i = length - 1; i >= 0; i--) {
result.add(list.get(i));
}
return result;
}
/**
* Returns true
if the given string starts with one of the given prefixes.
*
* @param string The object to be checked if it starts with one of the given prefixes.
* @param prefixes The argument list of prefixes to be checked
*
* @return true
if the given string starts with one of the given prefixes.
*/
public static boolean startsWithOneOf(String string, String... prefixes) {
if (prefixes == null) {
return false;
}
for (String prefix : prefixes) {
if (string.startsWith(prefix)) {
return true;
}
}
return false;
}
/**
* @param context the FacesContext
for the current request
* @return the Locale from the UIViewRoot, the the value of Locale.getDefault()
*/
public static Locale getLocaleFromContextOrSystem(FacesContext context) {
Locale result, temp = Locale.getDefault();
UIViewRoot root;
result = temp;
if (null != context && null != (root = context.getViewRoot()) && null == (result = root.getLocale())) {
result = temp;
}
return result;
}
public static Converter getConverterForClass(Class converterClass,
FacesContext context) {
if (converterClass == null) {
return null;
}
try {
Application application = context.getApplication();
return (application.createConverter(converterClass));
} catch (Exception e) {
return (null);
}
}
public static Converter getConverterForIdentifer(String converterId,
FacesContext context) {
if (converterId == null) {
return null;
}
try {
Application application = context.getApplication();
return (application.createConverter(converterId));
} catch (Exception e) {
return (null);
}
}
public static StateManager getStateManager(FacesContext context)
throws FacesException {
return (context.getApplication().getStateManager());
}
public static Class getTypeFromString(String type) throws ClassNotFoundException {
Class result;
switch (type) {
case "byte":
result = Byte.TYPE;
break;
case "short":
result = Short.TYPE;
break;
case "int":
result = Integer.TYPE;
break;
case "long":
result = Long.TYPE;
break;
case "float":
result = Float.TYPE;
break;
case "double":
result = Double.TYPE;
break;
case "boolean":
result = Boolean.TYPE;
break;
case "char":
result = Character.TYPE;
break;
case "void":
result = Void.TYPE;
break;
default:
if (type.indexOf('.') == -1) {
type = "java.lang." + type;
} result = Util.loadClass(type, Void.TYPE);
break;
}
return result;
}
public static ViewHandler getViewHandler(FacesContext context)
throws FacesException {
// Get Application instance
Application application = context.getApplication();
assert (application != null);
// Get the ViewHandler
ViewHandler viewHandler = application.getViewHandler();
assert (viewHandler != null);
return viewHandler;
}
public static boolean componentIsDisabled(UIComponent component) {
return (Boolean.valueOf(String.valueOf(component.getAttributes().get("disabled"))));
}
public static boolean componentIsDisabledOrReadonly(UIComponent component) {
return Boolean.valueOf(String.valueOf(component.getAttributes().get("disabled"))) || Boolean.valueOf(String.valueOf(component.getAttributes().get("readonly")));
}
// W3C XML specification refers to IETF RFC 1766 for language code
// structure, therefore the value for the xml:lang attribute should
// be in the form of language or language-country or
// language-country-variant.
public static Locale getLocaleFromString(String localeStr)
throws IllegalArgumentException {
// length must be at least 2.
if (null == localeStr || localeStr.length() < 2) {
throw new IllegalArgumentException("Illegal locale String: " +
localeStr);
}
Locale result = null;
try {
Method method = Locale.class.getMethod("forLanguageTag", String.class);
if (method != null) {
result = (Locale) method.invoke(null, localeStr);
}
} catch(NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException throwable) {
// if we are NOT running JavaSE 7 we end up here and we will
// default to the previous way of determining the Locale below.
}
if (result == null || result.getLanguage().equals("")) {
String lang = null;
String country = null;
String variant = null;
char[] seps = {
'-',
'_'
};
int inputLength = localeStr.length();
int i = 0;
int j = 0;
// to have a language, the length must be >= 2
if ((inputLength >= 2) &&
((i = indexOfSet(localeStr, seps, 0)) == -1)) {
// we have only Language, no country or variant
if (2 != localeStr.length()) {
throw new
IllegalArgumentException("Illegal locale String: " +
localeStr);
}
lang = localeStr.toLowerCase();
}
// we have a separator, it must be either '-' or '_'
if (i != -1) {
lang = localeStr.substring(0, i);
// look for the country sep.
// to have a country, the length must be >= 5
if ((inputLength >= 5) &&
((j = indexOfSet(localeStr, seps, i + 1)) == -1)) {
// no further separators, length must be 5
if (inputLength != 5) {
throw new
IllegalArgumentException("Illegal locale String: " +
localeStr);
}
country = localeStr.substring(i + 1);
}
if (j != -1) {
country = localeStr.substring(i + 1, j);
// if we have enough separators for language, locale,
// and variant, the length must be >= 8.
if (inputLength >= 8) {
variant = localeStr.substring(j + 1);
} else {
throw new
IllegalArgumentException("Illegal locale String: " +
localeStr);
}
}
}
if (variant != null && country != null && lang != null) {
result = new Locale(lang, country, variant);
} else if (lang != null && country != null) {
result = new Locale(lang, country);
} else if (lang != null) {
result = new Locale(lang, "");
}
}
return result;
}
/**
* @param str local string
* @param set the substring
* @param fromIndex starting index
* @return starting at fromIndex
, the index of the
* first occurrence of any substring from set
in
* toSearch
, or -1 if no such match is found
*/
public static int indexOfSet(String str, char[] set, int fromIndex) {
int result = -1;
for (int i = fromIndex, len = str.length(); i < len; i++) {
for (int j = 0, innerLen = set.length; j < innerLen; j++) {
if (str.charAt(i) == set[j]) {
result = i;
break;
}
}
if (-1 != result) {
break;
}
}
return result;
}
/**
* Leverage the Throwable.getStackTrace() method to produce a String
* version of the stack trace, with a "\n" before each line.
*
* @param e the Throwable to obtain the stacktrace from
*
* @return the String representation ofthe stack trace obtained by calling
* getStackTrace() on the passed in exception. If null is passed
* in, we return the empty String.
*/
public static String getStackTraceString(Throwable e) {
if (null == e) {
return "";
}
StackTraceElement[] stacks = e.getStackTrace();
StringBuffer sb = new StringBuffer();
for (StackTraceElement stack : stacks) {
sb.append(stack.toString()).append('\n');
}
return sb.toString();
}
/**
* PRECONDITION: argument response
is non-null and
* has a method called getContentType
that takes no
* arguments and returns a String, with no side-effects.
*
* This method allows us to get the contentType in both the
* servlet and portlet cases, without introducing a compile-time
* dependency on the portlet api.
*
* @param response the current response
* @return the content type of the response
*/
public static String getContentTypeFromResponse(Object response) {
String result = null;
if (null != response) {
try {
Method method = ReflectionUtils.lookupMethod(
response.getClass(),
"getContentType",
RIConstants.EMPTY_CLASS_ARGS
);
if (null != method) {
Object obj =
method.invoke(response, RIConstants.EMPTY_METH_ARGS);
if (null != obj) {
result = obj.toString();
}
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new FacesException(e);
}
}
return result;
}
public static FeatureDescriptor getFeatureDescriptor(String name, String
displayName, String desc, boolean expert, boolean hidden,
boolean preferred, Object type, Boolean designTime) {
FeatureDescriptor fd = new FeatureDescriptor();
fd.setName(name);
fd.setDisplayName(displayName);
fd.setShortDescription(desc);
fd.setExpert(expert);
fd.setHidden(hidden);
fd.setPreferred(preferred);
fd.setValue(ELResolver.TYPE, type);
fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, designTime);
return fd;
}
/**
* A slightly more efficient version of
* String.split()
which caches
* the Pattern
s in an LRUMap instead of
* creating a new Pattern
on each
* invocation.
* @param appMap the Application Map
* @param toSplit the string to split
* @param regex the regex used for splitting
* @return the result of Pattern.spit(String, int)
*/
public synchronized static String[] split(Map appMap, String toSplit, String regex) {
Map patternCache = getPatternCache(appMap);
Pattern pattern = patternCache.get(regex);
if (pattern == null) {
pattern = Pattern.compile(regex);
patternCache.put(regex, pattern);
}
return pattern.split(toSplit, 0);
}
public synchronized static String[] split(ServletContext sc,
String toSplit, String regex) {
Map patternCache = getPatternCache(sc);
Pattern pattern = patternCache.get(regex);
if (pattern == null) {
pattern = Pattern.compile(regex);
patternCache.put(regex, pattern);
}
return pattern.split(toSplit, 0);
}
/**
* Returns the URL pattern of the
* {@link javax.faces.webapp.FacesServlet} that
* is executing the current request. If there are multiple
* URL patterns, the value returned by
* HttpServletRequest.getServletPath()
and
* HttpServletRequest.getPathInfo()
is
* used to determine which mapping to return.
* If no mapping can be determined, it most likely means
* that this particular request wasn't dispatched through
* the {@link javax.faces.webapp.FacesServlet}.
*
*
* NOTE: This method was supposed to be replaced with the "mapping API"
* from Servlet 4, but this has not been implemented in time for JSF 2.3
* to depend on.
*
* @param context the {@link FacesContext} of the current request
*
* @return the URL pattern of the {@link javax.faces.webapp.FacesServlet}
* or null
if no mapping can be determined
*
* @throws NullPointerException if context
is null
*/
public static String getFacesMapping(FacesContext context) {
notNull("context", context);
// Check for a previously stored mapping
String mapping = (String) RequestStateManager.get(context, INVOCATION_PATH);
if (mapping == null) {
// First check for javax.servlet.forward.servlet_path
// and javax.servlet.forward.path_info for non-null
// values. If either is non-null, use this
// information to generate determine the mapping.
ExternalContext externalContext = context.getExternalContext();
String servletPath = externalContext.getRequestServletPath();
String pathInfo = externalContext.getRequestPathInfo();
mapping = getMappingForRequest(externalContext, servletPath, pathInfo);
if (mapping == null && LOGGER.isLoggable(FINE)) {
LOGGER.log(FINE,
"jsf.faces_servlet_mapping_cannot_be_determined_error",
new Object[]{servletPath});
}
if (mapping != null) {
RequestStateManager.set(context, INVOCATION_PATH, mapping);
}
}
if (LOGGER.isLoggable(FINE)) {
LOGGER.log(FINE, "URL pattern of the FacesServlet executing the current request " + mapping);
}
return mapping;
}
/**
*
Return the appropriate {@link javax.faces.webapp.FacesServlet} mapping
* based on the servlet path of the current request.
*
* @param externalContext the external context of the request
* @param servletPath the servlet path of the request
* @param pathInfo the path info of the request
*
* @return the appropriate mapping based on the current request
*
* @see javax.servlet.http.HttpServletRequest#getServletPath()
*/
private static String getMappingForRequest(ExternalContext externalContext, String servletPath, String pathInfo) {
if (servletPath == null) {
return null;
}
if (LOGGER.isLoggable(FINE)) {
LOGGER.log(FINE, "servletPath " + servletPath);
LOGGER.log(FINE, "pathInfo " + pathInfo);
}
// If the path returned by HttpServletRequest.getServletPath()
// returns a zero-length String, then the FacesServlet has
// been mapped to '/*'.
if (servletPath.length() == 0) {
return "/*";
}
// Presence of path info means we were invoked using a prefix path mapping
if (pathInfo != null) {
return servletPath;
} else if (servletPath.indexOf('.') < 0) {
// If pathInfo is null and no '.' is present, the FacesServlet
// could be invoked using prefix path but without any pathInfo -
// i.e. GET /contextroot/faces or GET /contextroot/faces/
//
// It could also be that the FacesServlet is invoked using an
// exact mapping, i.e. GET /contextroot/foo
// Look at the Servlet mappings to see which case we have here:
Object context = externalContext.getContext();
if (context instanceof ServletContext) {
Collection servletMappings = getFacesServletMappings((ServletContext) context);
if (servletMappings.contains(servletPath)) {
return addExactMappedMarker(servletPath); // It's not ideal, to be replaced by Servlet 4 mapping API types
}
}
return servletPath;
} else {
// Servlet invoked using extension mapping
return servletPath.substring(servletPath.lastIndexOf('.'));
}
}
/**
* Checks if the FacesServlet is exact mapped to the given resource.
*
* Not to be confused with {@link Util#isExactMapped(String)}, which checks
* if a string representing a mapping, not a resource, is an exact mapping.
*
* This should be replaced by the Servlet 4 mapping API when/if that becomes available
* and JSF/Mojarra can depend on it.
*
* @param viewId the view id to test
* @return true if the FacesServlet is exact mapped to the given viewId, false otherwise
*/
public static boolean isViewIdExactMappedToFacesServlet(String viewId) {
return isResourceExactMappedToFacesServlet(FacesContext.getCurrentInstance().getExternalContext(), viewId);
}
/**
* Checks if the FacesServlet is exact mapped to the given resource.
*
* Not to be confused with {@link Util#isExactMapped(String)}, which checks
* if a string representing a mapping, not a resource, is an exact mapping.
*
* This should be replaced by the Servlet 4 mapping API when/if that becomes available
* and JSF/Mojarra can depend on it.
*
* @param externalContext the external context for this request
* @param resource the resource to test
* @return true if the FacesServlet is exact mapped to the given resource, false otherwise
*/
public static boolean isResourceExactMappedToFacesServlet(ExternalContext externalContext, String resource) {
Object context = externalContext.getContext();
if (context instanceof ServletContext) {
return getFacesServletMappings((ServletContext) context).contains(resource);
}
return false;
}
public static String getFirstWildCardMappingToFacesServlet(ExternalContext externalContext) {
// If needed, cache this after initialization of JSF
Object context = externalContext.getContext();
if (context instanceof ServletContext) {
return getFacesServletMappings((ServletContext) context)
.stream()
.filter(mapping -> mapping.contains("*"))
.findFirst()
.orElse(null);
}
return null;
}
private static final String EXACT_MARKER = "* *";
public static String addExactMappedMarker(String mapping) {
return EXACT_MARKER + mapping;
}
public static String removeExactMappedMarker(String mapping) {
return mapping.substring(EXACT_MARKER.length());
}
/**
*
Returns true if the provided url-mapping
is
* an exact mapping (starts with {@link Util#EXACT_MARKER}).
*
* @param mapping a url-pattern
* @return true if the mapping starts with /
*/
public static boolean isExactMapped(String mapping) {
return mapping.startsWith("* *");
}
/**
* Returns true if the provided url-mapping
is
* a prefix path mapping (starts with /
).
*
* @param mapping a url-pattern
* @return true if the mapping starts with /
*/
public static boolean isPrefixMapped(String mapping) {
return mapping.charAt(0) == '/';
}
public static boolean isSpecialAttributeName(String name) {
boolean isSpecialAttributeName = name.equals("action") ||
name.equals("actionListener") || name.equals("validator")
|| name.equals("valueChangeListener");
return isSpecialAttributeName;
}
/**
* @param ctx the {@link FacesContext} for the current request
* @param viewToRender the {@link UIViewRoot} to check
* @return true
if the {@link FacesContext} attributes map
* contains a reference to the {@link UIViewRoot}'s view ID
*/
public static boolean isViewPopulated(FacesContext ctx, UIViewRoot viewToRender) {
return ctx.getAttributes().containsKey(viewToRender);
}
/**
*
* Flag the specified {@link UIViewRoot} as populated.
*
* @param ctx the {@link FacesContext} for the current request
* @param viewToRender the {@link UIViewRoot} to mark as populated
*/
public static void setViewPopulated(FacesContext ctx,
UIViewRoot viewToRender) {
ctx.getAttributes().put(viewToRender, Boolean.TRUE);
}
/**
* Utility method to validate ID uniqueness for the tree represented
* by component
.
*/
public static void checkIdUniqueness(FacesContext context,
UIComponent component,
Set componentIds) {
boolean uniquenessCheckDisabled = false;
if (context.isProjectStage(ProjectStage.Production)) {
WebConfiguration config = WebConfiguration.getInstance(context.getExternalContext());
uniquenessCheckDisabled = config.isOptionEnabled(
WebConfiguration.BooleanWebContextInitParameter.DisableIdUniquenessCheck);
}
if (!uniquenessCheckDisabled) {
// deal with children/facets that are marked transient.
for (Iterator kids = component.getFacetsAndChildren();
kids.hasNext();) {
UIComponent kid = kids.next();
// check for id uniqueness
String id = kid.getClientId(context);
if (componentIds.add(id)) {
checkIdUniqueness(context, kid, componentIds);
} else {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE,
"jsf.duplicate_component_id_error",
id);
FastStringWriter writer = new FastStringWriter(128);
DebugUtil.simplePrintTree(context.getViewRoot(), id, writer);
LOGGER.severe(writer.toString());
}
String message =
MessageUtils.getExceptionMessageString(
MessageUtils.DUPLICATE_COMPONENT_ID_ERROR_ID, id);
throw new IllegalStateException(message);
}
}
}
}
static public boolean classHasAnnotations(Class> clazz) {
if (clazz != null) {
while (clazz != Object.class) {
Field[] fields = clazz.getDeclaredFields();
if (fields != null) {
for (Field field : fields) {
if (field.getAnnotations().length > 0) {
return true;
}
}
}
Method[] methods = clazz.getDeclaredMethods();
if (methods != null) {
for (Method method : methods) {
if (method.getDeclaredAnnotations().length > 0) {
return true;
}
}
}
clazz = clazz.getSuperclass();
}
}
return false;
}
/**
* If view root is instance of naming container, return its container client id, suffixed with separator character.
* @param context Involved faces context.
* @return The naming container prefix, or an empty string if the view root is not an instance of naming container.
*/
public static String getNamingContainerPrefix(FacesContext context) {
UIViewRoot viewRoot = context.getViewRoot();
if (viewRoot == null) {
Application application = context.getApplication();
viewRoot = (UIViewRoot) application.createComponent(UIViewRoot.COMPONENT_TYPE);
}
if (viewRoot instanceof NamingContainer) {
return viewRoot.getContainerClientId(context) + UINamingContainer.getSeparatorChar(context);
} else {
return "";
}
}
public static String getViewStateId(FacesContext context) {
String result = null;
final String viewStateCounterKey = "com.sun.faces.util.ViewStateCounterKey";
Map