From 27b61ffe97c575cdc6c2e8b9f010ab1021e7160e Mon Sep 17 00:00:00 2001 From: Helius <wangdoubleone@gmail.com> Date: Sat, 02 Jul 2022 21:36:56 +0800 Subject: [PATCH] 添加模板解析逻辑 --- src/main/java/com/xcong/farmer/cms/cms/tag/TagsEnum.java | 60 +++ src/main/java/com/xcong/farmer/cms/cms/tag/model/Ad.java | 28 + src/main/java/com/xcong/farmer/cms/cms/handler/TemplateCodeDataParserHandler.java | 15 src/main/java/com/xcong/farmer/cms/cms/template/Configuration.java | 111 +++++ src/main/java/com/xcong/farmer/cms/cms/handler/NavDataParserHandler.java | 43 ++ src/main/java/com/xcong/farmer/cms/cms/template/TemplateConfiguration.java | 105 +++++ src/main/java/com/xcong/farmer/cms/cms/handler/ArticlesDataParserHandler.java | 33 + pom.xml | 14 src/main/java/com/xcong/farmer/cms/cms/tag/model/Column.java | 48 ++ src/main/java/com/xcong/farmer/cms/cms/tag/model/Article.java | 28 + src/main/java/com/xcong/farmer/cms/cms/handler/ChildDataParserHandler.java | 30 + src/main/java/com/xcong/farmer/cms/cms/tag/model/Columns.java | 9 src/main/java/com/xcong/farmer/cms/cms/tag/model/Nav.java | 18 src/main/java/com/xcong/farmer/cms/cms/node/AttrNode.java | 203 ++++++++++ src/main/java/com/xcong/farmer/cms/cms/tag/model/Articles.java | 48 ++ src/main/java/com/xcong/farmer/cms/cms/template/Template.java | 71 +++ src/main/java/com/xcong/farmer/cms/cms/handler/ArticleDataParserHandler.java | 22 + src/main/java/com/xcong/farmer/cms/cms/handler/DataParserHandler.java | 10 src/main/java/com/xcong/farmer/cms/cms/template/TemplateLoader.java | 66 +++ src/main/java/com/xcong/farmer/cms/cms/node/PartNode.java | 102 +++++ src/main/java/com/xcong/farmer/cms/cms/tag/model/Child.java | 28 + src/main/java/com/xcong/farmer/cms/cms/tag/model/Include.java | 27 + 22 files changed, 1,119 insertions(+), 0 deletions(-) diff --git a/pom.xml b/pom.xml index 0287bb3..5030755 100644 --- a/pom.xml +++ b/pom.xml @@ -265,6 +265,20 @@ <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> + + <!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy --> + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy</artifactId> + <version>2.5.6</version> + </dependency> + + <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-text</artifactId> + <version>1.9</version> + </dependency> </dependencies> <build> diff --git a/src/main/java/com/xcong/farmer/cms/cms/handler/ArticleDataParserHandler.java b/src/main/java/com/xcong/farmer/cms/cms/handler/ArticleDataParserHandler.java new file mode 100644 index 0000000..9e54a40 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/handler/ArticleDataParserHandler.java @@ -0,0 +1,22 @@ +package com.xcong.farmer.cms.cms.handler; + + +import com.xcong.farmer.cms.cms.node.AttrNode; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author wzy + * @date 2022-06-24 + **/ +public class ArticleDataParserHandler implements DataParserHandler { + + @Override + public void dataParser(AttrNode node) { + System.out.println("ArticleDataParserHandler"); + Map<String, Object> map = new HashMap<>(); + map.put("title", "这是单个文章标题"); + node.setData(map); + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/handler/ArticlesDataParserHandler.java b/src/main/java/com/xcong/farmer/cms/cms/handler/ArticlesDataParserHandler.java new file mode 100644 index 0000000..69a2178 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/handler/ArticlesDataParserHandler.java @@ -0,0 +1,33 @@ +package com.xcong.farmer.cms.cms.handler; + +import com.xcong.farmer.cms.cms.node.AttrNode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author wzy + * @date 2022-06-24 + **/ +public class ArticlesDataParserHandler implements DataParserHandler { + + + @Override + public void dataParser(AttrNode node) { + System.out.println("ArticlesDataParserHandler"); + List<Map<String, Object>> list = new ArrayList<>(); + Map<String, Object> map = new HashMap<>(); + map.put("path", "这是链接1"); + map.put("title", "这是标题1"); + list.add(map); + + Map<String, Object> map2 = new HashMap<>(); + map2.put("path", "这是链接2"); + map2.put("title", "这是标题2"); + list.add(map2); + + node.setData(list); + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/handler/ChildDataParserHandler.java b/src/main/java/com/xcong/farmer/cms/cms/handler/ChildDataParserHandler.java new file mode 100644 index 0000000..5f78333 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/handler/ChildDataParserHandler.java @@ -0,0 +1,30 @@ +package com.xcong.farmer.cms.cms.handler; + + +import com.alibaba.fastjson.JSONObject; +import com.xcong.farmer.cms.cms.node.AttrNode; + +import java.util.List; +import java.util.Map; + +/** + * @author wzy + * @date 2022-06-29 + **/ +public class ChildDataParserHandler implements DataParserHandler { + + @Override + public void dataParser(AttrNode attrNode) { + System.out.println("ChildDataParserHandler"); + Map<String, Object> parserData = attrNode.getParserData(); + + Object param = attrNode.getParam(); + JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(param)); + String obj = jsonObject.getString("obj"); + + Object o = parserData.get(obj); + Object state = JSONObject.parseObject(JSONObject.toJSONString(o)).get("state"); + List children = JSONObject.parseObject(JSONObject.toJSONString(state)).getObject("children", List.class); + attrNode.setData(children); + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/handler/DataParserHandler.java b/src/main/java/com/xcong/farmer/cms/cms/handler/DataParserHandler.java new file mode 100644 index 0000000..7a3ee0d --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/handler/DataParserHandler.java @@ -0,0 +1,10 @@ +package com.xcong.farmer.cms.cms.handler; + + +import com.xcong.farmer.cms.cms.node.AttrNode; + +public interface DataParserHandler { + + void dataParser(AttrNode attrNode); + +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/handler/NavDataParserHandler.java b/src/main/java/com/xcong/farmer/cms/cms/handler/NavDataParserHandler.java new file mode 100644 index 0000000..222da87 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/handler/NavDataParserHandler.java @@ -0,0 +1,43 @@ +package com.xcong.farmer.cms.cms.handler; + +import com.xcong.farmer.cms.cms.node.AttrNode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author wzy + * @date 2022-06-28 + **/ +public class NavDataParserHandler implements DataParserHandler { + + + @Override + public void dataParser(AttrNode node) { + System.out.println("NavDataParserHandler"); + List<Map<String, Object>> list = new ArrayList<>(); + Map<String, Object> aa = new HashMap<>(); + aa.put("title", "导航1"); + list.add(aa); + + Map<String, Object> bb = new HashMap<>(); + bb.put("title", "导航2"); + + List<Map<String, Object>> sub = new ArrayList<>(); + Map<String, Object> subBB = new HashMap<>(); + subBB.put("title", "子导航1"); + subBB.put("src", "http://1234"); + sub.add(subBB); + Map<String, Object> subAA = new HashMap<>(); + subAA.put("title", "子导航2"); + subAA.put("src", "http://123455555"); + sub.add(subAA); + + bb.put("children", sub); + list.add(bb); + + node.setData(list); + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/handler/TemplateCodeDataParserHandler.java b/src/main/java/com/xcong/farmer/cms/cms/handler/TemplateCodeDataParserHandler.java new file mode 100644 index 0000000..10b89d6 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/handler/TemplateCodeDataParserHandler.java @@ -0,0 +1,15 @@ +package com.xcong.farmer.cms.cms.handler; + +import com.xcong.farmer.cms.cms.node.AttrNode; + +/** + * @author wzy + * @date 2022-06-29 + **/ +public class TemplateCodeDataParserHandler implements DataParserHandler { + + @Override + public void dataParser(AttrNode tagNode) { + System.out.println("TemplateCodeDataParserHandler"); + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/node/AttrNode.java b/src/main/java/com/xcong/farmer/cms/cms/node/AttrNode.java new file mode 100644 index 0000000..adf7a84 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/node/AttrNode.java @@ -0,0 +1,203 @@ +package com.xcong.farmer.cms.cms.node; + + +import com.alibaba.fastjson.JSONObject; +import com.xcong.farmer.cms.cms.handler.DataParserHandler; +import com.xcong.farmer.cms.cms.tag.TagsEnum; +import com.xcong.farmer.cms.cms.tag.model.Articles; +import com.xcong.farmer.cms.cms.template.Configuration; +import groovy.lang.Binding; +import groovy.lang.GroovyShell; +import org.apache.commons.text.StringSubstitutor; +import org.jsoup.nodes.Attribute; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class AttrNode extends Configuration { + private String tag; + + public TagsEnum tagsEnum; + // tag标签中field字段的值 如 field=art 中的 art + private String field; + // 标签数据 如@artilces从数据库查询到的数据 + private Object data; + // 用于给这个标签attr注入的数据 + private Map<String, Object> parserData; + // Tag参数 {id=[1,2,3], page=1, limit=5, field=art} + private Object param; + + private Element element; + private Element originalElement; + + public AttrNode() { + } + + public AttrNode(Element element) { + this.element = element.clone(); + this.originalElement = element; + } + + public AttrNode(Element element, Map<String, Object> parserData) { + this.element = element.clone(); + this.originalElement = element; + this.parserData = parserData; + } + + public static void main(String[] args) { +// String data = "{id=[1,2,3], page=1, limit=5, field=art}"; +// Articles articles = new AttrNode().parserTag(data, Articles.class); + +// String value = "{id=${col.id}, page=1, limit=5, field=art}"; +// String pattern = "(?<=\\$\\{)[\\s\\S]*?(?=\\})"; +// Matcher matcher = Pattern.compile(pattern).matcher(value); +// while (matcher.find()) { +// String group = matcher.group(); +// System.out.println(1); +// } + + + System.out.println(1); + } + + public void parser() { + this.element.empty(); + Attributes attributes = this.element.attributes(); + if (attributes.isEmpty()) { + return; + } + + // i = 1表示每个element上最多有一个tag + int i = 1; + + // 判断element中是否包含tag,若有,则解析并查询对应数据 + for (TagsEnum tagsEnum : TagsEnum.values()) { + if (!attributes.hasKey(tagsEnum.getName())) { + continue; + } + if (i > 1) { + throw new RuntimeException("element most one tag"); + } + i++; + + try { + // {id=${col.id}, page=1, limit=5, field=art} ${col.id} 形式需先设置值 + String tagValue = attributes.get(tagsEnum.getName()); + tagValue = attrValueFormat(tagValue); + + this.param = parserTag(tagValue, Class.forName(tagsEnum.getClassName())); + + this.field = JSONObject.parseObject(JSONObject.toJSONString(param)).getString("field"); + this.tagsEnum = tagsEnum; + + DataParserHandler handler = (DataParserHandler) Class.forName(tagsEnum.getHandler()).newInstance(); + handler.dataParser(this); + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + + this.tag = tagsEnum.getName(); + } + + runDataInject(); + } + + public void runDataInject() { + Attributes attributes = this.element.attributes(); + for (Attribute attribute : attributes) { + String key = attribute.getKey().replaceAll("\\$", ""); + String value = attribute.getValue(); + + // @{} 为java表达式; ${}为需要注入的数据项 + if (value.startsWith("@{")) { + value = value.replaceAll("\\@\\{", "").replaceAll("}", ""); + Binding binding = new Binding(); + for (Map.Entry<String, Object> entry : this.parserData.entrySet()) { + String fieldKey = entry.getKey(); + Map<String, Object> data = (Map<String, Object>) entry.getValue(); + binding.setProperty(fieldKey, data); + binding.setVariable(fieldKey + ".index", 1); + } + GroovyShell shell = new GroovyShell(binding); + String evaluate = (String) shell.evaluate(value); + + this.element.removeAttr("class"); + this.element.attr("class", evaluate); + } else if (value.startsWith("${")) { + + String result = attrValueFormat(value); + if ("text".equals(key)) { + this.element.text(result); + } else { + this.element.attr(key, result); + } + } + } + } + + public String attrValueFormat(String value) { + String pattern = "(?<=\\$\\{)[\\s\\S]*?(?=\\})"; + Matcher matcher = Pattern.compile(pattern).matcher(value); + + Map<String, String> targetData = new HashMap<>(); + while (matcher.find()) { + String group = matcher.group(); + String splitValue = group.replaceAll("\\$\\{", "").replaceAll("}", ""); + String[] split = splitValue.split("\\."); + if (split.length == 0) { + continue; + } + + for (Map.Entry<String, Object> entry : this.parserData.entrySet()) { + String fieldKey = entry.getKey(); + Map<String, Object> data = (Map<String, Object>) entry.getValue(); + JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(data.get("state"))); + + for (Map.Entry<String, Object> map : jsonObject.entrySet()) { + if (map.getValue() instanceof String) { + targetData.put(fieldKey + "." + map.getKey(), (String) map.getValue()); + } + } + } + } + + StringSubstitutor str = new StringSubstitutor(targetData); + return str.replace(value); + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public Element getElement() { + return element; + } + + public Map<String, Object> getParserData() { + return parserData; + } + + public Object getParam() { + return param; + } + + public String getTag() { + return tag; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/node/PartNode.java b/src/main/java/com/xcong/farmer/cms/cms/node/PartNode.java new file mode 100644 index 0000000..3866f09 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/node/PartNode.java @@ -0,0 +1,102 @@ +package com.xcong.farmer.cms.cms.node; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.xcong.farmer.cms.cms.template.Configuration; +import org.jsoup.nodes.Element; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PartNode extends Configuration { + + private Element element; + private Element originalElement; + private String html; + + public PartNode(Element element) { + this.element = element.clone(); + this.originalElement = element; + } + + public void parser() { + this.html = parser(this.element, null); + } + + public String parser(Element element, Map<String, Object> tagDataMap) { + AttrNode attrNode = new AttrNode(element, tagDataMap); + attrNode.parser(); +// attrNode.runDataInject(); + + StringBuilder result = new StringBuilder(); + if (CollUtil.isNotEmpty(element.children())) { + Object parseData = attrNode.getData(); + if (tagDataMap == null) { + tagDataMap = new HashMap<>(); + } + + if (parseData == null) { + // 特殊处理。 如果有子节点标签@child,但数据中没有子节点数据,则将该子节点直接删除即直接返回空字符串 + if (!"@child".equals(attrNode.getTag())) { + for (Element children : element.children()) { + String html = parser(children, tagDataMap); + result.append(html); + } + } else { + return ""; + } + } else { + if (parseData instanceof List) { + List list = (List) parseData; + + int i = 1; + for (Object o : list) { + if (StrUtil.isNotBlank(attrNode.getField())) { + Map<String, Object> data = new HashMap<>(); + data.put("index", i); + data.put("state", o); + tagDataMap.put(attrNode.getField(), data); + } + + StringBuilder listHtml = new StringBuilder(); + for (Element children : element.children()) { + String html = parser(children, tagDataMap); + listHtml.append(html); + } + result.append(listHtml); + i++; + } + + } else if (parseData instanceof Map) { + if (StrUtil.isNotBlank(attrNode.getField())) { + Map<String, Object> data = new HashMap<>(); + data.put("index", 1); + data.put("state", parseData); + tagDataMap.put(attrNode.getField(), data); + } + + for (Element children : element.children()) { + String html = parser(children, tagDataMap); + result.append(html); + } + } + } + } + + if (attrNode.tagsEnum != null && attrNode.tagsEnum.getType() == 1) { + this.put(attrNode.getField(), result.toString()); + } + + attrNode.getElement().append(result.toString()); + return attrNode.getElement().toString(); + } + + public Element getElement() { + return element; + } + + public String getHtml() { + return html; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/TagsEnum.java b/src/main/java/com/xcong/farmer/cms/cms/tag/TagsEnum.java new file mode 100644 index 0000000..e782e0e --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/TagsEnum.java @@ -0,0 +1,60 @@ +package com.xcong.farmer.cms.cms.tag; + +/** + * @author wzy + * @date 2022-06-20 + **/ +public enum TagsEnum { + INCLUDE("@include", "com.xcong.farmer.cms.cms.tag.model.Include", "com.xcong.farmer.cms.cms.handler.TemplateCodeDataParserHandler", 1), + NAV("@nav", "com.xcong.farmer.cms.cms.tag.model.Nav", "com.xcong.farmer.cms.cms.handler.NavDataParserHandler", 2), + ARTICLES("@articles", "com.xcong.farmer.cms.cms.tag.model.Articles", "com.xcong.farmer.cms.cms.handler.ArticlesDataParserHandler",2), + ARTICLE("@article", "com.xcong.farmer.cms.cms.tag.model.Article", "com.xcong.farmer.cms.cms.handler.ArticleDataParserHandler",2), + CHILD("@child", "com.xcong.farmer.cms.cms.tag.model.Child", "com.xcong.farmer.cms.cms.handler.ChildDataParserHandler",2); +// AD("@ad", "com.xcong.farmer.cms.cms.tag.model.Ad", "",2), +// COLUMNS("@columns", "com.xcong.farmer.cms.cms.tag.model.Columns", "",2), +// COLUMN("@column", "com.xcong.farmer.cms.cms.tag.model.Column", "",2); + + private String name; + + private String className; + + private String handler; + + // 标签类型 1-模板标签 2-数据标签 + // 模板标签 : 该标签可以变为通用模板,在各个页面引入 + // 数据模板 : 该标签需要注入数据 + private int type; + + TagsEnum(String name, String className, String handler, int type) { + this.name = name; + this.className = className; + this.type = type; + this.handler = handler; + } + + public String getName() { + return name; + } + + public String getClassName() { + return className; + } + + public int getType() { + return type; + } + + public String getHandler() { + return handler; + } + + public static TagsEnum getEnumByName(String name) { + for (TagsEnum value : values()) { + if (name.equals(value.getName())) { + return value; + } + } + + return null; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Ad.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Ad.java new file mode 100644 index 0000000..4e0f869 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Ad.java @@ -0,0 +1,28 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-22 + **/ +public class Ad { + + private String id; + + private String field; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Article.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Article.java new file mode 100644 index 0000000..a0c72c1 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Article.java @@ -0,0 +1,28 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-22 + **/ +public class Article { + + private String id; + + private String field; + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Articles.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Articles.java new file mode 100644 index 0000000..e93e0ef --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Articles.java @@ -0,0 +1,48 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-20 + **/ +public class Articles { + + private String colId; + + private String page; + + private String limit; + + private String field; + + public String getColId() { + return colId; + } + + public void setColId(String colId) { + this.colId = colId; + } + + public String getPage() { + return page; + } + + public void setPage(String page) { + this.page = page; + } + + public String getLimit() { + return limit; + } + + public void setLimit(String limit) { + this.limit = limit; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Child.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Child.java new file mode 100644 index 0000000..7ae44fa --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Child.java @@ -0,0 +1,28 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-07-01 + **/ +public class Child { + + private String obj; + + private String field; + + public String getObj() { + return obj; + } + + public void setObj(String obj) { + this.obj = obj; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Column.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Column.java new file mode 100644 index 0000000..18b0146 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Column.java @@ -0,0 +1,48 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-22 + **/ +public class Column { + + private String id; + + private String field; + + private String code; + + private String hasChild; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getHasChild() { + return hasChild; + } + + public void setHasChild(String hasChild) { + this.hasChild = hasChild; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Columns.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Columns.java new file mode 100644 index 0000000..ed62f0b --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Columns.java @@ -0,0 +1,9 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-22 + **/ +public class Columns { + +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Include.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Include.java new file mode 100644 index 0000000..47e9c6a --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Include.java @@ -0,0 +1,27 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-23 + **/ +public class Include { + private String field; + + private String repeat = "1"; + + public String getRepeat() { + return repeat; + } + + public void setRepeat(String repeat) { + this.repeat = repeat; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/tag/model/Nav.java b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Nav.java new file mode 100644 index 0000000..45e5707 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/tag/model/Nav.java @@ -0,0 +1,18 @@ +package com.xcong.farmer.cms.cms.tag.model; + +/** + * @author wzy + * @date 2022-06-28 + **/ +public class Nav { + + String field; + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/template/Configuration.java b/src/main/java/com/xcong/farmer/cms/cms/template/Configuration.java new file mode 100644 index 0000000..76a24e6 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/template/Configuration.java @@ -0,0 +1,111 @@ +package com.xcong.farmer.cms.cms.template; + +import com.xcong.farmer.cms.cms.node.AttrNode; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public abstract class Configuration { + + public String staticPath; + public String templatePath; + public String outputPath; + + public Configuration() { + } + + public Configuration(String templatePath, String staticPath, String outputPath) { + this.staticPath = staticPath; + this.templatePath = templatePath; + this.outputPath = outputPath; + } + + public static Map<String, String> templateCode = new HashMap<>(); + + private final String PREFIX_DEFAULT = "{"; + private final String SUFFIX_DEFAULT = "}"; + + public <T> T parserTag(String attr, Class<T> clazz) { + if (!attr.startsWith(PREFIX_DEFAULT) || !attr.endsWith(SUFFIX_DEFAULT)) { + return null; + } + + int i = 1; + int length = attr.length(); + + int startIndex = 1; + int endIndex = 1; + T object = null; + try { + object = clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + + boolean hasMulti = false; + for (; i <= length - 1; i++) { + if (attr.charAt(i) =='[') { + hasMulti = true; + } else if (attr.charAt(i) == ']') { + hasMulti = false; + } + + if (!hasMulti) { + if (attr.charAt(i) == ',' || i == length - 1) { + String columnStr = attr.substring(startIndex, endIndex); + + String[] columns = columnStr.split("="); + if (columns.length != 2) { + return null; + } + + try { + Field field = clazz.getDeclaredField(columns[0].trim()); + field.setAccessible(true); + field.set(object, columns[1].replace("[", "").replace("]", "").trim()); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + return null; + } + startIndex = i + 1; + } + } + endIndex++; + } + + return object; + } + + public void put(String key, String templateCode) { + Configuration.templateCode.put(key, templateCode); + } + + public String get(String key) { + return Configuration.templateCode.get(key); + } + + public String getStaticPath() { + return staticPath; + } + + public void setStaticPath(String staticPath) { + this.staticPath = staticPath; + } + + public String getTemplatePath() { + return templatePath; + } + + public void setTemplatePath(String templatePath) { + this.templatePath = templatePath; + } + + public String getOutputPath() { + return outputPath; + } + + public void setOutputPath(String outputPath) { + this.outputPath = outputPath; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/template/Template.java b/src/main/java/com/xcong/farmer/cms/cms/template/Template.java new file mode 100644 index 0000000..f0a20f0 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/template/Template.java @@ -0,0 +1,71 @@ +package com.xcong.farmer.cms.cms.template; + +import cn.hutool.core.collection.CollUtil; +import com.xcong.farmer.cms.cms.node.PartNode; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author wzy + * @date 2022-06-22 + **/ +public class Template { + + private String name; + + private Document document; + + private Map<String, Map<String, Object>> params = new HashMap<>(); + + private List<PartNode> partNodes = new ArrayList<>(); + + public void parser() { + Elements children = document.body().children(); + if (CollUtil.isNotEmpty(children)) { + for (Element child : children) { + PartNode partNode = new PartNode(child); + partNode.parser(); + + this.add(partNode); + } + } + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Document getDocument() { + return document; + } + + public void setDocument(Document document) { + this.document = document; + } + + public void add(PartNode partNode) { + this.partNodes.add(partNode); + } + + public List<PartNode> getPartNodes() { + return partNodes; + } + + public Map<String, Map<String, Object>> getParams() { + return params; + } + + public void putParams(String key, Map<String, Object> value) { + this.params.put(key, value); + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/template/TemplateConfiguration.java b/src/main/java/com/xcong/farmer/cms/cms/template/TemplateConfiguration.java new file mode 100644 index 0000000..4162af3 --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/template/TemplateConfiguration.java @@ -0,0 +1,105 @@ +package com.xcong.farmer.cms.cms.template; + +import cn.hutool.core.collection.CollUtil; +import com.xcong.farmer.cms.cms.node.PartNode; +import com.xcong.farmer.cms.cms.tag.TagsEnum; +import org.jsoup.nodes.Document; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author wzy + * @date 2022-07-01 + **/ +public class TemplateConfiguration extends Configuration{ + + private TemplateLoader templateLoader; + + public TemplateConfiguration(String templatePath, String staticPath, String outputPath) { + super(templatePath, staticPath, outputPath); + } + + public void templateLoader(TemplateLoader templateLoader) { + this.templateLoader = templateLoader; + } + + public void process() { + if (this.templateLoader == null) { + throw new RuntimeException("TemplateLoader do not able to be null"); + } + + List<Template> templates = templateLoader.templates(); + + if (CollUtil.isEmpty(templates)) { + return; + } + + for (Template template : templates) { + output(template); + } + } + + public List<Template> templates() { + return this.templateLoader.templates(); + } + + public Template template(String templateName) { + return template(new File(path(this.templatePath) + templateName)); + } + + public Template template(File file) { + if (file == null) { + throw new RuntimeException("template not exist"); + } + + return this.templateLoader.template(file); + } + + public void columnProcess(Long id, String templateName) { + Template template = template(templateName); + } + + public void columnProcess(String code, String templateName) { + + } + + public void articleProcess(Long id, String templateName) { + Map<String, Map<String, Object>> map = new HashMap<>(); + + Map<String, Object> data = new HashMap<>(); + data.put("id", id); + map.put(TagsEnum.ARTICLE.getName(), data); + } + + public void output(Template template) { + Document document = template.getDocument(); + List<PartNode> partNodes = template.getPartNodes(); + StringBuilder sb = new StringBuilder(); + for (PartNode partNode : partNodes) { + sb.append(partNode.getHtml()); + } + document.body().empty().html(sb.toString()); + String outPath = path(this.outputPath); + + String html = document.html(); + try { + FileOutputStream outputStream = new FileOutputStream(outPath + template.getName()); + outputStream.write(html.getBytes()); + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String path(String path) { + if (!path.endsWith("/")) { + path = path + "/"; + } + return path; + } +} diff --git a/src/main/java/com/xcong/farmer/cms/cms/template/TemplateLoader.java b/src/main/java/com/xcong/farmer/cms/cms/template/TemplateLoader.java new file mode 100644 index 0000000..154732e --- /dev/null +++ b/src/main/java/com/xcong/farmer/cms/cms/template/TemplateLoader.java @@ -0,0 +1,66 @@ +package com.xcong.farmer.cms.cms.template; + +import cn.hutool.core.collection.CollUtil; +import com.xcong.farmer.cms.cms.node.AttrNode; +import com.xcong.farmer.cms.cms.node.PartNode; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class TemplateLoader { + + private Configuration cfg; + private List<Template> templates = new ArrayList<>(); + + public TemplateLoader() {} + + public TemplateLoader(Configuration cfg) { + this.cfg = cfg; + } + + public Template template(File file) { + Document document = null; + try { + document = Jsoup.parse(file, "utf-8"); + } catch (IOException e) { + e.printStackTrace(); + } + + if (document == null) { + throw new NullPointerException(); + } + + Template template = new Template(); + template.setDocument(document); + template.setName(file.getName()); + + template.parser(); + return template; + } + + public List<Template> templates(String templatePath) { + File files = new File(templatePath); + if (files.listFiles() == null) { + return null; + } + + for (File file : files.listFiles()) { + if (file.isDirectory()) { + continue; + } + templates.add(template(file)); + } + + return templates; + } + + public List<Template> templates() { + return templates(cfg.getTemplatePath()); + } +} -- Gitblit v1.9.1