Browse Source

REPORT-138249 cpt支持数据集替换

release/11.0
Destiny.Lin 3 weeks ago
parent
commit
1f20cb47bb
  1. 25
      designer-base/src/main/java/com/fr/design/data/datapane/AbstractTableDataTreeToolBarActionProvider.java
  2. 60
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java
  3. 25
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreeToolBarActionProvider.java
  4. 5
      designer-realize/src/main/java/com/fr/design/actions/replace/action/content/cell/SearchCellAction.java
  5. 14
      designer-realize/src/main/java/com/fr/design/actions/replace/action/content/formula/cell/SearchCellFormulaAction.java
  6. 223
      designer-realize/src/main/java/com/fr/design/actions/replace/action/content/tabledata/FormulaUtils.java
  7. 75
      designer-realize/src/main/java/com/fr/design/actions/replace/action/content/tabledata/TableDataFormulaType.java
  8. 20
      designer-realize/src/main/java/com/fr/design/actions/replace/action/content/widget/SearchWidgetAction.java
  9. 9
      designer-realize/src/main/java/com/fr/design/actions/replace/info/FormulaInfo.java
  10. 5
      designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceMainDialog.java
  11. 240
      designer-realize/src/main/java/com/fr/design/actions/replace/utils/ReplaceUtils.java
  12. 110
      designer-realize/src/test/java/com/fr/design/actions/replace/action/content/tabledata/FormulaUtilsTest.java

25
designer-base/src/main/java/com/fr/design/data/datapane/AbstractTableDataTreeToolBarActionProvider.java

@ -0,0 +1,25 @@
package com.fr.design.data.datapane;
import com.fr.stable.fun.mark.API;
/**
* 数据集Tree工具栏面板注入接口
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/11/1
*/
@API(level = TableDataTreeToolBarActionProvider.CURRENT_LEVEL)
public abstract class AbstractTableDataTreeToolBarActionProvider implements TableDataTreeToolBarActionProvider {
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
@Override
public String mark4Provider() {
return getClass().getName();
}
}

60
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java

@ -47,6 +47,7 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.menu.LineSeparator;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.esd.core.strategy.config.StrategyConfig;
@ -92,9 +93,11 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
public class TableDataTreePane extends BasicTableDataTreePane {
@ -145,6 +148,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
private EsdOffAction esdOffAction;
private SwitchAction switchAction;
private PreviewTableDataAction previewTableDataAction;
private Set<ExtraAction> extraActions = new HashSet<>();
private JPanel serverDatasetAuthTipJPanel = new JPanel();
private TableDataSearchRemindPane remindPane;
@ -246,6 +250,7 @@ public class TableDataTreePane extends BasicTableDataTreePane {
toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(addMenuDef, SeparatorDef.DEFAULT, editAction, removeAction, SeparatorDef.DEFAULT, previewTableDataAction, connectionTableAction, esdAction, esdOffAction, switchAction);
initExtraAction();
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolBar.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR));
toolBar.setBorderPainted(true);
@ -257,6 +262,18 @@ public class TableDataTreePane extends BasicTableDataTreePane {
return searchLayerdPane;
}
private void initExtraAction() {
Set<TableDataTreeToolBarActionProvider> toolBarActionProviders = ExtraDesignClassManager.getInstance().getArray(TableDataTreeToolBarActionProvider.XML_TAG);
for (TableDataTreeToolBarActionProvider handler : toolBarActionProviders) {
try {
extraActions.add(handler.createAction());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
toolbarDef.addShortCut(extraActions.toArray(new ShortCut[0]));
}
/**
* 数据集树面板
*
@ -706,6 +723,13 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
removeAction.setEnabled(true);
copyAction.setEnabled(true);
checkExtraActionEnable(op.getDataMode(), selectioncount, getDataTree().hasSelectedIndependentColumns());
}
private void checkExtraActionEnable(int dataMode, int selectioncount, boolean hasSelectedIndependentColumns) {
for (ExtraAction action : extraActions) {
action.setEnabled(action.checkEnable(dataMode, selectioncount, hasSelectedIndependentColumns));
}
}
@ -1215,6 +1239,42 @@ public class TableDataTreePane extends BasicTableDataTreePane {
}
}
public abstract class ExtraAction extends UpdateAction {
public ExtraAction() {
init();
}
/**
* 初始化逻辑
* <p>一般用于设置名称快捷键icon</p>
*/
protected abstract void init();
@Override
public void actionPerformed(ActionEvent e) {
doActionPerformed(e, tableDataTree.getSelectedTableDataNameObjects());
}
/**
* 点击事件
*
* @param e actionEvent
* @param selectedTableDataNameObjects 数据集tree选中的对象
*/
protected abstract void doActionPerformed(ActionEvent e, NameObject[] selectedTableDataNameObjects);
/**
* 是否可以启用
*
* @param dataMode 模板数据集还是服务器数据集
* @param selectioncount 选中的数据集个数
* @param hasSelectedIndependentColumns 是否存在单独选了数据列节点但没选其对应数据集的情况
* @return 返回启用与否
*/
protected abstract boolean checkEnable(int dataMode, int selectioncount, boolean hasSelectedIndependentColumns);
}
public String getNoRepeatedDsName4Paste(String oldName) {
while (isDsNameRepeaded(oldName)) {
oldName = oldName + Toolkit.i18nText("Fine-Design_Table_Data_Copy_Of_Table_Data");

25
designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreeToolBarActionProvider.java

@ -0,0 +1,25 @@
package com.fr.design.data.datapane;
import com.fr.stable.fun.mark.Mutable;
/**
* 数据集Tree工具栏面板注入接口
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/11/1
*/
public interface TableDataTreeToolBarActionProvider extends Mutable {
String XML_TAG = "TableDataTreeToolBarActionProvider";
int CURRENT_LEVEL = 1;
/**
* 创建Action对象,用于提供针对数据集的额外操作
*
* @return 创建出来的Action对象
*/
TableDataTreePane.ExtraAction createAction();
}

5
designer-realize/src/main/java/com/fr/design/actions/replace/action/content/cell/SearchCellAction.java

@ -152,7 +152,10 @@ public class SearchCellAction implements SearchAction {
}
private void getCellInfoFromElementCase(ElementCase elementCase, List<CellInfo> result, ITContent content) {
/**
* 从ElementCase获取单元格
*/
public void getCellInfoFromElementCase(ElementCase elementCase, List<CellInfo> result, ITContent content) {
Iterator cellIterator = elementCase.cellIterator();
while (cellIterator.hasNext()) {
ITContent newContent = ITContent.copy(content);

14
designer-realize/src/main/java/com/fr/design/actions/replace/action/content/formula/cell/SearchCellFormulaAction.java

@ -63,7 +63,17 @@ public class SearchCellFormulaAction implements SearchCellFormula {
SearchCellAction searchCellAction = SearchCellAction.getInstance();
searchCellAction.search4Infos(jTemplate);
if (searchCellAction.isCellInfosExist()) {
for (CellInfo cellInfo : searchCellAction.getCellInfos()) {
searchFormulaFromCellInfos(searchCellAction.getCellInfos(), formulaInfos);
}
}
/**
* 从单元格获取公式
*/
public void searchFormulaFromCellInfos(List<CellInfo> cellInfos, List<FormulaInfo> formulaInfos) {
for (CellInfo cellInfo : cellInfos) {
//根据单元格类型的不同来进行不同的操作
searchFormulaFromCellInfo(cellInfo, formulaInfos);
@ -87,8 +97,6 @@ public class SearchCellFormulaAction implements SearchCellFormula {
}
}
}
private void searchCellToolTip4Formula(CellInfo cellInfo, List<FormulaInfo> formulaInfos) {
if (cellInfo.getContent().getReplaceObject() instanceof TemplateCellElement) {
TemplateCellElement cellElement = (TemplateCellElement) cellInfo.getContent().getReplaceObject();

223
designer-realize/src/main/java/com/fr/design/actions/replace/action/content/tabledata/FormulaUtils.java

@ -0,0 +1,223 @@
package com.fr.design.actions.replace.action.content.tabledata;
import com.fr.data.TableReplacementEntity;
import com.fr.invoke.Reflect;
import com.fr.log.FineLoggerFactory;
import com.fr.parser.BinaryExpression;
import com.fr.parser.FunctionCall;
import com.fr.parser.StringLiteral;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import com.fr.stable.script.Expression;
import com.fr.stable.script.Node;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 公式工具
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/11/5
*/
public class FormulaUtils {
private static final String LEFT_BRACKET = "${";
private static final String RIGHT_BRACKET = "}";
private static final String FORMULA_MARK = "=";
private static final String STATEMENT = "statement";
/**
* 从公式中寻找数据集名称
*/
public static Set<String> search(String formula) {
Set<String> result = new HashSet<>();
for (TableDataFormulaType tableDataFormulaType : TableDataFormulaType.values()) {
result.addAll(FormulaUtils.fetchArgument(formula, tableDataFormulaType.name(), tableDataFormulaType.getArgumentIndex()));
}
return result;
}
/**
* 获取替换后的公式全文
*/
public static String replace(String formula, List<TableReplacementEntity> entities) {
try {
Expression expression = Calculator.createCalculator().parse(formula);
FormulaUtils.replace0(expression, entities);
String ans = expression.toString();
if (formula.startsWith(FORMULA_MARK) && !ans.startsWith(FORMULA_MARK)) {
return FORMULA_MARK + ans;
} else {
if (ans.startsWith(FORMULA_MARK)) {
return ans.substring(1);
}
}
return ans;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return formula;
}
}
private static void replace0(Expression expression, List<TableReplacementEntity> entities) {
if (expression != null) {
Node node = expression.getConditionalExpression();
if (node instanceof BinaryExpression) {
BinaryExpression binaryExpression = (BinaryExpression) node;
Node[] nodes = binaryExpression.getNodes();
if (nodes != null) {
for (Node subNode : nodes) {
if (subNode instanceof FunctionCall) {
FunctionCall functionCall = (FunctionCall) subNode;
FormulaUtils.replaceArgument(functionCall, entities);
}
}
}
} else if (node instanceof FunctionCall) {
FunctionCall functionCall = (FunctionCall) node;
FormulaUtils.replaceArgument(functionCall, entities);
}
}
}
/**
* 从公式可能存在嵌套中解析出某类型函数的第几个参数
*
* @param formula 公式
* @param functionName 函数名
* @param argumentIndex 参数位置
* @return 对应参数位置的值
*/
public static List<String> fetchArgument(String formula, String functionName, int argumentIndex) {
List<String> result = new ArrayList<>();
try {
Expression expression = Calculator.createCalculator().parse(formula);
if (expression != null) {
Node node = expression.getConditionalExpression();
if (node instanceof BinaryExpression) {
BinaryExpression binaryExpression = (BinaryExpression) node;
Node[] nodes = binaryExpression.getNodes();
if (nodes != null) {
for (Node subNode : nodes) {
if (subNode instanceof FunctionCall) {
FunctionCall functionCall = (FunctionCall) subNode;
result.addAll(FormulaUtils.fetchArgument(functionCall, functionName, argumentIndex));
}
}
}
} else if (node instanceof FunctionCall) {
FunctionCall functionCall = (FunctionCall) node;
result.addAll(FormulaUtils.fetchArgument(functionCall, functionName, argumentIndex));
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
return result;
}
private static void replaceArgument(FunctionCall functionCall, List<TableReplacementEntity> entities) {
Node[] subNodes = functionCall.getArguments();
if (subNodes != null) {
StringBuilder parent = new StringBuilder(StringUtils.EMPTY);
for (int i = 0; i < subNodes.length; i++) {
Node subNode = subNodes[i];
if (subNode instanceof FunctionCall) {
replaceArgument((FunctionCall) subNode, entities);
}
if (subNode instanceof StringLiteral) {
StringLiteral stringLiteral = (StringLiteral) subNode;
replaceArgument0(i, stringLiteral, functionCall, entities, parent);
}
}
}
}
private static void replaceArgument0(int i, StringLiteral stringLiteral, FunctionCall functionCall, List<TableReplacementEntity> entities, StringBuilder parent) {
try {
TableDataFormulaType type = TableDataFormulaType.get(functionCall.getName());
if (type != null) {
String name = stringLiteral.eval(Calculator.createCalculator()).toString();
for (TableReplacementEntity entity : entities) {
// 数据集名
if (i == type.getArgumentIndex()) {
if (StringUtils.equals(name, entity.getOldName())) {
// 替换数据集名
parent.append(name);
Reflect.on(stringLiteral).set(STATEMENT, entity.getNewName());
break;
}
} else {
String field = entity.getTargetField(name);
// 如果是需要匹配的字段
// 要走到字段匹配,就必须先经过数据集名匹配,目前所有公式都是数据集在前,字段在后
if (StringUtils.isNotEmpty(field) && StringUtils.equals(parent.toString(), name)) {
// 替换成匹配后的字段
Reflect.on(stringLiteral).set(STATEMENT, field);
break;
}
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().debug(e, e.getMessage());
}
}
/**
* 从公式可能存在嵌套中解析出某类型函数的第几个参数
*
* @param functionCall 公式
* @param functionName 函数名
* @param argumentIndex 参数位置
* @return 对应参数位置的值
*/
public static List<String> fetchArgument(FunctionCall functionCall, String functionName, int argumentIndex) {
List<String> result = new ArrayList<>();
Node[] subNodes = functionCall.getArguments();
if (subNodes != null) {
// 遍历子公式
for (int i = 0; i < subNodes.length; i++) {
Object subNode = subNodes[i];
if (i == argumentIndex && subNode instanceof StringLiteral && StringUtils.equalsIgnoreCase(functionCall.getName(), functionName)) {
StringLiteral stringLiteral = (StringLiteral) subNode;
try {
result.add(stringLiteral.eval(Calculator.createCalculator()).toString());
} catch (Exception e) {
FineLoggerFactory.getLogger().debug(e, e.getMessage());
}
continue;
}
if (subNode instanceof FunctionCall) {
for (TableDataFormulaType tableDataFormulaType : TableDataFormulaType.values()) {
result.addAll(FormulaUtils.fetchArgument((FunctionCall) subNode, tableDataFormulaType.name(), tableDataFormulaType.getArgumentIndex()));
}
}
}
}
return result;
}
/**
* 通过${content}格式获取公式内容
*
* @param formula 原公式值
* @return 最终公式值
*/
public static String getFormulaPureContent(String formula) {
if (formula.startsWith(LEFT_BRACKET) && formula.endsWith(RIGHT_BRACKET)) {
return formula.substring(LEFT_BRACKET.length() + 1, formula.length() - 1);
} else {
return formula;
}
}
}

75
designer-realize/src/main/java/com/fr/design/actions/replace/action/content/tabledata/TableDataFormulaType.java

@ -0,0 +1,75 @@
package com.fr.design.actions.replace.action.content.tabledata;
import com.fr.stable.StringUtils;
/**
* 涉及数据集的公式类型枚举
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/11/5
*/
public enum TableDataFormulaType {
/**
* COLCOUNT公式
*/
COLCOUNT("COLCOUNT", 0),
/**
* CLONAME公式
*/
COLNAME("COLNAME", 0),
/**
* MAP公式
*/
MAP("MAP", 1),
/**
* ROWCOUNT公式
*/
ROWCOUNT("ROWCOUNT", 0),
/**
* TABLEDATAFILEDS公式
*/
TABLEDATAFIELDS("TABLEDATAFIELDS", 0),
/**
* VALUE公式
*/
VALUE("VALUE", 0);
private int argumentIndex;
private String name;
TableDataFormulaType(String name, int argumentIndex) {
this.argumentIndex = argumentIndex;
this.name = name;
}
public int getArgumentIndex() {
return argumentIndex;
}
/**
* 公式content是否需要替换处理
*/
public static boolean needReplace(String value) {
for (TableDataFormulaType type : TableDataFormulaType.values()) {
if (value.contains(type.name())) {
return true;
}
}
return false;
}
/**
* 获取对应的公式类型
*/
public static TableDataFormulaType get(String functionName) {
for (TableDataFormulaType type : TableDataFormulaType.values()) {
if (StringUtils.equalsIgnoreCase(functionName, type.name())) {
return type;
}
}
return null;
}
}

20
designer-realize/src/main/java/com/fr/design/actions/replace/action/content/widget/SearchWidgetAction.java

@ -68,21 +68,29 @@ public class SearchWidgetAction implements SearchAction {
}
private void addCellWidget2Array(ArrayList<WidgetInfo> widgetInfos, JTemplate jTemplate) {
private void addCellWidget2Array(List<WidgetInfo> widgetInfos, JTemplate jTemplate) {
SearchCellAction searchCellAction = SearchCellAction.getInstance();
searchCellAction.search4Infos(jTemplate);
if (searchCellAction.getCellInfos().size() > 0) {
for (CellInfo cellInfo : searchCellAction.getCellInfos()) {
searchCellWidget(widgetInfos, searchCellAction.getCellInfos());
}
}
/**
* 搜索单元格中的控件
*/
public void searchCellWidget(List<WidgetInfo> widgetInfos, List<CellInfo> cellInfos) {
for (CellInfo cellInfo : cellInfos) {
//单元格本身的控件
addWidget2ArrayFromCell(widgetInfos, cellInfo);
//单元格条件属性中超链内的控件
addWidget2ArrayFromCellHighlight(widgetInfos, cellInfo);
}
}
}
private void addWidget2ArrayFromCellHighlight(ArrayList<WidgetInfo> widgetInfos, CellInfo cellInfo) {
private void addWidget2ArrayFromCellHighlight(List<WidgetInfo> widgetInfos, CellInfo cellInfo) {
if (cellInfo.getContent().getReplaceObject() instanceof TemplateCellElement) {
TemplateCellElement cell = (TemplateCellElement) cellInfo.getContent().getReplaceObject();
if (cell.getHighlightGroup() != null) {
@ -92,7 +100,7 @@ public class SearchWidgetAction implements SearchAction {
}
}
private void dealWithHighlightGroup4Widget(HighlightGroup highlightGroup, ArrayList<WidgetInfo> widgetInfos, CellInfo cellInfo) {
private void dealWithHighlightGroup4Widget(HighlightGroup highlightGroup, List<WidgetInfo> widgetInfos, CellInfo cellInfo) {
for (int i = 0; i < highlightGroup.size(); i++) {
for (int j = 0; j < ((DefaultHighlight) highlightGroup.getHighlight(i)).actionCount(); j++) {
HighlightAction highlightAction = ((DefaultHighlight) highlightGroup.getHighlight(i)).getHighlightAction(j);
@ -115,7 +123,7 @@ public class SearchWidgetAction implements SearchAction {
return highlightAction instanceof WidgetHighlightAction && ((WidgetHighlightAction) highlightAction).getWidget() != null;
}
private void addWidget2ArrayFromCell(ArrayList<WidgetInfo> widgetInfos, CellInfo cellInfo) {
private void addWidget2ArrayFromCell(List<WidgetInfo> widgetInfos, CellInfo cellInfo) {
if (cellInfo.getContent().getReplaceObject() instanceof TemplateCellElement
&& ((TemplateCellElement) cellInfo.getContent().getReplaceObject()).getWidget() != null) {
// 单元格内有控件

9
designer-realize/src/main/java/com/fr/design/actions/replace/info/FormulaInfo.java

@ -20,6 +20,8 @@ import java.util.Map;
* created by Destiny.Lin on 2022-08-17
*/
public class FormulaInfo implements Info {
public static final String CONTENT = "content";
private ITContent content;
private static final String DISPLAY = Toolkit.i18nText("Fine-Design_Basic_DS_Dictionary") + "-" + Toolkit.i18nText("Fine-Design_Chart_Formula") + "-" + Toolkit.i18nText("Fine-Design_Basic_Display_Value");
private static final String ACTUAL = Toolkit.i18nText("Fine-Design_Basic_DS_Dictionary") + "-" + Toolkit.i18nText("Fine-Design_Chart_Formula") + "-" + Toolkit.i18nText("Fine-Design_Basic_Actual_Value");
@ -76,4 +78,11 @@ public class FormulaInfo implements Info {
return map;
}
/**
* 获取公式值
*/
public String getPureValue() {
return getCommonValue().get(CONTENT);
}
}

5
designer-realize/src/main/java/com/fr/design/actions/replace/ui/ITReplaceMainDialog.java

@ -1,12 +1,14 @@
package com.fr.design.actions.replace.ui;
import com.fr.data.TableReplacementEntity;
import com.fr.design.actions.replace.action.ITChecker;
import com.fr.design.actions.replace.action.ShowSearchResultAction;
import com.fr.design.actions.replace.action.setting.SettingController;
import com.fr.design.actions.replace.info.Info;
import com.fr.design.actions.replace.utils.ReplaceUtils;
import com.fr.design.actions.replace.utils.ShowValueUtils;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
@ -35,6 +37,7 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
@ -126,6 +129,8 @@ public class ITReplaceMainDialog extends UIDialog {
setLocation(new Point(point.x, point.y + jTemplate.getHeight() / 2 + jTemplate.getHeight() / 2 - 385));
northPane.fitScreen(0, 0, width);
//ReplaceUtils.replaceCpt(jTemplate, new TableReplacementEntity().setOldName("test-测试").setNewName("test-测试的副本").setFields(new HashMap<>()));
}

240
designer-realize/src/main/java/com/fr/design/actions/replace/utils/ReplaceUtils.java

@ -0,0 +1,240 @@
package com.fr.design.actions.replace.utils;
import com.fr.base.Formula;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.data.TableReplacementEntity;
import com.fr.design.actions.replace.action.content.cell.SearchCellAction;
import com.fr.design.actions.replace.action.content.formula.SearchFormulaManager;
import com.fr.design.actions.replace.action.content.formula.cell.SearchCellFormulaAction;
import com.fr.design.actions.replace.action.content.formula.chart.SearchChartCollectionFormulaAction;
import com.fr.design.actions.replace.action.content.formula.widget.SearchWidgetFormulaAction;
import com.fr.design.actions.replace.action.content.tabledata.FormulaUtils;
import com.fr.design.actions.replace.action.content.tabledata.TableDataFormulaType;
import com.fr.design.actions.replace.action.content.widget.SearchWidgetAction;
import com.fr.design.actions.replace.info.CellInfo;
import com.fr.design.actions.replace.info.FormulaInfo;
import com.fr.design.actions.replace.info.WidgetInfo;
import com.fr.design.actions.replace.info.base.ITContent;
import com.fr.design.mainframe.JTemplate;
import com.fr.form.FormElementCaseProvider;
import com.fr.form.ui.ElementCaseEditor;
import com.fr.main.impl.WorkBook;
import com.fr.report.elementcase.ElementCase;
import com.fr.report.utils.ElementCaseHelper;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* 数据集查找替换工具
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/11/4
*/
public class ReplaceUtils {
/**
* ----------------------------------------------查找部分--------------------------------------------------
*/
/**
* 获取公式里使用的数据集
*
* @param formula 公式内容
* @return 返回公式中使用的数据集名称
*/
public static Set<String> getFormulaDependenceTables(String formula) {
return FormulaUtils.search(formula);
}
/**
* 获取图表块里使用的数据集(不包含公式里的)
*
* @param chartCollection 图表对象
* @return 使用的数据集名称
*/
public static Set<String> getChartDependenceTables(ChartCollection chartCollection) {
return chartCollection.getDataSetNames();
}
/**
* 获取图表里使用的公式
*
* @param chartCollection 图表对象
* @return 图表公式集合
*/
public static Set<String> getChartDependenceFormulas(ChartCollection chartCollection) {
List<FormulaInfo> formulaInfos = new ArrayList<>();
SearchChartCollectionFormulaAction.getInstance().searchChartCollectionFormula(formulaInfos, new ITContent(), chartCollection);
Set<String> ans = new HashSet<>();
for (FormulaInfo formulaInfo : formulaInfos) {
ans.add(formulaInfo.getContent().getReplaceObject().toString());
}
return ans;
}
/**
* 获取报表块里使用的数据集(不包含公式里的)
*
* @param elementCaseEditor 报表块
* @return 报表块使用的数据集
*/
public static Set<String> getElementCaseDependenceTables(ElementCaseEditor elementCaseEditor) {
FormElementCaseProvider elementCase = elementCaseEditor.getElementCase();
return elementCase.getCellTableDataSet();
}
/**
* 获取报表块里使用的公式
*
* @param elementCase 报表块
* @return 公式集合
*/
public static Set<String> getElementCaseDependenceFormulas(ElementCase elementCase) {
List<FormulaInfo> formulaInfos = getElementCaseFormulas(elementCase);
Set<String> ans = new HashSet<>();
for (FormulaInfo formulaInfo : formulaInfos) {
ans.add(formulaInfo.getContent().getReplaceObject().toString());
}
return ans;
}
/**
* 获取CPT里使用的数据集(不包含公式里的)
*
* @param template 模板
* @return 数据集名字集合
*/
public static Set<String> getCptDependenceTables(JTemplate template) {
Set<String> ans = new HashSet<>();
if (template.getTarget() instanceof WorkBook) {
WorkBook workBook = (WorkBook) template.getTarget();
Iterator<String> iterator = workBook.getTableDataNameIterator();
while (iterator.hasNext()) {
String tableName = iterator.next();
ans.add(tableName);
}
}
return ans;
}
/**
* 获取CPT里使用的公式
*
* @param template 包含workbook的Jtemplate
* @return 公式集合
*/
public static Set<String> getCptDependenceFormulas(JTemplate template) {
SearchFormulaManager.getInstance().search4Infos(template);
List<FormulaInfo> formulaInfos = SearchFormulaManager.getInstance().getFormulaInfos();
Set<String> ans = new HashSet<>();
for (FormulaInfo formulaInfo : formulaInfos) {
ans.add(formulaInfo.getContent().getReplaceObject().toString());
}
return ans;
}
/**
* ----------------------------------------------替换部分--------------------------------------------------
*/
/**
* 替换公式里的数据集
*
* @param formula 公式
* @param entity 替换信息
* @return 替换后的公式内容
*/
public static String replaceFormula(String formula, List<TableReplacementEntity> entity) {
return FormulaUtils.replace(formula, entity);
}
/**
* 替换公式里的数据集
*
* @param formula 公式
* @param entity 替换信息
*/
public static void replaceFormula(Formula formula, List<TableReplacementEntity> entity) {
String content = formula.getContent();
formula.setContent(FormulaUtils.replace(content, entity));
}
/**
* 替换图表里使用的数据集(包含公式里的)
*
* @param chartCollection 图表对象
* @param entities 替换信息
*/
public static void replaceChart(ChartCollection chartCollection, List<TableReplacementEntity> entities) {
// 非公式部分
chartCollection.replaceTableData(entities);
// 公式部分
List<FormulaInfo> formulaInfos = new ArrayList<>();
SearchChartCollectionFormulaAction.getInstance().searchChartCollectionFormula(formulaInfos, new ITContent(), chartCollection);
replaceFormulaInfos(formulaInfos, entities);
}
/**
* 替换报表块里使用的数据集(包含公式里的)
*
* @param elementCase 报表块控件
* @param entities 替换信息
*/
public static void replaceElementCase(ElementCase elementCase, List<TableReplacementEntity> entities) {
// 非公式部分
ElementCaseHelper.replaceTableDataWithOutFormula(elementCase, entities);
// 公式部分——理论上就只有单元格和控件(超链那些都包含)
List<FormulaInfo> formulaInfos = getElementCaseFormulas(elementCase);
replaceFormulaInfos(formulaInfos, entities);
}
/**
* 替换CPT使用的数据集(包含公式里的)
*
* @param template cpt对应的JTemplate
* @param entity 替换信息
*/
public static void replaceCpt(JTemplate template, List<TableReplacementEntity> entity) {
if (template.getTarget() instanceof WorkBook) {
WorkBook workBook = (WorkBook) template.getTarget();
// 非公式部分替换
workBook.replaceTableData(entity);
// 公式部分
SearchFormulaManager.getInstance().search4Infos(template);
List<FormulaInfo> formulaInfos = SearchFormulaManager.getInstance().getFormulaInfos();
replaceFormulaInfos(formulaInfos, entity);
}
}
private static void replaceFormulaInfos(List<FormulaInfo> formulaInfos, List<TableReplacementEntity> entity) {
for (FormulaInfo formulaInfo : formulaInfos) {
if (TableDataFormulaType.needReplace(formulaInfo.getPureValue())) {
formulaInfo.setValue(formulaInfo,
formulaInfo.getPureValue(),
FormulaUtils.replace(formulaInfo.getPureValue(), entity),
new ArrayList<>());
}
}
}
private static List<FormulaInfo> getElementCaseFormulas(ElementCase elementCase) {
List<CellInfo> cellInfos = new ArrayList<>();
List<FormulaInfo> formulaInfos = new ArrayList<>();
List<WidgetInfo> widgetInfos = new ArrayList<>();
SearchCellAction.getInstance().getCellInfoFromElementCase(elementCase, cellInfos, new ITContent());
SearchCellFormulaAction.getInstance().searchFormulaFromCellInfos(cellInfos, formulaInfos);
SearchWidgetAction.getInstance().searchCellWidget(widgetInfos, cellInfos);
for (WidgetInfo widgetInfo : widgetInfos) {
SearchWidgetFormulaAction.getInstance().searchFormulaFromWidgetInfos(widgetInfo, formulaInfos);
}
return formulaInfos;
}
}

110
designer-realize/src/test/java/com/fr/design/actions/replace/action/content/tabledata/FormulaUtilsTest.java

@ -0,0 +1,110 @@
package com.fr.design.actions.replace.action.content.tabledata;
import com.fr.data.TableReplacementEntity;
import junit.framework.TestCase;
import org.junit.Assert;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 公式工具类的单测
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/11/5
*/
public class FormulaUtilsTest extends TestCase {
public void testSearch() {
String rowcount = "=ROWCOUNT(\"123\")";
Set<String> strings = new HashSet<>();
strings.add("123");
Assert.assertEquals(FormulaUtils.search(rowcount), strings);
Set<String> errorSet = new HashSet<>();
errorSet.add("1223");
Assert.assertNotEquals(FormulaUtils.search(rowcount), errorSet);
String str = "=COLNAME(\"test-测试\",COLCOUNT(\"列数嵌套123\"))";
Set<String> qiantao = new HashSet<>();
qiantao.add("test-测试");
qiantao.add("列数嵌套123");
Assert.assertEquals(FormulaUtils.search(str), qiantao);
String str2 = "=sum(len(MAP(value(\"test-测试1\",COLNAME(\"test-测试2\",2),COLCOUNT(\"test-测试3\")),\"test-测试4\",COLNAME(\"test-测试5\",2),COLNAME(\"test-测试6\",4))),ROWCOUNT(\"test-测试7\"),len(TABLEDATAFIELDS(\"test-测试8\")))";
Set<String> qiantao2 = FormulaUtils.search(str2);
Assert.assertTrue(qiantao2.contains("test-测试1"));
Assert.assertTrue(qiantao2.contains("test-测试2"));
Assert.assertTrue(qiantao2.contains("test-测试3"));
Assert.assertTrue(qiantao2.contains("test-测试4"));
Assert.assertTrue(qiantao2.contains("test-测试5"));
Assert.assertTrue(qiantao2.contains("test-测试6"));
Assert.assertTrue(qiantao2.contains("test-测试7"));
Assert.assertTrue(qiantao2.contains("test-测试8"));
}
public void testReplace() {
String rowcount = "=ROWCOUNT(\"123\")";
TableReplacementEntity entity = new TableReplacementEntity();
entity.setOldName("123");
entity.setNewName("222");
List<TableReplacementEntity> entities = new ArrayList<>();
entities.add(entity);
Assert.assertEquals(FormulaUtils.replace(rowcount, entities), "=ROWCOUNT(\"222\")");
String colcount = "=COLCOUNT(\"test测试\")";
TableReplacementEntity entity1 = new TableReplacementEntity();
entity1.setOldName("test测试");
entity1.setNewName("替换");
List<TableReplacementEntity> entities1 = new ArrayList<>();
entities1.add(entity1);
Assert.assertEquals(FormulaUtils.replace(colcount, entities1), "=COLCOUNT(\"替换\")");
String colname = "=COLNAME(\"test测试\")";
TableReplacementEntity entity2 = new TableReplacementEntity();
entity2.setOldName("test测试");
entity2.setNewName("替换123");
List<TableReplacementEntity> entities2 = new ArrayList<>();
entities2.add(entity2);
Assert.assertEquals(FormulaUtils.replace(colname, entities2), "=COLNAME(\"替换123\")");
String TABLEDATAFIELDS = "=TABLEDATAFIELDS(\"test测试\")";
TableReplacementEntity entity3 = new TableReplacementEntity();
entity3.setOldName("test测试");
entity3.setNewName("替换111");
List<TableReplacementEntity> entities3 = new ArrayList<>();
entities3.add(entity3);
Assert.assertEquals(FormulaUtils.replace(TABLEDATAFIELDS, entities3), "=TABLEDATAFIELDS(\"替换111\")");
String test = "=sum(len(MAP(value(\"test-测试\",COLNAME(\"test-测试\",len(MAP(value(\"test-测试\",COLNAME(\"test-测试\",len(MAP(value(\"test-测试\",COLNAME(\"test-测试\",2),COLCOUNT(\"test-测试\")),\"test-测试\",COLNAME(\"test-测试\",2),COLNAME(\"test-测试\",4)))),COLCOUNT(\"test-测试\")),\"test-测试\",COLNAME(\"test-测试\",2),COLNAME(\"test-测试\",4)))),COLCOUNT(\"test-测试\")),\"test-测试\",COLNAME(\"test-测试\",2),COLNAME(\"test-测试\",4))),ROWCOUNT(\"test-测试\"),len(TABLEDATAFIELDS(\"test-测试\")))";
TableReplacementEntity entity4 = new TableReplacementEntity();
entity4.setOldName("test-测试");
entity4.setNewName("test-测试的副本");
List<TableReplacementEntity> entities4 = new ArrayList<>();
entities4.add(entity4);
Assert.assertEquals(FormulaUtils.replace(test, entities4), "=sum(len(MAP(value(\"test-测试的副本\",COLNAME(\"test-测试的副本\",len(MAP(value(\"test-测试的副本\",COLNAME(\"test-测试的副本\",len(MAP(value(\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLCOUNT(\"test-测试的副本\")),\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLNAME(\"test-测试的副本\",4)))),COLCOUNT(\"test-测试的副本\")),\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLNAME(\"test-测试的副本\",4)))),COLCOUNT(\"test-测试的副本\")),\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLNAME(\"test-测试的副本\",4))),ROWCOUNT(\"test-测试的副本\"),len(TABLEDATAFIELDS(\"test-测试的副本\")))");
String testCircle = "=sum(len(MAP(value(\"test-测试1\",COLNAME(\"test-测试2\",len(MAP(value(\"test-测试3\",COLNAME(\"test-测试4\",len(MAP(value(\"test-测试\",COLNAME(\"test-测试\",2),COLCOUNT(\"test-测试\")),\"test-测试\",COLNAME(\"test-测试\",2),COLNAME(\"test-测试\",4)))),COLCOUNT(\"test-测试\")),\"test-测试\",COLNAME(\"test-测试\",2),COLNAME(\"test-测试\",4)))),COLCOUNT(\"test-测试\")),\"test-测试\",COLNAME(\"test-测试\",2),COLNAME(\"test-测试\",4))),ROWCOUNT(\"test-测试\"),len(TABLEDATAFIELDS(\"test-测试\")))";
TableReplacementEntity entity5 = new TableReplacementEntity();
entity5.setOldName("test-测试");
entity5.setNewName("test-测试的副本");
TableReplacementEntity entity6 = new TableReplacementEntity();
entity6.setOldName("test-测试1");
entity6.setNewName("test-测试2");
TableReplacementEntity entity7 = new TableReplacementEntity();
entity7.setOldName("test-测试2");
entity7.setNewName("test-测试3");
TableReplacementEntity entity8 = new TableReplacementEntity();
entity8.setOldName("test-测试3");
entity8.setNewName("test-测试4");
List<TableReplacementEntity> entities5 = new ArrayList<>();
entities5.add(entity5);
entities5.add(entity6);
entities5.add(entity7);
entities5.add(entity8);
Assert.assertEquals(FormulaUtils.replace(testCircle, entities5), "=sum(len(MAP(value(\"test-测试2\",COLNAME(\"test-测试3\",len(MAP(value(\"test-测试4\",COLNAME(\"test-测试4\",len(MAP(value(\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLCOUNT(\"test-测试的副本\")),\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLNAME(\"test-测试的副本\",4)))),COLCOUNT(\"test-测试的副本\")),\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLNAME(\"test-测试的副本\",4)))),COLCOUNT(\"test-测试的副本\")),\"test-测试的副本\",COLNAME(\"test-测试的副本\",2),COLNAME(\"test-测试的副本\",4))),ROWCOUNT(\"test-测试的副本\"),len(TABLEDATAFIELDS(\"test-测试的副本\")))");
}
}
Loading…
Cancel
Save