📄 environment.java
字号:
// we just ignore it.
else if (!nodeType.equals("pi")
&& !nodeType.equals("comment")
&& !nodeType.equals("document_type"))
{
String nsBit = "";
String ns = node.getNodeNamespace();
if (ns != null) {
if (ns.length() >0) {
nsBit = " and namespace " + ns;
} else {
nsBit = " and no namespace";
}
}
throw new TemplateException("No macro or transform defined for node named "
+ node.getNodeName() + nsBit
+ ", and there is no fallback handler called @" + nodeType + " either.",
this);
}
}
else {
String nsBit = "";
String ns = node.getNodeNamespace();
if (ns != null) {
if (ns.length() >0) {
nsBit = " and namespace " + ns;
} else {
nsBit = " and no namespace";
}
}
throw new TemplateException("No macro or transform defined for node with name "
+ node.getNodeName() + nsBit
+ ", and there is no macro or transform called @default either.",
this);
}
}
}
finally {
this.currentVisitorNode = prevVisitorNode;
this.nodeNamespaceIndex = prevNodeNamespaceIndex;
this.currentNodeName = prevNodeName;
this.currentNodeNS = prevNodeNS;
this.nodeNamespaces = prevNodeNamespaces;
}
}
void fallback() throws TemplateException, IOException {
TemplateModel macroOrTransform = getNodeProcessor(currentNodeName, currentNodeNS, nodeNamespaceIndex);
if (macroOrTransform instanceof Macro) {
visit((Macro) macroOrTransform, null, null, null, null);
}
else if (macroOrTransform instanceof TemplateTransformModel) {
visit(null, (TemplateTransformModel) macroOrTransform, null);
}
}
/**
* "visit" a macro.
*/
void visit(Macro macro,
Map namedArgs,
List positionalArgs,
List bodyParameterNames,
TemplateElement nestedBlock)
throws TemplateException, IOException
{
if (macro == Macro.DO_NOTHING_MACRO) {
return;
}
pushElement(macro);
try {
Macro.Context previousMacroContext = currentMacroContext;
Macro.Context mc = macro.new Context(this, nestedBlock, bodyParameterNames);
String catchAll = macro.getCatchAll();
TemplateModel unknownVars = null;
if (namedArgs != null) {
if (catchAll != null)
unknownVars = new SimpleHash();
for (Iterator it = namedArgs.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String varName = (String) entry.getKey();
boolean hasVar = macro.hasArgNamed(varName);
if (hasVar || catchAll != null) {
Expression arg = (Expression) entry.getValue();
TemplateModel value = arg.getAsTemplateModel(this);
if (hasVar) {
mc.setLocalVar(varName, value);
} else {
((SimpleHash)unknownVars).put(varName, value);
}
} else {
String msg = "Macro " + macro.getName() + " has no such argument: " + varName;
throw new TemplateException(msg, this);
}
}
}
else if (positionalArgs != null) {
if (catchAll != null)
unknownVars = new SimpleSequence();
String[] argumentNames = macro.getArgumentNames();
int size = positionalArgs.size();
if (argumentNames.length < size && catchAll == null) {
throw new TemplateException("Macro " + macro.getName()
+ " only accepts " + argumentNames.length + " parameters.", this);
}
for (int i = 0; i < size; i++) {
Expression argExp = (Expression) positionalArgs.get(i);
TemplateModel argModel = argExp.getAsTemplateModel(this);
try {
if (i < argumentNames.length) {
String argName = argumentNames[i];
mc.setLocalVar(argName, argModel);
} else {
((SimpleSequence)unknownVars).add(argModel);
}
} catch (RuntimeException re) {
throw new TemplateException(re, this);
}
}
}
if (catchAll != null) {
mc.setLocalVar(catchAll, unknownVars);
}
ArrayList prevLocalContextStack = localContextStack;
localContextStack = null;
Namespace prevNamespace = currentNamespace;
Configurable prevParent = getParent();
currentNamespace = (Namespace) macroToNamespaceLookup.get(macro);
currentMacroContext = mc;
try {
mc.runMacro(this);
}
catch (ReturnInstruction.Return re) {
}
catch (TemplateException te) {
handleTemplateException(te);
} finally {
currentMacroContext = previousMacroContext;
localContextStack = prevLocalContextStack;
currentNamespace = prevNamespace;
setParent(prevParent);
}
} finally {
popElement();
}
}
void visitMacroDef(Macro macro) {
macroToNamespaceLookup.put(macro, currentNamespace);
currentNamespace.put(macro.getName(), macro);
}
Namespace getMacroNamespace(Macro macro) {
return (Namespace) macroToNamespaceLookup.get(macro);
}
void recurse(TemplateNodeModel node, TemplateSequenceModel namespaces)
throws TemplateException, IOException
{
if (node == null) {
node = this.getCurrentVisitorNode();
if (node == null) {
throw new TemplateModelException(
"The target node of recursion is missing or null.");
}
}
TemplateSequenceModel children = node.getChildNodes();
if (children == null) return;
for (int i=0; i<children.size(); i++) {
TemplateNodeModel child = (TemplateNodeModel) children.get(i);
if (child != null) {
visit(child, namespaces);
}
}
}
Macro.Context getCurrentMacroContext() {
return currentMacroContext;
}
private void handleTemplateException(TemplateException te)
throws TemplateException
{
// Logic to prevent double-handling of the exception in
// nested visit() calls.
if(lastThrowable == te) {
throw te;
}
lastThrowable = te;
// Log the exception
if(logger.isErrorEnabled()) {
logger.error("", te);
}
// Stop exception is not passed to the handler, but
// explicitly rethrown.
if(te instanceof StopException) {
throw te;
}
// Finally, pass the exception to the handler
getTemplateExceptionHandler().handleTemplateException(te, this, out);
}
public void setTemplateExceptionHandler(TemplateExceptionHandler templateExceptionHandler) {
super.setTemplateExceptionHandler(templateExceptionHandler);
lastThrowable = null;
}
public void setLocale(Locale locale) {
super.setLocale(locale);
// Clear local format cache
numberFormats = null;
numberFormat = null;
dateFormats = null;
timeFormat = dateFormat = dateTimeFormat = null;
collator = null;
}
public void setTimeZone(TimeZone timeZone) {
super.setTimeZone(timeZone);
// Clear local date format cache
dateFormats = null;
timeFormat = dateFormat = dateTimeFormat = null;
}
public void setURLEscapingCharset(String urlEscapingCharset) {
urlEscapingCharsetCached = false;
super.setURLEscapingCharset(urlEscapingCharset);
}
/*
* Note that altough it is not allowed to set this setting with the
* <tt>setting</tt> directive, it still must be allowed to set it from Java
* code while the template executes, since some frameworks allow templates
* to actually change the output encoding on-the-fly.
*/
public void setOutputEncoding(String outputEncoding) {
urlEscapingCharsetCached = false;
super.setOutputEncoding(outputEncoding);
}
/**
* Returns the name of the charset that should be used for URL encoding.
* This will be <code>null</code> if the information is not available.
* The function caches the return value, so it is quick to call it
* repeately.
*/
String getEffectiveURLEscapingCharset() {
if (!urlEscapingCharsetCached) {
cachedURLEscapingCharset = getURLEscapingCharset();
if (cachedURLEscapingCharset == null) {
cachedURLEscapingCharset = getOutputEncoding();
}
urlEscapingCharsetCached = true;
}
return cachedURLEscapingCharset;
}
Collator getCollator() {
if(collator == null) {
collator = Collator.getInstance(getLocale());
}
return collator;
}
public void setOut(Writer out) {
this.out = out;
}
public Writer getOut() {
return out;
}
String formatNumber(Number number) {
if(numberFormat == null) {
numberFormat = getNumberFormatObject(getNumberFormat());
}
return numberFormat.format(number);
}
public void setNumberFormat(String formatName) {
super.setNumberFormat(formatName);
numberFormat = null;
}
String formatDate(Date date, int type) throws TemplateModelException {
DateFormat df = getDateFormatObject(type);
if(df == null) {
throw new TemplateModelException("Can't convert the date to string, because it is not known which parts of the date variable are in use. Use ?date, ?time or ?datetime built-in, or ?string.<format> or ?string(format) built-in with this date.");
}
return df.format(date);
}
public void setTimeFormat(String formatName) {
super.setTimeFormat(formatName);
timeFormat = null;
}
public void setDateFormat(String formatName) {
super.setDateFormat(formatName);
dateFormat = null;
}
public void setDateTimeFormat(String formatName) {
super.setDateTimeFormat(formatName);
dateTimeFormat = null;
}
public Configuration getConfiguration() {
return getTemplate().getConfiguration();
}
TemplateModel getLastReturnValue() {
return lastReturnValue;
}
void setLastReturnValue(TemplateModel lastReturnValue) {
this.lastReturnValue = lastReturnValue;
}
void clearLastReturnValue() {
this.lastReturnValue = null;
}
NumberFormat getNumberFormatObject(String pattern)
{
if(numberFormats == null) {
numberFormats = new HashMap();
}
NumberFormat format = (NumberFormat) numberFormats.get(pattern);
if(format != null)
{
return format;
}
// Get format from global format cache
synchronized(localizedNumberFormats)
{
Locale locale = getLocale();
NumberFormatKey fk = new NumberFormatKey(pattern, locale);
format = (NumberFormat)localizedNumberFormats.get(fk);
if(format == null)
{
// Add format to global format cache. Note this is
// globally done once per locale per pattern.
if("number".equals(pattern))
{
format = NumberFormat.getNumberInstance(locale);
}
else if("currency".equals(pattern))
{
format = NumberFormat.getCurrencyInstance(locale);
}
else if("percent".equals(pattern))
{
format = NumberFormat.getPercentInstance(locale);
}
else
{
format = new DecimalFormat(pattern, new DecimalFormatSymbols(getLocale()));
}
localizedNumberFormats.put(fk, format);
}
}
// Clone it and store the clone in the local cache
format = (NumberFormat)format.clone();
numberFormats.put(pattern, format);
return format;
}
DateFormat getDateFormatObject(int dateType)
throws
TemplateModelException
{
switch(dateType) {
case TemplateDateModel.UNKNOWN: {
return null;
}
case TemplateDateModel.TIME: {
if(timeFormat == null) {
timeFormat = getDateFormatObject(dateType, getTimeFormat());
}
return timeFormat;
}
case TemplateDateModel.DATE: {
if(dateFormat == null) {
dateFormat = getDateFormatObject(dateType, getDateFormat());
}
return dateFormat;
}
case TemplateDateModel.DATETIME: {
if(dateTimeFormat == null) {
dateTimeFormat = getDateFormatObject(dateType, getDateTimeFormat());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -