/* * Hibernate Validator, declare and validate application constraints * * License: Apache License, Version 2.0 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>. */ package org.hibernate.validator.internal.engine.messageinterpolation.el; import java.beans.FeatureDescriptor; import java.util.IllegalFormatException; import java.util.Iterator; import javax.el.ELContext; import javax.el.ELException; import javax.el.ELResolver; import javax.el.PropertyNotWritableException; import org.hibernate.validator.internal.engine.messageinterpolation.FormatterWrapper; /** * @author Hardy Ferentschik * @author Guillaume Smet */ public class RootResolver extends ELResolver { /** * Name under which to bind a formatter to the EL context. */ public static final String FORMATTER = "formatter"; private static final String FORMAT = "format"; @Override public Class<?> getCommonPropertyType(ELContext context, Object base) { return null; } @Override public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) { return null; } @Override public Class<?> getType(ELContext context, Object base, Object property) { return null; } @Override public Object getValue(ELContext context, Object base, Object property) { return null; } @Override public boolean isReadOnly(ELContext context, Object base, Object property) { return true; } @Override public void setValue(ELContext context, Object base, Object property, Object value) { throw new PropertyNotWritableException(); } @Override public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) { if ( !( base instanceof FormatterWrapper ) ) { return null; } // due to bugs in most EL implementations when it comes to evaluating varargs we take care of the formatter call // ourselves. return evaluateFormatExpression( context, method, params ); } private Object evaluateFormatExpression(ELContext context, Object method, Object[] params) { if ( !FORMAT.equals( method ) ) { throw new ELException( "Wrong method name 'formatter#" + method + "' does not exist. Only formatter#format is supported." ); } if ( params.length == 0 ) { throw new ELException( "Invalid number of arguments to Formatter#format" ); } if ( !( params[0] instanceof String ) ) { throw new ELException( "The first argument to Formatter#format must be String" ); } FormatterWrapper formatterWrapper = (FormatterWrapper) context.getVariableMapper() .resolveVariable( FORMATTER ) .getValue( context ); Object[] formattingParameters = new Object[params.length - 1]; System.arraycopy( params, 1, formattingParameters, 0, params.length - 1 ); Object returnValue; try { returnValue = formatterWrapper.format( (String) params[0], formattingParameters ); context.setPropertyResolved( true ); } catch (IllegalFormatException e) { throw new ELException( "Error in Formatter#format call", e ); } return returnValue; } }