📄 configurable.java
字号:
} else if (TIME_FORMAT_KEY.equals(key)) {
setTimeFormat(value);
} else if (DATE_FORMAT_KEY.equals(key)) {
setDateFormat(value);
} else if (DATETIME_FORMAT_KEY.equals(key)) {
setDateTimeFormat(value);
} else if (TIME_ZONE_KEY.equals(key)) {
setTimeZone(TimeZone.getTimeZone(value));
} else if (CLASSIC_COMPATIBLE_KEY.equals(key)) {
setClassicCompatible(StringUtil.getYesNo(value));
} else if (TEMPLATE_EXCEPTION_HANDLER_KEY.equals(key)) {
if (value.indexOf('.') == -1) {
if ("debug".equalsIgnoreCase(value)) {
setTemplateExceptionHandler(
TemplateExceptionHandler.DEBUG_HANDLER);
} else if ("html_debug".equalsIgnoreCase(value)) {
setTemplateExceptionHandler(
TemplateExceptionHandler.HTML_DEBUG_HANDLER);
} else if ("ignore".equalsIgnoreCase(value)) {
setTemplateExceptionHandler(
TemplateExceptionHandler.IGNORE_HANDLER);
} else if ("rethrow".equalsIgnoreCase(value)) {
setTemplateExceptionHandler(
TemplateExceptionHandler.RETHROW_HANDLER);
} else {
throw invalidSettingValueException(key, value);
}
} else {
setTemplateExceptionHandler(
(TemplateExceptionHandler) ClassUtil.forName(value)
.newInstance());
}
} else if (ARITHMETIC_ENGINE_KEY.equals(key)) {
if (value.indexOf('.') == -1) {
if ("bigdecimal".equalsIgnoreCase(value)) {
setArithmeticEngine(ArithmeticEngine.BIGDECIMAL_ENGINE);
} else if ("conservative".equalsIgnoreCase(value)) {
setArithmeticEngine(ArithmeticEngine.CONSERVATIVE_ENGINE);
} else {
throw invalidSettingValueException(key, value);
}
} else {
setArithmeticEngine(
(ArithmeticEngine) ClassUtil.forName(value)
.newInstance());
}
} else if (OBJECT_WRAPPER_KEY.equals(key)) {
if (value.indexOf('.') == -1) {
if ("default".equalsIgnoreCase(value)) {
setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER);
} else if ("simple".equalsIgnoreCase(value)) {
setObjectWrapper(ObjectWrapper.SIMPLE_WRAPPER);
} else if ("beans".equalsIgnoreCase(value)) {
setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
} else if ("jython".equalsIgnoreCase(value)) {
Class clazz = Class.forName(
"freemarker.ext.jython.JythonWrapper");
setObjectWrapper(
(ObjectWrapper) clazz.getField("INSTANCE").get(null));
} else {
throw invalidSettingValueException(key, value);
}
} else {
setObjectWrapper((ObjectWrapper) ClassUtil.forName(value)
.newInstance());
}
} else if (BOOLEAN_FORMAT_KEY.equals(key)) {
setBooleanFormat(value);
} else if (OUTPUT_ENCODING_KEY.equals(key)) {
setOutputEncoding(value);
} else if (URL_ESCAPING_CHARSET_KEY.equals(key)) {
setURLEscapingCharset(value);
} else if (STRICT_BEAN_MODELS.equals(key)) {
setStrictBeanModels(StringUtil.getYesNo(key));
}
else {
throw unknownSettingException(key);
}
} catch(TemplateException e) {
throw e;
} catch(Exception e) {
throw new TemplateException(
"Failed to set setting " + key + " to value " + value,
e, getEnvironment());
}
}
public void setStrictBeanModels(boolean strict) {
if (!(objectWrapper instanceof BeansWrapper)) {
throw new IllegalStateException("Not a beans wrapper");
}
((BeansWrapper) objectWrapper).setStrict(strict);
}
/**
* Returns the textual representation of a setting.
* @param key the setting key. Can be any of standard <tt>XXX_KEY</tt>
* constants, or a custom key.
*
* @deprecated This method was always defective, and certainly it always
* will be. Don't use it. (Simply, it's hardly possible in general to
* convert setting values to text in a way that ensures that
* {@link #setSetting(String, String)} will work with them correctly.)
*/
public String getSetting(String key) {
return properties.getProperty(key);
}
/**
* This meant to return the String-to-String <code>Map</code> of the
* settings. So it actually should return a <code>Properties</code> object,
* but it doesn't by mistake. The returned <code>Map</code> is read-only,
* but it will reflect the further configuration changes (aliasing effect).
*
* @deprecated This method was always defective, and certainly it always
* will be. Don't use it. (Simply, it's hardly possible in general to
* convert setting values to text in a way that ensures that
* {@link #setSettings(Properties)} will work with them correctly.)
*/
public Map getSettings() {
return Collections.unmodifiableMap(properties);
}
protected Environment getEnvironment() {
return this instanceof Environment
? (Environment) this
: Environment.getCurrentEnvironment();
}
protected TemplateException unknownSettingException(String name) {
return new UnknownSettingException(name, getEnvironment());
}
protected TemplateException invalidSettingValueException(String name, String value) {
return new TemplateException("Invalid value for setting " + name + ": " + value, getEnvironment());
}
public class UnknownSettingException extends TemplateException {
private UnknownSettingException(String name, Environment env) {
super("Unknown setting: " + name, env);
}
}
/**
* Set the settings stored in a <code>Properties</code> object.
*
* @throws TemplateException 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 {
Iterator it = props.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
setSetting(key, props.getProperty(key).trim());
}
}
/**
* 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
*/
void setCustomAttribute(Object key, Object value) {
synchronized(customAttributes) {
customAttributes.put(key, value);
}
}
/**
* Internal entry point for getting unnamed custom attributes
*/
Object getCustomAttribute(Object key, CustomAttribute attr) {
synchronized(customAttributes) {
Object o = customAttributes.get(key);
if(o == null && !customAttributes.containsKey(key)) {
o = attr.create();
customAttributes.put(key, o);
}
return o;
}
}
/**
* Sets a named custom attribute for this configurable.
*
* @param name the name of the custom attribute
* @param value the value of the custom attribute. You can set the value to
* null, however note that there is a semantic difference between an
* attribute set to null and an attribute that is not present, see
* {@link #removeCustomAttribute(String)}.
*/
public void setCustomAttribute(String name, Object value) {
synchronized(customAttributes) {
customAttributes.put(name, value);
}
}
/**
* Returns an array with names of all custom attributes defined directly
* on this configurable. (That is, it doesn't contain the names of custom attributes
* defined indirectly on its parent configurables.) The returned array is never null,
* but can be zero-length.
* The order of elements in the returned array is not defined and can change
* between invocations.
*/
public String[] getCustomAttributeNames() {
synchronized(customAttributes) {
Collection names = new LinkedList(customAttributes.keySet());
for (Iterator iter = names.iterator(); iter.hasNext();) {
if(!(iter.next() instanceof String)) {
iter.remove();
}
}
return (String[])names.toArray(new String[names.size()]);
}
}
/**
* Removes a named custom attribute for this configurable. Note that this
* is different than setting the custom attribute value to null. If you
* set the value to null, {@link #getCustomAttribute(String)} will return
* null, while if you remove the attribute, it will return the value of
* the attribute in the parent configurable (if there is a parent
* configurable, that is).
*
* @param name the name of the custom attribute
*/
public void removeCustomAttribute(String name) {
synchronized(customAttributes) {
customAttributes.remove(name);
}
}
/**
* Retrieves a named custom attribute for this configurable. If the
* attribute is not present in the configurable, and the configurable has
* a parent, then the parent is looked up as well.
*
* @param name the name of the custom attribute
*
* @return the value of the custom attribute. Note that if the custom attribute
* was created with <tt><#ftl attributes={...}></tt>, then this value is already
* unwrapped (i.e. it's a <code>String</code>, or a <code>List</code>, or a
* <code>Map</code>, ...etc., not a FreeMarker specific class).
*/
public Object getCustomAttribute(String name) {
Object retval;
synchronized(customAttributes) {
retval = customAttributes.get(name);
if(retval == null && customAttributes.containsKey(name)) {
return null;
}
}
if(retval == null && parent != null) {
return parent.getCustomAttribute(name);
}
return retval;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -