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

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

There is a newer version: 14.0.0-RC3
Show newest version
/*
 * Copyright 2009-2014 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.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.el.ValueExpression;
import javax.faces.FacesException;
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 org.primefaces.component.api.RTLAware;
import org.primefaces.component.api.Widget;
import org.primefaces.config.ConfigContainer;
import org.primefaces.context.RequestContext;
import org.primefaces.expression.SearchExpressionFacade;

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_TEXT = ComponentUtils.class.getName() + "#escapeText";

    /**
     * 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
     * @return					End text
     */
    public static String getValueToRender(FacesContext context, UIComponent component) {
        if (component instanceof ValueHolder) {

            if (component instanceof EditableValueHolder) {
                EditableValueHolder input = (EditableValueHolder) component;
                Object submittedValue = input.getSubmittedValue();
                ConfigContainer config = RequestContext.getCurrentInstance().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;
            Object 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().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().getApplicationContext().getConfig().isStringConverterAvailable()) {
        	return null;
        }

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

    // used by p:component
    public static String findComponentClientId(String id) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UIComponent component = findComponent(facesContext.getViewRoot(), id);

        return component.getClientId(facesContext);
    }

    private static UIComponent findComponent(UIComponent base, String id) {
        if (id.equals(base.getId()))
          return base;

        UIComponent kid = null;
        UIComponent result = null;
        Iterator kids = base.getFacetsAndChildren();
        while (kids.hasNext() && (result == null)) {
          kid = (UIComponent) kids.next();
          if (id.equals(kid.getId())) {
            result = kid;
            break;
          }
          result = findComponent(kid, id);
          if (result != null) {
            break;
          }
        }
        return result;
    }

    public static UIComponent findParentForm(FacesContext context, UIComponent component) {
        UIComponent parent = component.getParent();

        while(parent != null) {
            if(parent instanceof UIForm) {
                return parent;
            }

            parent = parent.getParent();
        }

        return null;
    }

    public static UniqueIdVendor findParentUniqueIdVendor(UIComponent component) {
        UIComponent parent = component.getParent();

        while(parent != null) {
            if(parent instanceof UniqueIdVendor) {
                return (UniqueIdVendor) parent;
            }

            parent = parent.getParent();
        }

        return null;
    }

    public static UIComponent findParentNamingContainer(UIComponent component) {
        UIComponent parent = component.getParent();

        while(parent != null) {
            if(parent instanceof NamingContainer) {
                return (UIComponent) parent;
            }

            parent = parent.getParent();
        }

        return null;
    }

    public static String escapeJQueryId(String id) {
        return "#" + id.replaceAll(":", "\\\\\\\\:");
    }

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

    public static String resolveWidgetVar(String expression, UIComponent component) {
    	UIComponent resolvedComponent = SearchExpressionFacade.resolveComponent(
    			FacesContext.getCurrentInstance(),
    			component,
    			expression);

        if(resolvedComponent instanceof Widget) {
            return "PF('" + ((Widget) resolvedComponent).resolveWidgetVar() + "')";
        } else {
            throw new FacesException("Component with clientId " + resolvedComponent.getClientId() + " is not a Widget");
        }
    }

    /**
     * Implementation from Apache Commons Lang
     */
    public static Locale toLocale(String str) {
        if(str == null) {
            return null;
        }
        int len = str.length();
        if(len != 2 && len != 5 && len < 7) {
            throw new IllegalArgumentException("Invalid locale format: " + str);
        }
        char ch0 = str.charAt(0);
        char ch1 = str.charAt(1);
        if(ch0 < 'a' || ch0 > 'z' || ch1 < 'a' || ch1 > 'z') {
            throw new IllegalArgumentException("Invalid locale format: " + str);
        }
        if(len == 2) {
            return new Locale(str, "");
        } else {
            if(str.charAt(2) != '_') {
                throw new IllegalArgumentException("Invalid locale format: " + str);
            }
            char ch3 = str.charAt(3);
            if(ch3 == '_') {
                return new Locale(str.substring(0, 2), "", str.substring(4));
            }
            char ch4 = str.charAt(4);
            if(ch3 < 'A' || ch3 > 'Z' || ch4 < 'A' || ch4 > 'Z') {
                throw new IllegalArgumentException("Invalid locale format: " + str);
            }
            if(len == 5) {
                return new Locale(str.substring(0, 2), str.substring(3, 5));
            } else {
                if(str.charAt(5) != '_') {
                    throw new IllegalArgumentException("Invalid locale format: " + str);
                }
                return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
            }
        }
    }

    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().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) {
        if (RequestContext.getCurrentInstance().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 (userWidgetVar != null) {
            return userWidgetVar;
        }
        else {
            return "widget_" + component.getClientId(context).replaceAll("-|" + UINamingContainer.getSeparatorChar(context), "_");
        }
    }

    /**
     * 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_TEXT);

        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();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy