Browse Source

Pull request #7725: REPORT-66222【公式报错优化】模板名称中存在英文(),日志中的超链显示有问题

Merge in DESIGN/design from ~VITO/c-design:feature/x to feature/x

* commit '9908c5f109a330d22b4d2f20e4940a80b9251bfd':
  REPORT-66222【公式报错优化】模板名称中存在英文(),日志中的超链显示有问题
feature/x
vito 3 years ago
parent
commit
a44730ca73
  1. 125
      designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java
  2. 50
      designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java

125
designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java

@ -1,5 +1,6 @@
package com.fr.design.mainframe.loghandler; package com.fr.design.mainframe.loghandler;
import com.finebi.cbb.base.tuple.Pair;
import com.fr.base.BaseUtils; import com.fr.base.BaseUtils;
import com.fr.base.TRL; import com.fr.base.TRL;
import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListCache;
@ -17,6 +18,8 @@ import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants; import com.fr.stable.project.ProjectConstants;
import com.fr.third.apache.logging.log4j.Level; import com.fr.third.apache.logging.log4j.Level;
import com.fr.third.apache.logging.log4j.core.LogEvent; 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 org.jetbrains.annotations.Nullable;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
@ -51,10 +54,11 @@ import java.awt.event.MouseEvent;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Deque;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
@ -362,10 +366,7 @@ public class DesignerLogHandler {
SimpleAttributeSet attrSet = new SimpleAttributeSet(); SimpleAttributeSet attrSet = new SimpleAttributeSet();
if (style == DesignerLogger.ERROR_INT) { if (style == DesignerLogger.ERROR_INT) {
String[] tplLink = tryFindTplLink(str); if (renderLink(str)) {
if (tplLink != null
&& tplLink.length > 0
&& dealWithTplLink(str, tplLink)) {
return; return;
} }
StyleConstants.setForeground(attrSet, Color.RED); 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 模板链接 * @param tplLink 模板链接
* @return 是否处理成功 * @return 是否处理成功
*/ */
private boolean dealWithTplLink(String s, String[] tplLink) { private boolean link2Html(String s, String[] tplLink) {
String afterBr = s.replaceAll("\\n", "<br/>"); List<String> lineSeg = splitLineSeg(s, tplLink);
String[] lineSeg = pattern.split(afterBr); 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<String> lineSeg, String[] tplLink) {
StringBuilder sb = new StringBuilder("<span style=\"font-weight: bold;font-size:" + jTextArea.getFont().getSize() + "\">"); StringBuilder sb = new StringBuilder("<span style=\"font-weight: bold;font-size:" + jTextArea.getFont().getSize() + "\">");
for (int i = 0; i < tplLink.length; i++) { for (int i = 0; i < tplLink.length; i++) {
sb.append("<span style=\"color:red;\">") sb.append("<span style=\"color:red;\">")
.append(lineSeg[i]) .append(lineSeg.get(i))
.append("</span><a href=\"tpl://") .append("</span><a href=\"tpl://")
.append(tplLink[i], 1, tplLink[i].length() - 1) .append(tplLink[i], 1, tplLink[i].length() - 1)
.append("\">") .append("\">")
.append(tplLink[i]) .append(tplLink[i])
.append("</a>"); .append("</a>");
} }
if (lineSeg.length > tplLink.length) { if (lineSeg.size() > tplLink.length) {
sb.append("<span style=\"color:red;\">").append(lineSeg[lineSeg.length-1]).append("</span>"); sb.append("<span style=\"color:red;\">").append(lineSeg.get(lineSeg.size() - 1)).append("</span>");
} }
sb.append("</span>"); sb.append("</span>");
return sb.toString();
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;
} }
/** /**
* 尝试找到模板链接 * 将非公式部分切割为数组
*
* @param s 可能含有模板链接的字符串
* @return 模板链接
*/ */
@Nullable @NotNull
private String[] tryFindTplLink(String s) { private List<String> splitLineSeg(String s, String[] tplLink) {
Document doc = jTextArea.getStyledDocument(); String seg = s.replaceAll("\\n", "<br/>");
if (!(doc instanceof HTMLDocument)) { List<String> lineSeg = new ArrayList<>(2);
return null; List<String> 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<String> list = new ArrayList<>();
while (matcher.find()) {
list.add(matcher.group(0));
} }
return list.toArray(new String[0]); if (lineSegTmp.size() > 1) {
lineSeg.add(lineSegTmp.get(1));
}
return lineSeg;
} }
private String appendLocaleMark(String str, int style) { private String appendLocaleMark(String str, int style) {
if (style == DesignerLogger.ERROR_INT) { if (style == DesignerLogger.ERROR_INT) {
@ -505,4 +530,34 @@ public class DesignerLogHandler {
}; };
} }
/**
* 尝试找到模板链接
*
* @param s 可能含有模板链接的字符串
* @return 模板链接
*/
@Nullable
public static String[] findTplLink(String s) {
List<String> list = new ArrayList<>();
// 栈配对
Deque<Pair<Character, Integer>> 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<Character, Integer> left = stack.peek();
if (left != null && left.getFirst() == '(') {
Pair<Character, Integer> 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]);
}
} }

50
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)的飞机啊")
);
}
}
Loading…
Cancel
Save