/* * Copyright (C) 2010---2014 星星(wuweixing)<349446658@qq.com> * * This file is part of Wabacus * * Wabacus is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.wabacus.config.template; import java.util.ArrayList; import java.util.List; import com.wabacus.config.template.tags.AbsTagInTemplate; import com.wabacus.exception.WabacusConfigLoadingException; import com.wabacus.system.assistant.WabacusAssistant; import com.wabacus.util.RegexTools; public class TemplateParser { public static TemplateBean parseTemplateByPath(String templatepath) { if(templatepath==null||templatepath.trim().equals("")) return null; String templateContent=WabacusAssistant.getInstance().readFileContentByPath(templatepath.trim()); return parseTemplateByContent(templateContent); } public static TemplateBean parseTemplateByContent(String content) { if(content==null) return null; content=WabacusAssistant.getInstance().replaceSystemPlaceHolder(content); TemplateBean tplbean=new TemplateBean(); tplbean.setContent(content); tplbean.setLstTagChildren(parseHtmlContent(null,content)); if(tplbean.getLstTagChildren()!=null&&tplbean.getLstTagChildren().size()>0) { for(AbsTagInTemplate tagbeanTmp:tplbean.getLstTagChildren()) { tagbeanTmp.parseTagValue(); } } return tplbean; } public static List<AbsTagInTemplate> parseHtmlContent(AbsTagInTemplate parentTag,String content) { if(content==null||content.trim().equals("")) return null; int length=content.length(); boolean isInTagStartPart=false; StringBuffer fullContentBuf=new StringBuffer(); StringBuffer propBuf=null; AbsTagInTemplate tagbean=null; String endtag=null;//当前正在分析的标签的结束标签 List<String> lstEndChildTags=null; List<AbsTagInTemplate> lstResults=new ArrayList<AbsTagInTemplate>(); for(int i=0;i<length;i++) { if(fullContentBuf.length()>0) { if(isInTagStartPart) { if(content.charAt(i)=='>') { isInTagStartPart=false; fullContentBuf.append(">"); if(fullContentBuf.charAt(fullContentBuf.length()-2)=='/') {//这个标签没有内容,即为<wx:tag.../>的形式 tagbean.setEndposition(i); lstResults.add(tagbean); fullContentBuf=new StringBuffer(); if(propBuf.length()>0&&propBuf.charAt(propBuf.length()-1)=='/') { propBuf.deleteCharAt(propBuf.length()-1); } } if(propBuf.length()>0) {//如果当前标签有属性 tagbean.setMTagAttributes(RegexTools.parseXmlTagAttribute(propBuf.toString())); } propBuf=null; }else if(content.charAt(i)=='<') { throw new WabacusConfigLoadingException("模板中"+fullContentBuf.toString() +"标签不合法"); }else { fullContentBuf.append(content.charAt(i)); propBuf.append(content.charAt(i)); } }else { if(i+endtag.length()>length) { throw new WabacusConfigLoadingException("模板中标签不合法,没有找到结束标签"+endtag); } if((lstEndChildTags==null||lstEndChildTags.size()==0) &&content.substring(i,i+endtag.length()).equals(endtag)) { fullContentBuf.append(endtag); tagbean.setTagContent(getTagContent(fullContentBuf.toString())); tagbean.setEndposition(i+endtag.length()-1); lstResults.add(tagbean); fullContentBuf=new StringBuffer(); }else { fullContentBuf.append(content.charAt(i)); if(i+7<length) {//说明有可能包括子标签,因为如果后面还没有7个字符,则不可能包括子标签,因为子标签至少包括如下字符:<wx:x/> if(content.substring(i,i+4).equals("<wx:")) { String endTag=getEndTag(content.substring(i+4)); if(!endTag.equals("")) {//当前标签是一个有效的子标签,且需要</endtag>结束标签(即它不是<tag/>形式) lstEndChildTags.add(0,endTag); } }else if(lstEndChildTags!=null&&lstEndChildTags.size()>0) { String endTag=lstEndChildTags.get(0); if(i+endTag.length()>length) { throw new WabacusConfigLoadingException("模板中标签不合法,没有找到结束标签" +endtag); } if(content.substring(i,i+endTag.length()).equals(endTag)) {//碰到了此子标签的结束标签 lstEndChildTags.remove(0); } } } } } }else { if(i+7>=length) {//因为一个合法的标签,至少要包括<wx:x/>内容,因此后面的字符串如果小于7个字符,则不可能还有需要分析的标签。 break; } if(content.substring(i,i+4).equals("<wx:")) { int startposition=i; fullContentBuf.append("<wx:"); String tagname=""; for(i=i+4;i<length;i++) { if(content.charAt(i)==' ') break; if(content.charAt(i)=='>') { i=i-1; break; } if(content.charAt(i)=='/') { if(i<length-1&&content.charAt(i+1)=='>') {//是<wx:tag/>形式,即此标签既没有属性,也没有内容 i=i-1; break; }else { tagname=""; break; } } if(content.charAt(i)=='<'||content.charAt(i)=='\''||content.charAt(i)=='\"') { tagname=""; break; } tagname=tagname+content.charAt(i); } if(tagname.equals("")) {//不是有效标签,则略过 fullContentBuf=new StringBuffer(); }else { fullContentBuf.append(tagname).append(" "); endtag="</wx:"+tagname+">"; propBuf=new StringBuffer(); isInTagStartPart=true; tagbean=AbsTagInTemplate.createTagObj(parentTag,tagname,true); tagbean.setStartposition(startposition); lstEndChildTags=new ArrayList<String>(); } } } } if(fullContentBuf!=null&&fullContentBuf.length()>0) { throw new WabacusConfigLoadingException("解析模板失败,标签配置不合法"); } return lstResults; } private static String getTagContent(String tagFullContent) { if(tagFullContent==null||tagFullContent.trim().equals("")) return ""; int startidx=tagFullContent.indexOf(">"); int endidx=tagFullContent.lastIndexOf("</"); if(startidx<=0||endidx<=0||startidx>endidx) return ""; return tagFullContent.substring(startidx+1,endidx); } private static String getEndTag(String content) { if(content==null||content.trim().equals("")) return ""; String tagname=""; int i=0; for(;i<content.length();i++) { if(content.charAt(i)==' ') break;//标签名必须是紧跟在<wx:后面的,所以碰到空格或>说明标签名循环结束 if(content.charAt(i)=='>') { i--; break; } if(content.charAt(i)=='/') {//可能当前标签是<wx:tag/>形式,即既没有属性,也没有内容,则它也没有结束标签 return ""; } if(content.charAt(i)=='<'||content.charAt(i)=='\''||content.charAt(i)=='\"') { return ""; } tagname=tagname+content.charAt(i); } if(tagname.equals("")) return ""; int j=i; for(;j<content.length();j++) { if(content.charAt(j)=='<') { throw new WabacusConfigLoadingException("解析模板失败,标签<wx:"+tagname+">配置不合法"); } if(content.charAt(j)=='>') { if(content.charAt(j-1)=='/') {//当前标签是<tag .../>格式,则不需考虑它的结束标签 return ""; } break; } } if(j==content.length()) { throw new WabacusConfigLoadingException("解析模板失败,标签<wx:"+tagname+">配置不合法"); } return "</wx:"+tagname+">";//根据标签名拼凑出其结束标签 } }