Browse Source

REPORT-54887 公式编辑器优化一期

1.提供一个公式检验的接口,返回提示信息。
bugfix/11.0
Hoky 3 years ago
parent
commit
8c200726ca
  1. 88
      designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java
  2. 74
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

88
designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java

@ -0,0 +1,88 @@
package com.fr.design.formula;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.parser.FRLexer;
import com.fr.parser.FRParser;
import com.fr.script.checker.FunctionCheckerDispatcher;
import com.fr.script.checker.exception.ConditionCheckWrongException;
import com.fr.script.checker.exception.FunctionCheckWrongException;
import com.fr.script.rules.FunctionParameterType;
import com.fr.script.rules.FunctionRule;
import com.fr.stable.StringUtils;
import com.fr.stable.script.Expression;
import com.fr.stable.script.Node;
import java.io.StringReader;
import java.util.List;
/**
* @author Hoky
* @date 2021/9/28
*/
public class FormulaChecker {
private static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula");
private static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula");
public static final String COLON = ":";
public static String check(String formulaText) {
StringReader in = new StringReader(formulaText);
FRLexer lexer = new FRLexer(in);
FRParser parser = new FRParser(lexer);
try {
Expression expression = parser.parse();
Node node = expression.getConditionalExpression();
return FunctionCheckerDispatcher.getInstance()
.getFunctionChecker(node)
.checkFunction(node) ? VALID_FORMULA : INVALID_FORMULA;
} catch (ConditionCheckWrongException cce) {
String functionName = cce.getFunctionName();
return functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Condition_Tips") + COLON;
} catch (FunctionCheckWrongException ce) {
List<FunctionRule> rules = ce.getRules();
String functionName = ce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + COLON);
for (int i = 0; i < rules.size(); i++) {
errorMsg.append("(");
if (rules.get(i).getParameterList().isEmpty()) {
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param"));
}
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) {
errorMsg.append(getTypeString(functionParameterType)).append(",");
}
if (",".equals(errorMsg.charAt(errorMsg.length() - 1) + "")) {
errorMsg.deleteCharAt(errorMsg.length() - 1);
}
errorMsg.append(")");
if (i != rules.size() - 1) {
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or"));
}
}
return errorMsg.toString();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return INVALID_FORMULA;
// alex:继续往下面走,expression为null时告知不合法公式
}
}
private static String getTypeString(FunctionParameterType type) {
switch (type) {
case NUMBER:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number");
case STRING:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String");
case ANY:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any");
case DATE:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date");
case BOOLEAN:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean");
case ARRAY:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array");
}
return StringUtils.EMPTY;
}
}

74
designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

@ -38,18 +38,11 @@ import com.fr.log.FineLoggerFactory;
import com.fr.parser.ArrayExpression; import com.fr.parser.ArrayExpression;
import com.fr.parser.BlockIntervalLiteral; import com.fr.parser.BlockIntervalLiteral;
import com.fr.parser.ColumnRowRangeInPage; import com.fr.parser.ColumnRowRangeInPage;
import com.fr.parser.FRLexer;
import com.fr.parser.FRParser;
import com.fr.parser.NumberLiteral; import com.fr.parser.NumberLiteral;
import com.fr.parser.SheetIntervalLiteral; import com.fr.parser.SheetIntervalLiteral;
import com.fr.report.core.namespace.SimpleCellValueNameSpace; import com.fr.report.core.namespace.SimpleCellValueNameSpace;
import com.fr.script.Calculator; import com.fr.script.Calculator;
import com.fr.script.ScriptConstants; import com.fr.script.ScriptConstants;
import com.fr.script.checker.FunctionCheckerDispatcher;
import com.fr.script.checker.exception.ConditionCheckWrongException;
import com.fr.script.checker.exception.FunctionCheckWrongException;
import com.fr.script.rules.FunctionParameterType;
import com.fr.script.rules.FunctionRule;
import com.fr.stable.EncodeConstants; import com.fr.stable.EncodeConstants;
import com.fr.stable.EssentialUtils; import com.fr.stable.EssentialUtils;
import com.fr.stable.ParameterProvider; import com.fr.stable.ParameterProvider;
@ -657,7 +650,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
// Execute Formula default cell element. // Execute Formula default cell element.
String formulaText = formulaTextArea.getText().trim(); String formulaText = formulaTextArea.getText().trim();
String formulaValidMessage = getFormulaValidMessage(formulaText); String formulaValidMessage = FormulaChecker.check(formulaText);
FineJOptionPane.showMessageDialog( FineJOptionPane.showMessageDialog(
FormulaPane.this, FormulaPane.this,
formulaValidMessage + ".", formulaValidMessage + ".",
@ -666,73 +659,12 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
} }
}; };
private static String getFormulaValidMessage(String formulaText) {
StringReader in = new StringReader(formulaText);
FRLexer lexer = new FRLexer(in);
FRParser parser = new FRParser(lexer);
try {
Expression expression = parser.parse();
Node node = expression.getConditionalExpression();
return FunctionCheckerDispatcher.getInstance()
.getFunctionChecker(node)
.checkFunction(node) ? VALID_FORMULA : INVALID_FORMULA;
} catch (ConditionCheckWrongException cce) {
String functionName = cce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Condition_Tips") + ":");
return errorMsg.toString();
} catch (FunctionCheckWrongException ce) {
List<FunctionRule> rules = ce.getRules();
String functionName = ce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + ":");
for (int i = 0; i < rules.size(); i++) {
errorMsg.append("(");
if (rules.get(i).getParameterList().isEmpty()) {
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param"));
}
for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) {
errorMsg.append(getTypeString(functionParameterType)).append(",");
}
if (",".equals(errorMsg.charAt(errorMsg.length() - 1) + "")) {
errorMsg.deleteCharAt(errorMsg.length() - 1);
}
errorMsg.append(")");
if (i != rules.size() - 1) {
errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or"));
}
}
return errorMsg.toString();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return INVALID_FORMULA;
// alex:继续往下面走,expression为null时告知不合法公式
}
}
private static String getTypeString(FunctionParameterType type) {
switch (type) {
case NUMBER:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number");
case STRING:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String");
case ANY:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any");
case DATE:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date");
case BOOLEAN:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean");
case ARRAY:
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array");
}
return "";
}
private final ActionListener calculateActionListener = new ActionListener() { private final ActionListener calculateActionListener = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String formulaText = formulaTextArea.getText().trim(); String formulaText = formulaTextArea.getText().trim();
String formulaValidMessage = getFormulaValidMessage(formulaText); String formulaValidMessage = FormulaChecker.check(formulaText);
;
String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText); String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText);
if (unSupportFormula != null) { if (unSupportFormula != null) {
FineJOptionPane.showMessageDialog( FineJOptionPane.showMessageDialog(

Loading…
Cancel
Save