Repository: incubator-freemarker Updated Branches: refs/heads/3 a21c7c3f3 -> 612c42d80
setSetting (and the like) doesn't throw ParseException (the same exception used when parsing templates) anymore, but ConfigurationException. Also, on the places where ParseException was used for other than template parsing, o.a.f.core.util.GenericParseException is used now instead, which doesn't have the template parsing related fields that we can't fill. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/612c42d8 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/612c42d8 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/612c42d8 Branch: refs/heads/3 Commit: 612c42d80bef0636d6c2676a8f437f44208d61f8 Parents: a21c7c3 Author: ddekany <[email protected]> Authored: Tue Feb 21 09:20:47 2017 +0100 Committer: ddekany <[email protected]> Committed: Tue Feb 21 10:46:35 2017 +0100 ---------------------------------------------------------------------- .../apache/freemarker/core/Configuration.java | 2 +- .../freemarker/core/ConfigurationException.java | 37 +++++ .../freemarker/core/ast/Configurable.java | 142 ++++++++----------- .../freemarker/core/ast/ParseException.java | 19 +-- .../freemarker/core/ast/PropertySetting.java | 9 +- .../ast/_ObjectBuilderSettingEvaluator.java | 3 +- .../apache/freemarker/core/util/FTLUtil.java | 49 +++++-- .../core/util/GenericParseException.java | 40 ++++++ .../freemarker/servlet/FreemarkerServlet.java | 3 +- src/main/javacc/FTL.jj | 10 +- src/manual/en_US/FM3-CHANGE-LOG.txt | 5 +- .../freemarker/core/ConfigurationTest.java | 34 ++--- .../core/TemplateLookupStrategyTest.java | 2 +- .../core/ast/ObjectBuilderSettingsTest.java | 2 +- .../ast/OptInTemplateClassResolverTest.java | 9 +- .../freemarker/core/util/FTLUtilTest.java | 7 +- .../test/templatesuite/TemplateTestCase.java | 3 +- 17 files changed, 224 insertions(+), 152 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/core/Configuration.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/Configuration.java b/src/main/java/org/apache/freemarker/core/Configuration.java index 77ef138..49573ae 100644 --- a/src/main/java/org/apache/freemarker/core/Configuration.java +++ b/src/main/java/org/apache/freemarker/core/Configuration.java @@ -2330,7 +2330,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } @Override - public void setSetting(String name, String value) throws TemplateException { + public void setSetting(String name, String value) throws ConfigurationException { boolean unknown = false; try { if ("TemplateUpdateInterval".equalsIgnoreCase(name)) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/core/ConfigurationException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ConfigurationException.java b/src/main/java/org/apache/freemarker/core/ConfigurationException.java new file mode 100644 index 0000000..b932904 --- /dev/null +++ b/src/main/java/org/apache/freemarker/core/ConfigurationException.java @@ -0,0 +1,37 @@ +/* + * 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; + +/** + * Error while configuring FreeMarker. + */ +@SuppressWarnings("serial") +public class ConfigurationException extends Exception { + + public ConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + public ConfigurationException(String message) { + super(message); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/core/ast/Configurable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/Configurable.java b/src/main/java/org/apache/freemarker/core/ast/Configurable.java index d1a86f3..9ec30dc 100644 --- a/src/main/java/org/apache/freemarker/core/ast/Configurable.java +++ b/src/main/java/org/apache/freemarker/core/ast/Configurable.java @@ -20,7 +20,6 @@ package org.apache.freemarker.core.ast; import java.io.IOException; -import java.io.InputStream; import java.io.Writer; import java.text.NumberFormat; import java.text.SimpleDateFormat; @@ -41,6 +40,7 @@ import java.util.Set; import java.util.TimeZone; import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.ConfigurationException; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateException; import org.apache.freemarker.core.TemplateExceptionHandler; @@ -66,6 +66,7 @@ import org.apache.freemarker.core.templateresolver.TemplateLoader; import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormat; import org.apache.freemarker.core.templateresolver.impl.DefaultTemplateNameFormatFM2; import org.apache.freemarker.core.util.FTLUtil; +import org.apache.freemarker.core.util.GenericParseException; import org.apache.freemarker.core.util._NullArgumentException; import org.apache.freemarker.core.util._SortedArraySet; import org.apache.freemarker.core.util._StringUtil; @@ -2129,9 +2130,9 @@ public class Configurable { * @param value the string that describes the new value of the setting. * * @throws UnknownSettingException if the name is wrong. - * @throws TemplateException if the new value of the setting can't be set for any other reasons. + * @throws SettingValueAssignmentException if the new value of the setting can't be set for any other reasons. */ - public void setSetting(String name, String value) throws TemplateException { + public void setSetting(String name, String value) throws ConfigurationException { boolean unknown = false; try { if (LOCALE_KEY.equals(name)) { @@ -2247,10 +2248,10 @@ public class Configurable { } else if (segmentKey.equals(TRUSTED_TEMPLATES)) { trustedTemplates = segmentValue; } else { - throw new ParseException( + throw new GenericParseException( "Unrecognized list segment key: " + _StringUtil.jQuote(segmentKey) + ". Supported keys are: \"" + ALLOWED_CLASSES + "\", \"" + - TRUSTED_TEMPLATES + "\"", 0, 0); + TRUSTED_TEMPLATES + "\""); } } setNewBuiltinClassResolver( @@ -2319,11 +2320,11 @@ public class Configurable { /** * Creates the exception that should be thrown when a setting name isn't recognized. */ - protected TemplateException unknownSettingException(String name) { + protected final UnknownSettingException unknownSettingException(String name) { Version removalVersion = getRemovalVersionForUnknownSetting(name); return removalVersion != null - ? new UnknownSettingException(getEnvironment(), name, removalVersion) - : new UnknownSettingException(getEnvironment(), name, getCorrectedNameForUnknownSetting(name)); + ? new UnknownSettingException(name, removalVersion) + : new UnknownSettingException(name, getCorrectedNameForUnknownSetting(name)); } /** @@ -2346,11 +2347,9 @@ public class Configurable { return null; } - /** - * @since 2.3.21 - */ - protected final TemplateException settingValueAssignmentException(String name, String value, Throwable cause) { - return new SettingValueAssignmentException(getEnvironment(), name, value, cause); + protected final SettingValueAssignmentException settingValueAssignmentException( + String name, String value, Throwable cause) { + return new SettingValueAssignmentException(name, value, cause); } protected final TemplateException invalidSettingValueException(String name, String value) { @@ -2364,38 +2363,37 @@ public class Configurable { } /** - * The setting name was not recognized. + * Thrown by {@link Configuration#setSetting(String, String)}; The setting name was not recognized. */ - public static class UnknownSettingException extends _MiscTemplateException { + @SuppressWarnings("serial") + public static class UnknownSettingException extends ConfigurationException { - private UnknownSettingException(Environment env, String name, String correctedName) { - super(env, - "Unknown FreeMarker configuration setting: ", new _DelayedJQuote(name), - correctedName == null - ? "" : new Object[] { ". You may meant: ", new _DelayedJQuote(correctedName) }); + private UnknownSettingException(String name, String correctedName) { + super("Unknown FreeMarker configuration setting: " + _StringUtil.jQuote(name) + + (correctedName == null ? "" : ". You may meant: " + _StringUtil.jQuote(correctedName))); } - private UnknownSettingException(Environment env, String name, Version removedInVersion) { - super(env, - "Unknown FreeMarker configuration setting: ", new _DelayedJQuote(name), - removedInVersion == null - ? "" : new Object[] { ". This setting was removed in version ", removedInVersion }); + private UnknownSettingException(String name, Version removedInVersion) { + super("Unknown FreeMarker configuration setting: " + _StringUtil.jQuote(name) + + (removedInVersion == null ? "" : ". This setting was removed in version " + removedInVersion)); } } /** - * The setting name was recognized, but its value couldn't be parsed or the setting couldn't be set for some - * other reason. This exception always has a cause exception. + * Thrown by {@link Configuration#setSetting(String, String)}; The setting name was recognized, but its value + * couldn't be parsed or the setting couldn't be set for some other reason. This exception should always have a + * cause exception. * * @since 2.3.21 */ - public static class SettingValueAssignmentException extends _MiscTemplateException { + @SuppressWarnings("serial") + public static class SettingValueAssignmentException extends ConfigurationException { - private SettingValueAssignmentException(Environment env, String name, String value, Throwable cause) { - super(cause, env, - "Failed to set FreeMarker configuration setting ", new _DelayedJQuote(name), - " to value ", new _DelayedJQuote(value), "; see cause exception."); + private SettingValueAssignmentException(String name, String value, Throwable cause) { + super("Failed to set FreeMarker configuration setting " + _StringUtil.jQuote(name) + + " to value " + _StringUtil.jQuote(value) + "; see cause exception.", cause); + _NullArgumentException.check("cause", cause); } } @@ -2403,11 +2401,11 @@ public class Configurable { /** * Set the settings stored in a <code>Properties</code> object. * - * @throws TemplateException if the <code>Properties</code> object contains + * @throws ConfigurationException if the <code>Properties</code> object contains * invalid keys, or invalid setting values, or any other error occurs * while changing the settings. */ - public void setSettings(Properties props) throws TemplateException { + public void setSettings(Properties props) throws ConfigurationException { final _SettingEvaluationEnvironment prevEnv = _SettingEvaluationEnvironment.startScope(); try { for (String key : props.stringPropertyNames()) { @@ -2417,21 +2415,6 @@ public class Configurable { _SettingEvaluationEnvironment.endScope(prevEnv); } } - - /** - * Reads a setting list (key and element pairs) from the input stream. - * The stream has to follow the usual <code>.properties</code> format. - * - * @throws TemplateException if the stream contains - * invalid keys, or invalid setting values, or any other error occurs - * while changing the settings. - * @throws IOException if an error occurred when reading from the input stream. - */ - public void setSettings(InputStream propsIn) throws TemplateException, IOException { - Properties p = new Properties(); - p.load(propsIn); - setSettings(p); - } /** * Internal entry point for setting unnamed custom attributes. @@ -2573,16 +2556,16 @@ public class Configurable { if (parent != null) parent.doAutoImportsAndIncludes(env); } - protected List<String> parseAsList(String text) throws ParseException { + protected final List<String> parseAsList(String text) throws GenericParseException { return new SettingStringParser(text).parseAsList(); } - protected List<KeyValuePair<List<String>>> parseAsSegmentedList(String text) - throws ParseException { + protected final List<KeyValuePair<List<String>>> parseAsSegmentedList(String text) + throws GenericParseException { return new SettingStringParser(text).parseAsSegmentedList(); } - protected HashMap parseAsImportList(String text) throws ParseException { + protected final HashMap parseAsImportList(String text) throws GenericParseException { return new SettingStringParser(text).parseAsImportList(); } @@ -2618,7 +2601,7 @@ public class Configurable { ln = text.length(); } - List<KeyValuePair<List<String>>> parseAsSegmentedList() throws ParseException { + List<KeyValuePair<List<String>>> parseAsSegmentedList() throws GenericParseException { List<KeyValuePair<List<String>>> segments = new ArrayList(); List<String> currentSegment = null; @@ -2634,24 +2617,23 @@ public class Configurable { segments.add(new KeyValuePair<List<String>>(item, currentSegment)); } else { if (currentSegment == null) { - throw new ParseException( + throw new GenericParseException( "The very first list item must be followed by \":\" so " + - "it will be the key for the following sub-list.", - 0, 0); + "it will be the key for the following sub-list."); } currentSegment.add(item); } if (c == ' ') break; - if (c != ',' && c != ':') throw new ParseException( + if (c != ',' && c != ':') throw new GenericParseException( "Expected \",\" or \":\" or the end of text but " + - "found \"" + c + "\"", 0, 0); + "found \"" + c + "\""); p++; } return segments; } - ArrayList parseAsList() throws ParseException { + ArrayList parseAsList() throws GenericParseException { char c; ArrayList seq = new ArrayList(); while (true) { @@ -2660,15 +2642,15 @@ public class Configurable { seq.add(fetchStringValue()); c = skipWS(); if (c == ' ') break; - if (c != ',') throw new ParseException( + if (c != ',') throw new GenericParseException( "Expected \",\" or the end of text but " + - "found \"" + c + "\"", 0, 0); + "found \"" + c + "\""); p++; } return seq; } - HashMap parseAsImportList() throws ParseException { + HashMap parseAsImportList() throws GenericParseException { char c; HashMap map = new HashMap(); while (true) { @@ -2677,30 +2659,30 @@ public class Configurable { String lib = fetchStringValue(); c = skipWS(); - if (c == ' ') throw new ParseException( - "Unexpected end of text: expected \"as\"", 0, 0); + if (c == ' ') throw new GenericParseException( + "Unexpected end of text: expected \"as\""); String s = fetchKeyword(); - if (!s.equalsIgnoreCase("as")) throw new ParseException( - "Expected \"as\", but found " + _StringUtil.jQuote(s), 0, 0); + if (!s.equalsIgnoreCase("as")) throw new GenericParseException( + "Expected \"as\", but found " + _StringUtil.jQuote(s)); c = skipWS(); - if (c == ' ') throw new ParseException( - "Unexpected end of text: expected gate hash name", 0, 0); + if (c == ' ') throw new GenericParseException( + "Unexpected end of text: expected gate hash name"); String ns = fetchStringValue(); map.put(ns, lib); c = skipWS(); if (c == ' ') break; - if (c != ',') throw new ParseException( + if (c != ',') throw new GenericParseException( "Expected \",\" or the end of text but " - + "found \"" + c + "\"", 0, 0); + + "found \"" + c + "\""); p++; } return map; } - String fetchStringValue() throws ParseException { + String fetchStringValue() throws GenericParseException { String w = fetchWord(); if (w.startsWith("'") || w.startsWith("\"")) { w = w.substring(1, w.length() - 1); @@ -2708,11 +2690,11 @@ public class Configurable { return FTLUtil.unescapeStringLiteralPart(w); } - String fetchKeyword() throws ParseException { + String fetchKeyword() throws GenericParseException { String w = fetchWord(); if (w.startsWith("'") || w.startsWith("\"")) { - throw new ParseException( - "Keyword expected, but a string value found: " + w, 0, 0); + throw new GenericParseException( + "Keyword expected, but a string value found: " + w); } return w; } @@ -2727,9 +2709,9 @@ public class Configurable { return ' '; } - private String fetchWord() throws ParseException { - if (p == ln) throw new ParseException( - "Unexpeced end of text", 0, 0); + private String fetchWord() throws GenericParseException { + if (p == ln) throw new GenericParseException( + "Unexpeced end of text"); char c = text.charAt(p); int b = p; @@ -2751,7 +2733,7 @@ public class Configurable { p++; } if (p == ln) { - throw new ParseException("Missing " + q, 0, 0); + throw new GenericParseException("Missing " + q); } p++; return text.substring(b, p); @@ -2765,7 +2747,7 @@ public class Configurable { p++; } while (p < ln); if (b == p) { - throw new ParseException("Unexpected character: " + c, 0, 0); + throw new GenericParseException("Unexpected character: " + c); } else { return text.substring(b, p); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/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 index 3f13654..f834d8d 100644 --- a/src/main/java/org/apache/freemarker/core/ast/ParseException.java +++ b/src/main/java/org/apache/freemarker/core/ast/ParseException.java @@ -106,30 +106,13 @@ public class ParseException extends IOException implements FMParserConstants { } /** - * The following constructors are for use by you for whatever - * purpose you can think of. Constructing the exception in this - * manner makes the exception behave in the normal way - i.e., as - * documented in the class "Throwable". The fields "errorToken", - * "expectedTokenSequences", and "tokenImage" do not contain - * relevant information. The JavaCC generated code does not use - * these constructors. - * - * @deprecated Use a constructor to which you pass description, template, and positions. + * Used by JavaCC generated code. */ - @Deprecated protected ParseException() { super(); } /** - * @deprecated Use a constructor to which you can also pass the template, and the end positions. - */ - @Deprecated - public ParseException(String description, int lineNumber, int columnNumber) { - this(description, (Template) null, lineNumber, columnNumber, 0, 0, null); - } - - /** * @since 2.3.21 */ public ParseException(String description, Template template, http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/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 index a7083b7..6a91c22 100644 --- a/src/main/java/org/apache/freemarker/core/ast/PropertySetting.java +++ b/src/main/java/org/apache/freemarker/core/ast/PropertySetting.java @@ -22,10 +22,9 @@ 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.ast.FMParserTokenManager; -import org.apache.freemarker.core.ast.Token; import org.apache.freemarker.core.model.TemplateBooleanModel; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateNumberModel; @@ -121,7 +120,11 @@ final class PropertySetting extends TemplateElement { } else { strval = value.evalAndCoerceToStringOrUnsupportedMarkup(env); } - env.setSetting(key, strval); + try { + env.setSetting(key, strval); + } catch (ConfigurationException e) { + throw new _MiscTemplateException(env, e.getMessage(), e.getCause()); + } return null; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/core/ast/_ObjectBuilderSettingEvaluator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/ast/_ObjectBuilderSettingEvaluator.java b/src/main/java/org/apache/freemarker/core/ast/_ObjectBuilderSettingEvaluator.java index 554e047..a814168 100644 --- a/src/main/java/org/apache/freemarker/core/ast/_ObjectBuilderSettingEvaluator.java +++ b/src/main/java/org/apache/freemarker/core/ast/_ObjectBuilderSettingEvaluator.java @@ -55,6 +55,7 @@ import org.apache.freemarker.core.templateresolver.OrMatcher; import org.apache.freemarker.core.templateresolver.PathGlobMatcher; import org.apache.freemarker.core.templateresolver.PathRegexMatcher; import org.apache.freemarker.core.util.FTLUtil; +import org.apache.freemarker.core.util.GenericParseException; import org.apache.freemarker.core.util.WriteProtectable; import org.apache.freemarker.core.util._ClassUtil; import org.apache.freemarker.core.util._StringUtil; @@ -528,7 +529,7 @@ public class _ObjectBuilderSettingEvaluator { try { pos++; // skip closing quotation mark return raw ? sInside : FTLUtil.unescapeStringLiteralPart(sInside); - } catch (ParseException e) { + } catch (GenericParseException e) { throw new _ObjectBuilderSettingEvaluationException("Malformed string literal: " + sInside, e); } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/core/util/FTLUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/util/FTLUtil.java b/src/main/java/org/apache/freemarker/core/util/FTLUtil.java index af43310..b6c88b4 100644 --- a/src/main/java/org/apache/freemarker/core/util/FTLUtil.java +++ b/src/main/java/org/apache/freemarker/core/util/FTLUtil.java @@ -18,15 +18,42 @@ */ package org.apache.freemarker.core.util; +import java.util.HashSet; +import java.util.Set; + import org.apache.freemarker.core.ast.Environment; import org.apache.freemarker.core.ast.Macro; -import org.apache.freemarker.core.ast.ParseException; import org.apache.freemarker.core.ast.TemplateMarkupOutputModel; -import org.apache.freemarker.core.model.*; -import org.apache.freemarker.core.model.impl.beans.*; - -import java.util.HashSet; -import java.util.Set; +import org.apache.freemarker.core.model.AdapterTemplateModel; +import org.apache.freemarker.core.model.TemplateBooleanModel; +import org.apache.freemarker.core.model.TemplateCollectionModel; +import org.apache.freemarker.core.model.TemplateCollectionModelEx; +import org.apache.freemarker.core.model.TemplateDateModel; +import org.apache.freemarker.core.model.TemplateDirectiveModel; +import org.apache.freemarker.core.model.TemplateHashModel; +import org.apache.freemarker.core.model.TemplateHashModelEx; +import org.apache.freemarker.core.model.TemplateMethodModel; +import org.apache.freemarker.core.model.TemplateMethodModelEx; +import org.apache.freemarker.core.model.TemplateModel; +import org.apache.freemarker.core.model.TemplateModelIterator; +import org.apache.freemarker.core.model.TemplateNodeModel; +import org.apache.freemarker.core.model.TemplateNodeModelEx; +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.model.TemplateTransformModel; +import org.apache.freemarker.core.model.WrapperTemplateModel; +import org.apache.freemarker.core.model.impl.beans.BeanModel; +import org.apache.freemarker.core.model.impl.beans.BooleanModel; +import org.apache.freemarker.core.model.impl.beans.CollectionModel; +import org.apache.freemarker.core.model.impl.beans.DateModel; +import org.apache.freemarker.core.model.impl.beans.EnumerationModel; +import org.apache.freemarker.core.model.impl.beans.IteratorModel; +import org.apache.freemarker.core.model.impl.beans.MapModel; +import org.apache.freemarker.core.model.impl.beans.NumberModel; +import org.apache.freemarker.core.model.impl.beans.OverloadedMethodsModel; +import org.apache.freemarker.core.model.impl.beans.SimpleMethodModel; +import org.apache.freemarker.core.model.impl.beans.StringModel; /** * Static utility methods that perform tasks specific to the FreeMarker Template Language (FTL). @@ -165,9 +192,9 @@ public final class FTLUtil { * * @param s String literal <em>without</em> the surrounding quotation marks * @return String with all escape sequences resolved - * @throws ParseException if there string contains illegal escapes + * @throws GenericParseException if there string contains illegal escapes */ - public static String unescapeStringLiteralPart(String s) throws ParseException { + public static String unescapeStringLiteralPart(String s) throws GenericParseException { int idx = s.indexOf('\\'); if (idx == -1) { @@ -180,7 +207,7 @@ public final class FTLUtil { do { buf.append(s.substring(bidx, idx)); if (idx >= lidx) { - throw new ParseException("The last character of string literal is backslash", 0, 0); + throw new GenericParseException("The last character of string literal is backslash"); } char c = s.charAt(idx + 1); switch (c) { @@ -256,13 +283,13 @@ public final class FTLUtil { if (x < idx) { buf.append((char) y); } else { - throw new ParseException("Invalid \\x escape in a string literal", 0, 0); + throw new GenericParseException("Invalid \\x escape in a string literal"); } bidx = idx; break; } default: - throw new ParseException("Invalid escape sequence (\\" + c + ") in a string literal", 0, 0); + throw new GenericParseException("Invalid escape sequence (\\" + c + ") in a string literal"); } idx = s.indexOf('\\', bidx); } while (idx != -1); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/core/util/GenericParseException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/core/util/GenericParseException.java b/src/main/java/org/apache/freemarker/core/util/GenericParseException.java new file mode 100644 index 0000000..8e650e1 --- /dev/null +++ b/src/main/java/org/apache/freemarker/core/util/GenericParseException.java @@ -0,0 +1,40 @@ +/* + * 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.util; + +import org.apache.freemarker.core.ast.ParseException; + +/** + * Exception thrown when a we want to parse some text but its format doesn't match the expectations. This is a quite + * generic exception, which we use in cases that don't deserve a dedicated exception. + * + * @see ParseException + */ +@SuppressWarnings("serial") +public class GenericParseException extends Exception { + + public GenericParseException(String message) { + super(message); + } + + public GenericParseException(String message, Throwable cause) { + super(message, cause); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java index 1d8bfa2..7cb8cda 100644 --- a/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java +++ b/src/main/java/org/apache/freemarker/servlet/FreemarkerServlet.java @@ -42,6 +42,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.ConfigurationException; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateException; import org.apache.freemarker.core.TemplateExceptionHandler; @@ -1315,7 +1316,7 @@ public class FreemarkerServlet extends HttpServlet { } else { try { config.setSetting(Configurable.OBJECT_WRAPPER_KEY, wrapper); - } catch (TemplateException e) { + } catch (ConfigurationException e) { throw new RuntimeException("Failed to set " + Configurable.OBJECT_WRAPPER_KEY, e); } return config.getObjectWrapper(); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/main/javacc/FTL.jj ---------------------------------------------------------------------- diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj index 46f98a1..659d7bf 100644 --- a/src/main/javacc/FTL.jj +++ b/src/main/javacc/FTL.jj @@ -2144,13 +2144,9 @@ StringLiteral StringLiteral(boolean interpolate) : } else { try { s = FTLUtil.unescapeStringLiteralPart(t.image.substring(1, t.image.length() -1)); - } catch (ParseException pe) { - pe.lineNumber = t.beginLine; - pe.columnNumber = t.beginColumn; - pe.endLineNumber = t.endLine; - pe.endColumnNumber = t.endColumn; - throw pe; - } + } catch (GenericParseException e) { + throw new ParseException(e.getMessage(), template, t); + } } StringLiteral result = new StringLiteral(s); result.setLocation(template, t, t); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/manual/en_US/FM3-CHANGE-LOG.txt ---------------------------------------------------------------------- diff --git a/src/manual/en_US/FM3-CHANGE-LOG.txt b/src/manual/en_US/FM3-CHANGE-LOG.txt index 8af1138..b32149f 100644 --- a/src/manual/en_US/FM3-CHANGE-LOG.txt +++ b/src/manual/en_US/FM3-CHANGE-LOG.txt @@ -111,4 +111,7 @@ the FreeMarer 3 changelog here: - Removed the static default Configuration instance. (It's not possible to create a template with null Configuration constructor argument anymore.) - When specifying the templateUpdateDelay configuration setting with a String (with Properties), the time unit is - required, unless the value is 0. \ No newline at end of file + required, unless the value is 0. +- setSetting (and the like) doesn't throw ParseException (the same exception used when parsing templates) anymore, but ConfigurationException. + Also, on the places where ParseException was used for other than template parsing, o.a.f.core.util.GenericParseException is used now instead, + which doesn't have the template parsing related fields that we can't fill. http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/test/java/org/apache/freemarker/core/ConfigurationTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java index 2b4be56..6a7b4d9 100644 --- a/src/test/java/org/apache/freemarker/core/ConfigurationTest.java +++ b/src/test/java/org/apache/freemarker/core/ConfigurationTest.java @@ -262,7 +262,7 @@ public class ConfigurationTest extends TestCase { @Test @SuppressWarnings("boxing") - public void testGetTemplateOverloads() throws IOException, TemplateException { + public void testGetTemplateOverloads() throws Exception { final Locale hu = new Locale("hu", "HU"); final String latin1 = "ISO-8859-1"; final String latin2 = "ISO-8859-2"; @@ -536,8 +536,8 @@ public class ConfigurationTest extends TestCase { assertNull(cfg.getTemplate("missing.ftl", hu, custLookupCond, utf8, true, true)); } - private void assertOutputEquals(final String expectedContent, final Template t) throws TemplateException, - IOException { + private void assertOutputEquals(final String expectedContent, final Template t) throws ConfigurationException, + IOException, TemplateException { StringWriter sw = new StringWriter(); t.process(null, sw); assertEquals(expectedContent, sw.toString()); @@ -951,7 +951,7 @@ public class ConfigurationTest extends TestCase { assertFalse(cfg.isRecognizeStandardFileExtensionsExplicitlySet()); } - public void testSetTimeZone() throws TemplateException { + public void testSetTimeZone() throws ConfigurationException { TimeZone origSysDefTZ = TimeZone.getDefault(); try { TimeZone sysDefTZ = TimeZone.getTimeZone("GMT-01"); @@ -972,7 +972,7 @@ public class ConfigurationTest extends TestCase { } } - public void testSetSQLDateAndTimeTimeZone() throws TemplateException { + public void testSetSQLDateAndTimeTimeZone() throws ConfigurationException { TimeZone origSysDefTZ = TimeZone.getDefault(); try { TimeZone sysDefTZ = TimeZone.getTimeZone("GMT-01"); @@ -994,7 +994,7 @@ public class ConfigurationTest extends TestCase { } } - public void testTimeZoneLayers() throws TemplateException, IOException { + public void testTimeZoneLayers() throws Exception { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); Template t = new Template(null, "", cfg); Environment env1 = t.createProcessingEnvironment(null, new StringWriter()); @@ -1060,14 +1060,14 @@ public class ConfigurationTest extends TestCase { env2.setTimeZone(null); } - public void testSetICIViaSetSettingAPI() throws TemplateException { + public void testSetICIViaSetSettingAPI() throws ConfigurationException { Configuration cfg = new Configuration(); assertEquals(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS, cfg.getIncompatibleImprovements()); cfg.setSetting(Configuration.INCOMPATIBLE_IMPROVEMENTS_KEY, "3.0.0"); // This is the only valid value ATM... assertEquals(Configuration.VERSION_3_0_0, cfg.getIncompatibleImprovements()); } - public void testSetLogTemplateExceptionsViaSetSettingAPI() throws TemplateException { + public void testSetLogTemplateExceptionsViaSetSettingAPI() throws ConfigurationException { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); assertFalse(cfg.getLogTemplateExceptions()); cfg.setSetting(Configurable.LOG_TEMPLATE_EXCEPTIONS_KEY, "true"); @@ -1140,7 +1140,7 @@ public class ConfigurationTest extends TestCase { } @Test - public void testTemplateUpdateDelay() throws IOException, TemplateException { + public void testTemplateUpdateDelay() throws Exception { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); assertEquals(DefaultTemplateResolver.DEFAULT_TEMPLATE_UPDATE_DELAY_MILLIS, cfg.getTemplateUpdateDelayMilliseconds()); @@ -1253,7 +1253,7 @@ public class ConfigurationTest extends TestCase { cfg.setSetting(Configurable.CUSTOM_NUMBER_FORMATS_KEY_CAMEL_CASE, "{ 'x': " + EpochMillisTemplateDateFormatFactory.class.getName() + "() }"); fail(); - } catch (TemplateException e) { + } catch (ConfigurationException e) { assertThat(e.getCause().getMessage(), allOf( containsString(EpochMillisTemplateDateFormatFactory.class.getName()), containsString(TemplateNumberFormatFactory.class.getName()))); @@ -1308,7 +1308,7 @@ public class ConfigurationTest extends TestCase { try { cfg.setSetting(Configuration.TAB_SIZE_KEY_SNAKE_CASE, "x"); fail(); - } catch (TemplateException e) { + } catch (ConfigurationException e) { assertThat(e.getCause(), instanceOf(NumberFormatException.class)); } } @@ -1379,7 +1379,7 @@ public class ConfigurationTest extends TestCase { cfg.setSetting(Configurable.CUSTOM_DATE_FORMATS_KEY_CAMEL_CASE, "{ 'x': " + HexTemplateNumberFormatFactory.class.getName() + "() }"); fail(); - } catch (TemplateException e) { + } catch (ConfigurationException e) { assertThat(e.getCause().getMessage(), allOf( containsString(HexTemplateNumberFormatFactory.class.getName()), containsString(TemplateDateFormatFactory.class.getName()))); @@ -1451,7 +1451,7 @@ public class ConfigurationTest extends TestCase { assertTrue(env.hasCustomFormats()); } - public void testNamingConventionSetSetting() throws TemplateException { + public void testNamingConventionSetSetting() throws ConfigurationException { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); assertEquals(Configuration.AUTO_DETECT_NAMING_CONVENTION, cfg.getNamingConvention()); @@ -1466,7 +1466,7 @@ public class ConfigurationTest extends TestCase { assertEquals(Configuration.AUTO_DETECT_NAMING_CONVENTION, cfg.getNamingConvention()); } - public void testLazyImportsSetSetting() throws TemplateException { + public void testLazyImportsSetSetting() throws ConfigurationException { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); assertFalse(cfg.getLazyImports()); @@ -1477,7 +1477,7 @@ public class ConfigurationTest extends TestCase { assertFalse(cfg.getLazyImports()); } - public void testLazyAutoImportsSetSetting() throws TemplateException { + public void testLazyAutoImportsSetSetting() throws ConfigurationException { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); assertNull(cfg.getLazyAutoImports()); @@ -1649,13 +1649,13 @@ public class ConfigurationTest extends TestCase { try { cfg.setSetting("classic_compatible", "true"); fail(); - } catch (TemplateException e) { + } catch (ConfigurationException e) { assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0"))); } try { cfg.setSetting("strict_syntax", "true"); fail(); - } catch (TemplateException e) { + } catch (ConfigurationException e) { assertThat(e.getMessage(), allOf(containsString("removed"), containsString("3.0.0"))); } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java b/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java index 1638ff7..f8d9c17 100644 --- a/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java +++ b/src/test/java/org/apache/freemarker/core/TemplateLookupStrategyTest.java @@ -42,7 +42,7 @@ import com.google.common.collect.ImmutableList; public class TemplateLookupStrategyTest { @Test - public void testSetSetting() throws TemplateException { + public void testSetSetting() throws Exception { Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); assertSame(DefaultTemplateLookupStrategy.INSTANCE, cfg.getTemplateLookupStrategy()); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/test/java/org/apache/freemarker/core/ast/ObjectBuilderSettingsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ast/ObjectBuilderSettingsTest.java b/src/test/java/org/apache/freemarker/core/ast/ObjectBuilderSettingsTest.java index c7838fd..fed7a42 100644 --- a/src/test/java/org/apache/freemarker/core/ast/ObjectBuilderSettingsTest.java +++ b/src/test/java/org/apache/freemarker/core/ast/ObjectBuilderSettingsTest.java @@ -391,7 +391,7 @@ public class ObjectBuilderSettingsTest { } @Test - public void configurationPropertiesTest() throws TemplateException { + public void configurationPropertiesTest() throws Exception { final Configuration cfg = new Configuration(Configuration.getVersion()); { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/test/java/org/apache/freemarker/core/ast/OptInTemplateClassResolverTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/ast/OptInTemplateClassResolverTest.java b/src/test/java/org/apache/freemarker/core/ast/OptInTemplateClassResolverTest.java index 340e76b..3883873 100644 --- a/src/test/java/org/apache/freemarker/core/ast/OptInTemplateClassResolverTest.java +++ b/src/test/java/org/apache/freemarker/core/ast/OptInTemplateClassResolverTest.java @@ -25,10 +25,9 @@ import java.util.List; import java.util.Set; import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.ConfigurationException; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateException; -import org.apache.freemarker.core.ast.OptInTemplateClassResolver; -import org.apache.freemarker.core.ast.TemplateClassResolver; import junit.framework.AssertionFailedError; import junit.framework.TestCase; @@ -123,8 +122,8 @@ public class OptInTemplateClassResolverTest extends TestCase { } } - public void testSettingParser() throws TemplateException { - Configuration cfg = new Configuration(); + public void testSettingParser() throws Exception { + Configuration cfg = new Configuration(Configuration.VERSION_3_0_0); cfg.setSetting("new_builtin_class_resolver", "trusted_templates: foo.ftl, \"lib/*\""); @@ -186,7 +185,7 @@ public class OptInTemplateClassResolverTest extends TestCase { try { cfg.setSetting("new_builtin_class_resolver", "wrong: foo"); fail(); - } catch (TemplateException e) { + } catch (ConfigurationException e) { // Expected } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java b/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java index b5a27bf..451ea71 100644 --- a/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java +++ b/src/test/java/org/apache/freemarker/core/util/FTLUtilTest.java @@ -18,14 +18,13 @@ */ package org.apache.freemarker.core.util; -import org.apache.freemarker.core.ast.ParseException; -import org.junit.Test; - import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import org.junit.Test; + public class FTLUtilTest { @Test @@ -66,7 +65,7 @@ public class FTLUtilTest { } @Test - public void testUnescapeStringLiteralPart() throws ParseException { + public void testUnescapeStringLiteralPart() throws Exception { assertEquals("", FTLUtil.unescapeStringLiteralPart("")); assertEquals("1", FTLUtil.unescapeStringLiteralPart("1")); assertEquals("123", FTLUtil.unescapeStringLiteralPart("123")); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/612c42d8/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java b/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java index 9a59132..00e1e88 100644 --- a/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java +++ b/src/test/java/org/apache/freemarker/test/templatesuite/TemplateTestCase.java @@ -43,6 +43,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.freemarker.core.Configuration; +import org.apache.freemarker.core.ConfigurationException; import org.apache.freemarker.core.Template; import org.apache.freemarker.core.TemplateException; import org.apache.freemarker.core.Version; @@ -160,7 +161,7 @@ public class TemplateTestCase extends FileTestCase { } else if (!Configuration.INCOMPATIBLE_IMPROVEMENTS_KEY.equals(param)) { try { conf.setSetting(param, value); - } catch (TemplateException e) { + } catch (ConfigurationException e) { throw new RuntimeException( "Failed to set setting " + _StringUtil.jQuote(param) + " to " +
