From 76e92ae71bd15bbc946242034ec3c2a263cf2445 Mon Sep 17 00:00:00 2001 From: Hoky <303455184@qq.com> Date: Mon, 30 Aug 2021 16:30:32 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-58124=20=E5=85=AC=E5=BC=8F=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E4=BC=98=E5=8C=96=EF=BC=9A=E4=B8=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=AE=9E=E6=97=B6=E8=AE=A1=E7=AE=97=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=8F=90=E7=A4=BA=E5=A4=84=E7=90=86=201.=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=81=8D=E5=8E=86=E4=B8=8D=E6=94=AF=E6=8C=81=E5=85=AC?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/formula/FormulaPane.java | 136 ++++++++++++++---- .../formula/UnsupportedFormulaScanner.java | 49 +++++++ 2 files changed, 160 insertions(+), 25 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java index 7c4bde420..f836cd571 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java +++ b/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.ParameterMapNameSpace; import com.fr.base.TableDataNameSpace; +import com.fr.base.io.IOFile; import com.fr.data.TableDataSource; import com.fr.design.actions.UpdateAction; 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.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; import com.fr.design.parameter.ParameterInputPane; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; -import com.fr.general.GeneralUtils; +import com.fr.general.FArray; 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.FRParser; +import com.fr.parser.SheetIntervalLiteral; import com.fr.report.core.namespace.SimpleCellValueNameSpace; import com.fr.script.Calculator; 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.EssentialUtils; import com.fr.stable.ParameterProvider; import com.fr.stable.StringUtils; 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 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 RSyntaxTextArea formulaTextArea; private UITextField keyWordTextField = new UITextField(18); @@ -664,12 +673,19 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { 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 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(","); } @@ -711,38 +727,77 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { @Override public void actionPerformed(ActionEvent e) { String formulaText = formulaTextArea.getText().trim(); - String messageTips = getFormulaValidMessage(formulaText).equals(VALID_FORMULA) ? " " : getFormulaValidMessage(formulaText) + "\n"; - Map paramsMap = setParamsIfExist(formulaText); - Calculator calculator = Calculator.createCalculator(); - ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap); - calculator.pushNameSpace(parameterMapNameSpace); - - WorkBook workBook = (WorkBook) HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getTarget(); - calculator.pushNameSpace(SimpleCellValueNameSpace.getInstance()); - TableDataSource tableDataSource = workBook.getReport(0).getTableDataSource(); - calculator.setAttribute(TableDataSource.KEY, tableDataSource); - calculator.pushNameSpace(TableDataNameSpace.getInstance()); - BaseFormula baseFormula = BaseFormula.createFormulaBuilder().build(formulaText); - try { - Object value = calculator.evalValue(baseFormula); - messageTips = messageTips + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + GeneralUtils.objectToString(value); - FineLoggerFactory.getLogger().info("value:{}", value); - } catch (UtilEvalError utilEvalError) { - FineLoggerFactory.getLogger().error("", utilEvalError); + String formulaValidMessage = getFormulaValidMessage(formulaText); + String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText); + if (unSupportFormula != null) { + FineJOptionPane.showMessageDialog( + FormulaPane.this, + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.INFORMATION_MESSAGE); + return; + } + String messageTips; + if (formulaValidMessage.equals(INVALID_FORMULA)) { + messageTips = INVALID_FORMULA; + } else { + messageTips = formulaValidMessage.equals(VALID_FORMULA) ? "" : formulaValidMessage + "\n"; + Map paramsMap = setParamsIfExist(formulaText); + Calculator calculator = Calculator.createCalculator(); + 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( FormulaPane.this, messageTips, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), 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 setParamsIfExist(String formulaText) { Map parameterMap = new HashMap<>(); try { - Expression expression = Calculator.createCalculator().parse(formulaText); + Calculator calculator = Calculator.createCalculator(); + Expression expression = calculator.parse(formulaText); ParameterCellHunter parameterCellHunter = new ParameterCellHunter(); expression.traversal4Tiny(parameterCellHunter); Parameter[] parameters = parameterCellHunter.getParameterBooty(); @@ -757,10 +812,18 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { parameterMap.putAll(pPane.update()); } }).setVisible(true); + //过滤出数组参数,如:[1,2] + for (Map.Entry entry : parameterMap.entrySet()) { + if (entry.getValue().toString().startsWith("[") && entry.getValue().toString().endsWith("]")) { + Expression parse = calculator.parse(entry.getValue()); + ArrayExpression arrayExpression = (ArrayExpression) parse.getConditionalExpression(); + FArray fArray = new FArray<>(arrayExpression.getArrays()); + parameterMap.put(entry.getKey(), fArray); + } + } } catch (Exception e) { FineLoggerFactory.getLogger().error("", e); } - return parameterMap; } @@ -769,7 +832,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { private final Set parameterList = new HashSet<>(); Parameter[] getParameterBooty() { - return parameterList.toArray(new Parameter[0]); } @@ -777,12 +839,36 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { String statement = tiny.getStatement(); if (StringUtils.isNotBlank(statement) && statement.startsWith(ScriptConstants.DETAIL_TAG)) { 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())); } } } + 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 { private JTree variablesTree; diff --git a/designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java b/designer-base/src/main/java/com/fr/design/formula/UnsupportedFormulaScanner.java new file mode 100644 index 000000000..343086af5 --- /dev/null +++ b/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()); + } +}