From 7bd1c7ebdde2c2236a9152cccdbadc5b03739639 Mon Sep 17 00:00:00 2001 From: zhouhao Date: Tue, 9 May 2017 17:08:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=95=B0=E6=8D=AE=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E8=A7=A3=E6=9E=90=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/dictionary/DictionaryParser.java | 22 +- .../dictionary/DictionaryParserBuilder.java | 4 +- .../dictionary/DictionaryParserService.java | 4 +- .../pom.xml | 4 + .../simple/SimpleDictionaryParser.java | 83 ++++++ .../simple/SimpleDictionaryParserService.java | 5 +- .../simple/parser/DictParserFormat.java | 81 ++++++ .../simple/parser/DictParserFormatter.java | 13 + .../simple/parser/FormatterResult.java | 39 +++ .../parser/SimpleDictParserFormatter.java | 67 +++++ .../simple/parser/SimpleSingleDictParser.java | 251 ++++++++++++++++++ .../simple/parser/SingleDictParser.java | 17 ++ .../dictionary/DictionaryParserTests.java | 109 ++++++++ 13 files changed, 689 insertions(+), 10 deletions(-) create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParser.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormat.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormatter.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/FormatterResult.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleDictParserFormatter.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleSingleDictParser.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SingleDictParser.java create mode 100644 hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/test/java/org/hswebframework/web/starter/dictionary/DictionaryParserTests.java diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParser.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParser.java index 54f54ee6d..ed001b155 100644 --- a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParser.java +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParser.java @@ -18,17 +18,27 @@ package org.hswebframework.web.service.dictionary; -import org.hswebframework.web.entity.dictionary.DictionaryEntity; -import org.hswebframework.web.entity.dictionary.DictionaryItemEntity; - import java.io.Serializable; +import java.util.List; import java.util.Optional; /** + * 字典解析器接口 + * * @author zhouhao */ -public interface DictionaryParser extends Serializable { - Optional textToValue(DictionaryEntity dict, T text); +public interface DictionaryParser extends Serializable { + + Optional textToValue(String text, Object context); + + Optional valueToText(V value, Object context); + + default Optional textToValue(String text) { + return textToValue(text, null); + } + + default Optional valueToText(V value) { + return valueToText(value, null); + } - Optional valueToText(DictionaryEntity dict, V value); } diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserBuilder.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserBuilder.java index a03b5e27a..b1247f188 100644 --- a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserBuilder.java +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserBuilder.java @@ -22,7 +22,7 @@ package org.hswebframework.web.service.dictionary; * @author zhouhao */ public interface DictionaryParserBuilder { - DictionaryParser buildValueToTextParser(String config); + DictionaryParser buildValueToTextParser(String config); - DictionaryParser buildTextToValueParser(String config); + DictionaryParser buildTextToValueParser(String config); } diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserService.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserService.java index 6cd45db81..4a5b874ce 100644 --- a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserService.java +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-api/src/main/java/org/hswebframework/web/service/dictionary/DictionaryParserService.java @@ -16,6 +16,8 @@ */ package org.hswebframework.web.service.dictionary; +import org.hswebframework.web.entity.dictionary.DictionaryEntity; +import org.hswebframework.web.entity.dictionary.DictionaryItemEntity; import org.hswebframework.web.entity.dictionary.DictionaryParserEntity; import org.hswebframework.web.service.CrudService; @@ -26,7 +28,7 @@ import org.hswebframework.web.service.CrudService; */ public interface DictionaryParserService extends CrudService { - DictionaryParser getParser(String parserId); + DictionaryParser getParser(DictionaryEntity dict, String parserId); } diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/pom.xml b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/pom.xml index 6bf2cbc40..3eb7316e3 100644 --- a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/pom.xml +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/pom.xml @@ -38,5 +38,9 @@ hsweb-system-dictionary-service-api ${project.version} + + org.hswebframework + hsweb-expands-script + \ No newline at end of file diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParser.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParser.java new file mode 100644 index 000000000..bab6db635 --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParser.java @@ -0,0 +1,83 @@ +package org.hswebframework.web.service.dictionary.simple; + +import org.hswebframework.web.ExpressionUtils; +import org.hswebframework.web.entity.dictionary.DictionaryEntity; +import org.hswebframework.web.entity.dictionary.DictionaryItemEntity; +import org.hswebframework.web.service.dictionary.DictionaryParser; +import org.hswebframework.web.service.dictionary.simple.parser.SimpleSingleDictParser; +import org.hswebframework.web.service.dictionary.simple.parser.SingleDictParser; + +import java.io.Serializable; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * 简单的字典解析器实现,支持树形结构字典 + *

+ * e.g. + *

+ *   //字典
+ *   [
+ *    {text:"苹果",value:1,
+ *     children:[
+ *      {text:"青苹果",value:101},
+ *      {text:"红富士",value:102},
+ *      {text:"其他苹果",value:103,textExpression:"其他苹果(${#context.otherApple})"}
+ *    ]}
+ *    {text:"梨子",value:2}
+ *   ]
+ *   //调用
+ *   parser.valueToText("1,101,103",{otherApple:"其他苹果1"});
+ *   //返回结果  苹果(青苹果,其他苹果(其他苹果1))
+ *
+ *   //调用
+ *   parser.textToValue("苹果(青苹果,其他苹果)")
+ *   //返回结果 1,101,103
+ * 
+ * + * @author zhouhao + * @since 3.0 + */ +public class SimpleDictionaryParser implements DictionaryParser { + + private SimpleSingleDictParser toTextParser = new SimpleSingleDictParser(); + + private SimpleSingleDictParser toValueParser = new SimpleSingleDictParser(); + + public SimpleSingleDictParser getToTextParser() { + return toTextParser; + } + + public SimpleSingleDictParser getToValueParser() { + return toValueParser; + } + + //设置DictionaryEntity作为配置 + public void setDict(DictionaryEntity dict) { + toTextParser.setDict(dict, DictionaryItemEntity::getValue + , DictionaryItemEntity::getText + , DictionaryItemEntity::getTextExpression); + + toValueParser.setDict(dict, DictionaryItemEntity::getText + , DictionaryItemEntity::getValue, + DictionaryItemEntity::getValueExpression); + + toValueParser.getTargetFormat().setSplitter(","); + toValueParser.getTargetFormat().setChildStartChar(","); + toValueParser.getTargetFormat().setChildEndChar(""); + toValueParser.getTargetFormat().setChildSplitter(","); + } + + @Override + public Optional valueToText(V value, Object context) { + if (value == null) return Optional.empty(); + return toTextParser.parse(String.valueOf(value), context); + } + + @Override + public Optional textToValue(String text, Object context) { + return toValueParser.parse(text, context).map(v -> (V) v); + } +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParserService.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParserService.java index 6d6261bd8..12597ea15 100644 --- a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParserService.java +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/SimpleDictionaryParserService.java @@ -17,6 +17,8 @@ package org.hswebframework.web.service.dictionary.simple; import org.hswebframework.web.dao.dictionary.DictionaryParserDao; +import org.hswebframework.web.entity.dictionary.DictionaryEntity; +import org.hswebframework.web.entity.dictionary.DictionaryItemEntity; import org.hswebframework.web.entity.dictionary.DictionaryParserEntity; import org.hswebframework.web.id.IDGenerator; import org.hswebframework.web.service.GenericEntityService; @@ -47,7 +49,8 @@ public class SimpleDictionaryParserService extends GenericEntityService DictionaryParser getParser(String parserId) { + public DictionaryParser getParser(DictionaryEntity dict, String parserId) { + // TODO: 17-3-9 return null; } diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormat.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormat.java new file mode 100644 index 000000000..3372eed8b --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormat.java @@ -0,0 +1,81 @@ +package org.hswebframework.web.service.dictionary.simple.parser; + +import java.io.Serializable; +import java.util.StringJoiner; + +/** + * TODO 完成注释 + * + * @author zhouhao + */ +public class DictParserFormat implements Serializable { + //字典选项间的分割符 + private String splitter = ","; + + //子节点间的分割符 + private String childSplitter = ","; + + //子节点开始分割符 + private String childStartChar = "("; + + //子节点结束分割符 + private String childEndChar = ")"; + + //前缀 + private String prefix = ""; + + //后缀 + private String suffix = ""; + + public String getSplitter() { + return splitter; + } + + public void setSplitter(String splitter) { + this.splitter = splitter; + } + + public String getChildSplitter() { + return childSplitter; + } + + public void setChildSplitter(String childSplitter) { + this.childSplitter = childSplitter; + } + + public String getChildStartChar() { + return childStartChar; + } + + public void setChildStartChar(String childStartChar) { + this.childStartChar = childStartChar; + } + + public String getChildEndChar() { + return childEndChar; + } + + public void setChildEndChar(String childEndChar) { + this.childEndChar = childEndChar; + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public StringJoiner createJoiner() { + return new StringJoiner(splitter, prefix, suffix); + } +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormatter.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormatter.java new file mode 100644 index 000000000..3c5a7937e --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/DictParserFormatter.java @@ -0,0 +1,13 @@ +package org.hswebframework.web.service.dictionary.simple.parser; + +import java.util.List; +import java.util.function.BiFunction; + +/** + * TODO 完成注释 + * + * @author zhouhao + */ +public interface DictParserFormatter { + List> format(DictParserFormat format, Object value, BiFunction mapping); +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/FormatterResult.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/FormatterResult.java new file mode 100644 index 000000000..7b259a358 --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/FormatterResult.java @@ -0,0 +1,39 @@ +package org.hswebframework.web.service.dictionary.simple.parser; + +/** + * + * @author zhouhao + */ +public class FormatterResult { + private V result; + + private String pattern; + + public FormatterResult() { + } + + public FormatterResult(V result) { + this(result, String.valueOf(result)); + } + + public FormatterResult(V result, String pattern) { + this.result = result; + this.pattern = pattern; + } + + public V getResult() { + return result; + } + + public void setResult(V result) { + this.result = result; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleDictParserFormatter.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleDictParserFormatter.java new file mode 100644 index 000000000..ea0515465 --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleDictParserFormatter.java @@ -0,0 +1,67 @@ +package org.hswebframework.web.service.dictionary.simple.parser; + +import org.hswebframework.web.RegexUtils; + +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * TODO 完成注释 + * + * @author zhouhao + */ +public class SimpleDictParserFormatter implements DictParserFormatter { + + public boolean smartParse = true; + + public int smartLevel = 3; + + public void setSmartParse(boolean smartParse) { + this.smartParse = smartParse; + } + + public boolean needParse(String value, DictParserFormat format) { + return value.contains(format.getSplitter()) + || value.contains(format.getChildSplitter()) + || value.contains(format.getChildStartChar()); + } + + private FormatterResult createResult(T v, String pattern) { + return new FormatterResult<>(v, pattern); + } + + @Override + public List> format(DictParserFormat format + , Object value + , BiFunction mapping) { + if (value == null) return Collections.emptyList(); + String stringValue = String.valueOf(value); + if (!needParse(stringValue, format)) + return Collections.singletonList(createResult(mapping.apply(stringValue, stringValue), stringValue)); + + String splitter = "[" + RegexUtils.escape(format.getSplitter() + + " " + format.getChildStartChar() + + " " + format.getChildSplitter() + + " " + format.getChildEndChar()) + + "]"; + return Arrays.stream(stringValue.split(splitter)) + .map(val -> { + T v = mapping.apply(val, val); + if (v == null && smartParse) { + StringBuilder tmp = new StringBuilder(); + char[] arr = val.toCharArray(); + for (int i = 0; i < arr.length; i++) { + tmp.append(arr[i]); + if (i >= smartLevel) { + v = mapping.apply(tmp.toString(), val); + if (null != v) break; + } + } + } + return createResult(v, val); + }) + .collect(Collectors.toList()); + } +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleSingleDictParser.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleSingleDictParser.java new file mode 100644 index 000000000..e470cf12a --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SimpleSingleDictParser.java @@ -0,0 +1,251 @@ +package org.hswebframework.web.service.dictionary.simple.parser; + +import org.hswebframework.web.ExpressionUtils; +import org.hswebframework.web.entity.dictionary.DictionaryEntity; +import org.hswebframework.web.entity.dictionary.DictionaryItemEntity; + +import java.io.Serializable; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * TODO 完成注释 + * + * @author zhouhao + */ +public class SimpleSingleDictParser implements SingleDictParser { + + private Map mapping = new HashMap<>(); + + private DictParserFormat sourceFormat = new DictParserFormat(); + + private DictParserFormat targetFormat = new DictParserFormat(); + + private DictParserFormatter formatter = new SimpleDictParserFormatter(); + + //设置DictionaryEntity作为配置 + public void setDict(DictionaryEntity dict, + Function keyGetter, + Function valueGetter, + Function expressionGetter) { + dict.getItems().forEach(item -> addMapping(item, keyGetter, valueGetter, expressionGetter)); + } + + public DictParserFormat getTargetFormat() { + return targetFormat; + } + + public DictParserFormat getSourceFormat() { + return sourceFormat; + } + + private DictMapping addMapping(DictionaryItemEntity item, + Function keyGetter, + Function valueGetter, + Function expressionGetter) { + DictMapping dictMapping = new DictMapping(); + dictMapping.setValue(valueGetter.apply(item)); + dictMapping.setExpression(expressionGetter.apply(item)); + if (item.getChildren() != null) { + dictMapping.setChildren(item.getChildren().stream() + .map(DictionaryItemEntity.class::cast) + .map(i -> addMapping(i, keyGetter, valueGetter, expressionGetter)).collect(Collectors.toList())); + } + String key = keyGetter.apply(item); + dictMapping.setKey(key); + mapping.put(key, dictMapping); + return dictMapping; + } + + @Override + public Optional parse(String value, Object context) { + if (value == null) return Optional.empty(); + StringJoiner joiner = targetFormat.createJoiner(); + + List dictMappings = formatter + .format(sourceFormat, value, (key, pattern) -> { + DictMapping dictMapping = mapping.get(key); + if (dictMapping == null) return null; + dictMapping = dictMapping.clone(); + dictMapping.setDefaultVar(Collections.singletonMap("pattern", pattern)); + return dictMapping; + }) + .stream() + .filter(Objects::nonNull) + .map(FormatterResult::getResult) + .collect(Collectors.toList()); + + Set notAppendList = new HashSet<>(); + List mappingResult = dictMappings.stream() + .filter(Objects::nonNull) + // 过滤子节点 + .peek(dictMapping -> dictMapping.filterChildren((mapping -> { + String strVal = mapping.getValue(); + notAppendList.add(strVal); //子节点不拼接 + int index = dictMappings.indexOf(mappingOfValue(strVal)); + DictMapping tmp = null; + if (-1 != index) + tmp = dictMappings.get(index); + if (null != tmp) + mapping.setDefaultVar(tmp.getDefaultVar()); + return null != tmp; + }))) + .filter(mapping -> !notAppendList.contains(mapping.getValue())) + //字典转为text + .map(dict -> dict.toString(context)) + .collect(Collectors.toList()); + mappingResult.forEach(joiner::add); + return Optional.ofNullable(joiner.toString()); + } + + public void setMapping(Map mapping) { + this.mapping = mapping; + } + + DictMapping mappingOfValue(String value) { + DictMapping mapping = new DictMapping(); + mapping.setValue(value); + return mapping; + } + + protected class DictMapping implements Serializable { + private String key; + private String value; + private String expression; + private String expressionLanguage = "spel"; + private List children; + + private Map defaultVar; + + public void setDefaultVar(Map defaultVar) { + this.defaultVar = defaultVar; + } + + public Map getDefaultVar() { + return defaultVar; + } + + @Override + public int hashCode() { + if (value == null) return 0; + return value.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + return obj == this || hashCode() == obj.hashCode(); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getChildren() { + return children; + } + + public String getExpression() { + return expression; + } + + public void setExpression(String expression) { + this.expression = expression; + } + + public void setExpressionLanguage(String expressionLanguage) { + this.expressionLanguage = expressionLanguage; + } + + public String getExpressionLanguage() { + if (expressionLanguage == null) expressionLanguage = "spel"; + return expressionLanguage; + } + + public void setChildren(List children) { + this.children = children; + } + + public String toString(Function getter) { + StringBuilder stringBuilder = new StringBuilder(getter.apply(this)); + if (children != null) { + //根据getter 获取子节点的string + String childrenString = String.join(targetFormat.getChildSplitter(), children.stream() + .map(mapping -> mapping.toString(getter)).collect(Collectors.toList())); + + if (childrenString.isEmpty()) return stringBuilder.toString(); + //拼接子节点 + stringBuilder.append(targetFormat.getChildStartChar()) + .append(childrenString) + .append(targetFormat.getChildEndChar()); + } + return stringBuilder.toString(); + } + + public String toString(Object context) { + Function textGetter = + context == null ? DictMapping::getValue : + dictMapping -> { + if (dictMapping.getExpression() == null || dictMapping.getExpression().isEmpty()) + return dictMapping.getValue(); + // 解析表达式 + Map var = new HashMap<>(); + if (dictMapping.getDefaultVar() != null) var.putAll(dictMapping.getDefaultVar()); + var.put("value", dictMapping.getValue()); + var.put("key", dictMapping.getKey()); + var.put("context", context); + var.put("children", dictMapping.getChildren()); + try { + return ExpressionUtils.analytical(dictMapping.getExpression(), var, dictMapping.getExpressionLanguage()); + } catch (Exception e) { + throw new RuntimeException("analytical " + dictMapping.getExpressionLanguage() + " expression :" + dictMapping.getExpression() + " error", e); + } + }; + return toString(textGetter); + } + + public String toTextString() { + return toString(DictMapping::getValue); + } + + public String toValueString() { + return toString(mapping -> String.valueOf(mapping.getValue())); + } + + public DictMapping clone() { + DictMapping clone = new DictMapping(); + clone.value = value; + clone.key = key; + clone.expression = expression; + clone.expressionLanguage = expressionLanguage; + if (children != null) { + clone.children = children.stream().map(DictMapping::clone).collect(Collectors.toList()); + } + return clone; + } + + public void filterChildren(Predicate mappingPredicate) { + if (children != null) { + children = children.stream() + .filter(mappingPredicate) + .collect(Collectors.toList()); + children.forEach(children -> children.filterChildren(mappingPredicate)); + } + } + } +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SingleDictParser.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SingleDictParser.java new file mode 100644 index 000000000..cc248c38b --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/main/java/org/hswebframework/web/service/dictionary/simple/parser/SingleDictParser.java @@ -0,0 +1,17 @@ +package org.hswebframework.web.service.dictionary.simple.parser; + +import java.io.Serializable; +import java.util.Optional; + +/** + * TODO 完成注释 + * + * @author zhouhao + */ +public interface SingleDictParser extends Serializable { + Optional parse(String target, Object context); + + default Optional parse(String target) { + return parse(target, null); + } +} diff --git a/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/test/java/org/hswebframework/web/starter/dictionary/DictionaryParserTests.java b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/test/java/org/hswebframework/web/starter/dictionary/DictionaryParserTests.java new file mode 100644 index 000000000..a38bef35e --- /dev/null +++ b/hsweb-system/hsweb-system-dictionary/hsweb-system-dictionary-service/hsweb-system-dictionary-service-simple/src/test/java/org/hswebframework/web/starter/dictionary/DictionaryParserTests.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016 http://www.hswebframework.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ + +package org.hswebframework.web.starter.dictionary; + +import com.alibaba.fastjson.JSON; +import org.hswebframework.web.entity.dictionary.SimpleDictionaryEntity; +import org.hswebframework.web.entity.dictionary.SimpleDictionaryItemEntity; +import org.hswebframework.web.service.dictionary.DictionaryParser; +import org.hswebframework.web.service.dictionary.simple.SimpleDictionaryParser; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author + */ +public class DictionaryParserTests { + + DictionaryParser parser; + + @Before + public void init() { + SimpleDictionaryParser parser = new SimpleDictionaryParser<>(); + +// parser.getToTextParser().getTargetFormat().setSplitter("、"); +// parser.getToValueParser().getSourceFormat().setSplitter("、"); + + SimpleDictionaryEntity dictionaryEntity = new SimpleDictionaryEntity(); + String json = "[" + + "{'value':'1','text':'水果','children':" + + "[" + + "{'value':'101','text':'苹果'," + + "'children':[" + + "{'value':'10102','text':'红富士'}" + + ",{'value':'10103','text':'青苹果'}" + + //使用表达式进行解析 + ",{'value':'10105','text':'其他苹果'" + + ",'textExpression':'${#value}[${#context[otherApple]}]'" + + ",'valueExpression':'${(#context.put(\\'otherApple\\',#pattern.split(\"[ \\\\[ \\\\]]\")[1])==null)?#value:#value}'" + + "}" + + "]}" + + ",{'value':'102','text':'梨子'}]" + + "}" + + ",{'value':'2','text':'蔬菜'}" + + "]"; + + List itemEntities = JSON.parseArray(json, SimpleDictionaryItemEntity.class); + dictionaryEntity.setItems(itemEntities); + parser.setDict(dictionaryEntity); + this.parser = parser; + } + + //支持表达式 + @Test + public void testParseExpression() { + + String val = "1,2,101,10102,10105"; + + Map data = new HashMap<>(); + data.put("otherApple", "其他苹果1号"); + + String text = parser + .valueToText(val, data) + .get(); + + System.out.println(text); + data.clear(); + String parseVal = parser.textToValue(text, data) + .get(); + System.out.println(parseVal); + System.out.println(data); + + } + + //普通的解析 + @Test + public void testParseText() throws Exception { + String val = "1,101,10102,10103,2"; + + String text = parser.valueToText(val).get(); + + System.out.println(text); + String parsedVal = parser.textToValue(text).get(); + + System.out.println(parsedVal); + Assert.assertEquals(val, parsedVal); + + } +}