Browse Source

REPORT-58124 公式编辑器优化:不支持实时计算的功能提示处理

1.修改遍历不支持公式的逻辑
persist/11.0
Hoky 3 years ago
parent
commit
76e92ae71b
  1. 136
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  2. 49
      designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java

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

@ -5,6 +5,7 @@ import com.fr.base.BaseUtils;
import com.fr.base.Parameter; import com.fr.base.Parameter;
import com.fr.base.ParameterMapNameSpace; import com.fr.base.ParameterMapNameSpace;
import com.fr.base.TableDataNameSpace; import com.fr.base.TableDataNameSpace;
import com.fr.base.io.IOFile;
import com.fr.data.TableDataSource; import com.fr.data.TableDataSource;
import com.fr.design.actions.UpdateAction; import com.fr.design.actions.UpdateAction;
import com.fr.design.border.UIRoundedBorder; import com.fr.design.border.UIRoundedBorder;
@ -27,22 +28,28 @@ import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.parameter.ParameterInputPane; import com.fr.design.parameter.ParameterInputPane;
import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils; import com.fr.general.FArray;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.main.impl.WorkBook; import com.fr.parser.ArrayExpression;
import com.fr.parser.BlockIntervalLiteral;
import com.fr.parser.ColumnRowRangeInPage;
import com.fr.parser.FRLexer; import com.fr.parser.FRLexer;
import com.fr.parser.FRParser; import com.fr.parser.FRParser;
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.FunctionCheckerDispatcher;
import com.fr.script.checker.exception.ConditionCheckWrongException;
import com.fr.script.checker.exception.FunctionCheckWrongException; import com.fr.script.checker.exception.FunctionCheckWrongException;
import com.fr.script.rules.FunctionParameterType; import com.fr.script.rules.FunctionParameterType;
import com.fr.script.rules.FunctionRule; 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.ParameterProvider; import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.UtilEvalError; import com.fr.stable.UtilEvalError;
@ -110,6 +117,8 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula"); public static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula");
public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"); public static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula");
public static final int DEFUAL_FOMULA_LENGTH = 103;
public static final String ELLIPSIS = "...";
private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea; private VariableTreeAndDescriptionArea variableTreeAndDescriptionArea;
private RSyntaxTextArea formulaTextArea; private RSyntaxTextArea formulaTextArea;
private UITextField keyWordTextField = new UITextField(18); private UITextField keyWordTextField = new UITextField(18);
@ -664,12 +673,19 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
return FunctionCheckerDispatcher.getInstance() return FunctionCheckerDispatcher.getInstance()
.getFunctionChecker(node) .getFunctionChecker(node)
.checkFunction(node) ? VALID_FORMULA : INVALID_FORMULA; .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) { } catch (FunctionCheckWrongException ce) {
List<FunctionRule> rules = ce.getRules(); List<FunctionRule> rules = ce.getRules();
String functionName = ce.getFunctionName(); String functionName = ce.getFunctionName();
StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + ":"); 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++) { for (int i = 0; i < rules.size(); i++) {
errorMsg.append("("); 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()) { for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) {
errorMsg.append(getTypeString(functionParameterType)).append(","); errorMsg.append(getTypeString(functionParameterType)).append(",");
} }
@ -711,38 +727,77 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String formulaText = formulaTextArea.getText().trim(); String formulaText = formulaTextArea.getText().trim();
String messageTips = getFormulaValidMessage(formulaText).equals(VALID_FORMULA) ? " " : getFormulaValidMessage(formulaText) + "\n"; String formulaValidMessage = getFormulaValidMessage(formulaText);
Map<String, Object> paramsMap = setParamsIfExist(formulaText); String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText);
Calculator calculator = Calculator.createCalculator(); if (unSupportFormula != null) {
ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap); FineJOptionPane.showMessageDialog(
calculator.pushNameSpace(parameterMapNameSpace); FormulaPane.this,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula,
WorkBook workBook = (WorkBook) HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTarget(); com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
calculator.pushNameSpace(SimpleCellValueNameSpace.getInstance()); JOptionPane.INFORMATION_MESSAGE);
TableDataSource tableDataSource = workBook.getReport(0).getTableDataSource(); return;
calculator.setAttribute(TableDataSource.KEY, tableDataSource); }
calculator.pushNameSpace(TableDataNameSpace.getInstance()); String messageTips;
BaseFormula baseFormula = BaseFormula.createFormulaBuilder().build(formulaText); if (formulaValidMessage.equals(INVALID_FORMULA)) {
try { messageTips = INVALID_FORMULA;
Object value = calculator.evalValue(baseFormula); } else {
messageTips = messageTips + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + GeneralUtils.objectToString(value); messageTips = formulaValidMessage.equals(VALID_FORMULA) ? "" : formulaValidMessage + "\n";
FineLoggerFactory.getLogger().info("value:{}", value); Map<String, Object> paramsMap = setParamsIfExist(formulaText);
} catch (UtilEvalError utilEvalError) { Calculator calculator = Calculator.createCalculator();
FineLoggerFactory.getLogger().error("", utilEvalError); ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap);
calculator.pushNameSpace(parameterMapNameSpace);
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (currentEditingTemplate != null) {
IOFile file = (IOFile) currentEditingTemplate.getTarget();
calculator.setAttribute(TableDataSource.KEY, file);
calculator.pushNameSpace(TableDataNameSpace.getInstance());
calculator.pushNameSpace(SimpleCellValueNameSpace.getInstance());
}
BaseFormula baseFormula = BaseFormula.createFormulaBuilder().build(formulaText);
try {
Object value = calculator.evalValue(baseFormula);
String objectToString = EssentialUtils.objectToString(value);
String result = objectToString.length() > DEFUAL_FOMULA_LENGTH ?
objectToString.substring(0, DEFUAL_FOMULA_LENGTH - ELLIPSIS.length()) + ELLIPSIS : objectToString;
messageTips = messageTips +
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + result;
FineLoggerFactory.getLogger().info("value:{}", value);
} catch (UtilEvalError utilEvalError) {
FineLoggerFactory.getLogger().error("", utilEvalError);
}
} }
FineJOptionPane.showMessageDialog( FineJOptionPane.showMessageDialog(
FormulaPane.this, FormulaPane.this,
messageTips, messageTips,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.INFORMATION_MESSAGE); JOptionPane.INFORMATION_MESSAGE);
} }
}; };
private String containsUnsupportedSimulationFormulas(String formulaText) {
try {
Expression expression = Calculator.createCalculator().parse(formulaText);
UnsupportedFormulaScanner scanner = new UnsupportedFormulaScanner();
if (!scanner.travelFormula(expression.getConditionalExpression())) {
return scanner.getUnSupportFormula();
}
UnsupportedSimulationFormulaHunter unsupportedSimulationFormulaHunter = new UnsupportedSimulationFormulaHunter();
expression.traversal4Tiny(unsupportedSimulationFormulaHunter);
return unsupportedSimulationFormulaHunter.isSupported() ? null : unsupportedSimulationFormulaHunter.getUnSupportFormula();
} catch (Exception e) {
FineLoggerFactory.getLogger().error("", e);
}
return null;
}
private Map<String, Object> setParamsIfExist(String formulaText) { private Map<String, Object> setParamsIfExist(String formulaText) {
Map<String, Object> parameterMap = new HashMap<>(); Map<String, Object> parameterMap = new HashMap<>();
try { try {
Expression expression = Calculator.createCalculator().parse(formulaText); Calculator calculator = Calculator.createCalculator();
Expression expression = calculator.parse(formulaText);
ParameterCellHunter parameterCellHunter = new ParameterCellHunter(); ParameterCellHunter parameterCellHunter = new ParameterCellHunter();
expression.traversal4Tiny(parameterCellHunter); expression.traversal4Tiny(parameterCellHunter);
Parameter[] parameters = parameterCellHunter.getParameterBooty(); Parameter[] parameters = parameterCellHunter.getParameterBooty();
@ -757,10 +812,18 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
parameterMap.putAll(pPane.update()); parameterMap.putAll(pPane.update());
} }
}).setVisible(true); }).setVisible(true);
//过滤出数组参数,如:[1,2]
for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
if (entry.getValue().toString().startsWith("[") && entry.getValue().toString().endsWith("]")) {
Expression parse = calculator.parse(entry.getValue());
ArrayExpression arrayExpression = (ArrayExpression) parse.getConditionalExpression();
FArray<Node> fArray = new FArray<>(arrayExpression.getArrays());
parameterMap.put(entry.getKey(), fArray);
}
}
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().error("", e); FineLoggerFactory.getLogger().error("", e);
} }
return parameterMap; return parameterMap;
} }
@ -769,7 +832,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private final Set<Parameter> parameterList = new HashSet<>(); private final Set<Parameter> parameterList = new HashSet<>();
Parameter[] getParameterBooty() { Parameter[] getParameterBooty() {
return parameterList.toArray(new Parameter[0]); return parameterList.toArray(new Parameter[0]);
} }
@ -777,12 +839,36 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
String statement = tiny.getStatement(); String statement = tiny.getStatement();
if (StringUtils.isNotBlank(statement) && statement.startsWith(ScriptConstants.DETAIL_TAG)) { if (StringUtils.isNotBlank(statement) && statement.startsWith(ScriptConstants.DETAIL_TAG)) {
parameterList.add(new Parameter(statement.substring(1))); parameterList.add(new Parameter(statement.substring(1)));
} else if (tiny.getClass().equals(ColumnRowRange.class)) { } else if (tiny.getClass() == ColumnRowRange.class ||
tiny.getClass() == SheetIntervalLiteral.class || tiny.getClass() == BlockIntervalLiteral.class) {
parameterList.add(new Parameter(tiny.toString())); parameterList.add(new Parameter(tiny.toString()));
} }
} }
} }
private static class UnsupportedSimulationFormulaHunter extends TinyHunter {
private boolean supported = true;
private String unSupportFormula;
public boolean isSupported() {
return supported;
}
public String getUnSupportFormula() {
return unSupportFormula;
}
public void hunter4Tiny(Tiny tiny) {
if (tiny.getClass() == ColumnRowRangeInPage.class) {
supported = false;
unSupportFormula = tiny.toString();
}
}
}
public class VariableTreeAndDescriptionArea extends JPanel { public class VariableTreeAndDescriptionArea extends JPanel {
private JTree variablesTree; private JTree variablesTree;

49
designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java

@ -0,0 +1,49 @@
package com.fr.design.formula;
import com.fr.parser.BinaryExpression;
import com.fr.parser.FunctionCall;
import com.fr.stable.script.Node;
import java.util.Arrays;
/**
* @author Hoky
* @date 2021/8/30
*/
public class UnsupportedFormulaScanner {
public final static String[] UNSUPPORTED_FORMULAS = new String[]{"PROPORTION", "TOIMAGE",
"WEBIMAGE", "SORT", "CROSSLAYERTOTAL", "CIRCULAR", "LAYERTOTAL", "MOM", "HIERARCHY",
"FILENAME", "FILESIZE", "FILETYPE", "TREELAYER", "GETUSERDEPARTMENTS", "GETUSERJOBTITLES"};
private String unSupportFormula = "";
public boolean travelFormula(Node node) {
if (node instanceof FunctionCall) {
if (isUnsupportedFomula(((FunctionCall) node).getName())) {
unSupportFormula = ((FunctionCall) node).getName();
return false;
} else {
for (Node argument : ((FunctionCall) node).getArguments()) {
if (!travelFormula(argument)) {
return false;
}
}
}
} else if (node instanceof BinaryExpression) {
for (Node array : ((BinaryExpression) node).getNodes()) {
if (!travelFormula(array)) {
return false;
}
}
}
return true;
}
public String getUnSupportFormula() {
return unSupportFormula;
}
private static boolean isUnsupportedFomula(String formula) {
return Arrays.asList(UNSUPPORTED_FORMULAS).contains(formula.toUpperCase());
}
}
Loading…
Cancel
Save