All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.primefaces.util.ComponentUtils Maven / Gradle / Ivy

Go to download

PrimeFaces is one of the most popular UI libraries in Java EE Ecosystem and widely used by software companies, world renowned brands, banks, financial institutions, insurance companies, universities and more.

There is a newer version: 14.0.0-RC3
Show newest version
/**
 * Copyright 2009-2018 PrimeTek.
 *
 * Licensed 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 org.primefaces.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.FacesWrapper;
import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
import javax.faces.application.ResourceHandler;
import javax.faces.component.*;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitHint;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.render.Renderer;
import org.primefaces.component.api.RTLAware;
import org.primefaces.component.api.Widget;
import org.primefaces.config.PrimeConfiguration;
import org.primefaces.context.RequestContext;
import org.primefaces.expression.SearchExpressionUtils;

public class ComponentUtils {

    public static final EnumSet VISIT_HINTS_SKIP_UNRENDERED = EnumSet.of(VisitHint.SKIP_UNRENDERED);

    public static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";

    private static final String SB_ESCAPE = ComponentUtils.class.getName() + "#escape";

    // marker for a undefined value when a null check is not reliable enough
    private static final Object UNDEFINED_VALUE = new Object();
    
    private static final Pattern PATTERN_NEW_LINE = Pattern.compile("(\r\n|\n\r|\r|\n)");

    public static String getValueToRender(FacesContext context, UIComponent component) {
        return getValueToRender(context, component, UNDEFINED_VALUE);
    }

    /**
     * Algorithm works as follows;
     * - If it's an input component, submitted value is checked first since it'd be the value to be used in case validation errors
     * terminates jsf lifecycle
     * - Finally the value of the component is retrieved from backing bean and if there's a converter, converted value is returned
     *
     * @param context       FacesContext instance
     * @param component     UIComponent instance whose value will be returned
     * @param value         The value of UIComponent if already evaluated outside. E.g. in the renderer.
     * @return              End text
     */
    public static String getValueToRender(FacesContext context, UIComponent component, Object value) {
        if (component instanceof ValueHolder) {

            if (component instanceof EditableValueHolder) {
                EditableValueHolder input = (EditableValueHolder) component;
                Object submittedValue = input.getSubmittedValue();
                PrimeConfiguration config = RequestContext.getCurrentInstance(context).getApplicationContext().getConfig();

                if (config.isInterpretEmptyStringAsNull()
                        && submittedValue == null
                        && !input.isLocalValueSet()
                        && context.isValidationFailed()
                        && !input.isValid()) {
                    return null;
                }
                else if (submittedValue != null) {
                    return submittedValue.toString();
                }
            }

            ValueHolder valueHolder = (ValueHolder) component;
            if (value == UNDEFINED_VALUE) {
                value = valueHolder.getValue();
            }

            //format the value as string
            if (value != null) {
                Converter converter = valueHolder.getConverter();
                if (converter == null) {
                    Class valueType = value.getClass();
                    if (valueType == String.class
                            && !RequestContext.getCurrentInstance(context).getApplicationContext().getConfig().isStringConverterAvailable()) {
                        return (String) value;
                    }

                    converter = context.getApplication().createConverter(valueType);
                }

                if (converter != null) {
                    return converter.getAsString(context, component, value);
                }
                else {
                    return value.toString();    //Use toString as a fallback if there is no explicit or implicit converter
                }
            }
            else {
                //component is a value holder but has no value
                return null;
            }
        }

        //component it not a value holder
        return null;
    }

    /**
     * Finds appropriate converter for a given value holder
     *
     * @param context   FacesContext instance
     * @param component ValueHolder instance to look converter for
     * @return          Converter
     */
    public static Converter getConverter(FacesContext context, UIComponent component) {
        if (!(component instanceof ValueHolder)) {
            return null;
        }

        Converter converter = ((ValueHolder) component).getConverter();
        if (converter != null) {
            return converter;
        }

        ValueExpression valueExpression = component.getValueExpression("value");
        if (valueExpression == null) {
            return null;
        }

        Class converterType = valueExpression.getType(context.getELContext());
        if (converterType == null || converterType == Object.class) {
            // no conversion is needed
            return null;
        }

        if (converterType == String.class
                && !RequestContext.getCurrentInstance(context).getApplicationContext().getConfig().isStringConverterAvailable()) {
            return null;
        }

        return context.getApplication().createConverter(converterType);
    }

    // used by p:component - don't remove!
    @Deprecated
    public static String findComponentClientId(String id) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UIComponent component = ComponentTraversalUtils.firstWithId(id, facesContext.getViewRoot());

        return component.getClientId(facesContext);
    }

    public static String escapeSelector(String selector) {
        return selector.replaceAll(":", "\\\\\\\\:");
    }

    @Deprecated
    public static String resolveWidgetVar(String expression) {
        return resolveWidgetVar(expression, FacesContext.getCurrentInstance().getViewRoot());
    }

    @Deprecated
    public static String resolveWidgetVar(String expression, UIComponent component) {
        return SearchExpressionUtils.resolveWidgetVar(expression, component);
    }

    

    public static boolean isValueBlank(String value) {
        if (value == null) {
            return true;
        }

        return value.trim().equals("");
    }

    public static boolean isRTL(FacesContext context, RTLAware component) {
        boolean globalValue = RequestContext.getCurrentInstance(context).isRTL();

        return globalValue || component.isRTL();
    }

    public static void processDecodesOfFacetsAndChilds(UIComponent component, FacesContext context) {
        if (component.getFacetCount() > 0) {
            for (UIComponent facet : component.getFacets().values()) {
                facet.processDecodes(context);
            }
        }

        if (component.getChildCount() > 0) {
            for (int i = 0, childCount = component.getChildCount(); i < childCount; i++) {
                UIComponent child = component.getChildren().get(i);
                child.processDecodes(context);
            }
        }
    }

    public static void processValidatorsOfFacetsAndChilds(UIComponent component, FacesContext context) {
        if (component.getFacetCount() > 0) {
            for (UIComponent facet : component.getFacets().values()) {
                facet.processValidators(context);
            }
        }

        if (component.getChildCount() > 0) {
            for (int i = 0, childCount = component.getChildCount(); i < childCount; i++) {
                UIComponent child = component.getChildren().get(i);
                child.processValidators(context);
            }
        }
    }

    public static void processUpdatesOfFacetsAndChilds(UIComponent component, FacesContext context) {
        if (component.getFacetCount() > 0) {
            for (UIComponent facet : component.getFacets().values()) {
                facet.processUpdates(context);
            }
        }

        if (component.getChildCount() > 0) {
            for (int i = 0, childCount = component.getChildCount(); i < childCount; i++) {
                UIComponent child = component.getChildren().get(i);
                child.processUpdates(context);
            }
        }
    }

    public static NavigationCase findNavigationCase(FacesContext context, String outcome) {
        ConfigurableNavigationHandler navHandler = (ConfigurableNavigationHandler) context.getApplication().getNavigationHandler();
        String outcomeValue = (outcome == null) ? context.getViewRoot().getViewId() : outcome;

        return navHandler.getNavigationCase(context, null, outcomeValue);
    }

    public static Map> getUIParams(UIComponent component) {
        List children = component.getChildren();
        Map> params = null;

        if (children != null && children.size() > 0) {
            params = new LinkedHashMap>();

            for (UIComponent child : children) {
                if (child.isRendered() && (child instanceof UIParameter)) {
                    UIParameter uiParam = (UIParameter) child;

                    if (!uiParam.isDisable()) {
                        List paramValues = params.get(uiParam.getName());
                        if (paramValues == null) {
                            paramValues = new ArrayList();
                            params.put(uiParam.getName(), paramValues);
                        }

                        paramValues.add(String.valueOf(uiParam.getValue()));
                    }
                }
            }
        }

        return params;
    }

    public static String getResourceURL(FacesContext context, String value) {
        if (isValueBlank(value)) {
            return Constants.EMPTY_STRING;
        }
        else if (value.contains(ResourceHandler.RESOURCE_IDENTIFIER)) {
            return value;
        }
        else {
            String url = context.getApplication().getViewHandler().getResourceURL(context, value);

            return context.getExternalContext().encodeResourceURL(url);
        }
    }

    public static boolean isSkipIteration(VisitContext visitContext, FacesContext context) {
        if (RequestContext.getCurrentInstance(context).getApplicationContext().getConfig().isAtLeastJSF21()) {
            return visitContext.getHints().contains(VisitHint.SKIP_ITERATION);
        }
        else {
            Boolean skipIterationHint = (Boolean) visitContext.getFacesContext().getAttributes().get(SKIP_ITERATION_HINT);
            return skipIterationHint != null && skipIterationHint.booleanValue() == true;
        }
    }

    public static String resolveWidgetVar(FacesContext context, Widget widget) {
        UIComponent component = (UIComponent) widget;
        String userWidgetVar = (String) component.getAttributes().get("widgetVar");

        if (!isValueBlank(userWidgetVar)) {
            return userWidgetVar;
        }
        else {
            return "widget_" + component.getClientId(context).replaceAll("-|" + UINamingContainer.getSeparatorChar(context), "_");
        }
    }

    

    public static String replaceNewLineWithHtml(String text) {
        if (text == null) {
            return null;
        }

        Matcher match = PATTERN_NEW_LINE.matcher(text);
        if (match.find()) {
            return match.replaceAll("
"); } return text; } /** * Duplicate code from json-simple project under apache license * http://code.google.com/p/json-simple/source/browse/trunk/src/org/json/simple/JSONValue.java */ public static String escapeText(String text) { if (text == null) { return null; } StringBuilder sb = SharedStringBuilder.get(SB_ESCAPE); for (int i = 0; i < text.length(); i++) { char ch = text.charAt(i); switch (ch) { case '"': sb.append("\\\""); break; case '\\': sb.append("\\\\"); break; case '\b': sb.append("\\b"); break; case '\f': sb.append("\\f"); break; case '\n': sb.append("\\n"); break; case '\r': sb.append("\\r"); break; case '\t': sb.append("\\t"); break; case '/': sb.append("\\/"); break; default: //Reference: http://www.unicode.org/versions/Unicode5.1.0/ if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) { String ss = Integer.toHexString(ch); sb.append("\\u"); for (int k = 0; k < 4 - ss.length(); k++) { sb.append('0'); } sb.append(ss.toUpperCase()); } else { sb.append(ch); } } } return sb.toString(); } public static String escapeEcmaScriptText(String text) { if (text == null) { return null; } StringBuilder sb = SharedStringBuilder.get(SB_ESCAPE); for (int i = 0; i < text.length(); i++) { char ch = text.charAt(i); switch (ch) { case '"': sb.append("\\\""); break; case '\'': sb.append("\\'"); break; case '\\': sb.append("\\\\"); break; case '/': sb.append("\\/"); break; default: sb.append(ch); break; } } return sb.toString(); } /** * Replace special characters with XML escapes: *
     * & (ampersand) is replaced by &amp;
     * < (less than) is replaced by &lt;
     * > (greater than) is replaced by &gt;
     * " (double quote) is replaced by &quot;
     * 
* * @param string The string to be escaped. * @return The escaped string. */ public static String escapeXml(String string) { StringBuilder sb = SharedStringBuilder.get(SB_ESCAPE, string.length()); for (int i = 0, length = string.length(); i < length; i++) { char c = string.charAt(i); switch (c) { case '&': sb.append("&"); break; case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '\'': sb.append("'"); break; default: sb.append(c); } } return sb.toString(); } /** * Use {@link ComponentTraversalUtils#closestForm(javax.faces.context.FacesContext, javax.faces.component.UIComponent)} instead. * * @param context * @param component * @return * @deprecated */ @Deprecated public static UIComponent findParentForm(FacesContext context, UIComponent component) { return ComponentTraversalUtils.closestForm(context, component); } /** * Gets a {@link TimeZone} instance by the parameter "timeZone" which can be String or {@link TimeZone} or null. * * @param timeZone given time zone * @return resolved TimeZone */ public static TimeZone resolveTimeZone(Object timeZone) { if (timeZone instanceof String) { return TimeZone.getTimeZone((String) timeZone); } else if (timeZone instanceof TimeZone) { return (TimeZone) timeZone; } else { return TimeZone.getDefault(); } } public static T getUnwrappedRenderer(FacesContext context, String family, String rendererType, Class rendererClass) { Renderer renderer = context.getRenderKit().getRenderer(family, rendererType); while (renderer instanceof FacesWrapper) { renderer = (Renderer) ((FacesWrapper) renderer).getWrapped(); } return (T) renderer; } /** * Calculates the current viewId - we can't get it from the ViewRoot if it's not available. * * @param context The {@link FacesContext}. * @return The current viewId. */ public static String calculateViewId(FacesContext context) { Map requestMap = context.getExternalContext().getRequestMap(); String viewId = (String) requestMap.get("javax.servlet.include.path_info"); if (viewId == null) { viewId = context.getExternalContext().getRequestPathInfo(); } if (viewId == null) { viewId = (String) requestMap.get("javax.servlet.include.servlet_path"); } if (viewId == null) { viewId = context.getExternalContext().getRequestServletPath(); } return viewId; } /** * Duplicate code from OmniFacew project under apache license: * https://github.com/omnifaces/omnifaces/blob/develop/license.txt *

* URI-encode the given string using UTF-8. URIs (paths and filenames) have different encoding rules as compared to * URL query string parameters. {@link URLEncoder} is actually only for www (HTML) form based query string parameter * values (as used when a webbrowser submits a HTML form). URI encoding has a lot in common with URL encoding, but * the space has to be %20 and some chars doesn't necessarily need to be encoded. * @param string The string to be URI-encoded using UTF-8. * @return The given string, URI-encoded using UTF-8, or null if null was given. * @throws UnsupportedEncodingException if UTF-8 is not supported */ public static String encodeURI(String string) throws UnsupportedEncodingException { if (string == null) { return null; } return URLEncoder.encode(string, "UTF-8") .replace("+", "%20") .replace("%21", "!") .replace("%27", "'") .replace("%28", "(") .replace("%29", ")") .replace("%7E", "~"); } /** * Creates an RFC 6266 Content-Dispostion header following all UTF-8 conventions. *

* @param value e.g. "attachment" * @param filename the name of the file * @return a valid Content-Disposition header in UTF-8 format */ public static String createContentDisposition(String value, String filename) { try { return String.format("%s;filename=\"%2$s\"; filename*=UTF-8''%2$s", value, encodeURI(filename)); } catch (UnsupportedEncodingException e) { throw new FacesException(e); } } public static boolean isRequestSource(UIComponent component, FacesContext context) { return component.getClientId(context).equals(context.getExternalContext().getRequestParameterMap().get(Constants.RequestParams.PARTIAL_SOURCE_PARAM)); } /** * Checks if the facet and one of the first level child's is rendered. * @param facet The Facet component to check * @return true when facet and one of the first level child's is rendered. */ public static boolean shouldRenderFacet(UIComponent facet) { if (!facet.isRendered()) { // For any future version of JSF where the f:facet gets a rendered attribute (https://github.com/javaserverfaces/mojarra/issues/4299) // or there is only 1 child. return false; } // Facet contains only 1 child, which is rendered due to previous test. if (facet.getChildren().isEmpty()) { return true; } for (int i = 0; i < facet.getChildren().size(); i++) { // Stop when a child who is rendered is found. if (facet.getChildren().get(i).isRendered()) { return true; } } return false; } public static boolean equals(Object object1, Object object2) { if (object1 == object2) { return true; } if ((object1 == null) || (object2 == null)) { return false; } return object1.equals(object2); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy