Zhiqim Markup Language是知启蒙定义的、类似于JavaJavascript语法的语句和表达式,通常和XML/HTML混编在一起形成的一种新的标记语言。 ZML力求简单易用,目前支持常用的十二种标记语句和五十种表达式,在知启蒙技术体系中被用来代替JSP。

森中灵 最后提交于1年前 整理V8.0.6
Zmls.java9KB
/*
 * 版权所有 (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.StringWriter;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.model.maps.HashMapSO;
import org.zhiqim.kernel.model.maps.MapS;
import org.zhiqim.kernel.model.maps.MapSO;
import org.zhiqim.kernel.util.Validates;

/**
 * ZhiqimML工具类
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
@AnAlias("Zmls")
public class Zmls implements SignConstants
{
    /******************************************************************/
    //指定内容,把ZML标签转义为浏览器可读标签
    /******************************************************************/
    
    /**
     * 内容格式化,对<,>,\",\',${,@{,#{格式化,保证浏览器解释成字符串而不是ZML代码
     * 
     * @param content   要格式化的字符串
     * @return          格式化后的字符串
     */
    public static String format(String content)
    {
        if (content == null)
            return "";
        
        StringBuilder strb = new StringBuilder();
        for (int i=0;i<content.length();i++)
        {
            char c = content.charAt(i);
            switch (c)
            {
            //检查HTML/ZML非表达式语句标签,进行转化
            case '<':strb.append("&lt;");break;
            case '>':strb.append("&gt;");break;
            case '\'':strb.append("&apos;");break;
            case '\"':strb.append("&quot;");break;
            case '{':
            {//检查ZML表达式语句标签,进行转化
                if (i == 0)
                    strb.append(c);
                else
                {
                    switch (content.charAt(i-1))
                    {
                    case '$':strb.setLength(strb.length()-1);strb.append("&#x24;{");break;
                    case '@':strb.setLength(strb.length()-1);strb.append("&#x40;{");break;
                    case '#':strb.setLength(strb.length()-1);strb.append("&#x23;{");break;
                    default:strb.append(c);break;
                    }
                }
                break;
            }
            default:strb.append(c);break;
            }
        }
        
        return strb.toString();
    }
    
    /******************************************************************/
    //指定内容,解释内容生成结果
    /******************************************************************/
    
    /**
     * 解析ZML内容和属性表得到解析之后的内容
     * 
     * @param content       指定ZML的内容
     * @param key           变量KEY
     * @param value         变量VALUE
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(String content, String key, Object value) throws Exception
    {
        return parse(new Zml(content), key, value);
    }
    
    /**
     * 解析ZML内容和属性表得到解析之后的内容
     * 
     * @param content       指定ZML的内容
     * @param variableMap   页变量表
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(String content, MapSO variableMap, MapS... contextMap) throws Exception
    {
        return parse(new Zml(content), variableMap, contextMap);
    }
    
    /**
     * 解析ZML内容和属性表得到解析之后的内容
     * 
     * @param content       指定ZML的内容
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parseContext(String content, MapS... contextMap) throws Exception
    {
        return parseContext(new Zml(content), contextMap);
    }
    
    /******************************************************************/
    //指定ZML,解释ZML生成结果
    /******************************************************************/
    
    /**
     * 解析ZML和属性表得到解析之后的内容
     * 
     * @param zml           ZML对象
     * @param key           变量KEY
     * @param value         变量VALUE
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(Zml zml, String key, Object value) throws Exception
    {
        return parse(zml, new HashMapSO(key, value));
    }
    
    /**
     * 解析ZML和属性表得到解析之后的内容
     * 
     * @param zml           ZML对象
     * @param variableMap   页变量表
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parse(Zml zml, MapSO variableMap, MapS... contextMap) throws Exception
    {
        StringWriter writer = new StringWriter();
        zml.process(writer, variableMap, contextMap);
        
        return writer.toString();
    }
    
    /**
     * 解析ZML和属性表得到解析之后的内容
     * 
     * @param zml           ZML对象
     * @param contextMap    上下文变量表
     * @return String       解析之后的内容
     * @throws Exception    可能解析的异常 
     */
    public static String parseContext(Zml zml, MapS... contextMap) throws Exception
    {
        StringWriter writer = new StringWriter();
        zml.process(writer, null, contextMap);
        
        return writer.toString();
    }
    
    /******************************************************************/
    //字符串处理,从Strings转过来,目前只有ZML使用
    /******************************************************************/
    
    /**
     * 删除可能的最后一个空白,保留\r\n
     * 
     * @param s         字符串
     * @return          删除后的字符串
     */
    public static String removeRightMaybeEmptyBlank(String s)
    {
        if (Validates.isEmptyBlank(s))
            return _EMPTY_;

        int index = -1;
        for (int i=s.length()-1;i>=0;i--)
        {
            char c = s.charAt(i);
            if (c == _LF_ || c == _CR_){
                index = i;break;
            }else if (Validates.isWhitespace(c)){
                continue;
            }else{
                break;
            }
        }
        
        return (index == -1)?s:s.substring(0, index+1);
    }
    
    /**
     * 删除可能的最后一个空白,保留\r\n
     * 
     * @param s         字符串
     * @return          删除后的字符串
     */
    public static void removeRightMaybeEmptyBlank(StringBuilder strb)
    {
        //找到回车或换行的位置
        int index = -1;boolean allEmptyBlank = true;
        for (int i=strb.length()-1;i>=0;i--)
        {
            char c = strb.charAt(i);
            if (c == _LF_ || c == _CR_){
                index = i;allEmptyBlank=false;break;
            }else if (Validates.isWhitespace(c)){
                continue;
            }else{
                allEmptyBlank = false;break;
            }
        }
        
        if (allEmptyBlank)
            strb.setLength(0);
        else if (index != -1)
            strb.setLength(index+1);
    }
    
    /**
     * 删除可能的最后一个空行
     * 
     * @param s         字符串
     * @return          删除后的字符串
     */
    public static String removeRightMaybeEmptyBlankLine(String s)
    {
        if (Validates.isEmptyBlank(s))
            return _EMPTY_;

        int index = -1;
        for (int i=s.length()-1;i>=0;i--)
        {
            char c = s.charAt(i);
            if (c == _LF_)
            {//当最后为\n时再检查前面是否有\r,Windows使用\r\n分行
                if (i > 0 && s.charAt(i-1) == _CR_)
                    index = i-1;
                else
                    index = i;
                break;
            }
            else if (c == _CR_)
            {//Mac机器使用\r分行
                index = i;break;
            }
            else if (Validates.isWhitespace(c))
                continue;
            else
                break;
        }
        
        return (index == -1)?s:s.substring(0, index);
    }
    
    /**
     * 删除可能的最后一个空行
     * 
     * @param s         字符串
     * @return          删除后的字符串
     */
    public static void removeRightMaybeEmptyBlankLine(StringBuilder strb)
    {
        int index = -1;
        for (int i=strb.length()-1;i>=0;i--)
        {
            char c = strb.charAt(i);
            if (c == _LF_)
            {//当最后为\n时再检查前面是否有\r,Windows使用\r\n分行
                if (i > 0 && strb.charAt(i-1) == _CR_)
                    index = i-1;
                else
                    index = i;
                break;
            }
            else if (c == _CR_)
            {//Mac机器使用\r分行
                index = i;break;
            }
            else if (Validates.isWhitespace(c))
                continue;
            else
                break;
        }
        
        if (index != -1)
            strb.setLength(index);
    }
}