http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/OptInTemplateClassResolver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/OptInTemplateClassResolver.java b/src/main/java/org/apache/freemarker/core/ast/OptInTemplateClassResolver.java deleted file mode 100644 index eaa6adf..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/OptInTemplateClassResolver.java +++ /dev/null @@ -1,158 +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.ast; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.apache.freemarker.core.Template; -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.util._ClassUtil; -import org.apache.freemarker.core.util._StringUtil; - -/** - * A {@link TemplateClassResolver} that resolves only the classes whose name - * was specified in the constructor. - */ -public class OptInTemplateClassResolver implements TemplateClassResolver { - - private final Set/*<String>*/ allowedClasses; - private final List/*<String>*/ trustedTemplatePrefixes; - private final Set/*<String>*/ trustedTemplateNames; - - /** - * Creates a new instance. - * - * @param allowedClasses the {@link Set} of {@link String}-s that contains - * the full-qualified names of the allowed classes. - * Can be <code>null</code> (means not class is allowed). - * @param trustedTemplates the {@link List} of {@link String}-s that contains - * template names (i.e., template root directory relative paths) - * and prefix patterns (like <code>"include/*"</code>) of templates - * for which {@link TemplateClassResolver#UNRESTRICTED_RESOLVER} will be - * used (which is not as safe as {@link OptInTemplateClassResolver}). - * The list items need not start with <code>"/"</code> (if they are, it - * will be removed). List items ending with <code>"*"</code> are treated - * as prefixes (i.e. <code>"foo*"</code> matches <code>"foobar"</code>, - * <code>"foo/bar/baaz"</code>, <code>"foowhatever/bar/baaz"</code>, - * etc.). The <code>"*"</code> has no special meaning anywhere else. - * The matched template name is the name (template root directory - * relative path) of the template that directly (lexically) contains the - * operation (like <code>?new</code>) that wants to get the class. Thus, - * if a trusted template includes a non-trusted template, the - * <code>allowedClasses</code> restriction will apply in the included - * template. - * This parameter can be <code>null</code> (means no trusted templates). - */ - public OptInTemplateClassResolver( - Set allowedClasses, List<String> trustedTemplates) { - this.allowedClasses = allowedClasses != null ? allowedClasses : Collections.EMPTY_SET; - if (trustedTemplates != null) { - trustedTemplateNames = new HashSet(); - trustedTemplatePrefixes = new ArrayList(); - - Iterator<String> it = trustedTemplates.iterator(); - while (it.hasNext()) { - String li = it.next(); - if (li.startsWith("/")) li = li.substring(1); - if (li.endsWith("*")) { - trustedTemplatePrefixes.add(li.substring(0, li.length() - 1)); - } else { - trustedTemplateNames.add(li); - } - } - } else { - trustedTemplateNames = Collections.EMPTY_SET; - trustedTemplatePrefixes = Collections.EMPTY_LIST; - } - } - - @Override - public Class resolve(String className, Environment env, Template template) - throws TemplateException { - String templateName = safeGetTemplateName(template); - - if (templateName != null - && (trustedTemplateNames.contains(templateName) - || hasMatchingPrefix(templateName))) { - return TemplateClassResolver.UNRESTRICTED_RESOLVER.resolve(className, env, template); - } else { - if (!allowedClasses.contains(className)) { - throw new _MiscTemplateException(env, - "Instantiating ", className, " is not allowed in the template for security reasons. (If you " - + "run into this problem when using ?new in a template, you may want to check the \"", - Configurable.NEW_BUILTIN_CLASS_RESOLVER_KEY, - "\" setting in the FreeMarker configuration.)"); - } else { - try { - return _ClassUtil.forName(className); - } catch (ClassNotFoundException e) { - throw new _MiscTemplateException(e, env); - } - } - } - } - - /** - * Extract the template name from the template object which will be matched - * against the trusted template names and pattern. - */ - protected String safeGetTemplateName(Template template) { - if (template == null) return null; - - String name = template.getName(); - if (name == null) return null; - - // Detect exploits, return null if one is suspected: - String decodedName = name; - if (decodedName.indexOf('%') != -1) { - decodedName = _StringUtil.replace(decodedName, "%2e", ".", false, false); - decodedName = _StringUtil.replace(decodedName, "%2E", ".", false, false); - decodedName = _StringUtil.replace(decodedName, "%2f", "/", false, false); - decodedName = _StringUtil.replace(decodedName, "%2F", "/", false, false); - decodedName = _StringUtil.replace(decodedName, "%5c", "\\", false, false); - decodedName = _StringUtil.replace(decodedName, "%5C", "\\", false, false); - } - int dotDotIdx = decodedName.indexOf(".."); - if (dotDotIdx != -1) { - int before = dotDotIdx - 1 >= 0 ? decodedName.charAt(dotDotIdx - 1) : -1; - int after = dotDotIdx + 2 < decodedName.length() ? decodedName.charAt(dotDotIdx + 2) : -1; - if ((before == -1 || before == '/' || before == '\\') - && (after == -1 || after == '/' || after == '\\')) { - return null; - } - } - - return name.startsWith("/") ? name.substring(1) : name; - } - - private boolean hasMatchingPrefix(String name) { - for (int i = 0; i < trustedTemplatePrefixes.size(); i++) { - String prefix = (String) trustedTemplatePrefixes.get(i); - if (name.startsWith(prefix)) return true; - } - return false; - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/OrExpression.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/OrExpression.java b/src/main/java/org/apache/freemarker/core/ast/OrExpression.java deleted file mode 100644 index 6c0d3bf..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/OrExpression.java +++ /dev/null @@ -1,81 +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.ast; - -import org.apache.freemarker.core.TemplateException; - -final class OrExpression extends BooleanExpression { - - private final Expression lho; - private final Expression rho; - - OrExpression(Expression lho, Expression rho) { - this.lho = lho; - this.rho = rho; - } - - @Override - boolean evalToBoolean(Environment env) throws TemplateException { - return lho.evalToBoolean(env) || rho.evalToBoolean(env); - } - - @Override - public String getCanonicalForm() { - return lho.getCanonicalForm() + " || " + rho.getCanonicalForm(); - } - - @Override - String getNodeTypeSymbol() { - return "||"; - } - - @Override - boolean isLiteral() { - return constantValue != null || (lho.isLiteral() && rho.isLiteral()); - } - - @Override - protected Expression deepCloneWithIdentifierReplaced_inner( - String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) { - return new OrExpression( - lho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState), - rho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState)); - } - - @Override - int getParameterCount() { - return 2; - } - - @Override - Object getParameterValue(int idx) { - switch (idx) { - case 0: return lho; - case 1: return rho; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - ParameterRole getParameterRole(int idx) { - return ParameterRole.forBinaryOperatorOperand(idx); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/OutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/OutputFormat.java b/src/main/java/org/apache/freemarker/core/ast/OutputFormat.java deleted file mode 100644 index 506d4fa..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/OutputFormat.java +++ /dev/null @@ -1,84 +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.ast; - -import org.apache.freemarker.core.Configuration; -import org.apache.freemarker.core.util._ClassUtil; -import org.apache.freemarker.core.util._StringUtil; - -/** - * Represents an output format. If you need auto-escaping, see its subclass, {@link MarkupOutputFormat}. - * - * @see Configuration#setOutputFormat(OutputFormat) - * @see Configuration#setRegisteredCustomOutputFormats(java.util.Collection) - * @see MarkupOutputFormat - * - * @since 2.3.24 - */ -public abstract class OutputFormat { - - /** - * The short name used to refer to this format (like in the {@code #ftl} header). - */ - public abstract String getName(); - - /** - * Returns the MIME type of the output format. This might comes handy when generating a HTTP response. {@code null} - * if this output format doesn't clearly corresponds to a specific MIME type. - */ - public abstract String getMimeType(); - - /** - * Tells if this output format allows inserting {@link TemplateMarkupOutputModel}-s of another output formats into - * it. If {@code true}, the foreign {@link TemplateMarkupOutputModel} will be inserted into the output as is (like - * if the surrounding output format was the same). This is usually a bad idea allow, as such an event could indicate - * application bugs. If this method returns {@code false} (recommended), then FreeMarker will try to assimilate the - * inserted value by converting its format to this format, which will currently (2.3.24) cause exception, unless the - * inserted value is made by escaping plain text and the target format is non-escaping, in which case format - * conversion is trivially possible. (It's not impossible that conversions will be extended beyond this, if there - * will be demand for that.) - * - * <p> - * {@code true} value is used by {@link UndefinedOutputFormat}. - */ - public abstract boolean isOutputFormatMixingAllowed(); - - /** - * Returns the short description of this format, to be used in error messages. - * Override {@link #toStringExtraProperties()} to customize this. - */ - @Override - public final String toString() { - String extras = toStringExtraProperties(); - return getName() + "(" - + "mimeType=" + _StringUtil.jQuote(getMimeType()) + ", " - + "class=" + _ClassUtil.getShortClassNameOfObject(this, true) - + (extras.length() != 0 ? ", " : "") + extras - + ")"; - } - - /** - * Should be like {@code "foo=\"something\", bar=123"}; this will be inserted inside the parentheses in - * {@link #toString()}. Shouldn't return {@code null}; should return {@code ""} if there are no extra properties. - */ - protected String toStringExtraProperties() { - return ""; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/OutputFormatBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/OutputFormatBlock.java b/src/main/java/org/apache/freemarker/core/ast/OutputFormatBlock.java deleted file mode 100644 index 083ec24..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/OutputFormatBlock.java +++ /dev/null @@ -1,87 +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.ast; - -import java.io.IOException; - -import org.apache.freemarker.core.TemplateException; - -/** - * An #outputFormat element - */ -final class OutputFormatBlock extends TemplateElement { - - private final Expression paramExp; - - OutputFormatBlock(TemplateElements children, Expression paramExp) { - this.paramExp = paramExp; - setChildren(children); - } - - @Override - TemplateElement[] accept(Environment env) throws TemplateException, IOException { - return getChildBuffer(); - } - - @Override - protected String dump(boolean canonical) { - if (canonical) { - return "<" + getNodeTypeSymbol() + " \"" + paramExp.getCanonicalForm() + "\">" - + getChildrenCanonicalForm() + "</" + getNodeTypeSymbol() + ">"; - } else { - return getNodeTypeSymbol(); - } - } - - @Override - String getNodeTypeSymbol() { - return "#outputformat"; - } - - @Override - int getParameterCount() { - return 1; - } - - @Override - Object getParameterValue(int idx) { - if (idx == 0) return paramExp; - else - throw new IndexOutOfBoundsException(); - } - - @Override - ParameterRole getParameterRole(int idx) { - if (idx == 0) return ParameterRole.VALUE; - else - throw new IndexOutOfBoundsException(); - } - - @Override - boolean isIgnorable(boolean stripWhitespace) { - return getChildCount() == 0; - } - - @Override - boolean isNestedBlockRepeater() { - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/OutputFormatBoundBuiltIn.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/OutputFormatBoundBuiltIn.java b/src/main/java/org/apache/freemarker/core/ast/OutputFormatBoundBuiltIn.java deleted file mode 100644 index 92b0d89..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/OutputFormatBoundBuiltIn.java +++ /dev/null @@ -1,48 +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.ast; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.util._NullArgumentException; - -abstract class OutputFormatBoundBuiltIn extends SpecialBuiltIn { - - protected OutputFormat outputFormat; - protected int autoEscapingPolicy; - - void bindToOutputFormat(OutputFormat outputFormat, int autoEscapingPolicy) { - _NullArgumentException.check(outputFormat); - this.outputFormat = outputFormat; - this.autoEscapingPolicy = autoEscapingPolicy; - } - - @Override - TemplateModel _eval(Environment env) throws TemplateException { - if (outputFormat == null) { - // The parser should prevent this situation - throw new NullPointerException("outputFormat was null"); - } - return calculateResult(env); - } - - protected abstract TemplateModel calculateResult(Environment env) - throws TemplateException; - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ParameterRole.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ParameterRole.java b/src/main/java/org/apache/freemarker/core/ast/ParameterRole.java deleted file mode 100644 index 61dede4..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ParameterRole.java +++ /dev/null @@ -1,93 +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.ast; - -// Change this to an Enum in Java 5 -/** - * @see TemplateObject#getParameterRole(int) - */ -final class ParameterRole { - - private final String name; - - static final ParameterRole UNKNOWN = new ParameterRole("[unknown role]"); - - // When figuring out the names of these, always read them after the possible getName() values. It should sound OK. - // Like "`+` left hand operand", or "`#if` parameter". That is, the roles (only) have to make sense in the - // context of the possible TemplateObject classes. - static final ParameterRole LEFT_HAND_OPERAND = new ParameterRole("left-hand operand"); - static final ParameterRole RIGHT_HAND_OPERAND = new ParameterRole("right-hand operand"); - static final ParameterRole ENCLOSED_OPERAND = new ParameterRole("enclosed operand"); - static final ParameterRole ITEM_VALUE = new ParameterRole("item value"); - static final ParameterRole ITEM_KEY = new ParameterRole("item key"); - static final ParameterRole ASSIGNMENT_TARGET = new ParameterRole("assignment target"); - static final ParameterRole ASSIGNMENT_OPERATOR = new ParameterRole("assignment operator"); - static final ParameterRole ASSIGNMENT_SOURCE = new ParameterRole("assignment source"); - static final ParameterRole VARIABLE_SCOPE = new ParameterRole("variable scope"); - static final ParameterRole NAMESPACE = new ParameterRole("namespace"); - static final ParameterRole ERROR_HANDLER = new ParameterRole("error handler"); - static final ParameterRole PASSED_VALUE = new ParameterRole("passed value"); - static final ParameterRole CONDITION = new ParameterRole("condition"); - static final ParameterRole VALUE = new ParameterRole("value"); - static final ParameterRole AST_NODE_SUBTYPE = new ParameterRole("AST-node subtype"); - static final ParameterRole PLACEHOLDER_VARIABLE = new ParameterRole("placeholder variable"); - static final ParameterRole EXPRESSION_TEMPLATE = new ParameterRole("expression template"); - static final ParameterRole LIST_SOURCE = new ParameterRole("list source"); - static final ParameterRole TARGET_LOOP_VARIABLE = new ParameterRole("target loop variable"); - static final ParameterRole TEMPLATE_NAME = new ParameterRole("template name"); - static final ParameterRole PARSE_PARAMETER = new ParameterRole("\"parse\" parameter"); - static final ParameterRole ENCODING_PARAMETER = new ParameterRole("\"encoding\" parameter"); - static final ParameterRole IGNORE_MISSING_PARAMETER = new ParameterRole("\"ignore_missing\" parameter"); - static final ParameterRole PARAMETER_NAME = new ParameterRole("parameter name"); - static final ParameterRole PARAMETER_DEFAULT = new ParameterRole("parameter default"); - static final ParameterRole CATCH_ALL_PARAMETER_NAME = new ParameterRole("catch-all parameter name"); - static final ParameterRole ARGUMENT_NAME = new ParameterRole("argument name"); - static final ParameterRole ARGUMENT_VALUE = new ParameterRole("argument value"); - static final ParameterRole CONTENT = new ParameterRole("content"); - static final ParameterRole EMBEDDED_TEMPLATE = new ParameterRole("embedded template"); - static final ParameterRole VALUE_PART = new ParameterRole("value part"); - static final ParameterRole MINIMUM_DECIMALS = new ParameterRole("minimum decimals"); - static final ParameterRole MAXIMUM_DECIMALS = new ParameterRole("maximum decimals"); - static final ParameterRole NODE = new ParameterRole("node"); - static final ParameterRole CALLEE = new ParameterRole("callee"); - static final ParameterRole MESSAGE = new ParameterRole("message"); - - private ParameterRole(String name) { - this.name = name; - } - - static ParameterRole forBinaryOperatorOperand(int paramIndex) { - switch (paramIndex) { - case 0: return LEFT_HAND_OPERAND; - case 1: return RIGHT_HAND_OPERAND; - default: throw new IndexOutOfBoundsException(); - } - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ParentheticalExpression.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ParentheticalExpression.java b/src/main/java/org/apache/freemarker/core/ast/ParentheticalExpression.java deleted file mode 100644 index 5699f1c..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ParentheticalExpression.java +++ /dev/null @@ -1,86 +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.ast; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateModel; - -final class ParentheticalExpression extends Expression { - - private final Expression nested; - - ParentheticalExpression(Expression nested) { - this.nested = nested; - } - - @Override - boolean evalToBoolean(Environment env) throws TemplateException { - return nested.evalToBoolean(env); - } - - @Override - public String getCanonicalForm() { - return "(" + nested.getCanonicalForm() + ")"; - } - - @Override - String getNodeTypeSymbol() { - return "(...)"; - } - - @Override - TemplateModel _eval(Environment env) throws TemplateException { - return nested.eval(env); - } - - @Override - public boolean isLiteral() { - return nested.isLiteral(); - } - - Expression getNestedExpression() { - return nested; - } - - @Override - protected Expression deepCloneWithIdentifierReplaced_inner( - String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) { - return new ParentheticalExpression( - nested.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState)); - } - - @Override - int getParameterCount() { - return 1; - } - - @Override - Object getParameterValue(int idx) { - if (idx != 0) throw new IndexOutOfBoundsException(); - return nested; - } - - @Override - ParameterRole getParameterRole(int idx) { - if (idx != 0) throw new IndexOutOfBoundsException(); - return ParameterRole.ENCLOSED_OPERAND; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ParseException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ParseException.java b/src/main/java/org/apache/freemarker/core/ast/ParseException.java deleted file mode 100644 index f834d8d..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ParseException.java +++ /dev/null @@ -1,513 +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.ast; - -import java.io.IOException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.apache.freemarker.core.Template; -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.util._SecurityUtil; -import org.apache.freemarker.core.util._StringUtil; - -/** - * Parsing-time exception in a template (as opposed to a runtime exception, a {@link TemplateException}). This usually - * signals syntactical/lexical errors. - * - * Note that on JavaCC-level lexical errors throw {@link TokenMgrError} instead of this, however with the API-s that - * most users use those will be wrapped into {@link ParseException}-s. - * - * This is a modified version of file generated by JavaCC from FTL.jj. - * You can modify this class to customize the error reporting mechanisms so long as the public interface - * remains compatible with the original. - * - * @see TokenMgrError - */ -public class ParseException extends IOException implements FMParserConstants { - - /** - * This is the last token that has been consumed successfully. If - * this object has been created due to a parse error, the token - * following this token will (therefore) be the first error token. - */ - public Token currentToken; - - private static volatile Boolean jbossToolsMode; - - private boolean messageAndDescriptionRendered; - private String message; - private String description; - - public int columnNumber, lineNumber; - public int endColumnNumber, endLineNumber; - - /** - * Each entry in this array is an array of integers. Each array - * of integers represents a sequence of tokens (by their ordinal - * values) that is expected at this point of the parse. - */ - public int[][] expectedTokenSequences; - - /** - * This is a reference to the "tokenImage" array of the generated - * parser within which the parse error occurred. This array is - * defined in the generated ...Constants interface. - */ - public String[] tokenImage; - - /** - * The end of line string for this machine. - */ - protected String eol = _SecurityUtil.getSystemProperty("line.separator", "\n"); - - private String templateName; - - /** - * This constructor is used by the method "generateParseException" - * in the generated parser. Calling this constructor generates - * a new object of this type with the fields "currentToken", - * "expectedTokenSequences", and "tokenImage" set. - * This constructor calls its super class with the empty string - * to force the "toString" method of parent class "Throwable" to - * print the error message in the form: - * ParseException: <result of getMessage> - */ - public ParseException(Token currentTokenVal, - int[][] expectedTokenSequencesVal, - String[] tokenImageVal - ) { - super(""); - currentToken = currentTokenVal; - expectedTokenSequences = expectedTokenSequencesVal; - tokenImage = tokenImageVal; - lineNumber = currentToken.next.beginLine; - columnNumber = currentToken.next.beginColumn; - endLineNumber = currentToken.next.endLine; - endColumnNumber = currentToken.next.endColumn; - } - - /** - * Used by JavaCC generated code. - */ - protected ParseException() { - super(); - } - - /** - * @since 2.3.21 - */ - public ParseException(String description, Template template, - int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber) { - this(description, template, lineNumber, columnNumber, endLineNumber, endColumnNumber, null); - } - - /** - * @since 2.3.21 - */ - public ParseException(String description, Template template, - int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber, - Throwable cause) { - this(description, - template == null ? null : template.getSourceName(), - lineNumber, columnNumber, - endLineNumber, endColumnNumber, - cause); - } - - /** - * @since 2.3.20 - */ - public ParseException(String description, Template template, Token tk) { - this(description, template, tk, null); - } - - /** - * @since 2.3.20 - */ - public ParseException(String description, Template template, Token tk, Throwable cause) { - this(description, - template == null ? null : template.getSourceName(), - tk.beginLine, tk.beginColumn, - tk.endLine, tk.endColumn, - cause); - } - - /** - * @since 2.3.20 - */ - public ParseException(String description, TemplateObject tobj) { - this(description, tobj, null); - } - - /** - * @since 2.3.20 - */ - public ParseException(String description, TemplateObject tobj, Throwable cause) { - this(description, - tobj.getTemplate() == null ? null : tobj.getTemplate().getSourceName(), - tobj.beginLine, tobj.beginColumn, - tobj.endLine, tobj.endColumn, - cause); - } - - private ParseException(String description, String templateName, - int lineNumber, int columnNumber, - int endLineNumber, int endColumnNumber, - Throwable cause) { - super(description); // but we override getMessage, so it will be different - try { - initCause(cause); - } catch (Exception e) { - // Suppressed; we can't do more - } - this.description = description; - this.templateName = templateName; - this.lineNumber = lineNumber; - this.columnNumber = columnNumber; - this.endLineNumber = endLineNumber; - this.endColumnNumber = endColumnNumber; - } - - /** - * Should be used internally only; sets the name of the template that contains the error. - * This is needed as the constructor that JavaCC automatically calls doesn't pass in the template, so we - * set it somewhere later in an exception handler. - */ - public void setTemplateName(String templateName) { - this.templateName = templateName; - synchronized (this) { - messageAndDescriptionRendered = false; - message = null; - } - } - - /** - * Returns the error location plus the error description. - * - * @see #getDescription() - * @see #getTemplateName() - * @see #getLineNumber() - * @see #getColumnNumber() - */ - @Override - public String getMessage() { - synchronized (this) { - if (messageAndDescriptionRendered) return message; - } - renderMessageAndDescription(); - synchronized (this) { - return message; - } - } - - private String getDescription() { - synchronized (this) { - if (messageAndDescriptionRendered) return description; - } - renderMessageAndDescription(); - synchronized (this) { - return description; - } - } - - /** - * Returns the description of the error without error location or source quotations, or {@code null} if there's no - * description available. This is useful in editors (IDE-s) where the error markers and the editor window itself - * already carry this information, so it's redundant the repeat in the error dialog. - */ - public String getEditorMessage() { - return getDescription(); - } - - /** - * Returns the name (template-root relative path) of the template whose parsing was failed. - * Maybe {@code null} if this is a non-stored template. - * - * @since 2.3.20 - */ - public String getTemplateName() { - return templateName; - } - - /** - * 1-based line number of the failing section, or 0 is the information is not available. - */ - public int getLineNumber() { - return lineNumber; - } - - /** - * 1-based column number of the failing section, or 0 is the information is not available. - */ - public int getColumnNumber() { - return columnNumber; - } - - /** - * 1-based line number of the last line that contains the failing section, or 0 if the information is not available. - * - * @since 2.3.21 - */ - public int getEndLineNumber() { - return endLineNumber; - } - - /** - * 1-based column number of the last character of the failing section, or 0 if the information is not available. - * Note that unlike with Java string API-s, this column number is inclusive. - * - * @since 2.3.21 - */ - public int getEndColumnNumber() { - return endColumnNumber; - } - - private void renderMessageAndDescription() { - String desc = getOrRenderDescription(); - - String prefix; - if (!isInJBossToolsMode()) { - prefix = "Syntax error " - + MessageUtil.formatLocationForSimpleParsingError(templateName, lineNumber, columnNumber) - + ":\n"; - } else { - prefix = "[col. " + columnNumber + "] "; - } - - String msg = prefix + desc; - desc = msg.substring(prefix.length()); // so we reuse the backing char[] - - synchronized (this) { - message = msg; - description = desc; - messageAndDescriptionRendered = true; - } - } - - private boolean isInJBossToolsMode() { - if (jbossToolsMode == null) { - try { - jbossToolsMode = Boolean.valueOf( - ParseException.class.getClassLoader().toString().indexOf( - "[org.jboss.ide.eclipse.freemarker:") != -1); - } catch (Throwable e) { - jbossToolsMode = Boolean.FALSE; - } - } - return jbossToolsMode.booleanValue(); - } - - /** - * Returns the description of the error without the error location, or {@code null} if there's no description - * available. - */ - private String getOrRenderDescription() { - synchronized (this) { - if (description != null) return description; // When we already have it from the constructor - } - - String tokenErrDesc; - if (currentToken != null) { - tokenErrDesc = getCustomTokenErrorDescription(); - if (tokenErrDesc == null) { - // The default JavaCC message generation stuff follows. - StringBuilder expected = new StringBuilder(); - int maxSize = 0; - for (int i = 0; i < expectedTokenSequences.length; i++) { - if (i != 0) { - expected.append(eol); - } - expected.append(" "); - if (maxSize < expectedTokenSequences[i].length) { - maxSize = expectedTokenSequences[i].length; - } - for (int j = 0; j < expectedTokenSequences[i].length; j++) { - if (j != 0) expected.append(' '); - expected.append(tokenImage[expectedTokenSequences[i][j]]); - } - } - tokenErrDesc = "Encountered \""; - Token tok = currentToken.next; - for (int i = 0; i < maxSize; i++) { - if (i != 0) tokenErrDesc += " "; - if (tok.kind == 0) { - tokenErrDesc += tokenImage[0]; - break; - } - tokenErrDesc += add_escapes(tok.image); - tok = tok.next; - } - tokenErrDesc += "\", but "; - - if (expectedTokenSequences.length == 1) { - tokenErrDesc += "was expecting:" + eol; - } else { - tokenErrDesc += "was expecting one of:" + eol; - } - tokenErrDesc += expected; - } - } else { - tokenErrDesc = null; - } - return tokenErrDesc; - } - - private String getCustomTokenErrorDescription() { - final Token nextToken = currentToken.next; - final int kind = nextToken.kind; - if (kind == EOF) { - Set/*<String>*/ endNames = new HashSet(); - for (int[] sequence : expectedTokenSequences) { - for (int aSequence : sequence) { - switch (aSequence) { - case END_FOREACH: - endNames.add("#foreach"); - break; - case END_LIST: - endNames.add("#list"); - break; - case END_SWITCH: - endNames.add("#switch"); - break; - case END_IF: - endNames.add("#if"); - break; - case END_COMPRESS: - endNames.add("#compress"); - break; - case END_MACRO: - endNames.add("#macro"); - case END_FUNCTION: - endNames.add("#function"); - break; - case END_TRANSFORM: - endNames.add("#transform"); - break; - case END_ESCAPE: - endNames.add("#escape"); - break; - case END_NOESCAPE: - endNames.add("#noescape"); - break; - case END_ASSIGN: - endNames.add("#assign"); - break; - case END_LOCAL: - endNames.add("#local"); - break; - case END_GLOBAL: - endNames.add("#global"); - break; - case END_ATTEMPT: - endNames.add("#attempt"); - break; - case CLOSING_CURLY_BRACKET: - endNames.add("\"{\""); - break; - case CLOSE_BRACKET: - endNames.add("\"[\""); - break; - case CLOSE_PAREN: - endNames.add("\"(\""); - break; - case UNIFIED_CALL_END: - endNames.add("@..."); - break; - } - } - } - return "Unexpected end of file reached." - + (endNames.size() == 0 ? "" : " You have an unclosed " + concatWithOrs(endNames) + "."); - } else if (kind == ELSE) { - return "Unexpected directive, \"#else\". " - + "Check if you have a valid #if-#elseif-#else or #list-#else structure."; - } else if (kind == END_IF || kind == ELSE_IF) { - return "Unexpected directive, " - + _StringUtil.jQuote(nextToken) - + ". Check if you have a valid #if-#elseif-#else structure."; - } - return null; - } - - private String concatWithOrs(Set/*<String>*/ endNames) { - StringBuilder sb = new StringBuilder(); - for (Iterator/*<String>*/ it = endNames.iterator(); it.hasNext(); ) { - String endName = (String) it.next(); - if (sb.length() != 0) { - sb.append(" or "); - } - sb.append(endName); - } - return sb.toString(); - } - - /** - * Used to convert raw characters to their escaped version - * when these raw version cannot be used as part of an ASCII - * string literal. - */ - protected String add_escapes(String str) { - StringBuilder retval = new StringBuilder(); - char ch; - for (int i = 0; i < str.length(); i++) { - switch (str.charAt(i)) - { - case 0 : - continue; - case '\b': - retval.append("\\b"); - continue; - case '\t': - retval.append("\\t"); - continue; - case '\n': - retval.append("\\n"); - continue; - case '\f': - retval.append("\\f"); - continue; - case '\r': - retval.append("\\r"); - continue; - case '\"': - retval.append("\\\""); - continue; - case '\'': - retval.append("\\\'"); - continue; - case '\\': - retval.append("\\\\"); - continue; - default: - if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { - String s = "0000" + Integer.toString(ch, 16); - retval.append("\\u" + s.substring(s.length() - 4, s.length())); - } else { - retval.append(ch); - } - continue; - } - } - return retval.toString(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ParserConfiguration.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ParserConfiguration.java b/src/main/java/org/apache/freemarker/core/ast/ParserConfiguration.java deleted file mode 100644 index bd266ed..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ParserConfiguration.java +++ /dev/null @@ -1,80 +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.ast; - -import org.apache.freemarker.core.Configuration; -import org.apache.freemarker.core.Version; - -/** - * <b>Don't implement this interface yourself</b>; use the existing implementation(s). This interface is implemented by - * classes that hold settings that affect parsing. New parser settings can be added in new FreeMarker versions, which - * will break your implementation. - * - * @since 2.3.24 - */ -public interface ParserConfiguration { - - /** - * See {@link Configuration#getTagSyntax()}. - */ - int getTagSyntax(); - - /** - * See {@link Configuration#getNamingConvention()}. - */ - int getNamingConvention(); - - /** - * See {@link Configuration#getWhitespaceStripping()}. - */ - boolean getWhitespaceStripping(); - - /** - * Overlaps with {@link Configurable#getArithmeticEngine()}; the parser needs this for creating numerical literals. - */ - ArithmeticEngine getArithmeticEngine(); - - /** - * See {@link Configuration#getAutoEscapingPolicy()}. - */ - int getAutoEscapingPolicy(); - - /** - * See {@link Configuration#getOutputEncoding()}. - */ - OutputFormat getOutputFormat(); - - /** - * See {@link Configuration#getRecognizeStandardFileExtensions()}. - */ - boolean getRecognizeStandardFileExtensions(); - - /** - * See {@link Configuration#getIncompatibleImprovements()}. - */ - Version getIncompatibleImprovements(); - - /** - * See {@link Configuration#getTabSize()}. - * - * @since 2.3.25 - */ - int getTabSize(); - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/ParsingNotSupportedException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/ParsingNotSupportedException.java b/src/main/java/org/apache/freemarker/core/ast/ParsingNotSupportedException.java deleted file mode 100644 index ac8aadf..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/ParsingNotSupportedException.java +++ /dev/null @@ -1,37 +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.ast; - -/** - * Thrown when the {@link TemplateValueFormat} doesn't support parsing, and parsing was invoked. - * - * @since 2.3.24 - */ -public class ParsingNotSupportedException extends TemplateValueFormatException { - - public ParsingNotSupportedException(String message, Throwable cause) { - super(message, cause); - } - - public ParsingNotSupportedException(String message) { - this(message, null); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/PlainTextOutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/PlainTextOutputFormat.java b/src/main/java/org/apache/freemarker/core/ast/PlainTextOutputFormat.java deleted file mode 100644 index e7385c8..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/PlainTextOutputFormat.java +++ /dev/null @@ -1,56 +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.ast; - -/** - * Represents the plain text output format (MIME type "text/plain", name "plainText"). This format doesn't support - * escaping. This format doesn't allow mixing in template output values of other output formats. - * - * <p> - * The main difference from {@link UndefinedOutputFormat} is that this format doesn't allow inserting values of another - * output format into itself (unless they can be converted to plain text), while {@link UndefinedOutputFormat} would - * just insert the foreign "markup" as is. Also, this format has {"text/plain"} MIME type, while - * {@link UndefinedOutputFormat} has {@code null}. - * - * @since 2.3.24 - */ -public final class PlainTextOutputFormat extends OutputFormat { - - public static final PlainTextOutputFormat INSTANCE = new PlainTextOutputFormat(); - - private PlainTextOutputFormat() { - // Only to decrease visibility - } - - @Override - public boolean isOutputFormatMixingAllowed() { - return false; - } - - @Override - public String getName() { - return "plainText"; - } - - @Override - public String getMimeType() { - return "text/plain"; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/PropertySetting.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/PropertySetting.java b/src/main/java/org/apache/freemarker/core/ast/PropertySetting.java deleted file mode 100644 index 6a91c22..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/PropertySetting.java +++ /dev/null @@ -1,177 +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.ast; - -import java.util.Arrays; - -import org.apache.freemarker.core.Configuration; -import org.apache.freemarker.core.ConfigurationException; -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core._TemplateAPI; -import org.apache.freemarker.core.model.TemplateBooleanModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateNumberModel; -import org.apache.freemarker.core.model.TemplateScalarModel; -import org.apache.freemarker.core.util._StringUtil; - -/** - * An instruction that sets a property of the template rendering - * environment. - */ -final class PropertySetting extends TemplateElement { - - private final String key; - private final Expression value; - - static final String[] SETTING_NAMES = new String[] { - // Must be sorted alphabetically! - Configurable.BOOLEAN_FORMAT_KEY_CAMEL_CASE, - Configurable.BOOLEAN_FORMAT_KEY_SNAKE_CASE, - Configurable.DATE_FORMAT_KEY_CAMEL_CASE, - Configurable.DATE_FORMAT_KEY_SNAKE_CASE, - Configurable.DATETIME_FORMAT_KEY_CAMEL_CASE, - Configurable.DATETIME_FORMAT_KEY_SNAKE_CASE, - Configurable.LOCALE_KEY, - Configurable.NUMBER_FORMAT_KEY_CAMEL_CASE, - Configurable.NUMBER_FORMAT_KEY_SNAKE_CASE, - Configurable.OUTPUT_ENCODING_KEY_CAMEL_CASE, - Configurable.OUTPUT_ENCODING_KEY_SNAKE_CASE, - Configurable.SQL_DATE_AND_TIME_TIME_ZONE_KEY_CAMEL_CASE, - Configurable.SQL_DATE_AND_TIME_TIME_ZONE_KEY, - Configurable.TIME_FORMAT_KEY_CAMEL_CASE, - Configurable.TIME_ZONE_KEY_CAMEL_CASE, - Configurable.TIME_FORMAT_KEY_SNAKE_CASE, - Configurable.TIME_ZONE_KEY_SNAKE_CASE, - Configurable.URL_ESCAPING_CHARSET_KEY_CAMEL_CASE, - Configurable.URL_ESCAPING_CHARSET_KEY_SNAKE_CASE - }; - - PropertySetting(Token keyTk, FMParserTokenManager tokenManager, Expression value, Configuration cfg) - throws ParseException { - String key = keyTk.image; - if (Arrays.binarySearch(SETTING_NAMES, key) < 0) { - StringBuilder sb = new StringBuilder(); - if (_TemplateAPI.getConfigurationSettingNames(cfg, true).contains(key) - || _TemplateAPI.getConfigurationSettingNames(cfg, false).contains(key)) { - sb.append("The setting name is recognized, but changing this setting from inside a template isn't " - + "supported."); - } else { - sb.append("Unknown setting name: "); - sb.append(_StringUtil.jQuote(key)).append("."); - sb.append(" The allowed setting names are: "); - - int shownNamingConvention; - { - int namingConvention = tokenManager.namingConvention; - shownNamingConvention = namingConvention != Configuration.AUTO_DETECT_NAMING_CONVENTION - ? namingConvention : Configuration.LEGACY_NAMING_CONVENTION /* [2.4] CAMEL_CASE */; - } - - boolean first = true; - for (String correctName : SETTING_NAMES) { - int correctNameNamingConvention = _StringUtil.getIdentifierNamingConvention(correctName); - if (shownNamingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION - ? correctNameNamingConvention != Configuration.LEGACY_NAMING_CONVENTION - : correctNameNamingConvention != Configuration.CAMEL_CASE_NAMING_CONVENTION) { - if (first) { - first = false; - } else { - sb.append(", "); - } - - sb.append(correctName); - } - } - } - throw new ParseException(sb.toString(), null, keyTk); - } - - this.key = key; - this.value = value; - } - - @Override - TemplateElement[] accept(Environment env) throws TemplateException { - TemplateModel mval = value.eval(env); - String strval; - if (mval instanceof TemplateScalarModel) { - strval = ((TemplateScalarModel) mval).getAsString(); - } else if (mval instanceof TemplateBooleanModel) { - strval = ((TemplateBooleanModel) mval).getAsBoolean() ? "true" : "false"; - } else if (mval instanceof TemplateNumberModel) { - strval = ((TemplateNumberModel) mval).getAsNumber().toString(); - } else { - strval = value.evalAndCoerceToStringOrUnsupportedMarkup(env); - } - try { - env.setSetting(key, strval); - } catch (ConfigurationException e) { - throw new _MiscTemplateException(env, e.getMessage(), e.getCause()); - } - return null; - } - - @Override - protected String dump(boolean canonical) { - StringBuilder sb = new StringBuilder(); - if (canonical) sb.append('<'); - sb.append(getNodeTypeSymbol()); - sb.append(' '); - sb.append(_StringUtil.toFTLTopLevelTragetIdentifier(key)); - sb.append('='); - sb.append(value.getCanonicalForm()); - if (canonical) sb.append("/>"); - return sb.toString(); - } - - @Override - String getNodeTypeSymbol() { - return "#setting"; - } - - @Override - int getParameterCount() { - return 2; - } - - @Override - Object getParameterValue(int idx) { - switch (idx) { - case 0: return key; - case 1: return value; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - ParameterRole getParameterRole(int idx) { - switch (idx) { - case 0: return ParameterRole.ITEM_KEY; - case 1: return ParameterRole.ITEM_VALUE; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - boolean isNestedBlockRepeater() { - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/RTFOutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/RTFOutputFormat.java b/src/main/java/org/apache/freemarker/core/ast/RTFOutputFormat.java deleted file mode 100644 index d8f2ae1..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/RTFOutputFormat.java +++ /dev/null @@ -1,75 +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.ast; - -import java.io.IOException; -import java.io.Writer; - -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.util._StringUtil; - -/** - * Represents the Rich Text Format output format (MIME type "application/rtf", name "RTF"). This format escapes by - * default (via {@link _StringUtil#RTFEnc(String)}). The {@code ?rtf} built-in silently bypasses template output values - * of the type produced by this output format ({@link TemplateRTFOutputModel}). - * - * @since 2.3.24 - */ -public final class RTFOutputFormat extends CommonMarkupOutputFormat<TemplateRTFOutputModel> { - - /** - * The only instance (singleton) of this {@link OutputFormat}. - */ - public static final RTFOutputFormat INSTANCE = new RTFOutputFormat(); - - private RTFOutputFormat() { - // Only to decrease visibility - } - - @Override - public String getName() { - return "RTF"; - } - - @Override - public String getMimeType() { - return "application/rtf"; - } - - @Override - public void output(String textToEsc, Writer out) throws IOException, TemplateModelException { - _StringUtil.RTFEnc(textToEsc, out); - } - - @Override - public String escapePlainText(String plainTextContent) { - return _StringUtil.RTFEnc(plainTextContent); - } - - @Override - public boolean isLegacyBuiltInBypassed(String builtInName) { - return builtInName.equals("rtf"); - } - - @Override - protected TemplateRTFOutputModel newTemplateMarkupOutputModel(String plainTextContent, String markupContent) { - return new TemplateRTFOutputModel(plainTextContent, markupContent); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/Range.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/Range.java b/src/main/java/org/apache/freemarker/core/ast/Range.java deleted file mode 100644 index 8cd01cf..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/Range.java +++ /dev/null @@ -1,119 +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.ast; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateModel; - -/** - * A class that represents a Range between two integers. - */ -final class Range extends Expression { - - static final int END_INCLUSIVE = 0; - static final int END_EXCLUSIVE = 1; - static final int END_UNBOUND = 2; - static final int END_SIZE_LIMITED = 3; - - final Expression lho; - final Expression rho; - final int endType; - - Range(Expression lho, Expression rho, int endType) { - this.lho = lho; - this.rho = rho; - this.endType = endType; - } - - int getEndType() { - return endType; - } - - @Override - TemplateModel _eval(Environment env) throws TemplateException { - final int begin = lho.evalToNumber(env).intValue(); - if (endType != END_UNBOUND) { - final int lhoValue = rho.evalToNumber(env).intValue(); - return new BoundedRangeModel( - begin, endType != END_SIZE_LIMITED ? lhoValue : begin + lhoValue, - endType == END_INCLUSIVE, endType == END_SIZE_LIMITED); - } else { - return new ListableRightUnboundedRangeModel(begin); - } - } - - // Surely this way we can tell that it won't be a boolean without evaluating the range, but why was this important? - @Override - boolean evalToBoolean(Environment env) throws TemplateException { - throw new NonBooleanException(this, new BoundedRangeModel(0, 0, false, false), env); - } - - @Override - public String getCanonicalForm() { - String rhs = rho != null ? rho.getCanonicalForm() : ""; - return lho.getCanonicalForm() + getNodeTypeSymbol() + rhs; - } - - @Override - String getNodeTypeSymbol() { - switch (endType) { - case END_EXCLUSIVE: return "..<"; - case END_INCLUSIVE: return ".."; - case END_UNBOUND: return ".."; - case END_SIZE_LIMITED: return "..*"; - default: throw new BugException(endType); - } - } - - @Override - boolean isLiteral() { - boolean rightIsLiteral = rho == null || rho.isLiteral(); - return constantValue != null || (lho.isLiteral() && rightIsLiteral); - } - - @Override - protected Expression deepCloneWithIdentifierReplaced_inner( - String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) { - return new Range( - lho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState), - rho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState), - endType); - } - - @Override - int getParameterCount() { - return 2; - } - - @Override - Object getParameterValue(int idx) { - switch (idx) { - case 0: return lho; - case 1: return rho; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - ParameterRole getParameterRole(int idx) { - return ParameterRole.forBinaryOperatorOperand(idx); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/RangeModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/RangeModel.java b/src/main/java/org/apache/freemarker/core/ast/RangeModel.java deleted file mode 100644 index a038cf0..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/RangeModel.java +++ /dev/null @@ -1,59 +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.ast; - -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.model.TemplateSequenceModel; -import org.apache.freemarker.core.model.impl.SimpleNumber; - -abstract class RangeModel implements TemplateSequenceModel, java.io.Serializable { - - private final int begin; - - public RangeModel(int begin) { - this.begin = begin; - } - - final int getBegining() { - return begin; - } - - @Override - final public TemplateModel get(int index) throws TemplateModelException { - if (index < 0 || index >= size()) { - throw new _TemplateModelException("Range item index ", Integer.valueOf(index), " is out of bounds."); - } - long value = begin + getStep() * (long) index; - return value <= Integer.MAX_VALUE ? new SimpleNumber((int) value) : new SimpleNumber(value); - } - - /** - * @return {@code 1} or {@code -1}; other return values need not be properly handled until FTL supports other steps. - */ - abstract int getStep(); - - abstract boolean isRightUnbounded(); - - abstract boolean isRightAdaptive(); - - abstract boolean isAffactedByStringSlicingBug(); - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/RecoveryBlock.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/RecoveryBlock.java b/src/main/java/org/apache/freemarker/core/ast/RecoveryBlock.java deleted file mode 100644 index 08886bd..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/RecoveryBlock.java +++ /dev/null @@ -1,74 +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.ast; - -import java.io.IOException; - -import org.apache.freemarker.core.TemplateException; - -final class RecoveryBlock extends TemplateElement { - - RecoveryBlock(TemplateElements children) { - setChildren(children); - } - - @Override - TemplateElement[] accept(Environment env) throws TemplateException, IOException { - return getChildBuffer(); - } - - @Override - protected String dump(boolean canonical) { - if (canonical) { - StringBuilder buf = new StringBuilder(); - buf.append('<').append(getNodeTypeSymbol()).append('>'); - buf.append(getChildrenCanonicalForm()); - return buf.toString(); - } else { - return getNodeTypeSymbol(); - } - } - - @Override - String getNodeTypeSymbol() { - return "#recover"; - } - - @Override - int getParameterCount() { - return 0; - } - - @Override - Object getParameterValue(int idx) { - throw new IndexOutOfBoundsException(); - } - - @Override - ParameterRole getParameterRole(int idx) { - throw new IndexOutOfBoundsException(); - } - - @Override - boolean isNestedBlockRepeater() { - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/RecurseNode.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/RecurseNode.java b/src/main/java/org/apache/freemarker/core/ast/RecurseNode.java deleted file mode 100644 index 6eaacaf..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/RecurseNode.java +++ /dev/null @@ -1,132 +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.ast; - -import java.io.IOException; - -import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.model.TemplateHashModel; -import org.apache.freemarker.core.model.TemplateModel; -import org.apache.freemarker.core.model.TemplateNodeModel; -import org.apache.freemarker.core.model.TemplateScalarModel; -import org.apache.freemarker.core.model.TemplateSequenceModel; -import org.apache.freemarker.core.model.impl.SimpleSequence; - - -/** - * An instruction to visit the children of a node. - */ -final class RecurseNode extends TemplateElement { - - Expression targetNode, namespaces; - - RecurseNode(Expression targetNode, Expression namespaces) { - this.targetNode = targetNode; - this.namespaces = namespaces; - } - - @Override - TemplateElement[] accept(Environment env) throws IOException, TemplateException { - TemplateModel node = targetNode == null ? null : targetNode.eval(env); - if (node != null && !(node instanceof TemplateNodeModel)) { - throw new NonNodeException(targetNode, node, "node", env); - } - - TemplateModel nss = namespaces == null ? null : namespaces.eval(env); - if (namespaces instanceof StringLiteral) { - nss = env.importLib(((TemplateScalarModel) nss).getAsString(), null); - } else if (namespaces instanceof ListLiteral) { - nss = ((ListLiteral) namespaces).evaluateStringsToNamespaces(env); - } - if (nss != null) { - if (nss instanceof TemplateHashModel) { - SimpleSequence ss = new SimpleSequence(1); - ss.add(nss); - nss = ss; - } else if (!(nss instanceof TemplateSequenceModel)) { - if (namespaces != null) { - throw new NonSequenceException(namespaces, nss, env); - } else { - // Should not occur - throw new _MiscTemplateException(env, "Expecting a sequence of namespaces after \"using\""); - } - } - } - - env.recurse((TemplateNodeModel) node, (TemplateSequenceModel) nss); - return null; - } - - @Override - protected String dump(boolean canonical) { - StringBuilder sb = new StringBuilder(); - if (canonical) sb.append('<'); - sb.append(getNodeTypeSymbol()); - if (targetNode != null) { - sb.append(' '); - sb.append(targetNode.getCanonicalForm()); - } - if (namespaces != null) { - sb.append(" using "); - sb.append(namespaces.getCanonicalForm()); - } - if (canonical) sb.append("/>"); - return sb.toString(); - } - - @Override - String getNodeTypeSymbol() { - return "#recurse"; - } - - @Override - int getParameterCount() { - return 2; - } - - @Override - Object getParameterValue(int idx) { - switch (idx) { - case 0: return targetNode; - case 1: return namespaces; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - ParameterRole getParameterRole(int idx) { - switch (idx) { - case 0: return ParameterRole.NODE; - case 1: return ParameterRole.NAMESPACE; - default: throw new IndexOutOfBoundsException(); - } - } - - @Override - boolean isNestedBlockRepeater() { - return false; - } - - @Override - boolean isShownInStackTrace() { - return true; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7d784b2b/src/main/java/org/apache/freemarker/core/ast/RegexpHelper.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/RegexpHelper.java b/src/main/java/org/apache/freemarker/core/ast/RegexpHelper.java deleted file mode 100644 index 8853f6b..0000000 --- a/src/main/java/org/apache/freemarker/core/ast/RegexpHelper.java +++ /dev/null @@ -1,208 +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.ast; - -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import org.apache.freemarker.core._CoreLogs; -import org.apache.freemarker.core.model.TemplateModelException; -import org.apache.freemarker.core.templateresolver.impl.MruCacheStorage; -import org.apache.freemarker.core.util._StringUtil; -import org.slf4j.Logger; - -/** - * Helper for language features (like built-ins) that use regular expressions. - */ -final class RegexpHelper { - - private static final Logger LOG = _CoreLogs.RUNTIME; - - private static volatile boolean flagWarningsEnabled = LOG.isWarnEnabled(); - private static final int MAX_FLAG_WARNINGS_LOGGED = 25; - private static final Object flagWarningsCntSync = new Object(); - private static int flagWarningsCnt; - - private static final MruCacheStorage patternCache = new MruCacheStorage(50, 150); - - static private long intFlagToLong(int flag) { - return flag & 0x0000FFFFL; - } - - // Standard regular expression flags converted to long: - static final long RE_FLAG_CASE_INSENSITIVE = intFlagToLong(Pattern.CASE_INSENSITIVE); - - static final long RE_FLAG_MULTILINE = intFlagToLong(Pattern.MULTILINE); - - static final long RE_FLAG_COMMENTS = intFlagToLong(Pattern.COMMENTS); - - static final long RE_FLAG_DOTALL = intFlagToLong(Pattern.DOTALL); - - // FreeMarker-specific regular expression flags (using the higher 32 bits): - static final long RE_FLAG_REGEXP = 0x100000000L; - - static final long RE_FLAG_FIRST_ONLY = 0x200000000L; - - // Can't be instantiated - private RegexpHelper() { } - - static Pattern getPattern(String patternString, int flags) - throws TemplateModelException { - PatternCacheKey patternKey = new PatternCacheKey(patternString, flags); - - Pattern result; - - synchronized (patternCache) { - result = (Pattern) patternCache.get(patternKey); - } - if (result != null) { - return result; - } - - try { - result = Pattern.compile(patternString, flags); - } catch (PatternSyntaxException e) { - throw new _TemplateModelException(e, - "Malformed regular expression: ", new _DelayedGetMessage(e)); - } - synchronized (patternCache) { - patternCache.put(patternKey, result); - } - return result; - }; - - private static class PatternCacheKey { - private final String patternString; - private final int flags; - private final int hashCode; - - public PatternCacheKey(String patternString, int flags) { - this.patternString = patternString; - this.flags = flags; - hashCode = patternString.hashCode() + 31 * flags; - } - - @Override - public boolean equals(Object that) { - if (that instanceof PatternCacheKey) { - PatternCacheKey thatPCK = (PatternCacheKey) that; - return thatPCK.flags == flags - && thatPCK.patternString.equals(patternString); - } else { - return false; - } - } - - @Override - public int hashCode() { - return hashCode; - } - - } - - static long parseFlagString(String flagString) { - long flags = 0; - for (int i = 0; i < flagString.length(); i++) { - char c = flagString.charAt(i); - switch (c) { - case 'i': - flags |= RE_FLAG_CASE_INSENSITIVE; - break; - case 'm': - flags |= RE_FLAG_MULTILINE; - break; - case 'c': - flags |= RE_FLAG_COMMENTS; - break; - case 's': - flags |= RE_FLAG_DOTALL; - break; - case 'r': - flags |= RE_FLAG_REGEXP; - break; - case 'f': - flags |= RE_FLAG_FIRST_ONLY; - break; - default: - if (flagWarningsEnabled) { - // [FM3] Should be an error - RegexpHelper.logFlagWarning( - "Unrecognized regular expression flag: " - + _StringUtil.jQuote(String.valueOf(c)) + "."); - } - } // switch - } - return flags; - } - - /** - * Logs flag warning for a limited number of times. This is used to prevent - * log flooding. - */ - static void logFlagWarning(String message) { - if (!flagWarningsEnabled) return; - - int cnt; - synchronized (flagWarningsCntSync) { - cnt = flagWarningsCnt; - if (cnt < MAX_FLAG_WARNINGS_LOGGED) { - flagWarningsCnt++; - } else { - flagWarningsEnabled = false; - return; - } - } - message += " This will be an error in some later FreeMarker version!"; - if (cnt + 1 == MAX_FLAG_WARNINGS_LOGGED) { - message += " [Will not log more regular expression flag problems until restart!]"; - } - LOG.warn(message); - } - - static void checkNonRegexpFlags(String biName, long flags) throws _TemplateModelException { - checkOnlyHasNonRegexpFlags(biName, flags, false); - } - - static void checkOnlyHasNonRegexpFlags(String biName, long flags, boolean strict) - throws _TemplateModelException { - if (!strict && !flagWarningsEnabled) return; - - String flag; - if ((flags & RE_FLAG_MULTILINE) != 0) { - flag = "m"; - } else if ((flags & RE_FLAG_DOTALL) != 0) { - flag = "s"; - } else if ((flags & RE_FLAG_COMMENTS) != 0) { - flag = "c"; - } else { - return; - } - - final Object[] msg = { "?", biName ," doesn't support the \"", flag, "\" flag " - + "without the \"r\" flag." }; - if (strict) { - throw new _TemplateModelException(msg); - } else { - // Suppress error for backward compatibility - logFlagWarning(new _ErrorDescriptionBuilder(msg).toString()); - } - } - -}