📄 configurable.java
字号:
/*
* Copyright (c) 2003 The Visigoth Software Society. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Visigoth Software Society (http://www.visigoths.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
* project contributors may be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact visigoths@visigoths.org.
*
* 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
* nor may "FreeMarker" or "Visigoth" appear in their names
* without prior written permission of the Visigoth Software Society.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Visigoth Software Society. For more
* information on the Visigoth Software Society, please see
* http://www.visigoths.org/
*/
package freemarker.core;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import freemarker.template.*;
import freemarker.template.utility.ClassUtil;
import freemarker.template.utility.StringUtil;
import freemarker.ext.beans.BeansWrapper;
/**
* This is a common superclass of {@link freemarker.template.Configuration},
* {@link freemarker.template.Template}, and {@link Environment} classes.
* It provides settings that are common to each of them. FreeMarker
* uses a three-level setting hierarchy - the return value of every setting
* getter method on <code>Configurable</code> objects inherits its value from its parent
* <code>Configurable</code> object, unless explicitly overridden by a call to a
* corresponding setter method on the object itself. The parent of an
* <code>Environment</code> object is a <code>Template</code> object, the
* parent of a <code>Template</code> object is a <code>Configuration</code>
* object.
*
* @version $Id: Configurable.java,v 1.23.2.1 2006/02/03 17:49:35 revusky Exp $
* @author Attila Szegedi
*/
public class Configurable
{
public static final String LOCALE_KEY = "locale";
public static final String NUMBER_FORMAT_KEY = "number_format";
public static final String TIME_FORMAT_KEY = "time_format";
public static final String DATE_FORMAT_KEY = "date_format";
public static final String DATETIME_FORMAT_KEY = "datetime_format";
public static final String TIME_ZONE_KEY = "time_zone";
public static final String CLASSIC_COMPATIBLE_KEY = "classic_compatible";
public static final String TEMPLATE_EXCEPTION_HANDLER_KEY = "template_exception_handler";
public static final String ARITHMETIC_ENGINE_KEY = "arithmetic_engine";
public static final String OBJECT_WRAPPER_KEY = "object_wrapper";
public static final String BOOLEAN_FORMAT_KEY = "boolean_format";
public static final String OUTPUT_ENCODING_KEY = "output_encoding";
public static final String URL_ESCAPING_CHARSET_KEY = "url_escaping_charset";
public static final String STRICT_BEAN_MODELS = "strict_bean_models";
private static final char COMMA = ',';
private Configurable parent;
private Properties properties;
private HashMap customAttributes;
private Locale locale;
private String numberFormat;
private String timeFormat;
private String dateFormat;
private String dateTimeFormat;
private TimeZone timeZone;
private String trueFormat;
private String falseFormat;
private Boolean classicCompatible;
private TemplateExceptionHandler templateExceptionHandler;
private ArithmeticEngine arithmeticEngine;
private ObjectWrapper objectWrapper;
private String outputEncoding;
private boolean outputEncodingSet;
private String urlEscapingCharset;
private boolean urlEscapingCharsetSet;
public Configurable() {
parent = null;
locale = Locale.getDefault();
timeZone = TimeZone.getDefault();
numberFormat = "number";
timeFormat = "";
dateFormat = "";
dateTimeFormat = "";
trueFormat = "true";
falseFormat = "false";
classicCompatible = Boolean.FALSE;
templateExceptionHandler = TemplateExceptionHandler.DEBUG_HANDLER;
arithmeticEngine = ArithmeticEngine.BIGDECIMAL_ENGINE;
objectWrapper = ObjectWrapper.DEFAULT_WRAPPER;
// outputEncoding and urlEscapingCharset defaults to null,
// which means "not specified"
properties = new Properties();
properties.setProperty(LOCALE_KEY, locale.toString());
properties.setProperty(TIME_FORMAT_KEY, timeFormat);
properties.setProperty(DATE_FORMAT_KEY, dateFormat);
properties.setProperty(DATETIME_FORMAT_KEY, dateTimeFormat);
properties.setProperty(TIME_ZONE_KEY, timeZone.getID());
properties.setProperty(NUMBER_FORMAT_KEY, numberFormat);
properties.setProperty(CLASSIC_COMPATIBLE_KEY, classicCompatible.toString());
properties.setProperty(TEMPLATE_EXCEPTION_HANDLER_KEY, templateExceptionHandler.getClass().getName());
properties.setProperty(ARITHMETIC_ENGINE_KEY, arithmeticEngine.getClass().getName());
properties.setProperty(BOOLEAN_FORMAT_KEY, "true,false");
// as outputEncoding and urlEscapingCharset defaults to null,
// they are not set
customAttributes = new HashMap();
}
/**
* Creates a new instance. Normally you do not need to use this constructor,
* as you don't use <code>Configurable</code> directly, but its subclasses.
*/
public Configurable(Configurable parent) {
this.parent = parent;
locale = null;
numberFormat = null;
trueFormat = null;
falseFormat = null;
classicCompatible = null;
templateExceptionHandler = null;
properties = new Properties(parent.properties);
customAttributes = new HashMap();
}
protected Object clone() throws CloneNotSupportedException {
Configurable copy = (Configurable)super.clone();
copy.properties = new Properties(properties);
copy.customAttributes = (HashMap)customAttributes.clone();
return copy;
}
/**
* Returns the parent <tt>Configurable</tt> object of this object.
* The parent stores the default values for this configurable. For example,
* the parent of the {@link freemarker.template.Template} object is the
* {@link freemarker.template.Configuration} object, so setting values not
* specfied on template level are specified by the confuration object.
*
* @return the parent <tt>Configurable</tt> object, or null, if this is
* the root <tt>Configurable</tt> object.
*/
public final Configurable getParent() {
return parent;
}
/**
* Reparenting support. This is used by Environment when it includes a
* template - the included template becomes the parent configurable during
* its evaluation.
*/
final void setParent(Configurable parent) {
this.parent = parent;
}
/**
* Toggles the "Classic Compatibile" mode. For a comprehensive description
* of this mode, see {@link #isClassicCompatible()}.
*/
public void setClassicCompatible(boolean classicCompatibility) {
this.classicCompatible = classicCompatibility ? Boolean.TRUE : Boolean.FALSE;
properties.setProperty(CLASSIC_COMPATIBLE_KEY, classicCompatible.toString());
}
/**
* Returns whether the engine runs in the "Classic Compatibile" mode.
* When this mode is active, the engine behavior is altered in following
* way: (these resemble the behavior of the 1.7.x line of FreeMarker engine,
* now named "FreeMarker Classic", hence the name).
* <ul>
* <li>handle undefined expressions gracefully. Namely when an expression
* "expr" evaluates to null:
* <ul>
* <li>as argument of the <tt><assign varname=expr></tt> directive,
* <tt>${expr}</tt> directive, <tt>otherexpr == expr</tt> or
* <tt>otherexpr != expr</tt> conditional expressions, or
* <tt>hash[expr]</tt> expression, then it is treated as empty string.
* </li>
* <li>as argument of <tt><list expr as item></tt> or
* <tt><foreach item in expr></tt>, the loop body is not executed
* (as if it were a 0-length list)
* </li>
* <li>as argument of <tt><if></tt> directive, or otherwise where a
* boolean expression is expected, it is treated as false
* </li>
* </ul>
* </li>
* <li>Non-boolean models are accepted in <tt><if></tt> directive,
* or as operands of logical operators. "Empty" models (zero-length string,
* empty sequence or hash) are evaluated as false, all others are evaluated as
* true.</li>
* <li>When boolean value is treated as a string (i.e. output in
* <tt>${...}</tt> directive, or concatenated with other string), true
* values are converted to string "true", false values are converted to
* empty string.
* </li>
* <li>Scalar models supplied to <tt><list></tt> and
* <tt><foreach></tt> are treated as a one-element list consisting
* of the passed model.
* </li>
* <li>Paths parameter of <tt><include></tt> will be interpreted as
* absolute path.
* </li>
* </ul>
* In all other aspects, the engine is a 2.1 engine even in compatibility
* mode - you don't lose any of the new functionality by enabling it.
*/
public boolean isClassicCompatible() {
return classicCompatible != null ? classicCompatible.booleanValue() : parent.isClassicCompatible();
}
/**
* Sets the locale to assume when searching for template files with no
* explicit requested locale.
*/
public void setLocale(Locale locale) {
if (locale == null) throw new IllegalArgumentException("Setting \"locale\" can't be null");
this.locale = locale;
properties.setProperty(LOCALE_KEY, locale.toString());
}
/**
* Returns the time zone to use when formatting time values. Defaults to
* system time zone.
*/
public TimeZone getTimeZone() {
return timeZone != null ? timeZone : parent.getTimeZone();
}
/**
* Sets the time zone to use when formatting time values.
*/
public void setTimeZone(TimeZone timeZone) {
if (timeZone == null) throw new IllegalArgumentException("Setting \"time_zone\" can't be null");
this.timeZone = timeZone;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -