Zhiqim Markup Language是知启蒙定义的、类似于JavaJavascript语法的语句和表达式,通常和XML/HTML混编在一起形成的一种新的标记语言。 ZML力求简单易用,目前支持常用的十二种标记语句和五十种表达式,在知启蒙技术体系中被用来代替JSP。
Zml.java10KB
/*
* 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
*
* https://zhiqim.org/project/zhiqim_framework/zhiqim_zml.htm
*
* Zhiqim Zml is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.zhiqim.zml;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.List;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.model.maps.MapS;
import org.zhiqim.kernel.model.maps.MapSO;
import org.zhiqim.zml.exception.StatementException;
import org.zhiqim.zml.statement._Top;
import org.zhiqim.zml.statement._Function;
import org.zhiqim.zml.statement._Include;
import org.zhiqim.zml.statement._Return.ReturnException;
/**
* ZhiqimML主类
*
* @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
*/
public class Zml implements StatementNesting, SignConstants
{
private ZmlEngine engine; //ZML引擎
private Zml parent; //父ZML,在<#include>中有用
// ZML三要素
private String path; //ZML相对路径
private long lastModified; //ZML最后修改时间
private String content; //ZML内容
private boolean isParsed; //ZML是否已解析,在缓存中则不需要再解析
private List<Statement> stmtList; //ZML语句列表
private List<ZmlLineIndex> indexList; //ZML行索引
private long lastAccessed; //最后访问时间
/**
* 由业务创建ZML,加载当前内容生成ZML对象
*
* @param content ZML内容
*/
public Zml(String content)
{
this(null, null, 0, content);
}
/**
* 由业务创建ZML,需传入内容和ZML引擎
*
* @param engine ZML引擎
* @param content ZML内容
*/
public Zml(ZmlEngine engine, String content)
{
this(engine, null, 0, content);
}
/**
* 由ZmlLoader 加载ZML字符串进行处理
*
* @param engine ZML引擎
* @param path ZML相对路径
* @param lastModified ZML最后修改时间
* @param content ZML内容
*/
public Zml(ZmlEngine engine, String path, long lastModified, String content)
{
this.engine = engine;
this.path = path;
this.lastModified = lastModified;
this.content = content;
this.lastAccessed = System.currentTimeMillis();
}
/** 获取ZML索引列表 */
public List<ZmlLineIndex> getIndexList()
{
if (indexList != null)
return indexList;
synchronized (this)
{
if (indexList == null)
indexList = StatementParser.getIndexList(content);
}
return indexList;
}
/** 解析ZML得到语句列表 */
public void parse() throws StatementException
{
this.stmtList = StatementParser.parseStatementNesting(this);
//解析完之后把内容置为NULL,因为这个占用内存比较大
this.isParsed = true;
this.content = null;
}
/**
* 输出到返回结果中
*
* @param variableMap 指定的变量表,如_Include中调用
* @return 输出的内容
* @throws Exception 异常
*/
public void top(ZmlVariable variableMap) throws StatementException
{
if (!isParsed)
{//没有解析,优先作解析,验证表达式和语句级是否有异常
parse();
}
//把_Top的执行一遍
for (Statement statement : stmtList)
{
if (statement instanceof _Top)
{//执行顶级变量定义或函数执行
((_Top)statement).top(variableMap);
}
else if (statement instanceof _Include)
{//递归回调顶级变量定义或函数执行
((_Include)statement).top(variableMap);
}
}
}
/**
* 输出到返回结果中,在_Include中调用
*
* @param variableMap 指定的变量表
* @param parent 指定父ZML
* @return 输出的内容
* @throws Exception 异常
*/
public String process(ZmlVariable variableMap, Zml parent) throws StatementException
{
this.parent = parent;
return process(variableMap);
}
/**
* 输出到字节流中,不会调用flush()
*
* @param pageVariableMap 全页变量表
* @param contextVariableMap 上下文变量表
* @param out 输出流
* @param encoding 输出编码
* @throws StatementException 可能产生的语句异常
* @throws IOException 可能产生的IO异常
*/
public void process(OutputStream out, String encoding, MapSO pageVariableMap, MapS... contextVariableMap) throws StatementException, IOException
{
ZmlVariable variableMap = new ZmlVariable();
variableMap.setZml(this);
variableMap.setVariableMap(pageVariableMap);
variableMap.setContextMap(contextVariableMap);
out.write(process(variableMap).getBytes(encoding));
}
/**
* 输出到字符流中,不会调用flush()
*
* @param pageVariableMap 全页变量表
* @param contextVariableMap 上下文变量表
* @param writer 字符流
* @throws StatementException 可能产生的语句异常
* @throws IOException 可能产生的IO异常
*/
public void process(Writer writer, MapSO pageVariableMap, MapS... contextVariableMap) throws StatementException, IOException
{
ZmlVariable variableMap = new ZmlVariable();
variableMap.setZml(this);
variableMap.setVariableMap(pageVariableMap);
variableMap.setContextMap(contextVariableMap);
writer.write(process(variableMap));
}
/**
* 输出到返回结果中
*
* @param variableMap 指定的变量表,如_Include中调用
* @return 输出的内容
* @throws Exception 异常
*/
private String process(ZmlVariable variableMap) throws StatementException
{
if (!isParsed)
{//没有解析,优先作解析,验证表达式和语句级是否有异常
parse();
}
//1.先把_Top的执行一遍
top(variableMap);
//2.循环执行语句
StringBuilder strb = new StringBuilder();
try
{
StatementParser.processStatementList(stmtList, variableMap, strb);
return strb.toString();
}
catch(ReturnException e)
{
return e.hasValue()?String.valueOf(e.getValue()):strb.toString();
}
}
@Override
public String getPrevStatement(Statement stmt) throws StatementException
{
List<Statement> statementList = getStatementList();
int ind = statementList.indexOf(stmt);
if (ind <= 0)
return null;
return statementList.get(ind-1).getStatement();
}
@Override
public String getNextStatement(Statement stmt) throws StatementException
{
List<Statement> statementList = getStatementList();
int ind = statementList.indexOf(stmt);
if (ind == -1 || ind >= statementList.size()-1)
return null;
return statementList.get(ind+1).getStatement();
}
public ZmlEngine getEngine()
{
return engine;
}
public List<Statement> getStatementList() throws StatementException
{
if (!isParsed)
{//没有解析,优先作解析,验证表达式和语句级是否有异常
parse();
}
return stmtList;
}
public _Function getFunction(String name) throws StatementException
{
for (Statement stmt : getStatementList())
{
if (!(stmt instanceof _Function))
continue;
_Function function = (_Function)stmt;
if (!function.getName().equals(name))
continue;
return function;
}
return null;
}
public boolean hasParent()
{
return parent != null;
}
public String getPath()
{
return path;
}
public long getLastModified()
{
return lastModified;
}
public long getLastAccessed()
{
return lastAccessed;
}
/** 获取ZML内容,当被解析之后内容将清空置为NULL */
public String getContent()
{
return content;
}
/** 允许设置最后修改时间 */
public void setLastModified(long lastModified)
{
this.lastModified = lastModified;
}
/** 允许设置内容 */
public void setContent(String content)
{
this.content = content;
}
/** 重新设置最后访问时间 */
public void setLastAccessed()
{
this.lastAccessed = System.currentTimeMillis();
}
/**************************************************************/
//定义ZML内容从0开始,通过方向获取自身,适配Statement
/**************************************************************/
@Override
public Zml getZml()
{
return this;
}
@Override
public int getContentBeginIndex()
{
return 0;
}
}

