@SuppressWarnings("deprecation") public UIComponent processWidget( UIComponent component, String elementName, Map<String, String> attributes, UIMetawidget metawidget) { // Actions don't get converters if (ACTION.equals(elementName)) { return component; } // Recurse into stubs... if (component instanceof UIStub) { // ...whose children have the same value binding as us... // // (this is important because choice of Converter is based off the attributes Map, and // if the value binding is different then all bets are off as to the accuracy of the // attributes) javax.faces.el.ValueBinding valueBinding = component.getValueBinding("value"); if (valueBinding != null) { String expressionString = valueBinding.getExpressionString(); List<UIComponent> children = component.getChildren(); for (UIComponent componentChild : children) { javax.faces.el.ValueBinding childValueBinding = componentChild.getValueBinding("value"); if (childValueBinding == null) { continue; } if (!expressionString.equals(childValueBinding.getExpressionString())) { continue; } // ...and apply the Converter to them processWidget(componentChild, elementName, attributes, metawidget); } } return component; } // Ignore components that cannot have Converters if (!(component instanceof ValueHolder)) { return component; } // Defer evaluation of EL-based converters, else we will fail trying to store/restore them // from the ViewState ValueHolder valueHolder = (ValueHolder) component; String converterId = attributes.get(FACES_CONVERTER); if (converterId != null && FacesUtils.isExpression(converterId)) { FacesContext context = FacesContext.getCurrentInstance(); component.setValueBinding( "converter", context.getApplication().createValueBinding(converterId)); return component; } // Standard Converter valueHolder.setConverter(getConverter(valueHolder, attributes)); return component; }