diff --git a/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java b/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java
index f7ffe1aae..88e064fe0 100644
--- a/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java
+++ b/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java
@@ -1,5 +1,6 @@
package com.fr.design.mainframe.loghandler;
+import com.finebi.cbb.base.tuple.Pair;
import com.fr.base.BaseUtils;
import com.fr.base.TRL;
import com.fr.design.file.HistoryTemplateListCache;
@@ -17,6 +18,8 @@ import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.apache.logging.log4j.Level;
import com.fr.third.apache.logging.log4j.core.LogEvent;
+import com.fr.third.guava.base.Splitter;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.AbstractAction;
@@ -51,10 +54,11 @@ import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Deque;
import java.util.List;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
@@ -362,10 +366,7 @@ public class DesignerLogHandler {
SimpleAttributeSet attrSet = new SimpleAttributeSet();
if (style == DesignerLogger.ERROR_INT) {
- String[] tplLink = tryFindTplLink(str);
- if (tplLink != null
- && tplLink.length > 0
- && dealWithTplLink(str, tplLink)) {
+ if (renderLink(str)) {
return;
}
StyleConstants.setForeground(attrSet, Color.RED);
@@ -388,6 +389,23 @@ public class DesignerLogHandler {
}
}
+ /**
+ * 渲染模板链接
+ *
+ * @param str 可能包含模板链接字符串
+ * @return 是否处理成功
+ */
+ private boolean renderLink(String str) {
+ Document doc = jTextArea.getStyledDocument();
+ if (doc instanceof HTMLDocument) {
+ String[] tplLink = findTplLink(str);
+ return tplLink != null
+ && tplLink.length > 0
+ && link2Html(str, tplLink);
+ }
+ return false;
+ }
+
/**
* 处理模板链接
*
@@ -395,55 +413,62 @@ public class DesignerLogHandler {
* @param tplLink 模板链接
* @return 是否处理成功
*/
- private boolean dealWithTplLink(String s, String[] tplLink) {
- String afterBr = s.replaceAll("\\n", "
");
- String[] lineSeg = pattern.split(afterBr);
+ private boolean link2Html(String s, String[] tplLink) {
+ List lineSeg = splitLineSeg(s, tplLink);
+ String html = buildHtml(lineSeg, tplLink);
+ try {
+ Document doc = jTextArea.getStyledDocument();
+ HTMLDocument htmlDocument = (HTMLDocument) doc;
+ htmlDocument.insertAfterEnd(htmlDocument.getCharacterElement(doc.getLength()), html);
+ } catch (BadLocationException | IOException ignored) {
+ // 这里出问题不记录日志否则会导致死循环
+ return false;
+ }
+ return true;
+ }
+
+ @NotNull
+ private String buildHtml(List lineSeg, String[] tplLink) {
StringBuilder sb = new StringBuilder("");
- for(int i=0;i< tplLink.length;i++){
+ for (int i = 0; i < tplLink.length; i++) {
sb.append("")
- .append(lineSeg[i])
+ .append(lineSeg.get(i))
.append("")
.append(tplLink[i])
.append("");
}
- if (lineSeg.length > tplLink.length) {
- sb.append("").append(lineSeg[lineSeg.length-1]).append("");
+ if (lineSeg.size() > tplLink.length) {
+ sb.append("").append(lineSeg.get(lineSeg.size() - 1)).append("");
}
sb.append("");
-
- try {
- Document doc = jTextArea.getStyledDocument();
- HTMLDocument htmlDocument = (HTMLDocument) doc;
- htmlDocument.insertAfterEnd(htmlDocument.getCharacterElement(doc.getLength()), sb.toString());
- } catch (BadLocationException | IOException ignored) {
- // 这里出问题不记录日志否则会导致死循环
- return false;
- }
- return true;
+ return sb.toString();
}
/**
- * 尝试找到模板链接
- *
- * @param s 可能含有模板链接的字符串
- * @return 模板链接
+ * 将非公式部分切割为数组
*/
- @Nullable
- private String[] tryFindTplLink(String s) {
- Document doc = jTextArea.getStyledDocument();
- if (!(doc instanceof HTMLDocument)) {
- return null;
+ @NotNull
+ private List splitLineSeg(String s, String[] tplLink) {
+ String seg = s.replaceAll("\\n", "
");
+ List lineSeg = new ArrayList<>(2);
+ List lineSegTmp = new ArrayList<>();
+ String tmp = seg;
+ for (String link : tplLink) {
+ lineSegTmp = Splitter.on(link).omitEmptyStrings().splitToList(tmp);
+ lineSeg.add(lineSegTmp.get(0));
+ if (lineSegTmp.size() > 1) {
+ tmp = lineSegTmp.get(1);
+ }
}
- Matcher matcher = pattern.matcher(s);
- List list = new ArrayList<>();
- while (matcher.find()) {
- list.add(matcher.group(0));
+ if (lineSegTmp.size() > 1) {
+ lineSeg.add(lineSegTmp.get(1));
}
- return list.toArray(new String[0]);
+ return lineSeg;
}
+
private String appendLocaleMark(String str, int style) {
if (style == DesignerLogger.ERROR_INT) {
@@ -505,4 +530,34 @@ public class DesignerLogHandler {
};
}
+
+ /**
+ * 尝试找到模板链接
+ *
+ * @param s 可能含有模板链接的字符串
+ * @return 模板链接
+ */
+ @Nullable
+ public static String[] findTplLink(String s) {
+ List list = new ArrayList<>();
+ // 栈配对
+ Deque> stack = new ArrayDeque<>();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '(') {
+ stack.push(new Pair<>(c, i));
+ } else if (c == ')') {
+ Pair left = stack.peek();
+ if (left != null && left.getFirst() == '(') {
+ Pair pop = stack.pop();
+ String link = s.substring(pop.getSecond(), i + 1);
+ if (link.contains(ProjectConstants.CPT_SUFFIX)
+ || link.contains(ProjectConstants.FRM_SUFFIX)) {
+ list.add(link);
+ }
+ }
+ }
+ }
+ return list.toArray(new String[0]);
+ }
}
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java b/designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java
new file mode 100644
index 000000000..c7dd1de70
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java
@@ -0,0 +1,50 @@
+package com.fr.design.mainframe.loghandler;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author vito
+ * @version 10.0
+ * Created by vito on 2022/1/25
+ */
+public class DesignerLogHandlerTest {
+
+ @Test
+ public void findTplLink() {
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)", "(公式定位测试/单sheet2(2).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1),出错公式(公式定位测试/单sheet2(2).cpt:0:A1),的飞机啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).frm:0:A1)", "(公式定位测试/单sheet2(2).frm:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).frm:0:A1),出错公式(公式定位测试/单sheet2(2).frm:0:A1),的飞机啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式(计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式)计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机)啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机(啊")
+ );
+ Assert.assertArrayEquals(
+ new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"},
+ DesignerLogHandler.findTplLink("错误代码:11300310 公式(0fdasf)计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊")
+ );
+ }
+}
\ No newline at end of file