http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtil.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtil.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtil.java deleted file mode 100644 index 727085f..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtil.java +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.freemarker.core; - -import java.util.Date; - -import org.apache.freemarker.core.arithmetic.ArithmeticEngine; -import org.apache.freemarker.core.arithmetic.impl.BigDecimalArithmeticEngine; -import org.apache.freemarker.core.model.TemplateBooleanModel; -import org.apache.freemarker.core.model.TemplateCollectionModel; -import org.apache.freemarker.core.model.TemplateDateModel; -import org.apache.freemarker.core.model.TemplateMarkupOutputModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateNumberModel; -import org.apache.freemarker.core.model.TemplateScalarModel; -import org.apache.freemarker.core.model.TemplateSequenceModel; -import org.apache.freemarker.core.outputformat.MarkupOutputFormat; -import org.apache.freemarker.core.util.BugException; -import org.apache.freemarker.core.valueformat.TemplateDateFormat; -import org.apache.freemarker.core.valueformat.TemplateNumberFormat; -import org.apache.freemarker.core.valueformat.TemplateValueFormat; -import org.apache.freemarker.core.valueformat.TemplateValueFormatException; - -/** - * Internally used static utilities for evaluation expressions. - */ -public class _EvalUtil { - static final int CMP_OP_EQUALS = 1; - static final int CMP_OP_NOT_EQUALS = 2; - static final int CMP_OP_LESS_THAN = 3; - static final int CMP_OP_GREATER_THAN = 4; - static final int CMP_OP_LESS_THAN_EQUALS = 5; - static final int CMP_OP_GREATER_THAN_EQUALS = 6; - // If you add a new operator here, update the "compare" and "cmpOpToString" methods! - - // Prevents instantination. - private _EvalUtil() { } - - /** - * @param expr {@code null} is allowed, but may results in less helpful error messages - * @param env {@code null} is allowed - */ - static String modelToString(TemplateScalarModel model, ASTExpression expr, Environment env) - throws TemplateModelException { - String value = model.getAsString(); - if (value == null) { - throw newModelHasStoredNullException(String.class, model, expr); - } - return value; - } - - /** - * @param expr {@code null} is allowed, but may results in less helpful error messages - */ - static Number modelToNumber(TemplateNumberModel model, ASTExpression expr) - throws TemplateModelException { - Number value = model.getAsNumber(); - if (value == null) throw newModelHasStoredNullException(Number.class, model, expr); - return value; - } - - /** - * @param expr {@code null} is allowed, but may results in less helpful error messages - */ - static Date modelToDate(TemplateDateModel model, ASTExpression expr) - throws TemplateModelException { - Date value = model.getAsDate(); - if (value == null) throw newModelHasStoredNullException(Date.class, model, expr); - return value; - } - - /** Signals the buggy case where we have a non-null model, but it wraps a null. */ - public static TemplateModelException newModelHasStoredNullException( - Class expected, TemplateModel model, ASTExpression expr) { - return new _TemplateModelException(expr, - _TemplateModelException.modelHasStoredNullDescription(expected, model)); - } - - /** - * Compares two expressions according the rules of the FTL comparator operators. - * - * @param leftExp not {@code null} - * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}. - * @param operatorString can be null {@code null}; the actual operator used, used for more accurate error message. - * @param rightExp not {@code null} - * @param env {@code null} is tolerated, but should be avoided - */ - static boolean compare( - ASTExpression leftExp, - int operator, String operatorString, - ASTExpression rightExp, - ASTExpression defaultBlamed, - Environment env) throws TemplateException { - TemplateModel ltm = leftExp.eval(env); - TemplateModel rtm = rightExp.eval(env); - return compare( - ltm, leftExp, - operator, operatorString, - rtm, rightExp, - defaultBlamed, false, - false, false, false, - env); - } - - /** - * Compares values according the rules of the FTL comparator operators; if the {@link ASTExpression}-s are - * accessible, use {@link #compare(ASTExpression, int, String, ASTExpression, ASTExpression, Environment)} instead, - * as that gives better error messages. - * - * @param leftValue maybe {@code null}, which will usually cause the appropriate {@link TemplateException}. - * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}. - * @param rightValue maybe {@code null}, which will usually cause the appropriate {@link TemplateException}. - * @param env {@code null} is tolerated, but should be avoided - */ - static boolean compare( - TemplateModel leftValue, int operator, TemplateModel rightValue, - Environment env) throws TemplateException { - return compare( - leftValue, null, - operator, null, - rightValue, null, - null, false, - false, false, false, - env); - } - - /** - * Same as {@link #compare(TemplateModel, int, TemplateModel, Environment)}, but if the two types are incompatible, - * they are treated as non-equal instead of throwing an exception. Comparing dates of different types will - * still throw an exception, however. - */ - static boolean compareLenient( - TemplateModel leftValue, int operator, TemplateModel rightValue, - Environment env) throws TemplateException { - return compare( - leftValue, null, - operator, null, - rightValue, null, - null, false, - true, false, false, - env); - } - - private static final String VALUE_OF_THE_COMPARISON_IS_UNKNOWN_DATE_LIKE - = "value of the comparison is a date-like value where " - + "it's not known if it's a date (no time part), time, or date-time, " - + "and thus can't be used in a comparison."; - - /** - * @param leftExp {@code null} is allowed, but may results in less helpful error messages - * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}. - * @param operatorString can be null {@code null}; the actual operator used, used for more accurate error message. - * @param rightExp {@code null} is allowed, but may results in less helpful error messages - * @param defaultBlamed {@code null} allowed; the expression to which the error will point to if something goes - * wrong that is not specific to the left or right side expression, or if that expression is {@code null}. - * @param typeMismatchMeansNotEqual If the two types are incompatible, they are treated as non-equal instead - * of throwing an exception. Comparing dates of different types will still throw an exception, however. - * @param leftNullReturnsFalse if {@code true}, a {@code null} left value will not cause exception, but make the - * expression {@code false}. - * @param rightNullReturnsFalse if {@code true}, a {@code null} right value will not cause exception, but make the - * expression {@code false}. - */ - static boolean compare( - TemplateModel leftValue, ASTExpression leftExp, - int operator, String operatorString, - TemplateModel rightValue, ASTExpression rightExp, - ASTExpression defaultBlamed, boolean quoteOperandsInErrors, - boolean typeMismatchMeansNotEqual, - boolean leftNullReturnsFalse, boolean rightNullReturnsFalse, - Environment env) throws TemplateException { - if (leftValue == null) { - if (leftNullReturnsFalse) { - return false; - } else { - if (leftExp != null) { - throw InvalidReferenceException.getInstance(leftExp, env); - } else { - throw new _MiscTemplateException(defaultBlamed, env, - "The left operand of the comparison was undefined or null."); - } - } - } - - if (rightValue == null) { - if (rightNullReturnsFalse) { - return false; - } else { - if (rightExp != null) { - throw InvalidReferenceException.getInstance(rightExp, env); - } else { - throw new _MiscTemplateException(defaultBlamed, env, - "The right operand of the comparison was undefined or null."); - } - } - } - - final int cmpResult; - if (leftValue instanceof TemplateNumberModel && rightValue instanceof TemplateNumberModel) { - Number leftNum = _EvalUtil.modelToNumber((TemplateNumberModel) leftValue, leftExp); - Number rightNum = _EvalUtil.modelToNumber((TemplateNumberModel) rightValue, rightExp); - ArithmeticEngine ae = - env != null - ? env.getArithmeticEngine() - : (leftExp != null - ? leftExp.getTemplate().getArithmeticEngine() - : BigDecimalArithmeticEngine.INSTANCE); - try { - cmpResult = ae.compareNumbers(leftNum, rightNum); - } catch (RuntimeException e) { - throw new _MiscTemplateException(defaultBlamed, e, env, - "Unexpected error while comparing two numbers: ", e); - } - } else if (leftValue instanceof TemplateDateModel && rightValue instanceof TemplateDateModel) { - TemplateDateModel leftDateModel = (TemplateDateModel) leftValue; - TemplateDateModel rightDateModel = (TemplateDateModel) rightValue; - - int leftDateType = leftDateModel.getDateType(); - int rightDateType = rightDateModel.getDateType(); - - if (leftDateType == TemplateDateModel.UNKNOWN || rightDateType == TemplateDateModel.UNKNOWN) { - String sideName; - ASTExpression sideExp; - if (leftDateType == TemplateDateModel.UNKNOWN) { - sideName = "left"; - sideExp = leftExp; - } else { - sideName = "right"; - sideExp = rightExp; - } - - throw new _MiscTemplateException(sideExp != null ? sideExp : defaultBlamed, env, - "The ", sideName, " ", VALUE_OF_THE_COMPARISON_IS_UNKNOWN_DATE_LIKE); - } - - if (leftDateType != rightDateType) { - throw new _MiscTemplateException(defaultBlamed, env, - "Can't compare dates of different types. Left date type is ", - TemplateDateModel.TYPE_NAMES.get(leftDateType), ", right date type is ", - TemplateDateModel.TYPE_NAMES.get(rightDateType), "."); - } - - 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); - // FIXME NBC: Don't use the Collator here. That's locale-specific, but ==/!= should not be. - cmpResult = env.getCollator().compare(leftString, rightString); - } else if (leftValue instanceof TemplateBooleanModel && rightValue instanceof TemplateBooleanModel) { - 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."); - } - boolean leftBool = ((TemplateBooleanModel) leftValue).getAsBoolean(); - boolean rightBool = ((TemplateBooleanModel) rightValue).getAsBoolean(); - cmpResult = (leftBool ? 1 : 0) - (rightBool ? 1 : 0); - } else { - if (typeMismatchMeansNotEqual) { - if (operator == CMP_OP_EQUALS) { - return false; - } else if (operator == CMP_OP_NOT_EQUALS) { - return true; - } - // Falls through - } - throw new _MiscTemplateException(defaultBlamed, env, - "Can't compare values of these types. ", - "Allowed comparisons are between two numbers, two strings, two dates, or two booleans.\n", - "Left hand operand ", - (quoteOperandsInErrors && leftExp != null - ? new Object[] { "(", new _DelayedGetCanonicalForm(leftExp), ") value " } - : ""), - "is ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(leftValue)), ".\n", - "Right hand operand ", - (quoteOperandsInErrors && rightExp != null - ? new Object[] { "(", new _DelayedGetCanonicalForm(rightExp), ") value " } - : ""), - "is ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(rightValue)), - "."); - } - - switch (operator) { - case CMP_OP_EQUALS: return cmpResult == 0; - case CMP_OP_NOT_EQUALS: return cmpResult != 0; - case CMP_OP_LESS_THAN: return cmpResult < 0; - case CMP_OP_GREATER_THAN: return cmpResult > 0; - case CMP_OP_LESS_THAN_EQUALS: return cmpResult <= 0; - case CMP_OP_GREATER_THAN_EQUALS: return cmpResult >= 0; - default: throw new BugException("Unsupported comparator operator code: " + operator); - } - } - - private static String cmpOpToString(int operator, String operatorString) { - if (operatorString != null) { - return operatorString; - } else { - switch (operator) { - case CMP_OP_EQUALS: return "equals"; - case CMP_OP_NOT_EQUALS: return "not-equals"; - case CMP_OP_LESS_THAN: return "less-than"; - case CMP_OP_GREATER_THAN: return "greater-than"; - case CMP_OP_LESS_THAN_EQUALS: return "less-than-equals"; - case CMP_OP_GREATER_THAN_EQUALS: return "greater-than-equals"; - default: return "???"; - } - } - } - - /** - * 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} - */ - static Object coerceModelToStringOrMarkup(TemplateModel tm, ASTExpression exp, String seqTip, Environment env) - throws TemplateException { - return coerceModelToStringOrMarkup(tm, exp, false, seqTip, env); - } - - /** - * @return {@code null} if the {@code returnNullOnNonCoercableType} parameter is {@code true}, and the coercion is - * not possible, because of the type is not right for it. - * - * @see #coerceModelToStringOrMarkup(TemplateModel, ASTExpression, String, Environment) - */ - static Object coerceModelToStringOrMarkup( - TemplateModel tm, ASTExpression exp, boolean returnNullOnNonCoercableType, String seqTip, Environment env) - throws TemplateException { - if (tm instanceof TemplateNumberModel) { - TemplateNumberModel tnm = (TemplateNumberModel) tm; - TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false); - try { - return assertFormatResultNotNull(format.format(tnm)); - } catch (TemplateValueFormatException e) { - throw MessageUtil.newCantFormatNumberException(format, exp, e, false); - } - } else if (tm instanceof TemplateDateModel) { - TemplateDateModel tdm = (TemplateDateModel) tm; - TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false); - try { - return assertFormatResultNotNull(format.format(tdm)); - } catch (TemplateValueFormatException e) { - throw MessageUtil.newCantFormatDateException(format, exp, e, false); - } - } else if (tm instanceof TemplateMarkupOutputModel) { - return tm; - } else { - return coerceModelToTextualCommon(tm, exp, seqTip, true, returnNullOnNonCoercableType, env); - } - } - - /** - * Like {@link #coerceModelToStringOrMarkup(TemplateModel, ASTExpression, String, Environment)}, but gives error - * if the result is markup. This is what you normally use where markup results can't be used. - * - * @param seqTip - * Tip to display if the value type is not coercable, but it's sequence or collection. - * - * @return Never {@code null} - */ - static String coerceModelToStringOrUnsupportedMarkup( - TemplateModel tm, ASTExpression exp, String seqTip, Environment env) - throws TemplateException { - if (tm instanceof TemplateNumberModel) { - TemplateNumberModel tnm = (TemplateNumberModel) tm; - TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false); - try { - return ensureFormatResultString(format.format(tnm), exp, env); - } catch (TemplateValueFormatException e) { - throw MessageUtil.newCantFormatNumberException(format, exp, e, false); - } - } else if (tm instanceof TemplateDateModel) { - TemplateDateModel tdm = (TemplateDateModel) tm; - 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); - } - } else { - return coerceModelToTextualCommon(tm, exp, seqTip, false, false, env); - } - } - - /** - * 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, ASTExpression 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 tm - * If {@code null} that's an exception - * - * @param supportsTOM - * Whether the caller {@code coerceModelTo...} method could handle a {@link TemplateMarkupOutputModel}. - * - * @return Never {@code null} - */ - private static String coerceModelToTextualCommon( - TemplateModel tm, ASTExpression exp, String seqHint, boolean supportsTOM, boolean returnNullOnNonCoercableType, - Environment env) - throws TemplateException { - if (tm instanceof TemplateScalarModel) { - return modelToString((TemplateScalarModel) tm, exp, env); - } else if (tm == null) { - if (exp != null) { - throw InvalidReferenceException.getInstance(exp, env); - } else { - throw new InvalidReferenceException( - "Null/missing value (no more informatoin avilable)", - env); - } - } else if (tm instanceof TemplateBooleanModel) { - // [FM3] This should be before TemplateScalarModel, but automatic boolean-to-string is only non-error since - // 2.3.20, so to keep backward compatibility we couldn't insert this before TemplateScalarModel. - boolean booleanValue = ((TemplateBooleanModel) tm).getAsBoolean(); - return env.formatBoolean(booleanValue, false); - } else { - if (returnNullOnNonCoercableType) { - return null; - } - if (seqHint != null && (tm instanceof TemplateSequenceModel || tm instanceof TemplateCollectionModel)) { - if (supportsTOM) { - throw new NonStringOrTemplateOutputException(exp, tm, seqHint, env); - } else { - throw new NonStringException(exp, tm, seqHint, env); - } - } else { - if (supportsTOM) { - throw new NonStringOrTemplateOutputException(exp, tm, env); - } else { - throw new NonStringException(exp, tm, env); - } - } - } - } - - private static String ensureFormatResultString(Object formatResult, ASTExpression exp, Environment env) - throws NonStringException { - if (formatResult instanceof String) { - return (String) formatResult; - } - - assertFormatResultNotNull(formatResult); - - TemplateMarkupOutputModel mo = (TemplateMarkupOutputModel) formatResult; - _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder( - "Value was formatted to convert it to string, but the result was markup of ouput format ", - new _DelayedJQuote(mo.getOutputFormat()), ".") - .tip("Use value?string to force formatting to plain text.") - .blame(exp); - throw new NonStringException(null, desc); - } - - static String assertFormatResultNotNull(String r) { - if (r != null) { - return r; - } - throw new NullPointerException("TemplateValueFormatter result can't be null"); - } - - static Object assertFormatResultNotNull(Object r) { - if (r != null) { - return r; - } - throw new NullPointerException("TemplateValueFormatter result can't be null"); - } - - static TemplateMarkupOutputModel concatMarkupOutputs(ASTNode parent, TemplateMarkupOutputModel leftMO, - TemplateMarkupOutputModel rightMO) throws TemplateException { - MarkupOutputFormat leftOF = leftMO.getOutputFormat(); - MarkupOutputFormat rightOF = rightMO.getOutputFormat(); - if (rightOF != leftOF) { - String rightPT; - String leftPT; - if ((rightPT = rightOF.getSourcePlainText(rightMO)) != null) { - return leftOF.concat(leftMO, leftOF.fromPlainTextByEscaping(rightPT)); - } else if ((leftPT = leftOF.getSourcePlainText(leftMO)) != null) { - return rightOF.concat(rightOF.fromPlainTextByEscaping(leftPT), rightMO); - } else { - Object[] message = { "Concatenation left hand operand is in ", new _DelayedToString(leftOF), - " format, while the right hand operand is in ", new _DelayedToString(rightOF), - ". Conversion to common format wasn't possible." }; - if (parent instanceof ASTExpression) { - throw new _MiscTemplateException((ASTExpression) parent, message); - } else { - throw new _MiscTemplateException(message); - } - } - } else { - return leftOF.concat(leftMO, rightMO); - } - } - - /** - * Returns an {@link ArithmeticEngine} even if {@code env} is {@code null}, because we are in parsing phase. - */ - static ArithmeticEngine getArithmeticEngine(Environment env, ASTNode tObj) { - return env != null - ? env.getArithmeticEngine() - : tObj.getTemplate().getParsingConfiguration().getArithmeticEngine(); - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java new file mode 100644 index 0000000..199a88c --- /dev/null +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_EvalUtils.java @@ -0,0 +1,545 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.freemarker.core; + +import java.util.Date; + +import org.apache.freemarker.core.arithmetic.ArithmeticEngine; +import org.apache.freemarker.core.arithmetic.impl.BigDecimalArithmeticEngine; +import org.apache.freemarker.core.model.TemplateBooleanModel; +import org.apache.freemarker.core.model.TemplateCollectionModel; +import org.apache.freemarker.core.model.TemplateDateModel; +import org.apache.freemarker.core.model.TemplateMarkupOutputModel; +import org.apache.freemarker.core.model.TemplateModel; +import org.apache.freemarker.core.model.TemplateModelException; +import org.apache.freemarker.core.model.TemplateNumberModel; +import org.apache.freemarker.core.model.TemplateScalarModel; +import org.apache.freemarker.core.model.TemplateSequenceModel; +import org.apache.freemarker.core.outputformat.MarkupOutputFormat; +import org.apache.freemarker.core.util.BugException; +import org.apache.freemarker.core.valueformat.TemplateDateFormat; +import org.apache.freemarker.core.valueformat.TemplateNumberFormat; +import org.apache.freemarker.core.valueformat.TemplateValueFormat; +import org.apache.freemarker.core.valueformat.TemplateValueFormatException; + +/** + * Internally used static utilities for evaluation expressions. + */ +public class _EvalUtils { + static final int CMP_OP_EQUALS = 1; + static final int CMP_OP_NOT_EQUALS = 2; + static final int CMP_OP_LESS_THAN = 3; + static final int CMP_OP_GREATER_THAN = 4; + static final int CMP_OP_LESS_THAN_EQUALS = 5; + static final int CMP_OP_GREATER_THAN_EQUALS = 6; + // If you add a new operator here, update the "compare" and "cmpOpToString" methods! + + // Prevents instantiation. + private _EvalUtils() { } + + /** + * @param expr {@code null} is allowed, but may results in less helpful error messages + * @param env {@code null} is allowed + */ + static String modelToString(TemplateScalarModel model, ASTExpression expr, Environment env) + throws TemplateModelException { + String value = model.getAsString(); + if (value == null) { + throw newModelHasStoredNullException(String.class, model, expr); + } + return value; + } + + /** + * @param expr {@code null} is allowed, but may results in less helpful error messages + */ + static Number modelToNumber(TemplateNumberModel model, ASTExpression expr) + throws TemplateModelException { + Number value = model.getAsNumber(); + if (value == null) throw newModelHasStoredNullException(Number.class, model, expr); + return value; + } + + /** + * @param expr {@code null} is allowed, but may results in less helpful error messages + */ + static Date modelToDate(TemplateDateModel model, ASTExpression expr) + throws TemplateModelException { + Date value = model.getAsDate(); + if (value == null) throw newModelHasStoredNullException(Date.class, model, expr); + return value; + } + + /** Signals the buggy case where we have a non-null model, but it wraps a null. */ + public static TemplateModelException newModelHasStoredNullException( + Class expected, TemplateModel model, ASTExpression expr) { + return new _TemplateModelException(expr, + _TemplateModelException.modelHasStoredNullDescription(expected, model)); + } + + /** + * Compares two expressions according the rules of the FTL comparator operators. + * + * @param leftExp not {@code null} + * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}. + * @param operatorString can be null {@code null}; the actual operator used, used for more accurate error message. + * @param rightExp not {@code null} + * @param env {@code null} is tolerated, but should be avoided + */ + static boolean compare( + ASTExpression leftExp, + int operator, String operatorString, + ASTExpression rightExp, + ASTExpression defaultBlamed, + Environment env) throws TemplateException { + TemplateModel ltm = leftExp.eval(env); + TemplateModel rtm = rightExp.eval(env); + return compare( + ltm, leftExp, + operator, operatorString, + rtm, rightExp, + defaultBlamed, false, + false, false, false, + env); + } + + /** + * Compares values according the rules of the FTL comparator operators; if the {@link ASTExpression}-s are + * accessible, use {@link #compare(ASTExpression, int, String, ASTExpression, ASTExpression, Environment)} instead, + * as that gives better error messages. + * + * @param leftValue maybe {@code null}, which will usually cause the appropriate {@link TemplateException}. + * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}. + * @param rightValue maybe {@code null}, which will usually cause the appropriate {@link TemplateException}. + * @param env {@code null} is tolerated, but should be avoided + */ + static boolean compare( + TemplateModel leftValue, int operator, TemplateModel rightValue, + Environment env) throws TemplateException { + return compare( + leftValue, null, + operator, null, + rightValue, null, + null, false, + false, false, false, + env); + } + + /** + * Same as {@link #compare(TemplateModel, int, TemplateModel, Environment)}, but if the two types are incompatible, + * they are treated as non-equal instead of throwing an exception. Comparing dates of different types will + * still throw an exception, however. + */ + static boolean compareLenient( + TemplateModel leftValue, int operator, TemplateModel rightValue, + Environment env) throws TemplateException { + return compare( + leftValue, null, + operator, null, + rightValue, null, + null, false, + true, false, false, + env); + } + + private static final String VALUE_OF_THE_COMPARISON_IS_UNKNOWN_DATE_LIKE + = "value of the comparison is a date-like value where " + + "it's not known if it's a date (no time part), time, or date-time, " + + "and thus can't be used in a comparison."; + + /** + * @param leftExp {@code null} is allowed, but may results in less helpful error messages + * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}. + * @param operatorString can be null {@code null}; the actual operator used, used for more accurate error message. + * @param rightExp {@code null} is allowed, but may results in less helpful error messages + * @param defaultBlamed {@code null} allowed; the expression to which the error will point to if something goes + * wrong that is not specific to the left or right side expression, or if that expression is {@code null}. + * @param typeMismatchMeansNotEqual If the two types are incompatible, they are treated as non-equal instead + * of throwing an exception. Comparing dates of different types will still throw an exception, however. + * @param leftNullReturnsFalse if {@code true}, a {@code null} left value will not cause exception, but make the + * expression {@code false}. + * @param rightNullReturnsFalse if {@code true}, a {@code null} right value will not cause exception, but make the + * expression {@code false}. + */ + static boolean compare( + TemplateModel leftValue, ASTExpression leftExp, + int operator, String operatorString, + TemplateModel rightValue, ASTExpression rightExp, + ASTExpression defaultBlamed, boolean quoteOperandsInErrors, + boolean typeMismatchMeansNotEqual, + boolean leftNullReturnsFalse, boolean rightNullReturnsFalse, + Environment env) throws TemplateException { + if (leftValue == null) { + if (leftNullReturnsFalse) { + return false; + } else { + if (leftExp != null) { + throw InvalidReferenceException.getInstance(leftExp, env); + } else { + throw new _MiscTemplateException(defaultBlamed, env, + "The left operand of the comparison was undefined or null."); + } + } + } + + if (rightValue == null) { + if (rightNullReturnsFalse) { + return false; + } else { + if (rightExp != null) { + throw InvalidReferenceException.getInstance(rightExp, env); + } else { + throw new _MiscTemplateException(defaultBlamed, env, + "The right operand of the comparison was undefined or null."); + } + } + } + + final int cmpResult; + if (leftValue instanceof TemplateNumberModel && rightValue instanceof TemplateNumberModel) { + Number leftNum = _EvalUtils.modelToNumber((TemplateNumberModel) leftValue, leftExp); + Number rightNum = _EvalUtils.modelToNumber((TemplateNumberModel) rightValue, rightExp); + ArithmeticEngine ae = + env != null + ? env.getArithmeticEngine() + : (leftExp != null + ? leftExp.getTemplate().getArithmeticEngine() + : BigDecimalArithmeticEngine.INSTANCE); + try { + cmpResult = ae.compareNumbers(leftNum, rightNum); + } catch (RuntimeException e) { + throw new _MiscTemplateException(defaultBlamed, e, env, + "Unexpected error while comparing two numbers: ", e); + } + } else if (leftValue instanceof TemplateDateModel && rightValue instanceof TemplateDateModel) { + TemplateDateModel leftDateModel = (TemplateDateModel) leftValue; + TemplateDateModel rightDateModel = (TemplateDateModel) rightValue; + + int leftDateType = leftDateModel.getDateType(); + int rightDateType = rightDateModel.getDateType(); + + if (leftDateType == TemplateDateModel.UNKNOWN || rightDateType == TemplateDateModel.UNKNOWN) { + String sideName; + ASTExpression sideExp; + if (leftDateType == TemplateDateModel.UNKNOWN) { + sideName = "left"; + sideExp = leftExp; + } else { + sideName = "right"; + sideExp = rightExp; + } + + throw new _MiscTemplateException(sideExp != null ? sideExp : defaultBlamed, env, + "The ", sideName, " ", VALUE_OF_THE_COMPARISON_IS_UNKNOWN_DATE_LIKE); + } + + if (leftDateType != rightDateType) { + throw new _MiscTemplateException(defaultBlamed, env, + "Can't compare dates of different types. Left date type is ", + TemplateDateModel.TYPE_NAMES.get(leftDateType), ", right date type is ", + TemplateDateModel.TYPE_NAMES.get(rightDateType), "."); + } + + Date leftDate = _EvalUtils.modelToDate(leftDateModel, leftExp); + Date rightDate = _EvalUtils.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 = _EvalUtils.modelToString((TemplateScalarModel) leftValue, leftExp, env); + String rightString = _EvalUtils.modelToString((TemplateScalarModel) rightValue, rightExp, env); + // FIXME NBC: Don't use the Collator here. That's locale-specific, but ==/!= should not be. + cmpResult = env.getCollator().compare(leftString, rightString); + } else if (leftValue instanceof TemplateBooleanModel && rightValue instanceof TemplateBooleanModel) { + 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."); + } + boolean leftBool = ((TemplateBooleanModel) leftValue).getAsBoolean(); + boolean rightBool = ((TemplateBooleanModel) rightValue).getAsBoolean(); + cmpResult = (leftBool ? 1 : 0) - (rightBool ? 1 : 0); + } else { + if (typeMismatchMeansNotEqual) { + if (operator == CMP_OP_EQUALS) { + return false; + } else if (operator == CMP_OP_NOT_EQUALS) { + return true; + } + // Falls through + } + throw new _MiscTemplateException(defaultBlamed, env, + "Can't compare values of these types. ", + "Allowed comparisons are between two numbers, two strings, two dates, or two booleans.\n", + "Left hand operand ", + (quoteOperandsInErrors && leftExp != null + ? new Object[] { "(", new _DelayedGetCanonicalForm(leftExp), ") value " } + : ""), + "is ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(leftValue)), ".\n", + "Right hand operand ", + (quoteOperandsInErrors && rightExp != null + ? new Object[] { "(", new _DelayedGetCanonicalForm(rightExp), ") value " } + : ""), + "is ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(rightValue)), + "."); + } + + switch (operator) { + case CMP_OP_EQUALS: return cmpResult == 0; + case CMP_OP_NOT_EQUALS: return cmpResult != 0; + case CMP_OP_LESS_THAN: return cmpResult < 0; + case CMP_OP_GREATER_THAN: return cmpResult > 0; + case CMP_OP_LESS_THAN_EQUALS: return cmpResult <= 0; + case CMP_OP_GREATER_THAN_EQUALS: return cmpResult >= 0; + default: throw new BugException("Unsupported comparator operator code: " + operator); + } + } + + private static String cmpOpToString(int operator, String operatorString) { + if (operatorString != null) { + return operatorString; + } else { + switch (operator) { + case CMP_OP_EQUALS: return "equals"; + case CMP_OP_NOT_EQUALS: return "not-equals"; + case CMP_OP_LESS_THAN: return "less-than"; + case CMP_OP_GREATER_THAN: return "greater-than"; + case CMP_OP_LESS_THAN_EQUALS: return "less-than-equals"; + case CMP_OP_GREATER_THAN_EQUALS: return "greater-than-equals"; + default: return "???"; + } + } + } + + /** + * 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} + */ + static Object coerceModelToStringOrMarkup(TemplateModel tm, ASTExpression exp, String seqTip, Environment env) + throws TemplateException { + return coerceModelToStringOrMarkup(tm, exp, false, seqTip, env); + } + + /** + * @return {@code null} if the {@code returnNullOnNonCoercableType} parameter is {@code true}, and the coercion is + * not possible, because of the type is not right for it. + * + * @see #coerceModelToStringOrMarkup(TemplateModel, ASTExpression, String, Environment) + */ + static Object coerceModelToStringOrMarkup( + TemplateModel tm, ASTExpression exp, boolean returnNullOnNonCoercableType, String seqTip, Environment env) + throws TemplateException { + if (tm instanceof TemplateNumberModel) { + TemplateNumberModel tnm = (TemplateNumberModel) tm; + TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false); + try { + return assertFormatResultNotNull(format.format(tnm)); + } catch (TemplateValueFormatException e) { + throw MessageUtils.newCantFormatNumberException(format, exp, e, false); + } + } else if (tm instanceof TemplateDateModel) { + TemplateDateModel tdm = (TemplateDateModel) tm; + TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false); + try { + return assertFormatResultNotNull(format.format(tdm)); + } catch (TemplateValueFormatException e) { + throw MessageUtils.newCantFormatDateException(format, exp, e, false); + } + } else if (tm instanceof TemplateMarkupOutputModel) { + return tm; + } else { + return coerceModelToTextualCommon(tm, exp, seqTip, true, returnNullOnNonCoercableType, env); + } + } + + /** + * Like {@link #coerceModelToStringOrMarkup(TemplateModel, ASTExpression, String, Environment)}, but gives error + * if the result is markup. This is what you normally use where markup results can't be used. + * + * @param seqTip + * Tip to display if the value type is not coercable, but it's sequence or collection. + * + * @return Never {@code null} + */ + static String coerceModelToStringOrUnsupportedMarkup( + TemplateModel tm, ASTExpression exp, String seqTip, Environment env) + throws TemplateException { + if (tm instanceof TemplateNumberModel) { + TemplateNumberModel tnm = (TemplateNumberModel) tm; + TemplateNumberFormat format = env.getTemplateNumberFormat(exp, false); + try { + return ensureFormatResultString(format.format(tnm), exp, env); + } catch (TemplateValueFormatException e) { + throw MessageUtils.newCantFormatNumberException(format, exp, e, false); + } + } else if (tm instanceof TemplateDateModel) { + TemplateDateModel tdm = (TemplateDateModel) tm; + TemplateDateFormat format = env.getTemplateDateFormat(tdm, exp, false); + try { + return ensureFormatResultString(format.format(tdm), exp, env); + } catch (TemplateValueFormatException e) { + throw MessageUtils.newCantFormatDateException(format, exp, e, false); + } + } else { + return coerceModelToTextualCommon(tm, exp, seqTip, false, false, env); + } + } + + /** + * 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, ASTExpression 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 tm + * If {@code null} that's an exception + * + * @param supportsTOM + * Whether the caller {@code coerceModelTo...} method could handle a {@link TemplateMarkupOutputModel}. + * + * @return Never {@code null} + */ + private static String coerceModelToTextualCommon( + TemplateModel tm, ASTExpression exp, String seqHint, boolean supportsTOM, boolean returnNullOnNonCoercableType, + Environment env) + throws TemplateException { + if (tm instanceof TemplateScalarModel) { + return modelToString((TemplateScalarModel) tm, exp, env); + } else if (tm == null) { + if (exp != null) { + throw InvalidReferenceException.getInstance(exp, env); + } else { + throw new InvalidReferenceException( + "Null/missing value (no more informatoin avilable)", + env); + } + } else if (tm instanceof TemplateBooleanModel) { + // [FM3] This should be before TemplateScalarModel, but automatic boolean-to-string is only non-error since + // 2.3.20, so to keep backward compatibility we couldn't insert this before TemplateScalarModel. + boolean booleanValue = ((TemplateBooleanModel) tm).getAsBoolean(); + return env.formatBoolean(booleanValue, false); + } else { + if (returnNullOnNonCoercableType) { + return null; + } + if (seqHint != null && (tm instanceof TemplateSequenceModel || tm instanceof TemplateCollectionModel)) { + if (supportsTOM) { + throw new NonStringOrTemplateOutputException(exp, tm, seqHint, env); + } else { + throw new NonStringException(exp, tm, seqHint, env); + } + } else { + if (supportsTOM) { + throw new NonStringOrTemplateOutputException(exp, tm, env); + } else { + throw new NonStringException(exp, tm, env); + } + } + } + } + + private static String ensureFormatResultString(Object formatResult, ASTExpression exp, Environment env) + throws NonStringException { + if (formatResult instanceof String) { + return (String) formatResult; + } + + assertFormatResultNotNull(formatResult); + + TemplateMarkupOutputModel mo = (TemplateMarkupOutputModel) formatResult; + _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder( + "Value was formatted to convert it to string, but the result was markup of ouput format ", + new _DelayedJQuote(mo.getOutputFormat()), ".") + .tip("Use value?string to force formatting to plain text.") + .blame(exp); + throw new NonStringException(null, desc); + } + + static String assertFormatResultNotNull(String r) { + if (r != null) { + return r; + } + throw new NullPointerException("TemplateValueFormatter result can't be null"); + } + + static Object assertFormatResultNotNull(Object r) { + if (r != null) { + return r; + } + throw new NullPointerException("TemplateValueFormatter result can't be null"); + } + + static TemplateMarkupOutputModel concatMarkupOutputs(ASTNode parent, TemplateMarkupOutputModel leftMO, + TemplateMarkupOutputModel rightMO) throws TemplateException { + MarkupOutputFormat leftOF = leftMO.getOutputFormat(); + MarkupOutputFormat rightOF = rightMO.getOutputFormat(); + if (rightOF != leftOF) { + String rightPT; + String leftPT; + if ((rightPT = rightOF.getSourcePlainText(rightMO)) != null) { + return leftOF.concat(leftMO, leftOF.fromPlainTextByEscaping(rightPT)); + } else if ((leftPT = leftOF.getSourcePlainText(leftMO)) != null) { + return rightOF.concat(rightOF.fromPlainTextByEscaping(leftPT), rightMO); + } else { + Object[] message = { "Concatenation left hand operand is in ", new _DelayedToString(leftOF), + " format, while the right hand operand is in ", new _DelayedToString(rightOF), + ". Conversion to common format wasn't possible." }; + if (parent instanceof ASTExpression) { + throw new _MiscTemplateException((ASTExpression) parent, message); + } else { + throw new _MiscTemplateException(message); + } + } + } else { + return leftOF.concat(leftMO, rightMO); + } + } + + /** + * Returns an {@link ArithmeticEngine} even if {@code env} is {@code null}, because we are in parsing phase. + */ + static ArithmeticEngine getArithmeticEngine(Environment env, ASTNode tObj) { + return env != null + ? env.getArithmeticEngine() + : tObj.getTemplate().getParsingConfiguration().getArithmeticEngine(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluationException.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluationException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluationException.java index 620399a..6c8e700 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluationException.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluationException.java @@ -19,7 +19,7 @@ package org.apache.freemarker.core; -import org.apache.freemarker.core.util._StringUtil; +import org.apache.freemarker.core.util._StringUtils; /** * Don't use this; used internally by FreeMarker, might changes without notice. @@ -38,7 +38,7 @@ public class _ObjectBuilderSettingEvaluationException extends Exception { public _ObjectBuilderSettingEvaluationException(String expected, String src, int location) { super("Expression syntax error: Expected a(n) " + expected + ", but " + (location < src.length() - ? "found character " + _StringUtil.jQuote("" + src.charAt(location)) + " at position " + ? "found character " + _StringUtils.jQuote("" + src.charAt(location)) + " at position " + (location + 1) + "." : "the end of the parsed string was reached.") ); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java index 89a6fe8..7be4511 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_ObjectBuilderSettingEvaluator.java @@ -60,8 +60,8 @@ import org.apache.freemarker.core.templateresolver.PathRegexMatcher; import org.apache.freemarker.core.util.BugException; import org.apache.freemarker.core.util.FTLUtil; import org.apache.freemarker.core.util.GenericParseException; -import org.apache.freemarker.core.util._ClassUtil; -import org.apache.freemarker.core.util._StringUtil; +import org.apache.freemarker.core.util._ClassUtils; +import org.apache.freemarker.core.util._StringUtils; /** * Don't use this; used internally by FreeMarker, might changes without notice. @@ -634,7 +634,7 @@ public class _ObjectBuilderSettingEvaluator { if (i != 0) { sb.append(" or "); } - sb.append(_StringUtil.jQuote(expectedChars.substring(i, i + 1))); + sb.append(_StringUtils.jQuote(expectedChars.substring(i, i + 1))); } throw new _ObjectBuilderSettingEvaluationException( sb.toString(), @@ -739,13 +739,13 @@ public class _ObjectBuilderSettingEvaluator { if (!beanPropSetters.containsKey(name)) { throw new _ObjectBuilderSettingEvaluationException( "The " + cl.getName() + " class has no writeable JavaBeans property called " - + _StringUtil.jQuote(name) + "."); + + _StringUtils.jQuote(name) + "."); } Method beanPropSetter = beanPropSetters.put(name, null); if (beanPropSetter == null) { throw new _ObjectBuilderSettingEvaluationException( - "JavaBeans property " + _StringUtil.jQuote(name) + " is set twice."); + "JavaBeans property " + _StringUtils.jQuote(name) + " is set twice."); } try { @@ -765,7 +765,7 @@ public class _ObjectBuilderSettingEvaluator { } if (!(m instanceof JavaMethodModel)) { throw new _ObjectBuilderSettingEvaluationException( - _StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a JavaMethodModel."); + _StringUtils.jQuote(beanPropSetter.getName()) + " wasn't a JavaMethodModel."); } List/*TemplateModel*/ args = new ArrayList(); ((JavaMethodModel) m).execute( @@ -773,7 +773,7 @@ public class _ObjectBuilderSettingEvaluator { NonTemplateCallPlace.INSTANCE); } catch (Exception e) { throw new _ObjectBuilderSettingEvaluationException( - "Failed to set " + _StringUtil.jQuote(name), e); + "Failed to set " + _StringUtils.jQuote(name), e); } } } @@ -877,16 +877,16 @@ public class _ObjectBuilderSettingEvaluator { boolean clIsBuilderClass; try { - cl = _ClassUtil.forName(className + BUILDER_CLASS_POSTFIX_1); + cl = _ClassUtils.forName(className + BUILDER_CLASS_POSTFIX_1); clIsBuilderClass = true; } catch (ClassNotFoundException eIgnored) { try { - cl = _ClassUtil.forName(className + BUILDER_CLASS_POSTFIX_2); + cl = _ClassUtils.forName(className + BUILDER_CLASS_POSTFIX_2); clIsBuilderClass = true; } catch (ClassNotFoundException e) { clIsBuilderClass = false; try { - cl = _ClassUtil.forName(className); + cl = _ClassUtils.forName(className); } catch (Exception e2) { boolean failedToGetAsStaticField; if (canBeStaticField && className.indexOf('.') != -1) { @@ -901,7 +901,7 @@ public class _ObjectBuilderSettingEvaluator { failedToGetAsStaticField = false; } throw new _ObjectBuilderSettingEvaluationException( - "Failed to get class " + _StringUtil.jQuote(className) + "Failed to get class " + _StringUtils.jQuote(className) + (failedToGetAsStaticField ? " (also failed to resolve name as static field)" : "") + ".", e2); @@ -920,7 +920,7 @@ public class _ObjectBuilderSettingEvaluator { // Expected } catch (Exception e) { throw new _ObjectBuilderSettingEvaluationException( - "Error when trying to access " + _StringUtil.jQuote(className) + "." + "Error when trying to access " + _StringUtils.jQuote(className) + "." + INSTANCE_FIELD_NAME, e); } } @@ -944,10 +944,10 @@ public class _ObjectBuilderSettingEvaluator { Class<?> cl; try { - cl = _ClassUtil.forName(className); + cl = _ClassUtils.forName(className); } catch (Exception e) { throw new _ObjectBuilderSettingEvaluationException( - "Failed to get field's parent class, " + _StringUtil.jQuote(className) + ".", + "Failed to get field's parent class, " + _StringUtils.jQuote(className) + ".", e); } @@ -956,8 +956,8 @@ public class _ObjectBuilderSettingEvaluator { field = cl.getField(fieldName); } catch (Exception e) { throw new _ObjectBuilderSettingEvaluationException( - "Failed to get field " + _StringUtil.jQuote(fieldName) + " from class " - + _StringUtil.jQuote(className) + ".", + "Failed to get field " + _StringUtils.jQuote(fieldName) + " from class " + + _StringUtils.jQuote(className) + ".", e); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateModelException.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateModelException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateModelException.java index 76e9d2b..10ad99f 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateModelException.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/_TemplateModelException.java @@ -21,7 +21,7 @@ package org.apache.freemarker.core; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.util._ClassUtil; +import org.apache.freemarker.core.util._ClassUtils; public class _TemplateModelException extends TemplateModelException { @@ -126,7 +126,7 @@ public class _TemplateModelException extends TemplateModelException { return new Object[] { "The FreeMarker value exists, but has nothing inside it; the TemplateModel object (class: ", model.getClass().getName(), ") has returned a null", - (expected != null ? new Object[] { " instead of a ", _ClassUtil.getShortClassName(expected) } : ""), + (expected != null ? new Object[] { " instead of a ", _ClassUtils.getShortClassName(expected) } : ""), ". This is possibly a bug in the non-FreeMarker code that builds the data-model." }; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/BigDecimalArithmeticEngine.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/BigDecimalArithmeticEngine.java b/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/BigDecimalArithmeticEngine.java index 0d22656..d09d48f 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/BigDecimalArithmeticEngine.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/BigDecimalArithmeticEngine.java @@ -21,7 +21,7 @@ package org.apache.freemarker.core.arithmetic.impl; import java.math.BigDecimal; import org.apache.freemarker.core.arithmetic.ArithmeticEngine; -import org.apache.freemarker.core.util._NumberUtil; +import org.apache.freemarker.core.util._NumberUtils; /** * Arithmetic engine that converts all numbers to {@link BigDecimal} and then operates on them, and also keeps the @@ -40,37 +40,37 @@ public class BigDecimalArithmeticEngine extends ArithmeticEngine { // We try to find the result based on the sign (+/-/0) first, because: // - It's much faster than converting to BigDecial, and comparing to 0 is the most common comparison. // - It doesn't require any type conversions, and thus things like "Infinity > 0" won't fail. - int firstSignum = _NumberUtil.getSignum(first); - int secondSignum = _NumberUtil.getSignum(second); + int firstSignum = _NumberUtils.getSignum(first); + int secondSignum = _NumberUtils.getSignum(second); if (firstSignum != secondSignum) { return firstSignum < secondSignum ? -1 : (firstSignum > secondSignum ? 1 : 0); } else if (firstSignum == 0 && secondSignum == 0) { return 0; } else { - BigDecimal left = _NumberUtil.toBigDecimal(first); - BigDecimal right = _NumberUtil.toBigDecimal(second); + BigDecimal left = _NumberUtils.toBigDecimal(first); + BigDecimal right = _NumberUtils.toBigDecimal(second); return left.compareTo(right); } } @Override public Number add(Number first, Number second) { - BigDecimal left = _NumberUtil.toBigDecimal(first); - BigDecimal right = _NumberUtil.toBigDecimal(second); + BigDecimal left = _NumberUtils.toBigDecimal(first); + BigDecimal right = _NumberUtils.toBigDecimal(second); return left.add(right); } @Override public Number subtract(Number first, Number second) { - BigDecimal left = _NumberUtil.toBigDecimal(first); - BigDecimal right = _NumberUtil.toBigDecimal(second); + BigDecimal left = _NumberUtils.toBigDecimal(first); + BigDecimal right = _NumberUtils.toBigDecimal(second); return left.subtract(right); } @Override public Number multiply(Number first, Number second) { - BigDecimal left = _NumberUtil.toBigDecimal(first); - BigDecimal right = _NumberUtil.toBigDecimal(second); + BigDecimal left = _NumberUtils.toBigDecimal(first); + BigDecimal right = _NumberUtils.toBigDecimal(second); BigDecimal result = left.multiply(right); if (result.scale() > maxScale) { result = result.setScale(maxScale, roundingPolicy); @@ -80,8 +80,8 @@ public class BigDecimalArithmeticEngine extends ArithmeticEngine { @Override public Number divide(Number first, Number second) { - BigDecimal left = _NumberUtil.toBigDecimal(first); - BigDecimal right = _NumberUtil.toBigDecimal(second); + BigDecimal left = _NumberUtils.toBigDecimal(first); + BigDecimal right = _NumberUtils.toBigDecimal(second); return divide(left, right); } @@ -94,7 +94,7 @@ public class BigDecimalArithmeticEngine extends ArithmeticEngine { @Override public Number toNumber(String s) { - return _NumberUtil.toBigDecimalOrDouble(s); + return _NumberUtils.toBigDecimalOrDouble(s); } private BigDecimal divide(BigDecimal left, BigDecimal right) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/ConservativeArithmeticEngine.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/ConservativeArithmeticEngine.java b/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/ConservativeArithmeticEngine.java index 12c27d9..16f58a2 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/ConservativeArithmeticEngine.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/arithmetic/impl/ConservativeArithmeticEngine.java @@ -27,7 +27,7 @@ import org.apache.freemarker.core.TemplateException; import org.apache.freemarker.core._MiscTemplateException; import org.apache.freemarker.core.arithmetic.ArithmeticEngine; import org.apache.freemarker.core.util.BugException; -import org.apache.freemarker.core.util._NumberUtil; +import org.apache.freemarker.core.util._NumberUtils; /** * Arithmetic engine that uses (more-or-less) the widening conversions of @@ -96,8 +96,8 @@ public class ConservativeArithmeticEngine extends ArithmeticEngine { return n1.compareTo(n2); } case BIG_DECIMAL: { - BigDecimal n1 = _NumberUtil.toBigDecimal(first); - BigDecimal n2 = _NumberUtil.toBigDecimal(second); + BigDecimal n1 = _NumberUtils.toBigDecimal(first); + BigDecimal n2 = _NumberUtils.toBigDecimal(second); return n1.compareTo(n2); } } @@ -139,8 +139,8 @@ public class ConservativeArithmeticEngine extends ArithmeticEngine { return n1.add(n2); } case BIG_DECIMAL: { - BigDecimal n1 = _NumberUtil.toBigDecimal(first); - BigDecimal n2 = _NumberUtil.toBigDecimal(second); + BigDecimal n1 = _NumberUtils.toBigDecimal(first); + BigDecimal n2 = _NumberUtils.toBigDecimal(second); return n1.add(n2); } } @@ -182,8 +182,8 @@ public class ConservativeArithmeticEngine extends ArithmeticEngine { return n1.subtract(n2); } case BIG_DECIMAL: { - BigDecimal n1 = _NumberUtil.toBigDecimal(first); - BigDecimal n2 = _NumberUtil.toBigDecimal(second); + BigDecimal n1 = _NumberUtils.toBigDecimal(first); + BigDecimal n2 = _NumberUtils.toBigDecimal(second); return n1.subtract(n2); } } @@ -225,8 +225,8 @@ public class ConservativeArithmeticEngine extends ArithmeticEngine { return n1.multiply(n2); } case BIG_DECIMAL: { - BigDecimal n1 = _NumberUtil.toBigDecimal(first); - BigDecimal n2 = _NumberUtil.toBigDecimal(second); + BigDecimal n1 = _NumberUtils.toBigDecimal(first); + BigDecimal n2 = _NumberUtils.toBigDecimal(second); BigDecimal r = n1.multiply(n2); return r.scale() > maxScale ? r.setScale(maxScale, roundingPolicy) : r; } @@ -274,8 +274,8 @@ public class ConservativeArithmeticEngine extends ArithmeticEngine { } } case BIG_DECIMAL: { - BigDecimal n1 = _NumberUtil.toBigDecimal(first); - BigDecimal n2 = _NumberUtil.toBigDecimal(second); + BigDecimal n1 = _NumberUtils.toBigDecimal(first); + BigDecimal n2 = _NumberUtils.toBigDecimal(second); int scale1 = n1.scale(); int scale2 = n2.scale(); int scale = Math.max(scale1, scale2); @@ -319,8 +319,8 @@ public class ConservativeArithmeticEngine extends ArithmeticEngine { @Override public Number toNumber(String s) { - Number n = _NumberUtil.toBigDecimalOrDouble(s); - return n instanceof BigDecimal ? _NumberUtil.optimizeNumberRepresentation(n) : n; + Number n = _NumberUtils.toBigDecimalOrDouble(s); + return n instanceof BigDecimal ? _NumberUtils.optimizeNumberRepresentation(n) : n; } private static Map createClassCodesMap() { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java index c1428c1..4efc482 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/DebuggerServer.java @@ -33,7 +33,7 @@ import java.util.Arrays; import java.util.Random; import org.apache.freemarker.core.util.UndeclaredThrowableException; -import org.apache.freemarker.core.util._SecurityUtil; +import org.apache.freemarker.core.util._SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,9 +54,9 @@ class DebuggerServer { private ServerSocket serverSocket; public DebuggerServer(Serializable debuggerStub) { - port = _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.port", Debugger.DEFAULT_PORT).intValue(); + port = _SecurityUtils.getSystemProperty("org.apache.freemarker.core.debug.port", Debugger.DEFAULT_PORT).intValue(); try { - password = _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.password", "").getBytes( + password = _SecurityUtils.getSystemProperty("org.apache.freemarker.core.debug.password", "").getBytes( StandardCharsets.UTF_8); } catch (UnsupportedCharsetException e) { throw new UndeclaredThrowableException(e); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java index 37d094c..4d37917 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/debug/_DebuggerService.java @@ -25,7 +25,7 @@ import java.util.List; import org.apache.freemarker.core.Environment; import org.apache.freemarker.core.Template; -import org.apache.freemarker.core.util._SecurityUtil; +import org.apache.freemarker.core.util._SecurityUtils; /** * Don't use this; used internally by FreeMarker, might changes without notice. @@ -40,7 +40,7 @@ public abstract class _DebuggerService { // off, this is a fast no-op service, otherwise it's the real-thing // RMI service. return - _SecurityUtil.getSystemProperty("org.apache.freemarker.core.debug.password", null) == null + _SecurityUtils.getSystemProperty("org.apache.freemarker.core.debug.password", null) == null ? new NoOpDebuggerService() : new RmiDebuggerService(); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ArgumentTypes.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ArgumentTypes.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ArgumentTypes.java index 3b346e6..77d1790 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ArgumentTypes.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ArgumentTypes.java @@ -27,7 +27,7 @@ import java.util.List; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateModelException; import org.apache.freemarker.core.util.BugException; -import org.apache.freemarker.core.util._ClassUtil; +import org.apache.freemarker.core.util._ClassUtils; /** * The argument types of a method call; usable as cache key. @@ -152,7 +152,7 @@ final class ArgumentTypes { * specific than {@code Boolean}, because the former can't store {@code null}). The preferability decision gets * trickier when there's a possibility of numerical conversion from the actual argument type to the type of some of * the parameters. If such conversion is only possible for one of the competing parameter types, that parameter - * automatically wins. If it's possible for both, {@link OverloadedNumberUtil#getArgumentConversionPrice} will + * automatically wins. If it's possible for both, {@link OverloadedNumberUtils#getArgumentConversionPrice} will * be used to calculate the conversion "price", and the parameter type with lowest price wins. There are also * a twist with array-to-list and list-to-array conversions; we try to avoid those, so the parameter where such * conversion isn't needed will always win. @@ -190,10 +190,10 @@ final class ArgumentTypes { final boolean argIsNum = Number.class.isAssignableFrom(argType); final int numConvPrice1; - if (argIsNum && _ClassUtil.isNumerical(paramType1)) { + if (argIsNum && _ClassUtils.isNumerical(paramType1)) { final Class<?> nonPrimParamType1 = paramType1.isPrimitive() - ? _ClassUtil.primitiveClassToBoxingClass(paramType1) : paramType1; - numConvPrice1 = OverloadedNumberUtil.getArgumentConversionPrice(argType, nonPrimParamType1); + ? _ClassUtils.primitiveClassToBoxingClass(paramType1) : paramType1; + numConvPrice1 = OverloadedNumberUtils.getArgumentConversionPrice(argType, nonPrimParamType1); } else { numConvPrice1 = Integer.MAX_VALUE; } @@ -202,10 +202,10 @@ final class ArgumentTypes { // - FM doesn't know some of the numerical types, or the conversion between them is not allowed final int numConvPrice2; - if (argIsNum && _ClassUtil.isNumerical(paramType2)) { + if (argIsNum && _ClassUtils.isNumerical(paramType2)) { final Class<?> nonPrimParamType2 = paramType2.isPrimitive() - ? _ClassUtil.primitiveClassToBoxingClass(paramType2) : paramType2; - numConvPrice2 = OverloadedNumberUtil.getArgumentConversionPrice(argType, nonPrimParamType2); + ? _ClassUtils.primitiveClassToBoxingClass(paramType2) : paramType2; + numConvPrice2 = OverloadedNumberUtils.getArgumentConversionPrice(argType, nonPrimParamType2); } else { numConvPrice2 = Integer.MAX_VALUE; } @@ -300,16 +300,16 @@ final class ArgumentTypes { if (numConvPrice1 != numConvPrice2) { if (numConvPrice1 < numConvPrice2) { winerParam = 1; - if (numConvPrice1 < OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE - && numConvPrice2 > OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE) { + if (numConvPrice1 < OverloadedNumberUtils.BIG_MANTISSA_LOSS_PRICE + && numConvPrice2 > OverloadedNumberUtils.BIG_MANTISSA_LOSS_PRICE) { paramList1StrongWinCnt++; } else { paramList1WinCnt++; } } else { winerParam = -1; - if (numConvPrice2 < OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE - && numConvPrice1 > OverloadedNumberUtil.BIG_MANTISSA_LOSS_PRICE) { + if (numConvPrice2 < OverloadedNumberUtils.BIG_MANTISSA_LOSS_PRICE + && numConvPrice1 > OverloadedNumberUtils.BIG_MANTISSA_LOSS_PRICE) { paramList2StrongWinCnt++; } else { paramList2WinCnt++; @@ -347,8 +347,8 @@ final class ArgumentTypes { if (argTypesLen == paramTypes1Len - 1) { Class<?> paramType1 = getParamType(paramTypes1, paramTypes1Len, argTypesLen, true); Class<?> paramType2 = getParamType(paramTypes2, paramTypes2Len, argTypesLen, true); - if (_ClassUtil.isNumerical(paramType1) && _ClassUtil.isNumerical(paramType2)) { - int r = OverloadedNumberUtil.compareNumberTypeSpecificity(paramType1, paramType2); + if (_ClassUtils.isNumerical(paramType1) && _ClassUtils.isNumerical(paramType2)) { + int r = OverloadedNumberUtils.compareNumberTypeSpecificity(paramType1, paramType2); if (r != 0) return r; // falls through } @@ -377,9 +377,9 @@ final class ArgumentTypes { // The more specific (smaller) type wins. final Class<?> nonPrimParamType1 = paramType1.isPrimitive() - ? _ClassUtil.primitiveClassToBoxingClass(paramType1) : paramType1; + ? _ClassUtils.primitiveClassToBoxingClass(paramType1) : paramType1; final Class<?> nonPrimParamType2 = paramType2.isPrimitive() - ? _ClassUtil.primitiveClassToBoxingClass(paramType2) : paramType2; + ? _ClassUtils.primitiveClassToBoxingClass(paramType2) : paramType2; if (nonPrimParamType1 == nonPrimParamType2) { if (nonPrimParamType1 != paramType1) { @@ -505,7 +505,7 @@ final class ArgumentTypes { return CONVERSION_DIFFICULTY_IMPOSSIBLE; } - formalNP = _ClassUtil.primitiveClassToBoxingClass(formal); + formalNP = _ClassUtils.primitiveClassToBoxingClass(formal); if (actual == formalNP) { // Character and char, etc. return CONVERSION_DIFFICULTY_REFLECTION; @@ -518,7 +518,7 @@ final class ArgumentTypes { formalNP = formal; } if (Number.class.isAssignableFrom(actual) && Number.class.isAssignableFrom(formalNP)) { - return OverloadedNumberUtil.getArgumentConversionPrice(actual, formalNP) == Integer.MAX_VALUE + return OverloadedNumberUtils.getArgumentConversionPrice(actual, formalNP) == Integer.MAX_VALUE ? CONVERSION_DIFFICULTY_IMPOSSIBLE : CONVERSION_DIFFICULTY_REFLECTION; } else if (formal.isArray()) { // DefaultObjectWrapper method/constructor calls convert from List to array automatically http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java index 33d5e86..4320251 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/BeanModel.java @@ -45,7 +45,7 @@ import org.apache.freemarker.core.model.TemplateModelIterator; import org.apache.freemarker.core.model.TemplateModelWithAPISupport; import org.apache.freemarker.core.model.TemplateScalarModel; import org.apache.freemarker.core.model.WrapperTemplateModel; -import org.apache.freemarker.core.util._StringUtil; +import org.apache.freemarker.core.util._StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -164,7 +164,7 @@ public class BeanModel private void logNoSuchKey(String key, Map<?, ?> keyMap) { if (LOG.isDebugEnabled()) { - LOG.debug("Key " + _StringUtil.jQuoteNoXSS(key) + " was not found on instance of " + + LOG.debug("Key " + _StringUtils.jQuoteNoXSS(key) + " was not found on instance of " + object.getClass().getName() + ". Introspection information for " + "the class is: " + keyMap); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassBasedModelFactory.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassBasedModelFactory.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassBasedModelFactory.java index 3fd3a2d..c866d65 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassBasedModelFactory.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassBasedModelFactory.java @@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.freemarker.core.model.TemplateHashModel; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.util._ClassUtil; +import org.apache.freemarker.core.util._ClassUtils; /** * Base class for hash models keyed by Java class names. @@ -91,7 +91,7 @@ abstract class ClassBasedModelFactory implements TemplateHashModel { classIntrospectorClearingCounter = classIntrospector.getClearingCounter(); } try { - final Class clazz = _ClassUtil.forName(key); + final Class clazz = _ClassUtils.forName(key); // This is called so that we trigger the // class-reloading detector. If clazz is a reloaded class, http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ebb39b84/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassIntrospector.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassIntrospector.java b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassIntrospector.java index ead6c7a..a1f5935 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassIntrospector.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/ClassIntrospector.java @@ -411,7 +411,7 @@ class ClassIntrospector { Class<?>[] paramTypes = method.getParameterTypes(); if (paramTypes.length == 0 || paramTypes.length == 1 && paramTypes[0] == int.class /* indexed property reader */) { - String propName = _MethodUtil.getBeanPropertyNameFromReaderMethodName( + String propName = _MethodUtils.getBeanPropertyNameFromReaderMethodName( method.getName(), method.getReturnType()); if (propName != null) { if (mergedPRMPs == null) {