Browse Source
Merge in DESIGN/design from ~YVAN/design:feature/x to feature/x * commit '10bcd9acdece78afedb635299765b7a4c2bd02b8': REPORT-75091 - 数据脱敏(报表) 代码质量相关 REPORT-75091 - 数据脱敏(报表) 【问题原因】rt 【改动思路】详见开发文档:https://kms.fineres.com/pages/viewpage.action?pageId=504469104 【review建议】提交晚是因为虽然任务是一期,但是放到二期发布,需要在合并release/11.0后才提交featurefeature/x
Yvan-欧阳帆
2 years ago
21 changed files with 2175 additions and 89 deletions
@ -0,0 +1,182 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization; |
||||
|
||||
|
||||
import com.fr.base.TableData; |
||||
import com.fr.data.desensitize.base.AbstractDesensitizationTableData; |
||||
import com.fr.data.desensitize.base.TableDataDesensitizationBean; |
||||
import com.fr.data.desensitize.manage.DesensitizationManager; |
||||
import com.fr.data.desensitize.util.DesentizationUtils; |
||||
import com.fr.decision.webservice.bean.user.DepartmentPostBean; |
||||
import com.fr.decision.webservice.bean.user.RoleBean; |
||||
import com.fr.decision.webservice.utils.DecisionServiceConstants; |
||||
import com.fr.decision.webservice.v10.user.CustomRoleService; |
||||
import com.fr.decision.webservice.v10.user.PositionService; |
||||
import com.fr.design.data.DesignTableDataManager; |
||||
import com.fr.design.data.datapane.preview.PreviewTableModel; |
||||
import com.fr.design.data.datapane.preview.desensitization.model.DesensitizedPreviewTableModel; |
||||
import com.fr.design.data.tabledata.wrapper.TableDataWrapper; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.Comparator; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.stream.Collectors; |
||||
|
||||
|
||||
/** |
||||
* 管理所有数据集预览过程中的脱敏计算 |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/14 |
||||
*/ |
||||
public class TableDataPreviewDesensitizeManager implements DesensitizationManager { |
||||
|
||||
private static final String CONNECTOR = "_"; |
||||
|
||||
private TableDataPreviewDesensitizeManager() { |
||||
} |
||||
|
||||
private static class Holder { |
||||
private static final TableDataPreviewDesensitizeManager INSTANCE = new TableDataPreviewDesensitizeManager(); |
||||
} |
||||
|
||||
/** |
||||
* 获取TableDataPreviewDesensitizeManager单例 |
||||
* @return |
||||
*/ |
||||
public static TableDataPreviewDesensitizeManager getInstance() { |
||||
return TableDataPreviewDesensitizeManager.Holder.INSTANCE; |
||||
} |
||||
|
||||
/** |
||||
* 判断数据集预览时是否需要脱敏,这里不需要判断roleIds,因为默认有权限编辑的人一定有权限看脱敏前后字段值 |
||||
* |
||||
* @param tableData |
||||
* @return |
||||
*/ |
||||
public boolean needDesensitize(TableData tableData) { |
||||
return tableData instanceof AbstractDesensitizationTableData && |
||||
DesentizationUtils.isCollectionNotEmpty(((AbstractDesensitizationTableData) tableData).getDesensitizationBeans()) && |
||||
((AbstractDesensitizationTableData) tableData).getDesensitizationBeans().stream().noneMatch(TableDataDesensitizationBean::invalid); |
||||
} |
||||
|
||||
/** |
||||
* 数据集预览脱敏,使用DesensitizedPreviewTableModel对当前的预览TableModel做包装 |
||||
* |
||||
* @param model |
||||
* @return |
||||
*/ |
||||
public PreviewTableModel desensitizeTableModel(TableData tableData, PreviewTableModel model) { |
||||
if (needDesensitize(tableData)) { |
||||
Map<Integer, TableDataDesensitizationBean> desensitizationBeanMap = new LinkedHashMap<>(); |
||||
// 获取此数据集的所有脱敏信息
|
||||
Collection<TableDataDesensitizationBean> desensitizationBeans = ((AbstractDesensitizationTableData) tableData).getDesensitizationBeans(); |
||||
// 排个序
|
||||
List<TableDataDesensitizationBean> sortedBeans = desensitizationBeans.stream().sorted(Comparator.comparingInt(TableDataDesensitizationBean::getColumnIndex)).collect(Collectors.toList()); |
||||
int columnIndex = 0; |
||||
for (TableDataDesensitizationBean sortedBean : sortedBeans) { |
||||
// 当map中已包含列序号时,代表对这一列设置了不同的脱敏规则,将key + 1
|
||||
if (desensitizationBeanMap.containsKey(columnIndex)) { |
||||
columnIndex++; |
||||
} |
||||
desensitizationBeanMap.put(columnIndex, sortedBean); |
||||
} |
||||
// 包装TableModel
|
||||
return new DesensitizedPreviewTableModel(model, desensitizationBeanMap); |
||||
} |
||||
return model; |
||||
} |
||||
|
||||
/** |
||||
* 通过TableData获取其列名 |
||||
* 实现逻辑有点绕,TableData本身并不能返回列名集合,只能先去获取当前模板所有数据集,然后匹配名称拿到TableDataWrapper再获取列名 |
||||
* @param tableData |
||||
* @return |
||||
*/ |
||||
public List<String> getColumnNamesByTableData(TableData tableData) { |
||||
List<Map<String, TableDataWrapper>> editingDataSet = DesignTableDataManager.getEditingDataSet(DesignTableDataManager.getEditingTableDataSource()); |
||||
// 当前所有模板数据集Wrapper,不包括存储过程
|
||||
Map<String, TableDataWrapper> templeteDataMap = editingDataSet.get(0); |
||||
// 当前所有模板数据集Wrapper,包括存储过程
|
||||
Map<String, TableDataWrapper> dataWrapperMap = DesignTableDataManager.getAllDataSetIncludingProcedure(templeteDataMap); |
||||
// 找到匹配当前数据集名称的Wrapper
|
||||
TableDataWrapper tableDataWrapper = dataWrapperMap.get(tableData.getName()); |
||||
return tableDataWrapper == null ? |
||||
new ArrayList<>() : |
||||
tableDataWrapper.calculateColumnNameList(); |
||||
} |
||||
|
||||
/** |
||||
* 这个api会返回 部门职位 + 自定义角色 的Map |
||||
* 其中 key为 "pid" + "_" + "id",value为 "ptext" + "text" |
||||
* @return |
||||
*/ |
||||
public Map<String, String> getAllRoles() { |
||||
Map<String, String> rolesMap = new LinkedHashMap<>(); |
||||
// 处理部门职位相关的用户组
|
||||
addDepartmentAndPositionRoles2Map(rolesMap); |
||||
// 处理自定义角色相关的用户组
|
||||
addCustomRoles2Map(rolesMap); |
||||
return rolesMap; |
||||
} |
||||
|
||||
/** |
||||
* 获取所有的部门职位,按照 key为 "pid" + "_" + "id",value为 "ptext" + "text"的格式添加到参数Map中 |
||||
* @param rolesMap |
||||
*/ |
||||
private void addDepartmentAndPositionRoles2Map(Map<String, String> rolesMap) { |
||||
try { |
||||
List<DepartmentPostBean> postBeans = PositionService.getInstance().getDepartmentPostNameList(); |
||||
for (DepartmentPostBean postBean : postBeans) { |
||||
String department = postBean.getpText(); |
||||
String position = postBean.getText(); |
||||
String departmentId = postBean.getpId(); |
||||
String positionId = postBean.getId(); |
||||
if (!ComparatorUtils.equals(DecisionServiceConstants.DECISION_DEP_ROOT, postBean.getId()) && StringUtils.isNotEmpty(position)) { |
||||
// 只添加部门和职位同时存在的
|
||||
rolesMap.put(mergeRoleId(departmentId, positionId), mergeRoleText(department, position)); |
||||
} |
||||
} |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e, "[Desensitization] failed to add department and position roles to map for {}", e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取所有的自定义角色,按照 id - name添加到参数map里 |
||||
* @param rolesMap |
||||
*/ |
||||
private void addCustomRoles2Map(Map<String, String> rolesMap) { |
||||
try { |
||||
List<RoleBean> allCustomRole = CustomRoleService.getInstance().getAllCustomRoleNameList(null); |
||||
allCustomRole.forEach(roleBean -> rolesMap.put(roleBean.getId(), roleBean.getText())); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e, "[Desensitization] failed to add custom role to map for {}", e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 合并部门 + 职位的名称 |
||||
* @param departmentName |
||||
* @param positionName |
||||
* @return |
||||
*/ |
||||
public String mergeRoleText(String departmentName, String positionName) { |
||||
return departmentName + positionName; |
||||
} |
||||
|
||||
/** |
||||
* 合并部门 + 职位的id |
||||
* @param departmentId |
||||
* @param positionId |
||||
* @return |
||||
*/ |
||||
public String mergeRoleId(String departmentId, String positionId) { |
||||
return departmentId + CONNECTOR + positionId; |
||||
} |
||||
} |
@ -0,0 +1,113 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.model; |
||||
|
||||
|
||||
import com.fr.data.desensitize.base.TableDataDesensitizationBean; |
||||
import com.fr.data.desensitize.calculate.DesensitizationCalculator; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||
import com.fr.design.data.datapane.preview.PreviewTableModel; |
||||
|
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
|
||||
/** |
||||
* 数据集预览TableModel的脱敏实现 |
||||
* |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/14 |
||||
*/ |
||||
public class DesensitizedPreviewTableModel extends PreviewTableModel { |
||||
|
||||
/** |
||||
* 原始数据Model |
||||
*/ |
||||
private PreviewTableModel previewTableModel; |
||||
|
||||
/** |
||||
* 脱敏后新组装的TableModel中,列序号 - 脱敏信息 对应的Map |
||||
*/ |
||||
private Map<Integer, TableDataDesensitizationBean> desensitizationBeanMap; |
||||
|
||||
private boolean needDesensitize = false; |
||||
|
||||
public DesensitizedPreviewTableModel(PreviewTableModel previewTableModel, Map<Integer, TableDataDesensitizationBean> desensitizationBeanMap) { |
||||
this.previewTableModel = previewTableModel; |
||||
this.desensitizationBeanMap = desensitizationBeanMap; |
||||
} |
||||
|
||||
@Override |
||||
public String getColumnName(int column) { |
||||
int originIndex = needDesensitize && Objects.nonNull(desensitizationBeanMap.get(column)) ? |
||||
desensitizationBeanMap.get(column).getColumnIndex() : column; |
||||
return previewTableModel.getColumnName(originIndex); |
||||
} |
||||
|
||||
@Override |
||||
public int getRowCount() { |
||||
return previewTableModel.getRowCount(); |
||||
} |
||||
|
||||
@Override |
||||
public int getColumnCount() { |
||||
return needDesensitize ? |
||||
getDesensitizeColumnsCount() : |
||||
previewTableModel.getColumnCount(); |
||||
} |
||||
|
||||
@Override |
||||
public Object getValueAt(int rowIndex, int columnIndex) { |
||||
return needDesensitize && Objects.nonNull(desensitizationBeanMap.get(columnIndex)) ? |
||||
getDesensitizedValue(rowIndex, columnIndex) : |
||||
previewTableModel.getValueAt(rowIndex, columnIndex); |
||||
} |
||||
|
||||
/** |
||||
* 返回脱敏后的数据值 |
||||
* |
||||
* @param rowIndex |
||||
* @param columnIndex |
||||
* @return |
||||
*/ |
||||
private Object getDesensitizedValue(int rowIndex, int columnIndex) { |
||||
// 先通过columnIndex找到对应原TableModel的列序号
|
||||
int originColumnIndex = desensitizationBeanMap.get(columnIndex).getColumnIndex(); |
||||
// 获取原值
|
||||
Object value = previewTableModel.getValueAt(rowIndex, originColumnIndex); |
||||
// 判空
|
||||
if (Objects.isNull(value)) { |
||||
return value; |
||||
} |
||||
// 脱敏
|
||||
String strValue = String.valueOf(value); |
||||
value = desensitizeValue(strValue, columnIndex); |
||||
return value; |
||||
} |
||||
|
||||
/** |
||||
* 计算脱敏后的value,此时columnIndex对应的脱敏信息一定不为空 |
||||
* |
||||
* @param strValue |
||||
* @param columnIndex |
||||
* @return |
||||
*/ |
||||
private String desensitizeValue(String strValue, int columnIndex) { |
||||
TableDataDesensitizationBean desensitizationBean = desensitizationBeanMap.get(columnIndex); |
||||
DesensitizationRule desensitizationRule = desensitizationBean.getDesensitizationRule(); |
||||
return DesensitizationCalculator.getInstance().desensitize(strValue, desensitizationRule); |
||||
} |
||||
|
||||
/** |
||||
* 获取当前有效的脱敏字段个数 |
||||
* @return |
||||
*/ |
||||
public int getDesensitizeColumnsCount() { |
||||
return desensitizationBeanMap.size(); |
||||
} |
||||
|
||||
/** |
||||
* 切换脱敏状态 |
||||
*/ |
||||
public void toggleNeedDesensite() { |
||||
this.needDesensitize = !needDesensitize; |
||||
} |
||||
} |
@ -0,0 +1,312 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.rule; |
||||
|
||||
import com.fr.base.svg.IconUtils; |
||||
import com.fr.data.desensitize.rule.DesensitizationRuleManager; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource; |
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.gui.ibutton.UIRadioButton; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditAction; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditorPane; |
||||
import com.fr.design.gui.itableeditorpane.UITableModelAdapter; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.collections.CollectionUtils; |
||||
|
||||
import javax.swing.AbstractCellEditor; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.JTable; |
||||
import javax.swing.SwingUtilities; |
||||
import javax.swing.table.TableCellEditor; |
||||
import javax.swing.table.TableCellRenderer; |
||||
import java.awt.CardLayout; |
||||
import java.awt.Component; |
||||
import java.awt.event.ActionEvent; |
||||
import java.util.LinkedHashSet; |
||||
import java.util.List; |
||||
import java.util.Set; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 脱敏规则选择页面 |
||||
* |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/26 |
||||
*/ |
||||
public class DesensitizationRuleChoosePane extends JPanel { |
||||
|
||||
private CardLayout cardLayout; |
||||
|
||||
private UITableEditorPane<DesensitizationRule> serverRuleEditPane; |
||||
|
||||
private UITableEditorPane<DesensitizationRule> customRuleEditPane; |
||||
|
||||
private DesensitizationRuleSource currentRuleSource; |
||||
|
||||
public DesensitizationRuleChoosePane() { |
||||
this.cardLayout = new CardLayout(); |
||||
this.setLayout(cardLayout); |
||||
serverRuleEditPane = new UITableEditorPane<>(new DesensitizationRuleChooseTableModel(this, true)); |
||||
customRuleEditPane = new UITableEditorPane<>(new DesensitizationRuleChooseTableModel(this, false)); |
||||
serverRuleEditPane.setHeaderResizing(false); |
||||
customRuleEditPane.setHeaderResizing(false); |
||||
populateDesensitizationRules(); |
||||
this.add(serverRuleEditPane, DesensitizationRuleSource.SERVER.name()); |
||||
this.add(customRuleEditPane, DesensitizationRuleSource.CUSTOM.name()); |
||||
// 默认显示平台规则
|
||||
switchPaneByRuleSource(DesensitizationRuleSource.SERVER); |
||||
} |
||||
|
||||
/** |
||||
* 通过脱敏规则来源,切换显示不同的脱敏规则Table面板 |
||||
* @param ruleSource |
||||
*/ |
||||
public void switchPaneByRuleSource(DesensitizationRuleSource ruleSource) { |
||||
this.currentRuleSource = ruleSource; |
||||
this.cardLayout.show(this, ruleSource.name()); |
||||
} |
||||
|
||||
/** |
||||
* 展示当前规则 |
||||
*/ |
||||
private void populateDesensitizationRules() { |
||||
serverRuleEditPane.populate(DesensitizationRuleManager.getInstance().getRules(DesensitizationRuleSource.SERVER)); |
||||
customRuleEditPane.populate(DesensitizationRuleManager.getInstance().getRules(DesensitizationRuleSource.CUSTOM)); |
||||
} |
||||
|
||||
/** |
||||
* 获取当前选中的规则 |
||||
* |
||||
* @return |
||||
*/ |
||||
public DesensitizationRule getSelectedDesensitizationRule() { |
||||
switch (currentRuleSource) { |
||||
case SERVER: |
||||
return serverRuleEditPane.getTableModel().getSelectedValue(); |
||||
case CUSTOM: |
||||
return customRuleEditPane.getTableModel().getSelectedValue(); |
||||
default: |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 规则选择Table的TableModel |
||||
*/ |
||||
private class DesensitizationRuleChooseTableModel extends UITableModelAdapter<DesensitizationRule> { |
||||
|
||||
private Component parent; |
||||
|
||||
private boolean debugActionOnly; |
||||
|
||||
protected DesensitizationRuleChooseTableModel(Component parent, boolean debugActionOnly) { |
||||
super(new String[]{ |
||||
StringUtils.EMPTY, |
||||
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name"), |
||||
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Description") |
||||
}); |
||||
this.parent = parent; |
||||
this.debugActionOnly = debugActionOnly; |
||||
this.setColumnClass(new Class[]{ |
||||
RuleChoosePane.class, |
||||
UILabel.class, |
||||
UILabel.class |
||||
}); |
||||
this.setDefaultEditor(RuleChoosePane.class, new RuleChoosePane()); |
||||
this.setDefaultRenderer(RuleChoosePane.class, new RuleChoosePane()); |
||||
this.createTable().getColumnModel().getColumn(0).setMaxWidth(20); |
||||
} |
||||
|
||||
@Override |
||||
public Object getValueAt(int rowIndex, int columnIndex) { |
||||
DesensitizationRule rule = getList().get(rowIndex); |
||||
switch (columnIndex) { |
||||
case 0: |
||||
return rule.equals(getSelectedValue()); |
||||
case 1: |
||||
return rule.getRuleName(); |
||||
case 2: |
||||
return DesensitizationRule.getDescription(rule); |
||||
default: |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean isCellEditable(int row, int col) { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public UITableEditAction[] createAction() { |
||||
return debugActionOnly ? |
||||
new UITableEditAction[]{new DebugRuleAction(parent)} : |
||||
new UITableEditAction[]{new AddRuleAction(), new EditRuleAction(), new DeleteRuleAction(parent), new DebugRuleAction(parent)}; |
||||
} |
||||
|
||||
private Set<String> getCurrentExistRuleNames(String excludeName) { |
||||
List<DesensitizationRule> rules = getList(); |
||||
return CollectionUtils.isEmpty(rules) ? |
||||
new LinkedHashSet<>() : |
||||
rules.stream() |
||||
.map(DesensitizationRule::getRuleName) |
||||
.filter(name -> !StringUtils.equals(name, excludeName)) |
||||
.collect(Collectors.toSet()); |
||||
} |
||||
|
||||
private class RuleChoosePane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||
|
||||
private UIRadioButton selectedButton; |
||||
|
||||
public RuleChoosePane() { |
||||
this.selectedButton = new UIRadioButton(); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||
selectedButton.setSelected(isSelected); |
||||
return selectedButton; |
||||
} |
||||
|
||||
@Override |
||||
public Object getCellEditorValue() { |
||||
return selectedButton.isSelected(); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||
selectedButton.setSelected(isSelected); |
||||
return selectedButton; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 添加规则 |
||||
*/ |
||||
private class AddRuleAction extends AddTableRowAction { |
||||
|
||||
public AddRuleAction() { |
||||
this.setName(Toolkit.i18nText("Fine-Design_Report_Desensitization_Add")); |
||||
this.setSmallIcon("/com/fr/design/standard/add/add_black", false); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
// 新增一条规则
|
||||
DesensitizationRuleEditPane editPane = new DesensitizationRuleEditPane(getCurrentExistRuleNames(StringUtils.EMPTY)); |
||||
BasicDialog basicDialog = editPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() { |
||||
@Override |
||||
public void doOk() { |
||||
DesensitizationRule rule = editPane.updateBean(); |
||||
// 添加到Rule Manager中
|
||||
if (DesensitizationRule.valid(rule)) { |
||||
DesensitizationRuleManager.getInstance().addRule(rule); |
||||
} |
||||
// 添加到Table中
|
||||
addRow(rule); |
||||
fireTableDataChanged(); |
||||
} |
||||
|
||||
@Override |
||||
public void doCancel() { |
||||
super.doCancel(); |
||||
} |
||||
}, BasicDialog.DEFAULT); |
||||
basicDialog.setVisible(true); |
||||
} |
||||
} |
||||
|
||||
private class EditRuleAction extends UITableEditAction { |
||||
|
||||
public EditRuleAction() { |
||||
this.setName(Toolkit.i18nText("Fine-Design_Basic_Edit")); |
||||
this.setSmallIcon(IconUtils.readIcon("/com/fr/design/standard/edit/edit")); |
||||
} |
||||
|
||||
@Override |
||||
public void checkEnabled() { |
||||
setEnabled(table.getSelectedRow() != -1); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
// 获取当前选中规则
|
||||
DesensitizationRule selectedValue = getSelectedValue(); |
||||
DesensitizationRuleEditPane editPane = new DesensitizationRuleEditPane(getCurrentExistRuleNames(selectedValue.getRuleName())); |
||||
editPane.populateBean(selectedValue); |
||||
BasicDialog basicDialog = editPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() { |
||||
@Override |
||||
public void doOk() { |
||||
DesensitizationRule rule = editPane.updateBean(); |
||||
// 修改同步到RuleManager中
|
||||
if (DesensitizationRule.valid(rule)) { |
||||
DesensitizationRuleManager.getInstance().updateRule(rule); |
||||
} |
||||
fireTableDataChanged(); |
||||
} |
||||
|
||||
@Override |
||||
public void doCancel() { |
||||
super.doCancel(); |
||||
} |
||||
}, BasicDialog.DEFAULT); |
||||
basicDialog.setVisible(true); |
||||
} |
||||
} |
||||
|
||||
private class DeleteRuleAction extends DeleteAction { |
||||
|
||||
public DeleteRuleAction(Component parent) { |
||||
super(parent); |
||||
this.setName(Toolkit.i18nText("Fine-Design_Basic_Base_Remove")); |
||||
this.setSmallIcon("/com/fr/design/images/control/remove"); |
||||
} |
||||
|
||||
@Override |
||||
public void checkEnabled() { |
||||
setEnabled(table.getSelectedRow() != -1); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
// 获取当前选中规则
|
||||
DesensitizationRule selectedRule = getSelectedValue(); |
||||
// 删除同步到RuleManager中
|
||||
if (DesensitizationRule.valid(selectedRule)) { |
||||
DesensitizationRuleManager.getInstance().removeRule(selectedRule); |
||||
} |
||||
super.actionPerformed(e); |
||||
} |
||||
} |
||||
|
||||
private class DebugRuleAction extends UITableEditAction { |
||||
|
||||
private Component parent; |
||||
|
||||
public DebugRuleAction(Component parent) { |
||||
this.parent = parent; |
||||
this.setName(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Debug")); |
||||
this.setSmallIcon("/com/fr/design/standard/debug/debug"); |
||||
} |
||||
|
||||
@Override |
||||
public void checkEnabled() { |
||||
setEnabled(table.getSelectedRow() != -1); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
// 获取当前选中规则
|
||||
DesensitizationRule selectedRule = getSelectedValue(); |
||||
DesensitizationRuleDebugPane ruleDebugPane = new DesensitizationRuleDebugPane(selectedRule); |
||||
BasicDialog ruleDebugDialog = ruleDebugPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), null, BasicDialog.DEFAULT); |
||||
ruleDebugDialog.setVisible(true); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,127 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.rule; |
||||
|
||||
import com.fr.data.desensitize.calculate.DesensitizationCalculator; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||
import com.fr.design.dialog.BasicPane; |
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.awt.event.FocusEvent; |
||||
import java.awt.event.FocusListener; |
||||
|
||||
/** |
||||
* 脱敏规则调试页 |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/8 |
||||
*/ |
||||
public class DesensitizationRuleDebugPane extends BasicPane { |
||||
|
||||
/** |
||||
* 脱敏规则 |
||||
*/ |
||||
private DesensitizationRule rule; |
||||
|
||||
public DesensitizationRuleDebugPane(DesensitizationRule rule) { |
||||
this.rule = rule; |
||||
initComponent(); |
||||
} |
||||
|
||||
private void initComponent() { |
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
this.add(initNorthPane(), BorderLayout.NORTH); |
||||
this.add(initCenterPane(), BorderLayout.CENTER); |
||||
} |
||||
|
||||
private JPanel initNorthPane() { |
||||
JPanel northPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Description")); |
||||
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0)); |
||||
UILabel desensitizationRule = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Algorithm")); |
||||
UILabel characterReplace = new UILabel(rule.getRuleType().getTypeName()); |
||||
UILabel description = new UILabel(DesensitizationRule.getDescription(rule)); |
||||
JComponent[][] components = new JComponent[][] { |
||||
{desensitizationRule, characterReplace}, |
||||
{new UILabel(), description} |
||||
}; |
||||
panel.add( |
||||
TableLayoutHelper.createCommonTableLayoutPane( |
||||
components, |
||||
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED}, |
||||
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED}, |
||||
20), |
||||
BorderLayout.CENTER); |
||||
northPane.add(panel); |
||||
return northPane; |
||||
} |
||||
|
||||
private JPanel initCenterPane() { |
||||
JPanel centerPane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Debug")); |
||||
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0)); |
||||
|
||||
UILabel beforeDesensitize = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Before")); |
||||
UITextField beforeDesensitizeText = new UITextField(20); |
||||
beforeDesensitizeText.setPlaceholder(Toolkit.i18nText("Fine-Design_Report_Desensitization_Enter_Content")); |
||||
UILabel afterDesensitize = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_After")); |
||||
UITextField afterDesensitizeText = new UITextField(20); |
||||
afterDesensitizeText.setEditable(false); |
||||
UIButton desensitizeButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Debug")); |
||||
beforeDesensitizeText.addFocusListener(new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
afterDesensitizeText.setText(StringUtils.EMPTY); |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
|
||||
} |
||||
}); |
||||
desensitizeButton.addActionListener(new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
String text = beforeDesensitizeText.getText(); |
||||
if (StringUtils.isEmpty(text)) { |
||||
FineJOptionPane.showMessageDialog(DesensitizationRuleDebugPane.this, |
||||
Toolkit.i18nText("Fine-Design_Report_Desensitization_Please_Enter_Valid_Content")); |
||||
} |
||||
String desensitizedText = DesensitizationCalculator.getInstance().desensitize(text, rule); |
||||
afterDesensitizeText.setText(desensitizedText); |
||||
} |
||||
}); |
||||
|
||||
JComponent[][] components = new JComponent[][] { |
||||
{beforeDesensitize, beforeDesensitizeText, desensitizeButton}, |
||||
{afterDesensitize, afterDesensitizeText, new UILabel()} |
||||
}; |
||||
panel.add( |
||||
TableLayoutHelper.createCommonTableLayoutPane( |
||||
components, |
||||
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED}, |
||||
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED}, |
||||
20), |
||||
BorderLayout.CENTER); |
||||
|
||||
centerPane.add(panel); |
||||
return centerPane; |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Debug"); |
||||
} |
||||
} |
@ -0,0 +1,296 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.rule; |
||||
|
||||
import com.fr.data.desensitize.rule.base.DesensitizationCondition; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRuleType; |
||||
import com.fr.design.beans.BasicBeanPane; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.event.UIObserverListener; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itextfield.UINumberField; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.JComponent; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.CardLayout; |
||||
import java.awt.Insets; |
||||
import java.awt.event.FocusEvent; |
||||
import java.awt.event.FocusListener; |
||||
import java.util.Arrays; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 脱敏规则编辑页 |
||||
* |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/8 |
||||
*/ |
||||
public class DesensitizationRuleEditPane extends BasicBeanPane<DesensitizationRule> { |
||||
/** |
||||
* 已经存在的规则名称,用于检测重名 |
||||
*/ |
||||
private Set<String> existRuleNames; |
||||
|
||||
private UITextField ruleNameTextField; |
||||
private UIComboBox ruleTypeComboBox; |
||||
private UINumberField retainFrontTextField; |
||||
private UINumberField retainBackTextField; |
||||
private UITextField firstSymbolTextField; |
||||
private UITextField secondSymbolTextField; |
||||
private CardLayout cardLayout; |
||||
private JPanel ruleConditionPane; |
||||
|
||||
|
||||
private DesensitizationRule rule = DesensitizationRule.createDefaultEmptyRule(); |
||||
|
||||
private final FocusListener retainFrontListener = new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
rule.getCondition().setRetainFront((int) retainFrontTextField.getValue()); |
||||
} |
||||
}; |
||||
|
||||
private final FocusListener retainBackListener = new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
rule.getCondition().setRetainBack((int) retainBackTextField.getValue()); |
||||
} |
||||
}; |
||||
|
||||
private final FocusListener firstSymbolListener = new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
rule.getCondition().setSymbol(firstSymbolTextField.getText()); |
||||
} |
||||
}; |
||||
|
||||
private final FocusListener secondSymbolListener = new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
rule.getCondition().setRetainFront(0); |
||||
rule.getCondition().setRetainBack(0); |
||||
rule.getCondition().setSymbol(secondSymbolTextField.getText()); |
||||
} |
||||
}; |
||||
|
||||
public DesensitizationRuleEditPane(Set<String> existRuleNames) { |
||||
this.existRuleNames = existRuleNames; |
||||
initComponent(); |
||||
} |
||||
|
||||
/** |
||||
* 初始化面板 |
||||
*/ |
||||
private void initComponent() { |
||||
this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout()); |
||||
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0)); |
||||
UILabel ruleNameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name")); |
||||
// 规则名称输入框
|
||||
initRuleNameTextField(); |
||||
UILabel ruleTypeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Algorithm")); |
||||
// 脱敏算法Type设置
|
||||
JPanel ruleTypePane = initRuleTypePane(); |
||||
// 脱敏算法Condition设置
|
||||
JPanel ruleConditionPane = initRuleConditionPane(); |
||||
JComponent[][] components = { |
||||
{ruleNameLabel, ruleNameTextField}, |
||||
{ruleTypeLabel, ruleTypePane}, |
||||
{new UILabel(), ruleConditionPane} |
||||
}; |
||||
panel.add( |
||||
TableLayoutHelper.createGapTableLayoutPane( |
||||
components, |
||||
new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.FILL}, |
||||
new double[]{TableLayout.FILL, TableLayout.PREFERRED}, |
||||
20, |
||||
20), |
||||
BorderLayout.CENTER); |
||||
this.add(panel); |
||||
} |
||||
|
||||
/** |
||||
* 初始化规则类型面板 |
||||
* @return |
||||
*/ |
||||
private JPanel initRuleTypePane() { |
||||
JPanel ruleTypePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
// 脱敏算法类型下拉框
|
||||
initRuleTypeComboBox(); |
||||
ruleTypePane.add(ruleTypeComboBox, BorderLayout.CENTER); |
||||
return ruleTypePane; |
||||
} |
||||
|
||||
/** |
||||
* 初始化规则条件面板 |
||||
* @return |
||||
*/ |
||||
private JPanel initRuleConditionPane() { |
||||
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
cardLayout = new CardLayout(); |
||||
ruleConditionPane = new JPanel(cardLayout); |
||||
// 字符替换
|
||||
JPanel characterReplacePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); |
||||
UILabel retainFrontLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Retain_Front") + StringUtils.BLANK); |
||||
retainFrontTextField = new UINumberField(5); |
||||
retainFrontTextField.addFocusListener(retainFrontListener); |
||||
|
||||
UILabel retainBackLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Count_And_Back") + StringUtils.BLANK); |
||||
retainBackTextField = new UINumberField(5); |
||||
retainBackTextField.addFocusListener(retainBackListener); |
||||
|
||||
UILabel replaceLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Count_And_Other_Character_Replace_By") + StringUtils.BLANK); |
||||
firstSymbolTextField = new UITextField(10); |
||||
firstSymbolTextField.addFocusListener(firstSymbolListener); |
||||
|
||||
characterReplacePane.add(retainFrontLabel); |
||||
characterReplacePane.add(retainFrontTextField); |
||||
characterReplacePane.add(retainBackLabel); |
||||
characterReplacePane.add(retainBackTextField); |
||||
characterReplacePane.add(replaceLabel); |
||||
characterReplacePane.add(firstSymbolTextField); |
||||
// 整体替换
|
||||
JPanel characterAllReplacePane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); |
||||
UILabel allReplaceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_All_Character_Replace_By") + StringUtils.BLANK); |
||||
secondSymbolTextField = new UITextField(10); |
||||
secondSymbolTextField.addFocusListener(secondSymbolListener); |
||||
|
||||
characterAllReplacePane.add(allReplaceLabel); |
||||
characterAllReplacePane.add(secondSymbolTextField); |
||||
|
||||
ruleConditionPane.add(characterReplacePane, DesensitizationRuleType.CHARACTER_REPLACE.getTypeName()); |
||||
ruleConditionPane.add(characterAllReplacePane, DesensitizationRuleType.ALL_CHARACTERS_REPLACE.getTypeName()); |
||||
// 初始化状态为字符替换
|
||||
switchRuleConditionPane(DesensitizationRuleType.CHARACTER_REPLACE); |
||||
|
||||
panel.add(ruleConditionPane, BorderLayout.CENTER); |
||||
return panel; |
||||
} |
||||
|
||||
/** |
||||
* 切换规则类型面板 |
||||
* @param ruleType |
||||
*/ |
||||
private void switchRuleConditionPane(DesensitizationRuleType ruleType) { |
||||
this.cardLayout.show(ruleConditionPane, ruleType.getTypeName()); |
||||
} |
||||
|
||||
/** |
||||
* 初始化规则类型下拉框 |
||||
*/ |
||||
private void initRuleTypeComboBox() { |
||||
ruleTypeComboBox = new UIComboBox(Arrays.stream(DesensitizationRuleType.values()).map(DesensitizationRuleType::getTypeName).toArray()); |
||||
ruleTypeComboBox.setSelectedIndex(0); |
||||
ruleTypeComboBox.registerChangeListener(new UIObserverListener() { |
||||
@Override |
||||
public void doChange() { |
||||
DesensitizationRuleType ruleType = DesensitizationRuleType.matchByTypeName((String) ruleTypeComboBox.getSelectedItem()); |
||||
rule.setRuleType(ruleType); |
||||
// 修改底下的conditionPane
|
||||
switchRuleConditionPane(ruleType); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 初始化规则名称输入框 |
||||
*/ |
||||
private void initRuleNameTextField() { |
||||
ruleNameTextField = new UITextField(20) { |
||||
@Override |
||||
public Insets getInsets() { |
||||
return new Insets(2, 4, 0, 4); |
||||
} |
||||
}; |
||||
ruleNameTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Report_Desensitization_Please_Enter_Rule_Name")); |
||||
ruleNameTextField.setBorderPainted(true); |
||||
ruleNameTextField.addFocusListener(new FocusListener() { |
||||
@Override |
||||
public void focusGained(FocusEvent e) { |
||||
ruleNameTextField.setBorder(BorderFactory.createLineBorder(UIConstants.NORMAL_BLUE)); |
||||
ruleNameTextField.repaint(); |
||||
} |
||||
|
||||
@Override |
||||
public void focusLost(FocusEvent e) { |
||||
ruleNameTextField.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR)); |
||||
rule.setRuleName(ruleNameTextField.getText()); |
||||
ruleNameTextField.repaint(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void populateBean(DesensitizationRule ob) { |
||||
this.rule = ob; |
||||
this.ruleNameTextField.setText(rule.getRuleName()); |
||||
String typeName = rule.getRuleType().getTypeName(); |
||||
this.ruleTypeComboBox.setSelectedItem(typeName); |
||||
switch (DesensitizationRuleType.matchByTypeName(typeName)) { |
||||
case CHARACTER_REPLACE: |
||||
this.retainFrontTextField.setValue(rule.getCondition().getRetainFront()); |
||||
this.retainBackTextField.setValue(rule.getCondition().getRetainBack()); |
||||
this.firstSymbolTextField.setText(rule.getCondition().getSymbol()); |
||||
break; |
||||
case ALL_CHARACTERS_REPLACE: |
||||
this.secondSymbolTextField.setText(rule.getCondition().getSymbol()); |
||||
break; |
||||
default: |
||||
} |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public DesensitizationRule updateBean() { |
||||
rule.setEnable(true); |
||||
return rule; |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Custom_Config_Rules"); |
||||
} |
||||
|
||||
@Override |
||||
public void checkValid() throws Exception { |
||||
// 保存rule前检查下
|
||||
String checkMessage = StringUtils.EMPTY; |
||||
if (StringUtils.isEmpty(rule.getRuleName())) { |
||||
checkMessage = Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name_Cannot_Be_Empty"); |
||||
} else if (existRuleNames.contains(rule.getRuleName())) { |
||||
checkMessage = Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Name_Cannot_Repeat"); |
||||
} else if (DesensitizationCondition.invalid(rule.getCondition())) { |
||||
checkMessage = Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Wrong_Condition"); |
||||
} |
||||
if (StringUtils.isNotEmpty(checkMessage)) { |
||||
throw new Exception(checkMessage); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,80 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.rule; |
||||
|
||||
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource; |
||||
import com.fr.design.beans.BasicBeanPane; |
||||
import com.fr.design.border.UITitledBorder; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
|
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
|
||||
/** |
||||
* 脱敏规则展示页 |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/8 |
||||
*/ |
||||
public class DesensitizationRulePane extends BasicBeanPane<DesensitizationRule> { |
||||
|
||||
/** |
||||
* 规则来源选择面板 |
||||
*/ |
||||
private DesensitizationRuleSourceChoosePane ruleSourceChoosePane; |
||||
|
||||
/** |
||||
* 规则选择面板 |
||||
*/ |
||||
private DesensitizationRuleChoosePane ruleChoosePane; |
||||
|
||||
/** |
||||
* 内容面板 |
||||
*/ |
||||
private JPanel contentPane; |
||||
|
||||
public DesensitizationRulePane() { |
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
initPane(); |
||||
} |
||||
|
||||
private void initPane() { |
||||
// 内容面板
|
||||
contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||
contentPane.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Choose"))); |
||||
this.add(contentPane, BorderLayout.CENTER); |
||||
// 规则来源选择Pane
|
||||
ruleSourceChoosePane = new DesensitizationRuleSourceChoosePane(this); |
||||
// 规则选择Pane
|
||||
ruleChoosePane = new DesensitizationRuleChoosePane(); |
||||
contentPane.add(ruleSourceChoosePane, BorderLayout.NORTH); |
||||
contentPane.add(ruleChoosePane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
/** |
||||
* 处理规则来源选择面板中改动来源的事件 |
||||
* @param newRuleSource |
||||
*/ |
||||
public void dealWithRuleSourceChanged(DesensitizationRuleSource newRuleSource) { |
||||
ruleChoosePane.switchPaneByRuleSource(newRuleSource); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void populateBean(DesensitizationRule ob) { |
||||
// 这边展示当前所有规则时,不依靠外界传值,初始化的时候,从规则管理中心去获取
|
||||
} |
||||
|
||||
@Override |
||||
public DesensitizationRule updateBean() { |
||||
DesensitizationRule desensitizationRule = ruleChoosePane.getSelectedDesensitizationRule(); |
||||
return DesensitizationRule.valid(desensitizationRule) ? |
||||
desensitizationRule : |
||||
DesensitizationRule.createDefaultEmptyRule(); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule"); |
||||
} |
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.rule; |
||||
|
||||
import com.fr.data.desensitize.rule.base.DesensitizationRuleSource; |
||||
import com.fr.design.gui.ibutton.UIRadioButton; |
||||
import com.fr.design.i18n.Toolkit; |
||||
|
||||
import javax.swing.BorderFactory; |
||||
import javax.swing.ButtonGroup; |
||||
import javax.swing.JPanel; |
||||
import java.awt.FlowLayout; |
||||
|
||||
/** |
||||
* 脱敏规则来源选择页面 |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/26 |
||||
*/ |
||||
public class DesensitizationRuleSourceChoosePane extends JPanel { |
||||
|
||||
/** |
||||
* 来源平台的按钮 |
||||
*/ |
||||
private UIRadioButton serverSource; |
||||
|
||||
/** |
||||
* 来源本地的按钮 |
||||
*/ |
||||
private UIRadioButton customSource; |
||||
|
||||
public DesensitizationRuleSourceChoosePane(DesensitizationRulePane desensitizationRulePane) { |
||||
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); |
||||
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); |
||||
|
||||
serverSource = new UIRadioButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Server_Config_Rules")); |
||||
customSource = new UIRadioButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Custom_Config_Rules")); |
||||
|
||||
ButtonGroup buttonGroup = new ButtonGroup(); |
||||
buttonGroup.add(serverSource); |
||||
buttonGroup.add(customSource); |
||||
serverSource.setSelected(true); |
||||
|
||||
serverSource.registerChangeListener(() -> desensitizationRulePane.dealWithRuleSourceChanged(DesensitizationRuleSource.SERVER)); |
||||
customSource.registerChangeListener(() -> desensitizationRulePane.dealWithRuleSourceChanged(DesensitizationRuleSource.CUSTOM)); |
||||
|
||||
this.add(serverSource); |
||||
this.add(customSource); |
||||
} |
||||
} |
@ -0,0 +1,110 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.setting; |
||||
|
||||
import com.fr.data.desensitize.base.AbstractDesensitizationTableData; |
||||
import com.fr.data.desensitize.base.TableDataDesensitizationBean; |
||||
import com.fr.design.beans.BasicBeanPane; |
||||
import com.fr.design.constants.UIConstants; |
||||
import com.fr.design.gui.icheckbox.UICheckBox; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
|
||||
import javax.swing.JComponent; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 数据集脱敏字段设置页面 |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/8 |
||||
*/ |
||||
public class TableDataDesensitizationSettingPane extends BasicBeanPane<AbstractDesensitizationTableData> { |
||||
|
||||
/** |
||||
* 设置针对的数据集 |
||||
*/ |
||||
private AbstractDesensitizationTableData tableData; |
||||
|
||||
private UICheckBox desensitizeOpen; |
||||
|
||||
private TableDataDesensitizationTablePane tableDataDesensitizationTablePane; |
||||
|
||||
|
||||
public TableDataDesensitizationSettingPane(AbstractDesensitizationTableData tableData) { |
||||
this.tableData = tableData; |
||||
initComponents(); |
||||
} |
||||
|
||||
private void initComponents() { |
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
this.add(initNorthPane(), BorderLayout.NORTH); |
||||
this.add(initCenterPane(), BorderLayout.CENTER); |
||||
} |
||||
|
||||
/** |
||||
* 初始化启用数据脱敏面板 |
||||
* @return |
||||
*/ |
||||
private JComponent initNorthPane() { |
||||
JPanel northPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Desensitization_Config")); |
||||
this.desensitizeOpen = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened")); |
||||
northPane.add(desensitizeOpen); |
||||
UILabel tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened_Tooltips")); |
||||
tipLabel.setForeground(UIConstants.CHECK_BOX_TIP_FONT_COLOR); |
||||
northPane.add(tipLabel); |
||||
return northPane; |
||||
} |
||||
|
||||
/** |
||||
* 初始化数据脱敏规则表面板 |
||||
* @return |
||||
*/ |
||||
private JComponent initCenterPane() { |
||||
this.tableDataDesensitizationTablePane = new TableDataDesensitizationTablePane(tableData, this); |
||||
return tableDataDesensitizationTablePane; |
||||
} |
||||
|
||||
/** |
||||
* 是否启用脱敏 |
||||
* @return |
||||
*/ |
||||
public boolean isDesensitizeOpened() { |
||||
return desensitizeOpen.isSelected(); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Config"); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(AbstractDesensitizationTableData tableData) { |
||||
this.tableData = tableData; |
||||
this.desensitizeOpen.setSelected(tableData.getDesensitizeOpen()); |
||||
tableDataDesensitizationTablePane.populateDesensitizationSetting(tableData); |
||||
} |
||||
|
||||
@Override |
||||
public AbstractDesensitizationTableData updateBean() { |
||||
saveDesensitizeOpened(); |
||||
saveDesensitizationBeans(tableDataDesensitizationTablePane.updateDesensitizationSetting()); |
||||
return tableData; |
||||
} |
||||
|
||||
/** |
||||
* 保存脱敏启用状态 |
||||
*/ |
||||
public void saveDesensitizeOpened() { |
||||
tableData.setDesensitizeOpen(desensitizeOpen.isSelected()); |
||||
} |
||||
|
||||
/** |
||||
* 保存脱敏规则配置信息 |
||||
* @param tableDataDesensitizationBeans |
||||
*/ |
||||
public void saveDesensitizationBeans(List<TableDataDesensitizationBean> tableDataDesensitizationBeans) { |
||||
tableData.setDesensitizationBeans(tableDataDesensitizationBeans); |
||||
} |
||||
} |
@ -0,0 +1,459 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.setting; |
||||
|
||||
import com.fr.data.desensitize.base.AbstractDesensitizationTableData; |
||||
import com.fr.data.desensitize.base.TableDataDesensitizationBean; |
||||
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager; |
||||
import com.fr.design.data.datapane.preview.desensitization.view.rule.DesensitizationRulePane; |
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.DialogActionAdapter; |
||||
import com.fr.design.gui.ibutton.UIButton; |
||||
import com.fr.design.gui.icombobox.UIComboBox; |
||||
import com.fr.design.gui.icombocheckbox.UIComboCheckBox; |
||||
import com.fr.design.gui.ilable.UILabel; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditAction; |
||||
import com.fr.design.gui.itableeditorpane.UITableModelAdapter; |
||||
import com.fr.design.gui.itextfield.UITextField; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.layout.TableLayout; |
||||
import com.fr.design.layout.TableLayoutHelper; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.collections.CollectionUtils; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import javax.swing.AbstractCellEditor; |
||||
import javax.swing.JPanel; |
||||
import javax.swing.JTable; |
||||
import javax.swing.SwingUtilities; |
||||
import javax.swing.event.CellEditorListener; |
||||
import javax.swing.event.ChangeEvent; |
||||
import javax.swing.table.TableCellEditor; |
||||
import javax.swing.table.TableCellRenderer; |
||||
import java.awt.Component; |
||||
import java.awt.event.ActionEvent; |
||||
import java.awt.event.ActionListener; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.LinkedHashSet; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
import java.util.Optional; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 处理TableDataDesensitizationTablePane中TableEditPane的Model |
||||
* |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/23 |
||||
*/ |
||||
public class TableDataDesensitizationTableModel extends UITableModelAdapter<TableDataDesensitizationBean> { |
||||
|
||||
private static final String APOSTROPHE = "..."; |
||||
|
||||
private AbstractDesensitizationTableData tableData; |
||||
|
||||
/** |
||||
* 当前数据集的所有列名 |
||||
*/ |
||||
private List<String> columnNames; |
||||
|
||||
/** |
||||
* key为用户组唯一标识(id拼接),value为用户组名称 |
||||
*/ |
||||
private Map<String, String> roleMap; |
||||
|
||||
private Component parent; |
||||
|
||||
private DesensitizationRuleChooser ruleChooser; |
||||
|
||||
private DesensitizationRuleDescriptionPane descriptionPane; |
||||
|
||||
public TableDataDesensitizationTableModel(AbstractDesensitizationTableData tableData, Component parent) { |
||||
// table相关
|
||||
super(new String[]{ |
||||
Toolkit.i18nText("Fine-Design_Report_Desensitization_Column"), |
||||
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule"), |
||||
StringUtils.EMPTY, |
||||
Toolkit.i18nText("Fine-Design_Report_Desensitization_Effected_Roles") |
||||
}); |
||||
// 一些数据相关
|
||||
this.tableData = tableData; |
||||
// 获取当前数据集的所有列名
|
||||
this.columnNames = TableDataPreviewDesensitizeManager.getInstance().getColumnNamesByTableData(tableData); |
||||
// 获取当前所有用户组
|
||||
this.roleMap = TableDataPreviewDesensitizeManager.getInstance().getAllRoles(); |
||||
this.parent = parent; |
||||
this.setColumnClass(new Class[]{ |
||||
// 列名选择
|
||||
ColumnNamesComboBox.class, |
||||
// 规则选择
|
||||
DesensitizationRuleChooser.class, |
||||
// 规则详情展示
|
||||
DesensitizationRuleDescriptionPane.class, |
||||
// 生效用户组选择
|
||||
EffectedRolesChooser.class |
||||
}); |
||||
this.setDefaultEditor(ColumnNamesComboBox.class, new ColumnNamesComboBox()); |
||||
this.ruleChooser = new DesensitizationRuleChooser(); |
||||
this.setDefaultEditor(DesensitizationRuleChooser.class, ruleChooser); |
||||
this.setDefaultRenderer(DesensitizationRuleChooser.class, ruleChooser); |
||||
this.descriptionPane = new DesensitizationRuleDescriptionPane(); |
||||
this.setDefaultEditor(DesensitizationRuleDescriptionPane.class, new DesensitizationRuleDescriptionPane()); |
||||
this.setDefaultEditor(EffectedRolesChooser.class, new EffectedRolesChooser()); |
||||
} |
||||
|
||||
@Override |
||||
public Object getValueAt(int rowIndex, int columnIndex) { |
||||
TableDataDesensitizationBean desensitizationBean = this.getList().get(rowIndex); |
||||
switch (columnIndex) { |
||||
case 0: |
||||
return getColumnNameValue(desensitizationBean); |
||||
case 1: |
||||
return desensitizationBean.getDesensitizationRule().getRuleName(); |
||||
case 2: |
||||
return DesensitizationRule.getDescription(desensitizationBean.getDesensitizationRule()); |
||||
case 3: |
||||
return matchRoleNamesByIds(desensitizationBean.getRoleIds()); |
||||
default: |
||||
return StringUtils.EMPTY; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 根据当前选中的Bean,获取其对应的列名字段 |
||||
* @param desensitizationBean |
||||
* @return |
||||
*/ |
||||
private Object getColumnNameValue(TableDataDesensitizationBean desensitizationBean) { |
||||
// 内部列名list为空时直接返回空字符串
|
||||
if (CollectionUtils.isEmpty(columnNames)) { |
||||
return StringUtils.EMPTY; |
||||
} |
||||
// bean的列字段index不对劲时,返回空字符串
|
||||
return validColumnIndex(desensitizationBean.getColumnIndex()) ? |
||||
columnNames.get(desensitizationBean.getColumnIndex()) : |
||||
StringUtils.EMPTY; |
||||
} |
||||
|
||||
/** |
||||
* 判断字段索引是否越界 |
||||
* @param columnIndex |
||||
* @return |
||||
*/ |
||||
private boolean validColumnIndex(int columnIndex) { |
||||
return columnIndex >= 0 && columnIndex < columnNames.size(); |
||||
} |
||||
|
||||
/** |
||||
* 通过id匹配此用户组对应的部门职位名称(或者说自定义角色名称) |
||||
* |
||||
* @param roleIds |
||||
* @return |
||||
*/ |
||||
private List<String> matchRoleNamesByIds(Set<String> roleIds) { |
||||
List<String> result = new ArrayList<>(); |
||||
for (String roleId : roleIds) { |
||||
if (roleMap != null && roleMap.containsKey(roleId)) { |
||||
result.add(roleMap.get(roleId)); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isCellEditable(int row, int col) { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public UITableEditAction[] createAction() { |
||||
return new UITableEditAction[]{new AddDesensitizationAction(), new RemoveDesensitizationAction(parent)}; |
||||
} |
||||
|
||||
/** |
||||
* 获取当前选中的item,可能为null |
||||
* |
||||
* @return |
||||
*/ |
||||
@Nullable |
||||
private TableDataDesensitizationBean getCurrentSelectBean() { |
||||
return table.getSelectedRow() == -1 ? |
||||
null : |
||||
getList().get(table.getSelectedRow()); |
||||
} |
||||
|
||||
/** |
||||
* 列名选择下拉框 |
||||
*/ |
||||
private class ColumnNamesComboBox extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||
|
||||
private UIComboBox columnNameComboBox; |
||||
|
||||
ColumnNamesComboBox() { |
||||
columnNameComboBox = new UIComboBox(columnNames.toArray(new String[0])); |
||||
this.addCellEditorListener(new CellEditorListener() { |
||||
@Override |
||||
public void editingStopped(ChangeEvent e) { |
||||
|
||||
TableDataDesensitizationBean desensitizationBean = getCurrentSelectBean(); |
||||
if (Objects.nonNull(desensitizationBean)) { |
||||
desensitizationBean.setColumnIndex(columnNameComboBox.getSelectedIndex()); |
||||
fireTableDataChanged(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void editingCanceled(ChangeEvent e) { |
||||
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||
columnNameComboBox.setSelectedIndex(getList().get(row).getColumnIndex()); |
||||
return columnNameComboBox; |
||||
} |
||||
|
||||
@Override |
||||
public Object getCellEditorValue() { |
||||
Object selectedItem = columnNameComboBox.getSelectedItem(); |
||||
return Objects.isNull(selectedItem) ? StringUtils.EMPTY : selectedItem.toString(); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||
columnNameComboBox.setSelectedIndex(getList().get(row).getColumnIndex()); |
||||
return columnNameComboBox; |
||||
} |
||||
} |
||||
|
||||
private class DesensitizationRuleChooser extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||
/** |
||||
* 规则选择页面 |
||||
*/ |
||||
private JPanel choosePane; |
||||
/** |
||||
* 规则名称 |
||||
*/ |
||||
private UITextField ruleNameTextField; |
||||
/** |
||||
* 规则选择按钮 |
||||
*/ |
||||
private UIButton chooseButton; |
||||
/** |
||||
* 规则 |
||||
*/ |
||||
private DesensitizationRule rule; |
||||
|
||||
private ActionListener chooseRuleListener = new ActionListener() { |
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
DesensitizationRulePane rulePane = new DesensitizationRulePane(); |
||||
BasicDialog ruleDialog = rulePane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() { |
||||
@Override |
||||
public void doOk() { |
||||
rule = rulePane.updateBean(); |
||||
TableDataDesensitizationBean desensitizationBean = getCurrentSelectBean(); |
||||
if (Objects.nonNull(desensitizationBean) && Objects.nonNull(rule)) { |
||||
desensitizationBean.setDesensitizationRule(rule); |
||||
fireTableDataChanged(); |
||||
} |
||||
rule = null; |
||||
} |
||||
}, BasicDialog.DEFAULT); |
||||
ruleDialog.setVisible(true); |
||||
} |
||||
}; |
||||
|
||||
DesensitizationRuleChooser() { |
||||
// 规则名称展示
|
||||
ruleNameTextField = new UITextField(); |
||||
ruleNameTextField.setEnabled(false); |
||||
// 规则选择按钮
|
||||
chooseButton = new UIButton(APOSTROPHE); |
||||
chooseButton.addActionListener(chooseRuleListener); |
||||
// 规则选择页面
|
||||
Component[][] templateChooserComponent = {{ruleNameTextField, chooseButton}}; |
||||
double[] rowSize = {TableLayout.PREFERRED}; |
||||
double[] columnSize = {TableLayout.FILL, 22}; |
||||
choosePane = TableLayoutHelper.createCommonTableLayoutPane(templateChooserComponent, rowSize, columnSize, 0); |
||||
this.addCellEditorListener(new CellEditorListener() { |
||||
|
||||
@Override |
||||
public void editingCanceled(ChangeEvent e) { |
||||
|
||||
} |
||||
|
||||
@Override |
||||
public void editingStopped(ChangeEvent e) { |
||||
TableDataDesensitizationBean desensitizationBean = getCurrentSelectBean(); |
||||
if (Objects.nonNull(desensitizationBean) && Objects.nonNull(rule)) { |
||||
desensitizationBean.setDesensitizationRule(rule); |
||||
fireTableDataChanged(); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||
ruleNameTextField.setText(getList().get(row).getDesensitizationRule().getRuleName()); |
||||
return choosePane; |
||||
} |
||||
|
||||
@Override |
||||
public Object getCellEditorValue() { |
||||
return ruleNameTextField.getText(); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||
ruleNameTextField.setText((String) value); |
||||
return choosePane; |
||||
} |
||||
} |
||||
|
||||
private class DesensitizationRuleDescriptionPane extends AbstractCellEditor implements TableCellEditor { |
||||
|
||||
private UILabel descriptionLabel; |
||||
|
||||
DesensitizationRuleDescriptionPane() { |
||||
// 规则描述
|
||||
this.descriptionLabel = new UILabel(); |
||||
} |
||||
|
||||
/** |
||||
* 根据脱敏规则信息,刷新下规则描述文字,主要用于与规则选择器的联动 |
||||
* |
||||
* @param desensitizationRule |
||||
*/ |
||||
public void refreshDescription(DesensitizationRule desensitizationRule) { |
||||
this.descriptionLabel.setText(DesensitizationRule.getDescription(desensitizationRule)); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||
refreshDescription(getList().get(row).getDesensitizationRule()); |
||||
return descriptionLabel; |
||||
} |
||||
|
||||
@Override |
||||
public Object getCellEditorValue() { |
||||
return this.descriptionLabel.getText(); |
||||
} |
||||
} |
||||
|
||||
private class EffectedRolesChooser extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||
|
||||
private UIComboCheckBox rolesCheckBox; |
||||
|
||||
EffectedRolesChooser() { |
||||
this.rolesCheckBox = new UIComboCheckBox(roleMap.values().toArray(), true); |
||||
this.addCellEditorListener(new CellEditorListener() { |
||||
@Override |
||||
public void editingStopped(ChangeEvent e) { |
||||
TableDataDesensitizationBean desensitizationBean = getCurrentSelectBean(); |
||||
if (Objects.nonNull(desensitizationBean)) { |
||||
desensitizationBean.setRoleIds(generateRolesIdsBySelectedValues()); |
||||
fireTableDataChanged(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void editingCanceled(ChangeEvent e) { |
||||
|
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||
rolesCheckBox.setSelectedValues(generateRolesCheckBoxSelectedValues(getList().get(row))); |
||||
return rolesCheckBox; |
||||
} |
||||
|
||||
/** |
||||
* 根据当前的规则配置信息,生成选中的rolesMap用来展示 |
||||
* @param desensitizationBean |
||||
* @return |
||||
*/ |
||||
private Map<Object, Boolean> generateRolesCheckBoxSelectedValues(TableDataDesensitizationBean desensitizationBean) { |
||||
Map<Object, Boolean> result = new HashMap<>(roleMap.size()); |
||||
for (Map.Entry<String, String> roleEntry : roleMap.entrySet()) { |
||||
String roleId = roleEntry.getKey(); |
||||
String roleName = roleEntry.getValue(); |
||||
if (desensitizationBean.getRoleIds().contains(roleId)) { |
||||
result.put(roleName, true); |
||||
} else { |
||||
result.put(roleName, false); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* 根据当前的RoleName选择项,生成其对应的RoleId的set存入规则配置信息 |
||||
* @return |
||||
*/ |
||||
private Set<String> generateRolesIdsBySelectedValues() { |
||||
Set<String> result = new LinkedHashSet<>(); |
||||
Object[] selectedValues = rolesCheckBox.getSelectedValues(); |
||||
for (Object selectedValue : selectedValues) { |
||||
String selectedRoleName = (String) selectedValue; |
||||
if (roleMap.containsValue(selectedRoleName)) { |
||||
Optional<Map.Entry<String, String>> matchedEntry = roleMap.entrySet().stream().filter(entry -> StringUtils.equals(entry.getValue(), selectedRoleName)).findFirst(); |
||||
matchedEntry.ifPresent(stringStringEntry -> result.add(stringStringEntry.getKey())); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
@Override |
||||
public Object getCellEditorValue() { |
||||
return rolesCheckBox.getSelectedValues(); |
||||
} |
||||
|
||||
@Override |
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||
rolesCheckBox.setSelectedValues(generateRolesCheckBoxSelectedValues(getList().get(row))); |
||||
return rolesCheckBox; |
||||
} |
||||
} |
||||
|
||||
|
||||
private class AddDesensitizationAction extends AddTableRowAction { |
||||
|
||||
public AddDesensitizationAction() { |
||||
this.setName(Toolkit.i18nText("Fine-Design_Report_Desensitization_Add")); |
||||
this.setSmallIcon("/com/fr/design/standard/add/add_black", false); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
super.actionPerformed(e); |
||||
// 添加一条空白数据
|
||||
addRow(TableDataDesensitizationBean.createEmyptBean()); |
||||
fireTableDataChanged(); |
||||
table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1); |
||||
} |
||||
} |
||||
|
||||
private class RemoveDesensitizationAction extends DeleteAction { |
||||
|
||||
public RemoveDesensitizationAction(Component component) { |
||||
super(component); |
||||
this.setName(Toolkit.i18nText("Fine-Design_Basic_Base_Remove")); |
||||
this.setSmallIcon("/com/fr/design/standard/remove/remove_red", false); |
||||
} |
||||
|
||||
@Override |
||||
public void actionPerformed(ActionEvent e) { |
||||
super.actionPerformed(e); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,64 @@
|
||||
package com.fr.design.data.datapane.preview.desensitization.view.setting; |
||||
|
||||
import com.fr.data.desensitize.base.AbstractDesensitizationTableData; |
||||
import com.fr.data.desensitize.base.TableDataDesensitizationBean; |
||||
import com.fr.design.gui.itableeditorpane.UITableEditorPane; |
||||
import com.fr.design.layout.FRGUIPaneFactory; |
||||
|
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
import java.awt.Component; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 脱敏字段设置页面中的Table |
||||
* @author Yvan |
||||
* @version 11.0 |
||||
* Created by Yvan on 2022/9/14 |
||||
*/ |
||||
public class TableDataDesensitizationTablePane extends JPanel { |
||||
|
||||
/** |
||||
* 脱敏数据集 |
||||
*/ |
||||
private AbstractDesensitizationTableData tableData; |
||||
|
||||
/** |
||||
* 父页面 |
||||
*/ |
||||
private Component parent; |
||||
|
||||
/** |
||||
* 脱敏信息Table |
||||
*/ |
||||
private UITableEditorPane<TableDataDesensitizationBean> editorPane; |
||||
|
||||
public TableDataDesensitizationTablePane(AbstractDesensitizationTableData tableData, Component parent) { |
||||
this.tableData = tableData; |
||||
this.parent = parent; |
||||
initComponent(); |
||||
} |
||||
|
||||
private void initComponent() { |
||||
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||
this.editorPane = new UITableEditorPane<>(new TableDataDesensitizationTableModel(tableData, parent)); |
||||
this.editorPane.setHeaderResizing(false); |
||||
this.add(editorPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
/** |
||||
* 展示此TableData中已配置的脱敏规则信息 |
||||
* @param tableData |
||||
*/ |
||||
public void populateDesensitizationSetting(AbstractDesensitizationTableData tableData) { |
||||
this.tableData = tableData; |
||||
editorPane.populate(tableData.getDesensitizationBeans().toArray(new TableDataDesensitizationBean[0])); |
||||
} |
||||
|
||||
/** |
||||
* 获取当前对TableData的配置脱敏规则信息 |
||||
*/ |
||||
public List<TableDataDesensitizationBean> updateDesensitizationSetting() { |
||||
return editorPane.update(); |
||||
} |
||||
} |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 430 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 473 B |
After Width: | Height: | Size: 450 B |
Loading…
Reference in new issue