public static Converter getItemConverter(FacesContext facesContext, UIComponent component) { Converter converter = null; if (component instanceof ValueHolder) { // If the component has an attached Converter, use it. converter = ((ValueHolder) component).getConverter(); if (converter != null) { return converter; } } // If not, look for a ValueExpression for value (if any). The ValueExpression must point to // something that is: ValueExpression ve = component.getValueExpression("value"); if (ve != null) { Class<?> valueType = ve.getType(facesContext.getELContext()); // An array of primitives (such as int[]). Look up the registered by-class Converter for this // primitive type. // An array of objects (such as Integer[] or String[]). Look up the registered by-class // Converter for the underlying element type. if (valueType != null && valueType.isArray()) { converter = facesContext.getApplication().createConverter(valueType); } // A java.util.Collection. Do not convert the values. } if (converter == null) { // Spec says "If for any reason a Converter cannot be found, assume the type to be a String // array." However // if we don't have an explicit converter, see if one is registered for the class of the // SelectItem values Iterator<SelectItem> selectItems = SelectUtils.getSelectItems(facesContext, component); converter = getSelectItemConverter(facesContext.getApplication(), selectItems); } return converter; }
protected Converter findImplicitConverter(FacesContext context, UIComponent component) { ValueExpression ve = component.getValueExpression("value"); if (ve != null) { Class<?> valueType = ve.getType(context.getELContext()); if (valueType != null) return context.getApplication().createConverter(valueType); } return null; }
public void processAction(ActionEvent e) throws AbortProcessingException { FacesContext facesContext = FacesContext.getCurrentInstance(); ELContext elContext = facesContext.getELContext(); try { Object value = source.getValue(elContext); if (value != null) { ExpressionFactory factory = facesContext.getApplication().getExpressionFactory(); value = factory.coerceToType(value, target.getType(elContext)); } target.setValue(elContext, value); } catch (ELException ele) { throw new AbortProcessingException(ele); } }
@Override public void submitValue(String expression, Object value) throws UnsupportedEvaluationException { FacesContext facesContext = getFacesContext(); ELContext elContext = facesContext.getELContext(); ValueExpression valueExpression = getValueExpression(facesContext, expression); Class<?> referencedType = valueExpression.getType(elContext); // the value that will be injected Object toInject = null; // the expression is referencing an array if (referencedType.isArray()) { // ensure the value that will be injected is an array if (value != null && !value.getClass().isArray()) { toInject = new Object[] {value}; } else { toInject = value; } } // expression is not referencing an array else { // if value to inject is an array, just use the first element if (value != null && value.getClass().isArray()) { Object[] valueAsArray = (Object[]) value; if (valueAsArray.length > 0) { toInject = valueAsArray[0]; } else { toInject = null; } } // simple case: neither the expression is referencing an array nor the value is one else { toInject = value; } } // set the value Object coercedValue = facesContext.getApplication().getExpressionFactory().coerceToType(toInject, referencedType); valueExpression.setValue(elContext, coercedValue); }
@Override public Class<?> getType(EvaluationContext ctx) throws ELException { VariableMapper varMapper = ctx.getVariableMapper(); if (varMapper != null) { ValueExpression expr = varMapper.resolveVariable(this.image); if (expr != null) { return expr.getType(ctx.getELContext()); } } ctx.setPropertyResolved(false); Class<?> result = ctx.getELResolver().getType(ctx, null, this.image); if (!ctx.isPropertyResolved()) { throw new PropertyNotFoundException( MessageFactory.get("error.resolver.unhandled.null", this.image)); } return result; }
/** * 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 * * <p>- If the component is not a value holder, toString of component is used to support Facelets * UIInstructions. * * @param facesContext FacesContext instance * @param component UIComponent instance whose value will be returned * @return End text */ public static String getStringValueToRender(FacesContext facesContext, UIComponent component) { if (component instanceof ValueHolder) { if (component instanceof EditableValueHolder) { Object submittedValue = ((EditableValueHolder) component).getSubmittedValue(); if (submittedValue != null) { return submittedValue.toString(); } } ValueHolder valueHolder = (ValueHolder) component; Object value = valueHolder.getValue(); if (value == null) return ""; // first ask the converter if (valueHolder.getConverter() != null) { return valueHolder.getConverter().getAsString(facesContext, component, value); } // Try to guess else { ValueExpression expr = component.getValueExpression("value"); if (expr != null) { Class<?> valueType = expr.getType(facesContext.getELContext()); if (valueType != null) { Converter converterForType = facesContext.getApplication().createConverter(valueType); if (converterForType != null) return converterForType.getAsString(facesContext, component, value); } } } // No converter found just return the value as string return value.toString(); } else { // This would get the plain texts on UIInstructions when using Facelets String value = component.toString(); if (value != null) return value.trim(); else return ""; } }
public Object getAsObject(FacesContext context, UIComponent comp, String value) throws ConverterException { ValueExpression expr = comp.getValueExpression("value"); Class enumType = expr == null ? null : expr.getType(context.getELContext()); if (enumType != null && enumType.isEnum()) { Enum result = null; try { result = Enum.valueOf(enumType, value); } catch (IllegalArgumentException ie) { // for noselection values } return result; } else { for (Object child : comp.getChildren()) { if (child instanceof UIComponent) { UIComponent c = (UIComponent) child; expr = c.getValueExpression("value"); Object val = expr == null ? null : expr.getValue(context.getELContext()); if (val == null) { throw new ConverterException("Cannot get items"); } Class t = val.getClass(); if (t.isArray() && t.getComponentType().isEnum()) { return Enum.valueOf(t.getComponentType(), value); } else if (val instanceof Collection) { Object firstItem = ((Collection) val).iterator().next(); if (firstItem instanceof Enum) { t = ((Enum) firstItem).getDeclaringClass(); } else { t = firstItem.getClass(); } return Enum.valueOf(t, value); } } } } throw new ConverterException("Unable to find selectItems with enum values."); }
/** * Resolves the end text to render by using a specified value * * @param facesContext FacesContext instance * @param component UIComponent instance whose value will be returned * @return End text */ public static String getStringValueToRender( FacesContext facesContext, UIComponent component, Object value) { if (value == null) return null; ValueHolder valueHolder = (ValueHolder) component; Converter converter = valueHolder.getConverter(); if (converter != null) { return converter.getAsString(facesContext, component, value); } else { ValueExpression expr = component.getValueExpression("value"); if (expr != null) { Class<?> valueType = expr.getType(facesContext.getELContext()); Converter converterForType = facesContext.getApplication().createConverter(valueType); if (converterForType != null) return converterForType.getAsString(facesContext, component, value); } } return value.toString(); }
@Override public Class<?> getType(ELContext context) { ELContext nxcontext = getLocalContext(context); // XXX should invoke first... return originalValueExpression.getType(nxcontext); }
public static Object getConvertedValue( FacesContext facesContext, UIComponent component, Object val) throws ConverterException { String[] values = (val == null) ? new String[0] : (String[]) val; Converter converter = SelectManyHelper.getItemConverter(facesContext, component); ValueExpression ve = component.getValueExpression("value"); Object targetForConvertedValues = null; if (ve != null) { // If the component has a ValueExpression for value, let modelType be the type of the value // expression Class<?> modelType = ve.getType(facesContext.getELContext()); if (modelType.isArray()) { // If the component has a ValueExpression for value and the type of the expression is an // array, let targetForConvertedValues be a new array of the expected type. Class<?> arrayComponentType = modelType.getComponentType(); targetForConvertedValues = Array.newInstance(arrayComponentType, values.length); } else if (Collection.class.isAssignableFrom(modelType) || Object.class.equals(modelType)) { // If modelType is a Collection, do the following to arrive at targetForConvertedValues: // Ask the component for its attribute under the key "collectionType" String collectionType = (String) component.getAttributes().get("collectionType"); if (collectionType != null) { // Let targetForConvertedValues be a new instance of Collection implemented by the // concrete class specified in collectionType Class<?> collectionClass = getCollectionClass(collectionType); try { targetForConvertedValues = collectionClass.newInstance(); } catch (Exception e) { throw new FacesException(e); } } else { // If there is no "collectionType" attribute, call getValue() on the component // The result will implement Collection. Collection value = (Collection) ((EditableValueHolder) component).getValue(); if (value instanceof Cloneable) { // If the result also implements Cloneable, let targetForConvertedValues be the result // of calling its clone() method, // then calling clear() on the cloned Collection. try { targetForConvertedValues = (Collection) value.getClass().getMethod("clone").invoke(value); ((Collection) targetForConvertedValues).clear(); } catch (Exception e) { // If unable to clone the value for any reason, log a message LOG.log(Logger.Level.WARNING, "Unable to clone collection"); } } if (targetForConvertedValues == null) { // and proceed to the next step Class<?> collectionClass = value == null ? modelType : value.getClass(); try { // If modelType is a concrete class, let targetForConvertedValues be a new instance of // that class. targetForConvertedValues = collectionClass.newInstance(); ((Collection) targetForConvertedValues).clear(); } catch (Exception e) { // Otherwise, the concrete type for targetForConvertedValues is taken from the // following table if (Collection.class.isAssignableFrom(modelType)) { if (SortedSet.class.isAssignableFrom(modelType)) { targetForConvertedValues = new TreeSet(); } else if (Queue.class.isAssignableFrom(modelType)) { targetForConvertedValues = new LinkedList(); } else if (Set.class.isAssignableFrom(modelType)) { targetForConvertedValues = new HashSet(values.length); } else { targetForConvertedValues = new ArrayList(values.length); } } } } } } else { throw new FacesException("ValueExpression must be either an Array, or a Collection"); } } else { // If the component does not have a ValueExpression for value, let targetForConvertedValues be // an array of type Object. targetForConvertedValues = new Object[values.length]; } for (int i = 0; i < values.length; i++) { Object value; if (converter == null) { value = values[i]; } else { value = converter.getAsObject(facesContext, component, values[i]); } if (targetForConvertedValues.getClass().isArray()) { Array.set(targetForConvertedValues, i, value); } else { ((Collection) targetForConvertedValues).add(value); } } return targetForConvertedValues; }