/** * Converts a value to plain text {@link String}, even if the {@link TemplateValueFormat} involved normally produces * markup. This should be used rarely, where the user clearly intend to use the plain text variant of the format. * * @param seqTip * Tip to display if the value type is not coercable, but it's sequence or collection. * * @return Never {@code null} */ static String coerceModelToPlainText(TemplateModel tm, Expression exp, String seqTip, Environment env) throws TemplateException { if (tm instanceof TemplateNumberModel) { return assertFormatResultNotNull(env.formatNumberToPlainText((TemplateNumberModel) tm, exp, false)); } else if (tm instanceof TemplateDateModel) { return assertFormatResultNotNull(env.formatDateToPlainText((TemplateDateModel) tm, exp, false)); } else { return coerceModelToTextualCommon(tm, exp, seqTip, false, false, env); } }
/** * @param seqTip Tip to display if the value type is not coercable, but it's sequence or collection. */ String evalAndCoerceToPlainText(Environment env, String seqTip) throws TemplateException { return EvalUtil.coerceModelToPlainText(eval(env), this, seqTip, env); }
throws TemplateModelException, TemplateException, NonStringException { if (leftModel instanceof TemplateNumberModel && rightModel instanceof TemplateNumberModel) { Number first = EvalUtil.modelToNumber((TemplateNumberModel) leftModel, leftExp); Number second = EvalUtil.modelToNumber((TemplateNumberModel) rightModel, rightExp); return _evalOnNumbers(env, parent, first, second); } else if (leftModel instanceof TemplateSequenceModel && rightModel instanceof TemplateSequenceModel) { Object leftOMOrStr = EvalUtil.coerceModelToStringOrMarkup( Object rightOMOrStr = EvalUtil.coerceModelToStringOrMarkup( } else { // rightOMOrStr instanceof TemplateMarkupOutputModel TemplateMarkupOutputModel<?> rightMO = (TemplateMarkupOutputModel<?>) rightOMOrStr; return EvalUtil.concatMarkupOutputs(parent, rightMO.getOutputFormat().fromPlainTextByEscaping((String) leftOMOrStr), rightMO); TemplateMarkupOutputModel<?> leftMO = (TemplateMarkupOutputModel<?>) leftOMOrStr; if (rightOMOrStr instanceof String) { // markup output return EvalUtil.concatMarkupOutputs(parent, leftMO, leftMO.getOutputFormat().fromPlainTextByEscaping((String) rightOMOrStr)); } else { // rightOMOrStr instanceof TemplateMarkupOutputModel return EvalUtil.concatMarkupOutputs(parent, leftMO, (TemplateMarkupOutputModel<?>) rightOMOrStr);
/** * @param blamedDateSourceExp * The blamed expression if an error occurs; only used for error messages. * @param blamedFormatterExp * The blamed expression if an error occurs; only used for error messages. */ String formatDateToPlainText(TemplateDateModel tdm, String formatString, Expression blamedDateSourceExp, Expression blamedFormatterExp, boolean useTempModelExc) throws TemplateException { Date date = EvalUtil.modelToDate(tdm, blamedDateSourceExp); TemplateDateFormat format = getTemplateDateFormat( formatString, tdm.getDateType(), date.getClass(), blamedDateSourceExp, blamedFormatterExp, useTempModelExc); try { return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(tdm)); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatDateException(format, blamedDateSourceExp, e, useTempModelExc); } }
TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false); try { return ensureFormatResultString(format.format(tnm), exp, env); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatNumberException(format, exp, e, false); TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false); try { return ensureFormatResultString(format.format(tdm), exp, env); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatDateException(format, exp, e, false); return coerceModelToTextualCommon(tm, exp, seqTip, false, false, env);
Number leftNum = EvalUtil.modelToNumber((TemplateNumberModel) leftValue, leftExp); Number rightNum = EvalUtil.modelToNumber((TemplateNumberModel) rightValue, rightExp); ArithmeticEngine ae = env != null Date leftDate = EvalUtil.modelToDate(leftDateModel, leftExp); Date rightDate = EvalUtil.modelToDate(rightDateModel, rightExp); cmpResult = leftDate.compareTo(rightDate); } else if (leftValue instanceof TemplateScalarModel && rightValue instanceof TemplateScalarModel) { if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) { throw new _MiscTemplateException(defaultBlamed, env, "Can't use operator \"", cmpOpToString(operator, operatorString), "\" on string values."); String leftString = EvalUtil.modelToString((TemplateScalarModel) leftValue, leftExp, env); String rightString = EvalUtil.modelToString((TemplateScalarModel) rightValue, rightExp, env); if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) { throw new _MiscTemplateException(defaultBlamed, env, "Can't use operator \"", cmpOpToString(operator, operatorString), "\" on boolean values.");
/** * Compares two {@link TemplateModel}-s according the rules of the FTL "==" operator. * * @since 2.3.20 */ public boolean applyEqualsOperator(TemplateModel leftValue, TemplateModel rightValue) throws TemplateException { return EvalUtil.compare(leftValue, EvalUtil.CMP_OP_EQUALS, rightValue, this); }
/** * Converts a value to plain text {@link String}, or a {@link TemplateMarkupOutputModel} if that's what the * {@link TemplateValueFormat} involved produces. * * @param seqTip * Tip to display if the value type is not coercable, but it's sequence or collection. * * @return Never {@code null} * @throws TemplateException */ static Object coerceModelToStringOrMarkup(TemplateModel tm, Expression exp, String seqTip, Environment env) throws TemplateException { return coerceModelToStringOrMarkup(tm, exp, false, seqTip, env); }
/** * Format number with the number format specified as the parameter, with the current locale. * * @param exp * The blamed expression if an error occurs; it's only needed for better error messages */ String formatNumberToPlainText( TemplateNumberModel number, TemplateNumberFormat format, Expression exp, boolean useTempModelExc) throws TemplateException { try { return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(number)); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatNumberException(format, exp, e, useTempModelExc); } }
/** * @param seqTip Tip to display if the value type is not coercable, but it's sequence or collection. */ String evalAndCoerceToStringOrUnsupportedMarkup(Environment env, String seqTip) throws TemplateException { return EvalUtil.coerceModelToStringOrUnsupportedMarkup(eval(env), this, seqTip, env); }
/** * Compares two {@link TemplateModel}-s according the rules of the FTL "==" operator, except that if the two types * are incompatible, they are treated as non-equal instead of throwing an exception. Comparing dates of different * types (date-only VS time-only VS date-time) will still throw an exception, however. * * @since 2.3.20 */ public boolean applyEqualsOperatorLenient(TemplateModel leftValue, TemplateModel rightValue) throws TemplateException { return EvalUtil.compareLenient(leftValue, EvalUtil.CMP_OP_EQUALS, rightValue, this); }
? markupResult.getOutputFormat().fromPlainTextByEscaping((String) calcedPart) : (TemplateMarkupOutputModel<?>) calcedPart; markupResult = EvalUtil.concatMarkupOutputs(this, markupResult, partMO); } else { // We are using `plainTextOutput` (or nothing yet) if (calcedPart instanceof String) { TemplateMarkupOutputModel<?> leftHandMO = moPart.getOutputFormat() .fromPlainTextByEscaping(plainTextResult.toString()); markupResult = EvalUtil.concatMarkupOutputs(this, leftHandMO, moPart); plainTextResult = null; } else {
Number leftNum = EvalUtil.modelToNumber((TemplateNumberModel) leftValue, leftExp); Number rightNum = EvalUtil.modelToNumber((TemplateNumberModel) rightValue, rightExp); ArithmeticEngine ae = env != null Date leftDate = EvalUtil.modelToDate(leftDateModel, leftExp); Date rightDate = EvalUtil.modelToDate(rightDateModel, rightExp); cmpResult = leftDate.compareTo(rightDate); } else if (leftValue instanceof TemplateScalarModel && rightValue instanceof TemplateScalarModel) { if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) { throw new _MiscTemplateException(defaultBlamed, env, "Can't use operator \"", cmpOpToString(operator, operatorString), "\" on string values."); String leftString = EvalUtil.modelToString((TemplateScalarModel) leftValue, leftExp, env); String rightString = EvalUtil.modelToString((TemplateScalarModel) rightValue, rightExp, env); if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) { throw new _MiscTemplateException(defaultBlamed, env, "Can't use operator \"", cmpOpToString(operator, operatorString), "\" on boolean values.");
/** * Compares two {@link TemplateModel}-s according the rules of the FTL "<" operator. * * @since 2.3.20 */ public boolean applyLessThanOperator(TemplateModel leftValue, TemplateModel rightValue) throws TemplateException { return EvalUtil.compare(leftValue, EvalUtil.CMP_OP_LESS_THAN, rightValue, this); }
@Override protected Object calculateInterpolatedStringOrMarkup(Environment env) throws TemplateException { return EvalUtil.coerceModelToStringOrMarkup(escapedExpression.eval(env), escapedExpression, null, env); }
/** * @param tdmSourceExpr * The blamed expression if an error occurs; only used for error messages. */ String formatDateToPlainText(TemplateDateModel tdm, Expression tdmSourceExpr, boolean useTempModelExc) throws TemplateException { TemplateDateFormat format = getTemplateDateFormat(tdm, tdmSourceExpr, useTempModelExc); try { return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(tdm)); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatDateException(format, tdmSourceExpr, e, useTempModelExc); } }
/** * @param blamedDateSourceExp * The blamed expression if an error occurs; only used for error messages. * @param blamedFormatterExp * The blamed expression if an error occurs; only used for error messages. */ String formatDateToPlainText(TemplateDateModel tdm, String formatString, Expression blamedDateSourceExp, Expression blamedFormatterExp, boolean useTempModelExc) throws TemplateException { Date date = EvalUtil.modelToDate(tdm, blamedDateSourceExp); TemplateDateFormat format = getTemplateDateFormat( formatString, tdm.getDateType(), date.getClass(), blamedDateSourceExp, blamedFormatterExp, useTempModelExc); try { return EvalUtil.assertFormatResultNotNull(format.formatToPlainText(tdm)); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatDateException(format, blamedDateSourceExp, e, useTempModelExc); } }
TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false); try { return ensureFormatResultString(format.format(tnm), exp, env); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatNumberException(format, exp, e, false); TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false); try { return ensureFormatResultString(format.format(tdm), exp, env); } catch (TemplateValueFormatException e) { throw _MessageUtil.newCantFormatDateException(format, exp, e, false); return coerceModelToTextualCommon(tm, exp, seqTip, false, false, env);
String evalAndCoerceToStringOrUnsupportedMarkup(Environment env) throws TemplateException { return EvalUtil.coerceModelToStringOrUnsupportedMarkup(eval(env), this, null, env); }
/** * Compares two {@link TemplateModel}-s according the rules of the FTL "==" operator, except that if the two types * are incompatible, they are treated as non-equal instead of throwing an exception. Comparing dates of different * types (date-only VS time-only VS date-time) will still throw an exception, however. * * @since 2.3.20 */ public boolean applyEqualsOperatorLenient(TemplateModel leftValue, TemplateModel rightValue) throws TemplateException { return EvalUtil.compareLenient(leftValue, EvalUtil.CMP_OP_EQUALS, rightValue, this); }