329 changed files with 14618 additions and 3280 deletions
@ -0,0 +1,19 @@ |
|||||||
|
package com.fr.design.actions.help.replace; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 定义一些底层操作 |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @version 11.0 |
||||||
|
* created by Destiny.Lin on 2022-09-27 |
||||||
|
*/ |
||||||
|
public interface ITReplaceOperator { |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 关闭面板 |
||||||
|
*/ |
||||||
|
void close(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.base.TableData; |
||||||
|
import com.fr.data.TableDataSource; |
||||||
|
import com.fr.data.desensitize.TableDataDesensitizeManager; |
||||||
|
import com.fr.data.desensitize.base.DesensitizationTableData; |
||||||
|
import com.fr.data.desensitize.base.TableDataDesensitizationItem; |
||||||
|
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.esd.query.StrategicTableData; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.Collections; |
||||||
|
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 DesensitizationTableData && |
||||||
|
DesentizationUtils.isCollectionNotEmpty(((DesensitizationTableData) tableData).getDesensitizationConfig().getDesensitizationItems()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据集预览脱敏,使用DesensitizedPreviewTableModel对当前的预览TableModel做包装 |
||||||
|
* |
||||||
|
* @param model |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public PreviewTableModel desensitizeTableModel(TableData tableData, PreviewTableModel model) { |
||||||
|
|
||||||
|
Map<Integer, TableDataDesensitizationItem> desensitizationItemMap = new LinkedHashMap<>(); |
||||||
|
// 获取此数据集的所有脱敏信息
|
||||||
|
Collection<TableDataDesensitizationItem> desensitizationItems = ((DesensitizationTableData) tableData).getDesensitizationConfig().getDesensitizationItems(); |
||||||
|
if (DesentizationUtils.isCollectionNotEmpty(desensitizationItems)) { |
||||||
|
// 更新规则
|
||||||
|
desensitizationItems = TableDataDesensitizeManager.getInstance().dealWithlatestRules(desensitizationItems); |
||||||
|
// 对脱敏配置项集合做过滤和排序处理
|
||||||
|
List<TableDataDesensitizationItem> items = desensitizationItems.stream() |
||||||
|
.filter(item -> isAvaliableItem4Preview(item, model)) |
||||||
|
.sorted(Comparator.comparingInt(item -> matchColumnIndex(item, model))) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
// 然后转换成Map
|
||||||
|
for (int i = 0; i < items.size(); i++) { |
||||||
|
desensitizationItemMap.put(i, items.get(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
// 包装TableModel
|
||||||
|
return new DesensitizedPreviewTableModel(model, desensitizationItemMap); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否为有效的用于预览脱敏效果的DesensitizationItem |
||||||
|
* |
||||||
|
* @param item 脱敏配置项 |
||||||
|
* @param model 数据集预览数据 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private boolean isAvaliableItem4Preview(TableDataDesensitizationItem item, PreviewTableModel model) { |
||||||
|
return item.getRule().isEnable() && |
||||||
|
matchColumnIndex(item, model) >= 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过TableData获取其列名,理论上一定存在缓存值 |
||||||
|
* |
||||||
|
* @param tableData |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public List<String> getColumnNamesByTableData(TableData tableData) { |
||||||
|
TableDataSource editingTableDataSource = DesignTableDataManager.getEditingTableDataSource(); |
||||||
|
if (editingTableDataSource != null && tableData instanceof StrategicTableData) { |
||||||
|
return Arrays.asList(DesignTableDataManager.getSelectedColumnNames(editingTableDataSource, ((StrategicTableData) tableData).getDsName())); |
||||||
|
} |
||||||
|
return Collections.EMPTY_LIST; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据列名,从PreviewTableModel中匹配列序号,如果返回-1代表未匹配到 |
||||||
|
* @param desensitizationItem |
||||||
|
* @param previewModel |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public int matchColumnIndex(TableDataDesensitizationItem desensitizationItem, PreviewTableModel previewModel) { |
||||||
|
return previewModel.getColumnIndexWithExceptionIngore(desensitizationItem.getColumnName()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.model; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.data.desensitize.base.TableDataDesensitizationItem; |
||||||
|
import com.fr.data.desensitize.calculate.DesensitizationCalculator; |
||||||
|
import com.fr.data.desensitize.rule.base.DesensitizationRule; |
||||||
|
import com.fr.design.data.datapane.preview.PreviewTableModel; |
||||||
|
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager; |
||||||
|
|
||||||
|
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, TableDataDesensitizationItem> desensitizationItemMap; |
||||||
|
|
||||||
|
private boolean needDesensitize = false; |
||||||
|
|
||||||
|
public DesensitizedPreviewTableModel(PreviewTableModel previewTableModel, Map<Integer, TableDataDesensitizationItem> desensitizationItemMap) { |
||||||
|
this.previewTableModel = previewTableModel; |
||||||
|
this.desensitizationItemMap = desensitizationItemMap; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(int column) { |
||||||
|
return needDesensitize ? |
||||||
|
desensitizationItemMap.get(column).getColumnName() : |
||||||
|
previewTableModel.getColumnName(column); |
||||||
|
} |
||||||
|
|
||||||
|
@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(desensitizationItemMap.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 = TableDataPreviewDesensitizeManager.getInstance().matchColumnIndex(desensitizationItemMap.get(columnIndex), previewTableModel); |
||||||
|
// 获取原值
|
||||||
|
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) { |
||||||
|
DesensitizationRule rule = desensitizationItemMap.get(columnIndex).getRule(); |
||||||
|
return DesensitizationCalculator.getInstance().desensitize(strValue, rule); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前有效的脱敏字段个数 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public int getDesensitizeColumnsCount() { |
||||||
|
return desensitizationItemMap.size(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换脱敏状态 |
||||||
|
*/ |
||||||
|
public void toggleNeedDesensite() { |
||||||
|
this.needDesensitize = !needDesensitize; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.view; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.constants.UIConstants; |
||||||
|
import com.fr.design.data.datapane.preview.PreviewTablePane; |
||||||
|
import com.fr.design.gui.ibutton.UIToggleButton; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.gui.itoolbar.UIToolbar; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.menu.SeparatorDef; |
||||||
|
import com.fr.design.menu.ToolBarDef; |
||||||
|
|
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.FlowLayout; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据集预览-脱敏配置面板,主要展示当前脱敏开启状态、当前脱敏设定数量等 |
||||||
|
* |
||||||
|
* @author Yvan |
||||||
|
* @version 11.0 |
||||||
|
* Created by Yvan on 2022/11/14 |
||||||
|
*/ |
||||||
|
public class PreviewTableDesensitizationPane extends JPanel { |
||||||
|
|
||||||
|
private static final String DATA_DESENSITIZATION_CONFIG = Toolkit.i18nText("Fine-Design_Report_Desensitization_Config"); |
||||||
|
private static final String LEFT_BRACKET = "("; |
||||||
|
private static final String RIGHT_BRACKET = ")"; |
||||||
|
private static final String COUNT = Toolkit.i18nText("Fine-Design_Report_Desensitization_Count"); |
||||||
|
|
||||||
|
/** |
||||||
|
* 预览面板 |
||||||
|
*/ |
||||||
|
private PreviewTablePane previewTablePane; |
||||||
|
|
||||||
|
/** |
||||||
|
* "数据脱敏设置"-标签 |
||||||
|
*/ |
||||||
|
private UILabel desensitizationLabel; |
||||||
|
|
||||||
|
/** |
||||||
|
* 脱敏效果预览按钮 |
||||||
|
*/ |
||||||
|
private UIToggleButton previewToggle; |
||||||
|
|
||||||
|
|
||||||
|
public PreviewTableDesensitizationPane(PreviewTablePane previewTablePane) { |
||||||
|
this.previewTablePane = previewTablePane; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化面板 |
||||||
|
*/ |
||||||
|
private void initComponents() { |
||||||
|
this.setLayout(new FlowLayout(FlowLayout.LEFT)); |
||||||
|
this.add(initDesensitizationLabel()); |
||||||
|
this.add(initToolBar()); |
||||||
|
this.add(initPreviewButton()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化Label |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private Component initDesensitizationLabel() { |
||||||
|
// 初始化Label
|
||||||
|
desensitizationLabel = new UILabel(DATA_DESENSITIZATION_CONFIG); |
||||||
|
desensitizationLabel.setForeground(UIConstants.NORMAL_BLUE); |
||||||
|
desensitizationLabel.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
previewTablePane.clickDesensitizationLabel(); |
||||||
|
} |
||||||
|
}); |
||||||
|
return desensitizationLabel; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化分隔符 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private UIToolbar initToolBar() { |
||||||
|
ToolBarDef toolbarDef = new ToolBarDef(); |
||||||
|
toolbarDef.addShortCut(SeparatorDef.DEFAULT); |
||||||
|
UIToolbar toolBar = ToolBarDef.createJToolBar(); |
||||||
|
toolBar.setBorderPainted(false); |
||||||
|
toolbarDef.updateToolBar(toolBar); |
||||||
|
return toolBar; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化脱敏效果预览按钮 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private UIToggleButton initPreviewButton() { |
||||||
|
previewToggle = new UIToggleButton(new Icon[]{IconUtils.readIcon("/com/fr/design/images/m_file/preview"), IconUtils.readIcon("/com/fr/design/images/m_file/preview")}, true); |
||||||
|
previewToggle.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Preview")); |
||||||
|
previewToggle.setSelected(false); |
||||||
|
previewToggle.addActionListener(e -> { |
||||||
|
// 切换TableModel的脱敏状态
|
||||||
|
previewTablePane.togglePreviewTableModelDesensitizeStatus(); |
||||||
|
// 刷新预览页面,展示
|
||||||
|
previewTablePane.refreshTable(); |
||||||
|
}); |
||||||
|
return previewToggle; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置Label的值,主要是需要动态修改配置的脱敏规则的数量 |
||||||
|
* |
||||||
|
* @param desensitizeOpen |
||||||
|
* @param count |
||||||
|
*/ |
||||||
|
public void setDesensitizationCount(boolean desensitizeOpen, int count) { |
||||||
|
desensitizationLabel.setText(desensitizeOpen ? |
||||||
|
DATA_DESENSITIZATION_CONFIG + LEFT_BRACKET + count + RIGHT_BRACKET + COUNT : |
||||||
|
DATA_DESENSITIZATION_CONFIG); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 服务器数据集时,Label需要置灰 |
||||||
|
*/ |
||||||
|
public void dealWithTableDataType(boolean globalTableData) { |
||||||
|
desensitizationLabel.setForeground(globalTableData ? UIConstants.DISABLED_ICON_COLOR : UIConstants.NORMAL_BLUE); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.view.common; |
||||||
|
|
||||||
|
import com.fr.design.gui.ibutton.UIRadioButton; |
||||||
|
|
||||||
|
import javax.swing.AbstractCellEditor; |
||||||
|
import javax.swing.JTable; |
||||||
|
import javax.swing.table.TableCellEditor; |
||||||
|
import javax.swing.table.TableCellRenderer; |
||||||
|
import java.awt.Component; |
||||||
|
|
||||||
|
/** |
||||||
|
* 标记选中的CellEditor |
||||||
|
* |
||||||
|
* @author Yvan |
||||||
|
* @version 11.0 |
||||||
|
* Created by Yvan on 2022/12/20 |
||||||
|
*/ |
||||||
|
public class ChooseMark extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||||
|
|
||||||
|
private final UIRadioButton selectedButton; |
||||||
|
|
||||||
|
public ChooseMark() { |
||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,94 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.view.common; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.design.border.UITitledBorder; |
||||||
|
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 com.fr.design.layout.VerticalFlowLayout; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Desktop; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.net.URL; |
||||||
|
|
||||||
|
/** |
||||||
|
* 启用数据脱敏的面板 |
||||||
|
* |
||||||
|
* @author Yvan |
||||||
|
* @version 11.0 |
||||||
|
* Created by Yvan on 2022/10/12 |
||||||
|
*/ |
||||||
|
public class DesensitizationOpenPane extends JPanel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据脱敏启用框 |
||||||
|
*/ |
||||||
|
private UICheckBox desensitizeOpenCheckBox; |
||||||
|
|
||||||
|
/** |
||||||
|
* 跳转帮助文档Label |
||||||
|
*/ |
||||||
|
private UILabel hyperlinkLabel; |
||||||
|
|
||||||
|
/** |
||||||
|
* 启用提示Label |
||||||
|
*/ |
||||||
|
private UILabel tipsLabel; |
||||||
|
|
||||||
|
|
||||||
|
public DesensitizationOpenPane() { |
||||||
|
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP); |
||||||
|
layout.setAlignLeft(true); |
||||||
|
this.setLayout(layout); |
||||||
|
this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Report_Desensitization_Config"))); |
||||||
|
|
||||||
|
JPanel panel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); |
||||||
|
// 启用数据脱敏的勾选框
|
||||||
|
desensitizeOpenCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened")); |
||||||
|
// 跳转帮助文档Label
|
||||||
|
hyperlinkLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/tip/tips")); |
||||||
|
hyperlinkLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Open_Tips")); |
||||||
|
hyperlinkLabel.addMouseListener(new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent event) { |
||||||
|
try { |
||||||
|
URL url = new URL(Toolkit.i18nText("Fine-Design_Report_Desensitization_Help_Document_Url")); |
||||||
|
Desktop.getDesktop().browse(url.toURI()); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, "open browse of table data desensitization help document failed for {}", e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
panel.add(desensitizeOpenCheckBox); |
||||||
|
panel.add(hyperlinkLabel); |
||||||
|
|
||||||
|
// 提示Label
|
||||||
|
tipsLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Opened_Tooltips")); |
||||||
|
tipsLabel.setForeground(UIConstants.CHECK_BOX_TIP_FONT_COLOR); |
||||||
|
|
||||||
|
this.add(panel); |
||||||
|
this.add(tipsLabel); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据脱敏启用状态 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean isDesensitizationOpened() { |
||||||
|
return desensitizeOpenCheckBox.isSelected(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置数据脱敏启用状态 |
||||||
|
* @param opened |
||||||
|
*/ |
||||||
|
public void setDesensitizationOpened(boolean opened) { |
||||||
|
desensitizeOpenCheckBox.setSelected(opened); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,364 @@ |
|||||||
|
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.data.desensitize.rule.base.DesensitizationRuleStatus; |
||||||
|
import com.fr.design.data.datapane.preview.desensitization.view.common.ChooseMark; |
||||||
|
import com.fr.design.dialog.BasicDialog; |
||||||
|
import com.fr.design.dialog.DialogActionAdapter; |
||||||
|
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.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.util.LinkedHashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
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; |
||||||
|
|
||||||
|
private Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules; |
||||||
|
|
||||||
|
public DesensitizationRuleChoosePane(Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules) { |
||||||
|
this.latestRules = latestRules; |
||||||
|
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(latestRules.get(DesensitizationRuleSource.SERVER).values().toArray(new DesensitizationRule[0])); |
||||||
|
customRuleEditPane.populate(latestRules.get(DesensitizationRuleSource.CUSTOM).values().toArray(new DesensitizationRule[0])); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前选中的规则 |
||||||
|
* |
||||||
|
* @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"), |
||||||
|
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status"), |
||||||
|
}); |
||||||
|
this.parent = parent; |
||||||
|
this.debugActionOnly = debugActionOnly; |
||||||
|
this.setColumnClass(new Class[]{ |
||||||
|
ChooseMark.class, |
||||||
|
UILabel.class, |
||||||
|
UILabel.class, |
||||||
|
DesensitizationRuleStatusPane.class |
||||||
|
}); |
||||||
|
this.setDefaultEditor(ChooseMark.class, new ChooseMark()); |
||||||
|
this.setDefaultRenderer(ChooseMark.class, new ChooseMark()); |
||||||
|
this.setDefaultEditor(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane()); |
||||||
|
this.setDefaultRenderer(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane()); |
||||||
|
this.createTable().getColumnModel().getColumn(0).setMaxWidth(20); |
||||||
|
this.createTable().getColumnModel().getColumn(3).setMaxWidth(60); |
||||||
|
} |
||||||
|
|
||||||
|
@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); |
||||||
|
case 3: |
||||||
|
// 脱敏规则状态
|
||||||
|
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules); |
||||||
|
// 非正常状态需要标记为异常
|
||||||
|
return ruleStatus == DesensitizationRuleStatus.NORMAL ? StringUtils.EMPTY : Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal"); |
||||||
|
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 DesensitizationRuleStatusPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||||
|
|
||||||
|
private UILabel ruleStatusLabel; |
||||||
|
|
||||||
|
DesensitizationRuleStatusPane() { |
||||||
|
// 规则状态
|
||||||
|
this.ruleStatusLabel = new UILabel(); |
||||||
|
this.ruleStatusLabel.setForeground(Color.RED); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据脱敏规则信息,刷新规则状态,主要用于与规则选择器的联动 |
||||||
|
* |
||||||
|
* @param rule |
||||||
|
*/ |
||||||
|
public void refreshRuleStatus(DesensitizationRule rule) { |
||||||
|
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules); |
||||||
|
if (ruleStatus == DesensitizationRuleStatus.NORMAL) { |
||||||
|
// 正常规则时,重置提示Label
|
||||||
|
this.ruleStatusLabel.setText(StringUtils.EMPTY); |
||||||
|
this.ruleStatusLabel.setToolTipText(null); |
||||||
|
} else { |
||||||
|
this.ruleStatusLabel.setText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal")); |
||||||
|
this.ruleStatusLabel.setToolTipText(ruleStatus.getDescription()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
refreshRuleStatus(getList().get(row)); |
||||||
|
return ruleStatusLabel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return ruleStatusLabel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||||
|
refreshRuleStatus(getList().get(row)); |
||||||
|
return ruleStatusLabel; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 添加规则 |
||||||
|
*/ |
||||||
|
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 = null; |
||||||
|
try { |
||||||
|
selectedValue = (DesensitizationRule) getSelectedValue().clone(); |
||||||
|
} catch (CloneNotSupportedException ex) { |
||||||
|
throw new RuntimeException(ex); |
||||||
|
} |
||||||
|
DesensitizationRuleEditPane editPane = new DesensitizationRuleEditPane(getCurrentExistRuleNames(selectedValue.getRuleName())); |
||||||
|
editPane.populateBean(selectedValue); |
||||||
|
final DesensitizationRule finalRule = 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(finalRule, rule); |
||||||
|
} |
||||||
|
setSelectedValue(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 && getList().get(table.getSelectedRow()).isEnable()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
// 获取当前选中规则
|
||||||
|
DesensitizationRule selectedRule = getSelectedValue(); |
||||||
|
if (selectedRule == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
DesensitizationRuleDebugPane ruleDebugPane = new DesensitizationRuleDebugPane(selectedRule); |
||||||
|
BasicDialog ruleDebugDialog = ruleDebugPane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), null, BasicDialog.DEFAULT); |
||||||
|
ruleDebugDialog.setVisible(true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
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().getRuleTypeName()); |
||||||
|
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,309 @@ |
|||||||
|
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.DesensitizationRuleSource; |
||||||
|
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_Part_One") + StringUtils.BLANK); |
||||||
|
retainFrontTextField = new UINumberField(5); |
||||||
|
retainFrontTextField.addFocusListener(retainFrontListener); |
||||||
|
|
||||||
|
UILabel retainBackLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Two") + StringUtils.BLANK); |
||||||
|
retainBackTextField = new UINumberField(5); |
||||||
|
retainBackTextField.addFocusListener(retainBackListener); |
||||||
|
|
||||||
|
UILabel replaceLabel = new UILabel(StringUtils.BLANK + Toolkit.i18nText("Fine-Design_Report_Desensitization_Part_Three") + 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.getRuleTypeName()); |
||||||
|
ruleConditionPane.add(characterAllReplacePane, DesensitizationRuleType.ALL_CHARACTERS_REPLACE.getRuleTypeName()); |
||||||
|
// 初始化状态为字符替换
|
||||||
|
switchRuleConditionPane(DesensitizationRuleType.CHARACTER_REPLACE); |
||||||
|
|
||||||
|
panel.add(ruleConditionPane, BorderLayout.CENTER); |
||||||
|
return panel; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换规则类型面板 |
||||||
|
* |
||||||
|
* @param ruleType |
||||||
|
*/ |
||||||
|
private void switchRuleConditionPane(DesensitizationRuleType ruleType) { |
||||||
|
this.cardLayout.show(ruleConditionPane, ruleType.getRuleTypeName()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化规则类型下拉框 |
||||||
|
*/ |
||||||
|
private void initRuleTypeComboBox() { |
||||||
|
ruleTypeComboBox = new UIComboBox(Arrays.stream(DesensitizationRuleType.values()).map(DesensitizationRuleType::getRuleTypeName).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().getRuleTypeName(); |
||||||
|
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.setRuleName(this.ruleNameTextField.getText()); |
||||||
|
rule.setRuleSource(DesensitizationRuleSource.CUSTOM); |
||||||
|
DesensitizationRuleType ruleType = DesensitizationRuleType.matchByTypeName(String.valueOf(this.ruleTypeComboBox.getSelectedItem())); |
||||||
|
rule.setRuleType(ruleType); |
||||||
|
rule.getCondition().setRetainFront((int) this.retainFrontTextField.getValue()); |
||||||
|
rule.getCondition().setRetainBack((int) this.retainBackTextField.getValue()); |
||||||
|
rule.getCondition().setSymbol(ruleType == DesensitizationRuleType.CHARACTER_REPLACE ? |
||||||
|
this.firstSymbolTextField.getText() : |
||||||
|
this.secondSymbolTextField.getText()); |
||||||
|
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,89 @@ |
|||||||
|
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; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 脱敏规则展示页 |
||||||
|
* |
||||||
|
* @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 Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules; |
||||||
|
|
||||||
|
/** |
||||||
|
* 内容面板 |
||||||
|
*/ |
||||||
|
private JPanel contentPane; |
||||||
|
|
||||||
|
public DesensitizationRulePane(Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules) { |
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.latestRules = latestRules; |
||||||
|
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(latestRules); |
||||||
|
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,49 @@ |
|||||||
|
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,98 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.view.setting; |
||||||
|
|
||||||
|
import com.fr.data.desensitize.base.DesensitizationTableData; |
||||||
|
import com.fr.data.desensitize.base.TableDataDesensitizationItem; |
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.design.data.datapane.preview.desensitization.view.common.DesensitizationOpenPane; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
|
||||||
|
import javax.swing.JComponent; |
||||||
|
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<DesensitizationTableData> { |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置针对的数据集 |
||||||
|
*/ |
||||||
|
private DesensitizationTableData tableData; |
||||||
|
|
||||||
|
private DesensitizationOpenPane desensitizationOpenPane; |
||||||
|
|
||||||
|
private TableDataDesensitizationTablePane tableDataDesensitizationTablePane; |
||||||
|
|
||||||
|
|
||||||
|
public TableDataDesensitizationSettingPane(DesensitizationTableData 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() { |
||||||
|
this.desensitizationOpenPane = new DesensitizationOpenPane(); |
||||||
|
return desensitizationOpenPane; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化数据脱敏规则表面板 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private JComponent initCenterPane() { |
||||||
|
this.tableDataDesensitizationTablePane = new TableDataDesensitizationTablePane(tableData, this); |
||||||
|
return tableDataDesensitizationTablePane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return Toolkit.i18nText("Fine-Design_Report_Desensitization_Config"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(DesensitizationTableData tableData) { |
||||||
|
this.tableData = tableData; |
||||||
|
this.desensitizationOpenPane.setDesensitizationOpened(tableData.getDesensitizationConfig().isDesensitizeOpened()); |
||||||
|
tableDataDesensitizationTablePane.populateDesensitizationSetting(tableData); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DesensitizationTableData updateBean() { |
||||||
|
saveDesensitizeOpened(); |
||||||
|
saveDesensitizationBeans(tableDataDesensitizationTablePane.updateDesensitizationSetting()); |
||||||
|
return tableData; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存脱敏启用状态 |
||||||
|
*/ |
||||||
|
public void saveDesensitizeOpened() { |
||||||
|
tableData.getDesensitizationConfig().setDesensitizeOpened(this.desensitizationOpenPane.isDesensitizationOpened()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 保存脱敏规则配置信息 |
||||||
|
* |
||||||
|
* @param desensitizationItems |
||||||
|
*/ |
||||||
|
public void saveDesensitizationBeans(List<TableDataDesensitizationItem> desensitizationItems) { |
||||||
|
tableData.getDesensitizationConfig().setDesensitizationItems(desensitizationItems); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,619 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.view.setting; |
||||||
|
|
||||||
|
import com.fr.data.desensitize.base.DesensitizationTableData; |
||||||
|
import com.fr.data.desensitize.base.TableDataDesensitizationItem; |
||||||
|
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.data.desensitize.rule.base.DesensitizationRuleStatus; |
||||||
|
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.FRGUIPaneFactory; |
||||||
|
import com.fr.design.layout.TableLayout; |
||||||
|
import com.fr.design.layout.TableLayoutHelper; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import org.jetbrains.annotations.Nullable; |
||||||
|
|
||||||
|
import javax.swing.AbstractCellEditor; |
||||||
|
import javax.swing.JComponent; |
||||||
|
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.BorderLayout; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
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<TableDataDesensitizationItem> { |
||||||
|
|
||||||
|
private static final String APOSTROPHE = "..."; |
||||||
|
|
||||||
|
private static final String COMMA = ","; |
||||||
|
|
||||||
|
/** |
||||||
|
* 当前数据集的所有列名 |
||||||
|
*/ |
||||||
|
private List<String> columnNames = new ArrayList<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* key为用户组唯一标识(id拼接),value为用户组名称 |
||||||
|
*/ |
||||||
|
private Map<String, String> roleMap = new LinkedHashMap<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 当前最新的所有规则 |
||||||
|
*/ |
||||||
|
private Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules = new LinkedHashMap<>(); |
||||||
|
|
||||||
|
private Component parent; |
||||||
|
|
||||||
|
public TableDataDesensitizationTableModel(DesensitizationTableData tableData, Component parent, List<String> columnNames, Map<String, String> roleMap, Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules) { |
||||||
|
// table相关
|
||||||
|
super(new String[]{ |
||||||
|
Toolkit.i18nText("Fine-Design_Report_Desensitization_Column"), |
||||||
|
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule"), |
||||||
|
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Description"), |
||||||
|
Toolkit.i18nText("Fine-Design_Report_Desensitization_Effected_Roles"), |
||||||
|
Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status"), |
||||||
|
}); |
||||||
|
this.parent = parent; |
||||||
|
this.columnNames = columnNames; |
||||||
|
this.roleMap = roleMap; |
||||||
|
this.latestRules = latestRules; |
||||||
|
|
||||||
|
initTable(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化Table |
||||||
|
*/ |
||||||
|
private void initTable() { |
||||||
|
this.setColumnClass(new Class[]{ |
||||||
|
// 列名选择
|
||||||
|
ColumnNamesComboBox.class, |
||||||
|
// 规则选择
|
||||||
|
DesensitizationRuleChooser.class, |
||||||
|
// 规则详情展示
|
||||||
|
DesensitizationRuleDescriptionPane.class, |
||||||
|
// 生效用户组选择
|
||||||
|
EffectedRolesChooser.class, |
||||||
|
// 规则状态
|
||||||
|
DesensitizationRuleStatusPane.class |
||||||
|
}); |
||||||
|
ColumnNamesComboBox columnNamesComboBox = new ColumnNamesComboBox(); |
||||||
|
this.setDefaultEditor(ColumnNamesComboBox.class, columnNamesComboBox); |
||||||
|
this.setDefaultEditor(DesensitizationRuleChooser.class, new DesensitizationRuleChooser()); |
||||||
|
this.setDefaultEditor(DesensitizationRuleDescriptionPane.class, new DesensitizationRuleDescriptionPane()); |
||||||
|
EffectedRolesChooser effectedRolesChooser = new EffectedRolesChooser(); |
||||||
|
this.setDefaultEditor(EffectedRolesChooser.class, effectedRolesChooser); |
||||||
|
this.setDefaultEditor(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane()); |
||||||
|
this.setDefaultRenderer(DesensitizationRuleStatusPane.class, new DesensitizationRuleStatusPane()); |
||||||
|
|
||||||
|
this.createTable().getColumnModel().getColumn(TableSequences.DesensitizationRuleStatus.getNum()).setMaxWidth(60); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) { |
||||||
|
TableDataDesensitizationItem desensitizationItem = this.getList().get(rowIndex); |
||||||
|
TableSequences match = TableSequences.match(columnIndex); |
||||||
|
switch (match) { |
||||||
|
case ColumnName: |
||||||
|
// 选中的数据集字段名称
|
||||||
|
return desensitizationItem.getColumnName(); |
||||||
|
case DesensitizationRule: |
||||||
|
// 脱敏规则名称
|
||||||
|
return desensitizationItem.getRule().getRuleName(); |
||||||
|
case DesensitizationRuleDescription: |
||||||
|
// 脱敏规则详情
|
||||||
|
return DesensitizationRule.getDescription(desensitizationItem.getRule()); |
||||||
|
case EffectedRoles: |
||||||
|
// 生效用户组
|
||||||
|
return matchRoleNamesByIds(desensitizationItem.getRoleIds()); |
||||||
|
case DesensitizationRuleStatus: |
||||||
|
// 规则状态
|
||||||
|
return needMarkRule(desensitizationItem.getRule()) ? StringUtils.EMPTY : Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal"); |
||||||
|
default: |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过id匹配此用户组对应的部门职位名称(或者说自定义角色名称),并拼接成字符串返回 |
||||||
|
* |
||||||
|
* @param roleIds |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private String matchRoleNamesByIds(Collection<String> roleIds) { |
||||||
|
StringBuilder builder = new StringBuilder(); |
||||||
|
for (String roleId : roleIds) { |
||||||
|
if (roleMap != null && roleMap.containsKey(roleId)) { |
||||||
|
builder.append(roleMap.get(roleId)); |
||||||
|
builder.append(COMMA); |
||||||
|
} |
||||||
|
} |
||||||
|
return builder.length() <= 1 ? StringUtils.EMPTY : builder.substring(0, builder.length() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isCellEditable(int row, int col) { |
||||||
|
TableSequences match = TableSequences.match(col); |
||||||
|
return match != TableSequences.DesensitizationRuleStatus; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public UITableEditAction[] createAction() { |
||||||
|
return new UITableEditAction[]{ |
||||||
|
new AddDesensitizationAction(), |
||||||
|
new RemoveDesensitizationAction(parent), |
||||||
|
new RefreshTableAction(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前选中的item,可能为null |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Nullable |
||||||
|
private TableDataDesensitizationItem getCurrentSelectBean() { |
||||||
|
return table.getSelectedRow() == -1 ? |
||||||
|
null : |
||||||
|
getList().get(table.getSelectedRow()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 列名选择下拉框 |
||||||
|
*/ |
||||||
|
private class ColumnNamesComboBox extends AbstractCellEditor implements TableCellEditor { |
||||||
|
|
||||||
|
private UIComboBox columnNameComboBox; |
||||||
|
|
||||||
|
ColumnNamesComboBox() { |
||||||
|
columnNameComboBox = new UIComboBox(columnNames.toArray(new String[0])); |
||||||
|
this.addCellEditorListener(new CellEditorListener() { |
||||||
|
@Override |
||||||
|
public void editingStopped(ChangeEvent e) { |
||||||
|
|
||||||
|
TableDataDesensitizationItem desensitizationItem = getCurrentSelectBean(); |
||||||
|
if (Objects.nonNull(desensitizationItem)) { |
||||||
|
desensitizationItem.setColumnName(columnNames.get(columnNameComboBox.getSelectedIndex())); |
||||||
|
fireTableDataChanged(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void editingCanceled(ChangeEvent e) { |
||||||
|
|
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
columnNameComboBox.setSelectedItem(getList().get(row).getColumnName()); |
||||||
|
return columnNameComboBox; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
Object selectedItem = columnNameComboBox.getSelectedItem(); |
||||||
|
return Objects.isNull(selectedItem) ? StringUtils.EMPTY : selectedItem.toString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class DesensitizationRuleChooser extends AbstractCellEditor implements TableCellEditor { |
||||||
|
/** |
||||||
|
* 规则选择页面 |
||||||
|
*/ |
||||||
|
private JPanel choosePane; |
||||||
|
/** |
||||||
|
* 规则名称 |
||||||
|
*/ |
||||||
|
private UITextField ruleNameTextField; |
||||||
|
/** |
||||||
|
* 规则选择按钮 |
||||||
|
*/ |
||||||
|
private UIButton chooseButton; |
||||||
|
|
||||||
|
private ActionListener chooseRuleListener = new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
// 重新获取一下本地规则缓存
|
||||||
|
refreshCustomRuleCache(); |
||||||
|
DesensitizationRulePane rulePane = new DesensitizationRulePane(latestRules); |
||||||
|
TableDataDesensitizationItem desensitizationItem = getCurrentSelectBean(); |
||||||
|
int selectedRow = table.getSelectedRow(); |
||||||
|
BasicDialog ruleDialog = rulePane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
DesensitizationRule rule = rulePane.updateBean(); |
||||||
|
if (Objects.nonNull(desensitizationItem) && DesensitizationRule.valid(rule)) { |
||||||
|
desensitizationItem.setRule(rule); |
||||||
|
desensitizationItem.setRuleName(rule.getRuleName()); |
||||||
|
// 刷新规则名称、描述、状态
|
||||||
|
ruleNameTextField.setText(rule.getRuleName()); |
||||||
|
fireTableDataChanged(); |
||||||
|
table.getSelectionModel().setSelectionInterval(selectedRow, selectedRow); |
||||||
|
} |
||||||
|
} |
||||||
|
}, BasicDialog.DEFAULT); |
||||||
|
ruleDialog.setVisible(true); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
DesensitizationRuleChooser() { |
||||||
|
// 规则名称展示
|
||||||
|
ruleNameTextField = new UITextField(); |
||||||
|
ruleNameTextField.setEnabled(false); |
||||||
|
// 规则选择按钮
|
||||||
|
chooseButton = new UIButton(APOSTROPHE); |
||||||
|
chooseButton.setToolTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Click_To_Choose_Rule")); |
||||||
|
chooseButton.addActionListener(chooseRuleListener); |
||||||
|
// 规则选择页面
|
||||||
|
Component[][] templateChooserComponent = {{ruleNameTextField, chooseButton}}; |
||||||
|
double[] rowSize = {TableLayout.PREFERRED}; |
||||||
|
double[] columnSize = {TableLayout.FILL, 22}; |
||||||
|
choosePane = TableLayoutHelper.createCommonTableLayoutPane(templateChooserComponent, rowSize, columnSize, 0); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
ruleNameTextField.setText(getList().get(row).getRule().getRuleName()); |
||||||
|
return choosePane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return ruleNameTextField.getText(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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)); |
||||||
|
this.descriptionLabel.setToolTipText(this.descriptionLabel.getText()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
refreshDescription(getList().get(row).getRule()); |
||||||
|
return descriptionLabel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return this.descriptionLabel.getText(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 生效用户组复选框 |
||||||
|
*/ |
||||||
|
private class EffectedRolesChooser extends AbstractCellEditor implements TableCellEditor { |
||||||
|
|
||||||
|
private UIComboCheckBox rolesCheckBox; |
||||||
|
|
||||||
|
EffectedRolesChooser() { |
||||||
|
this.rolesCheckBox = new UIComboCheckBox(roleMap.values().toArray(), true) { |
||||||
|
@Override |
||||||
|
protected void setLayoutAndAddComponents() { |
||||||
|
// 使用BorderLayout,否则默认使用的FlowLayout会让整个下拉选框使用最小Size,然后TableCell这边会出现空白
|
||||||
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
||||||
|
this.add(getEditor(), BorderLayout.CENTER); |
||||||
|
this.add(getArrowButton(), BorderLayout.EAST); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setEditorToolTipText(JComponent editor, String text) { |
||||||
|
// 选项过多时,已选中的值会做省略显示处理,此处添加一个Tooltips,显示完整值
|
||||||
|
if (text != null) { |
||||||
|
editor.setToolTipText(text); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
this.addCellEditorListener(new CellEditorListener() { |
||||||
|
@Override |
||||||
|
public void editingStopped(ChangeEvent e) { |
||||||
|
TableDataDesensitizationItem desensitizationItem = getCurrentSelectBean(); |
||||||
|
if (Objects.nonNull(desensitizationItem)) { |
||||||
|
desensitizationItem.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 desensitizationItem |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private Map<Object, Boolean> generateRolesCheckBoxSelectedValues(TableDataDesensitizationItem desensitizationItem) { |
||||||
|
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 (desensitizationItem.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(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 规则状态展示页面 |
||||||
|
*/ |
||||||
|
private class DesensitizationRuleStatusPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { |
||||||
|
|
||||||
|
private UILabel ruleStatusLabel; |
||||||
|
|
||||||
|
DesensitizationRuleStatusPane() { |
||||||
|
// 规则状态
|
||||||
|
this.ruleStatusLabel = new UILabel(); |
||||||
|
this.ruleStatusLabel.setForeground(Color.RED); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据脱敏规则信息,刷新规则状态,主要用于与规则选择器的联动 |
||||||
|
* |
||||||
|
* @param currentItem |
||||||
|
*/ |
||||||
|
public void refreshRuleStatus(TableDataDesensitizationItem currentItem) { |
||||||
|
DesensitizationRule rule = currentItem.getRule(); |
||||||
|
if (needMarkRule(rule)) { |
||||||
|
// 非正常规则,根据规则状态展示不同提示文字
|
||||||
|
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules); |
||||||
|
this.ruleStatusLabel.setText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Status_Abnormal")); |
||||||
|
this.ruleStatusLabel.setToolTipText(ruleStatus.getDescription()); |
||||||
|
} else { |
||||||
|
// 正常规则,重置提示Label
|
||||||
|
this.ruleStatusLabel.setText(StringUtils.EMPTY); |
||||||
|
this.ruleStatusLabel.setToolTipText(null); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
refreshRuleStatus(getList().get(row)); |
||||||
|
return ruleStatusLabel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getCellEditorValue() { |
||||||
|
return ruleStatusLabel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
||||||
|
refreshRuleStatus(getList().get(row)); |
||||||
|
return ruleStatusLabel; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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(TableDataDesensitizationItem.createDefault()); |
||||||
|
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); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class RefreshTableAction extends UITableEditAction { |
||||||
|
|
||||||
|
public RefreshTableAction() { |
||||||
|
this.setName(Toolkit.i18nText("Fine-Design_Basic_Refresh")); |
||||||
|
this.setSmallIcon("/com/fr/design/standard/refresh/refresh", false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
// 刷新TableData的规则,主要是为了自动替换掉平台中被修改的规则
|
||||||
|
List<TableDataDesensitizationItem> items = getList(); |
||||||
|
Iterator<TableDataDesensitizationItem> iterator = items.iterator(); |
||||||
|
while (iterator.hasNext()) { |
||||||
|
TableDataDesensitizationItem item = iterator.next(); |
||||||
|
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(item.getRule(), latestRules); |
||||||
|
if (ruleStatus == DesensitizationRuleStatus.REMOVED) { |
||||||
|
// 规则被移除,则删除整条脱敏Item
|
||||||
|
iterator.remove(); |
||||||
|
} else { |
||||||
|
// 规则被修改、禁用等,更新一下规则
|
||||||
|
item.setRule(DesensitizationRuleManager.getInstance().getLastedDesentizationRule(item.getRule(), latestRules)); |
||||||
|
} |
||||||
|
} |
||||||
|
fireTableDataChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkEnabled() {} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 规则表-列字段编号 |
||||||
|
*/ |
||||||
|
private enum TableSequences { |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据集列名选择 |
||||||
|
*/ |
||||||
|
ColumnName(0), |
||||||
|
|
||||||
|
/** |
||||||
|
* 规则选择 |
||||||
|
*/ |
||||||
|
DesensitizationRule(1), |
||||||
|
|
||||||
|
/** |
||||||
|
* 规则描述 |
||||||
|
*/ |
||||||
|
DesensitizationRuleDescription(2), |
||||||
|
|
||||||
|
/** |
||||||
|
* 规则生效用户组 |
||||||
|
*/ |
||||||
|
EffectedRoles(3), |
||||||
|
|
||||||
|
/** |
||||||
|
* 规则状态 |
||||||
|
*/ |
||||||
|
DesensitizationRuleStatus(4), |
||||||
|
|
||||||
|
/** |
||||||
|
* 未知,用于无法匹配时的返回 |
||||||
|
*/ |
||||||
|
Unknown(100); |
||||||
|
|
||||||
|
|
||||||
|
private int num; |
||||||
|
|
||||||
|
TableSequences(int num) { |
||||||
|
this.num = num; |
||||||
|
} |
||||||
|
|
||||||
|
public int getNum() { |
||||||
|
return num; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据列序号匹配列字段 |
||||||
|
* |
||||||
|
* @param num |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static TableSequences match(int num) { |
||||||
|
for (TableSequences value : TableSequences.values()) { |
||||||
|
if (value.getNum() == num) { |
||||||
|
return value; |
||||||
|
} |
||||||
|
} |
||||||
|
return Unknown; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 是否需要对异常规则做标记,需要满足 |
||||||
|
* 1. 规则非默认空规则 |
||||||
|
* 2. 规则本身异常 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private boolean needMarkRule(DesensitizationRule rule) { |
||||||
|
return !rule.equals(DesensitizationRule.createDefaultEmptyRule()) && |
||||||
|
DesensitizationRuleManager.getInstance().getRuleStatus(rule, latestRules) != DesensitizationRuleStatus.NORMAL; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 刷新当前页面的本地规则缓存,查询最新本地规则的逻辑也是使用了缓存,因此无需考虑耗时 |
||||||
|
*/ |
||||||
|
private void refreshCustomRuleCache() { |
||||||
|
Map<String, DesensitizationRule> customRules = DesensitizationRuleManager.getInstance().getRulesBySource(DesensitizationRuleSource.CUSTOM); |
||||||
|
latestRules.put(DesensitizationRuleSource.CUSTOM, customRules); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,153 @@ |
|||||||
|
package com.fr.design.data.datapane.preview.desensitization.view.setting; |
||||||
|
|
||||||
|
import com.fr.base.operator.org.OrganizationOperator; |
||||||
|
import com.fr.data.desensitize.base.DesensitizationTableData; |
||||||
|
import com.fr.data.desensitize.base.TableDataDesensitizationItem; |
||||||
|
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.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager; |
||||||
|
import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane; |
||||||
|
import com.fr.design.gui.itableeditorpane.UITableEditorPane; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingWorker; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.CardLayout; |
||||||
|
import java.awt.Component; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* 脱敏字段设置页面中的Table |
||||||
|
* |
||||||
|
* @author Yvan |
||||||
|
* @version 11.0 |
||||||
|
* Created by Yvan on 2022/9/14 |
||||||
|
*/ |
||||||
|
public class TableDataDesensitizationTablePane extends JPanel { |
||||||
|
|
||||||
|
/** |
||||||
|
* 脱敏数据集 |
||||||
|
*/ |
||||||
|
private DesensitizationTableData tableData; |
||||||
|
|
||||||
|
/** |
||||||
|
* 父页面 |
||||||
|
*/ |
||||||
|
private Component parent; |
||||||
|
|
||||||
|
/** |
||||||
|
* 脱敏信息Table |
||||||
|
*/ |
||||||
|
private UITableEditorPane<TableDataDesensitizationItem> editorPane; |
||||||
|
|
||||||
|
private static final String LOADING_PANE = "loading"; |
||||||
|
private static final String CONTENT_PANE = "content"; |
||||||
|
|
||||||
|
private CardLayout card; |
||||||
|
|
||||||
|
private JPanel loadingPane; |
||||||
|
|
||||||
|
private JPanel contentPane; |
||||||
|
|
||||||
|
public TableDataDesensitizationTablePane(DesensitizationTableData tableData, Component parent) { |
||||||
|
this.tableData = tableData; |
||||||
|
this.parent = parent; |
||||||
|
initComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponent() { |
||||||
|
|
||||||
|
card = new CardLayout(); |
||||||
|
this.setLayout(card); |
||||||
|
// 初始化Loading面板
|
||||||
|
loadingPane = new TipsPane(true); |
||||||
|
this.add(LOADING_PANE, loadingPane); |
||||||
|
switchTo(LOADING_PANE); |
||||||
|
|
||||||
|
// 在SwingWorker中初始化Content面板并切换
|
||||||
|
initContent(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化内容面板 |
||||||
|
* 考虑到远程设计下的性能,需要限制查询数据库的次数,所以这里查一次,之后子面板内复用 |
||||||
|
*/ |
||||||
|
private void initContent() { |
||||||
|
final List<String> columnNames = new ArrayList<>(); |
||||||
|
final Map<String, String> roleMap = new LinkedHashMap<>(); |
||||||
|
final Map<DesensitizationRuleSource, Map<String, DesensitizationRule>> latestRules = new LinkedHashMap<>(); |
||||||
|
new SwingWorker<Void, Void>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Void doInBackground() throws Exception { |
||||||
|
// 获取当前数据集的所有列名
|
||||||
|
columnNames.addAll(TableDataPreviewDesensitizeManager.getInstance().getColumnNamesByTableData(tableData)); |
||||||
|
// 获取当前所有用户组
|
||||||
|
roleMap.putAll(WorkContext.getCurrent().get(OrganizationOperator.class).getAllRoles4Desensitization()); |
||||||
|
// 获取当前最新的所有规则
|
||||||
|
latestRules.putAll(DesensitizationRuleManager.getInstance().getAllRules()); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void done() { |
||||||
|
contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
editorPane = new UITableEditorPane<>(new TableDataDesensitizationTableModel(tableData, parent, columnNames, roleMap, latestRules)); |
||||||
|
editorPane.setHeaderResizing(false); |
||||||
|
editorPane.populate(tableData.getDesensitizationConfig().getDesensitizationItems().toArray(new TableDataDesensitizationItem[0])); |
||||||
|
contentPane.add(editorPane, BorderLayout.CENTER); |
||||||
|
add(CONTENT_PANE, contentPane); |
||||||
|
switchTo(CONTENT_PANE); |
||||||
|
} |
||||||
|
}.execute(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换面板 |
||||||
|
* |
||||||
|
* @param panelName |
||||||
|
*/ |
||||||
|
public void switchTo(String panelName) { |
||||||
|
try { |
||||||
|
if (panelName != null) { |
||||||
|
card.show(this, panelName); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 展示此TableData中已配置的脱敏规则信息 |
||||||
|
* |
||||||
|
* @param tableData |
||||||
|
*/ |
||||||
|
public void populateDesensitizationSetting(DesensitizationTableData tableData) { |
||||||
|
this.tableData = tableData; |
||||||
|
if (editorPane != null) { |
||||||
|
// editorPane的初始化在SwingWorker中完成,这里做个判空
|
||||||
|
editorPane.populate(tableData.getDesensitizationConfig().getDesensitizationItems().toArray(new TableDataDesensitizationItem[0])); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前对TableData的配置脱敏规则信息 |
||||||
|
*/ |
||||||
|
public List<TableDataDesensitizationItem> updateDesensitizationSetting() { |
||||||
|
|
||||||
|
return editorPane == null ? |
||||||
|
new ArrayList<>() : |
||||||
|
editorPane.update() |
||||||
|
.stream() |
||||||
|
.filter(item -> TableDataDesensitizationItem.valid(item)) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@ |
|||||||
|
package com.fr.design.fun; |
||||||
|
|
||||||
|
import com.fr.base.Utils; |
||||||
|
import com.fr.base.chart.BaseChartCollection; |
||||||
|
import com.fr.chartx.attr.ChartProvider; |
||||||
|
import com.fr.general.FRFont; |
||||||
|
import com.fr.report.cell.CellElement; |
||||||
|
import com.fr.stable.fun.mark.Selectable; |
||||||
|
|
||||||
|
import java.awt.Font; |
||||||
|
|
||||||
|
/** |
||||||
|
* 主要用于fvs报表块内元素默认值的调整,以达到所见所得效果,后续fvs内置后删除 |
||||||
|
*/ |
||||||
|
public interface DefaultValueAdjustProvider extends Selectable { |
||||||
|
String MARK_STRING = "DefaultValueAdjustProvider"; |
||||||
|
int CURRENT_LEVEL = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* 调整单元格对象默认值 |
||||||
|
* |
||||||
|
* @param cellElement |
||||||
|
*/ |
||||||
|
void adjustCellElement(CellElement cellElement); |
||||||
|
|
||||||
|
/** |
||||||
|
* 调整富文本默认值 |
||||||
|
* |
||||||
|
* @param fontSize |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
int adjustRichTextTransform(int fontSize, double transformedFontSize); |
||||||
|
|
||||||
|
/** |
||||||
|
* 调整ChartCollection |
||||||
|
* |
||||||
|
* @param chartCollection |
||||||
|
*/ |
||||||
|
void adjustChartCollectionStyle(BaseChartCollection chartCollection); |
||||||
|
|
||||||
|
/** |
||||||
|
* 调整图表 |
||||||
|
* |
||||||
|
* @param chartProvider |
||||||
|
*/ |
||||||
|
void adjustChart(ChartProvider chartProvider); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 转成当前分辨率下显示的font |
||||||
|
* @param font |
||||||
|
* @param resolution |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
Font transformFontByResolution(FRFont font, int resolution); |
||||||
|
|
||||||
|
/** |
||||||
|
* 修改设计可用字体默认列表 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
default String[] getAvailableFontFamilyNames4Report() { |
||||||
|
return Utils.getAvailableFontFamilyNames4Report(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fr.design.fun; |
||||||
|
|
||||||
|
import com.fr.design.beans.BasicBeanPane; |
||||||
|
import com.fr.stable.fun.mark.Mutable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 设计器模板主题管理-细节定制部分,支持添加tab |
||||||
|
* |
||||||
|
* @author Bruce.Deng |
||||||
|
* @version 11.0 |
||||||
|
* Created by Bruce.Deng on 2023/2/7 |
||||||
|
*/ |
||||||
|
public interface TemplateThemePaneProvider<T> extends Mutable { |
||||||
|
|
||||||
|
String XML_TAG = "TemplateThemePaneProvider"; |
||||||
|
|
||||||
|
int CURRENT_LEVEL = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* 插入tab的位置 |
||||||
|
* |
||||||
|
* @param total 已插入的tab数 |
||||||
|
* @return 插入位置,如果想放到最后,则返回-1 |
||||||
|
*/ |
||||||
|
int getInsertPosition(int total); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取tab对象 |
||||||
|
* |
||||||
|
* @return tab对象 |
||||||
|
*/ |
||||||
|
BasicBeanPane<T> getTab(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.fr.design.fun.impl; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.design.fun.DefaultValueAdjustProvider; |
||||||
|
import com.fr.stable.fun.assist.Selector; |
||||||
|
import com.fr.stable.fun.impl.AbstractProvider; |
||||||
|
import com.fr.stable.fun.mark.API; |
||||||
|
|
||||||
|
@API(level = DefaultValueAdjustProvider.CURRENT_LEVEL) |
||||||
|
public abstract class AbstractDefaultValueAdjustProvider extends AbstractProvider implements DefaultValueAdjustProvider { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int currentAPILevel() { |
||||||
|
return CURRENT_LEVEL; |
||||||
|
} |
||||||
|
|
||||||
|
public String mark4Provider() { |
||||||
|
return this.getClass().getName(); |
||||||
|
} |
||||||
|
|
||||||
|
public Selector selector() { |
||||||
|
return Selector.ALWAYS; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.fr.design.fun.impl; |
||||||
|
|
||||||
|
import com.fr.design.fun.TemplateThemePaneProvider; |
||||||
|
import com.fr.stable.fun.impl.AbstractProvider; |
||||||
|
import com.fr.stable.fun.mark.API; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bruce.Deng |
||||||
|
* @version 11.0 |
||||||
|
* @see TemplateThemePaneProvider |
||||||
|
* Created by Bruce.Deng on 2023/2/7 |
||||||
|
*/ |
||||||
|
@API(level = TemplateThemePaneProvider.CURRENT_LEVEL) |
||||||
|
public abstract class AbstractTemplateThemePaneProvider<T> extends AbstractProvider implements TemplateThemePaneProvider<T> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int currentAPILevel() { |
||||||
|
return CURRENT_LEVEL; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String mark4Provider() { |
||||||
|
return getClass().getName(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.fr.design.gui.style; |
||||||
|
|
||||||
|
import com.fr.base.Style; |
||||||
|
import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; |
||||||
|
import com.fr.design.gui.frpane.AttributeChangeListener; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dimension; |
||||||
|
|
||||||
|
/** |
||||||
|
* 封装格式panel,管理 AttributeChangeListener |
||||||
|
* |
||||||
|
* @author Leo.Qin |
||||||
|
* @version 11.0 |
||||||
|
* Created by Leo.Qin on 2022/10/31 |
||||||
|
*/ |
||||||
|
public class TextFormatPaneContainer extends AbstractAttrNoScrollPane { |
||||||
|
private TextFormatPane formatPane; |
||||||
|
private AttributeChangeListener oldListner; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected JPanel createContentPane() { |
||||||
|
formatPane = new TextFormatPane(); |
||||||
|
return formatPane; |
||||||
|
} |
||||||
|
|
||||||
|
protected void initContentPane() { |
||||||
|
leftContentPane = createContentPane(); |
||||||
|
if (leftContentPane != null) { |
||||||
|
leftContentPane.setBorder(BorderFactory.createEmptyBorder()); |
||||||
|
this.add(leftContentPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize() { |
||||||
|
if (formatPane == null) { |
||||||
|
return super.getPreferredSize(); |
||||||
|
} |
||||||
|
return formatPane.getPreferredSize(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据单元格样式填充面板设置 |
||||||
|
* |
||||||
|
* @param style 单元格样式 |
||||||
|
*/ |
||||||
|
public void populateBean(Style style) { |
||||||
|
formatPane.populateBean(style); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据面板设置获取修改后的单元格样式 |
||||||
|
* |
||||||
|
* @param style 单元格当前样式 |
||||||
|
* @return 更新后的单元格样式 |
||||||
|
*/ |
||||||
|
public Style update(Style style) { |
||||||
|
return formatPane.update(style); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeAttributeChangeListener() { |
||||||
|
super.removeAttributeChangeListener(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addAttributeChangeListener(AttributeChangeListener listener) { |
||||||
|
oldListner = listener; |
||||||
|
super.addAttributeChangeListener(listener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 恢复使用AttributeChangeListener |
||||||
|
*/ |
||||||
|
public void restoreAttributeChangeListener() { |
||||||
|
super.addAttributeChangeListener(oldListner); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.base.AutoChangeLineProvider; |
||||||
|
import com.fr.base.DefaultAutoChangeLine; |
||||||
|
import com.fr.base.ScreenResolution; |
||||||
|
import com.fr.design.fun.ReportLengthUNITProvider; |
||||||
|
import com.fr.design.unit.UnitConvertUtil; |
||||||
|
|
||||||
|
public class AbsoluteMeasureUIMode implements DesignerUIMode { |
||||||
|
|
||||||
|
private static class AbsoluteMeasureUIModeHolder { |
||||||
|
private static final AbsoluteMeasureUIMode absoluteMeasureUIMode = new AbsoluteMeasureUIMode(); |
||||||
|
} |
||||||
|
|
||||||
|
private AbsoluteMeasureUIMode() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static AbsoluteMeasureUIMode getInstance() { |
||||||
|
return AbsoluteMeasureUIModeHolder.absoluteMeasureUIMode; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ReportLengthUNITProvider parseLengthUNIT(int unitType) { |
||||||
|
return UnitConvertUtil.parseLengthUNIT(unitType); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AutoChangeLineProvider getAutoChangeLineStrategy() { |
||||||
|
return new DefaultAutoChangeLine(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getScreenResolution() { |
||||||
|
return ScreenResolution.getScreenResolution(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.base.AutoChangeLineProvider;; |
||||||
|
import com.fr.design.fun.ReportLengthUNITProvider; |
||||||
|
|
||||||
|
/** |
||||||
|
* 设计器上和展示相关配置 |
||||||
|
*/ |
||||||
|
public interface DesignerUIMode { |
||||||
|
|
||||||
|
ReportLengthUNITProvider parseLengthUNIT(int unitType); |
||||||
|
|
||||||
|
AutoChangeLineProvider getAutoChangeLineStrategy(); |
||||||
|
|
||||||
|
int getScreenResolution(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.base.AutoChangeLineProvider; |
||||||
|
import com.fr.design.fun.ReportLengthUNITProvider; |
||||||
|
import com.fr.form.fit.NewUIModeAutoChangeLine; |
||||||
|
import com.fr.stable.Constants; |
||||||
|
|
||||||
|
public class SimulateWebUIMode implements DesignerUIMode { |
||||||
|
|
||||||
|
private static class SimulateWebUIModeHolder { |
||||||
|
private static final SimulateWebUIMode simulateWebUIMode = new SimulateWebUIMode(); |
||||||
|
} |
||||||
|
|
||||||
|
private SimulateWebUIMode() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static SimulateWebUIMode getInstance() { |
||||||
|
return SimulateWebUIModeHolder.simulateWebUIMode; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public ReportLengthUNITProvider parseLengthUNIT(int unitType) { |
||||||
|
return new PXReportLengthUNIT(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AutoChangeLineProvider getAutoChangeLineStrategy() { |
||||||
|
return new NewUIModeAutoChangeLine(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getScreenResolution() { |
||||||
|
return Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.fr.design.mainframe.platform; |
||||||
|
|
||||||
|
import com.fr.design.actions.UpdateAction; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.utils.BrowseUtils; |
||||||
|
import com.fr.general.CloudCenter; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.awt.Desktop; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.net.URI; |
||||||
|
|
||||||
|
/** |
||||||
|
* 帮助-服务平台 |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @version 11.0 |
||||||
|
* created by Destiny.Lin on 2022-12-14 |
||||||
|
*/ |
||||||
|
public class ServicePlatformAction extends UpdateAction { |
||||||
|
public ServicePlatformAction() { |
||||||
|
this.setName(Toolkit.i18nText("Fine-Design_Basic_Service_Platform_Title")); |
||||||
|
this.setSmallIcon("/com/fr/design/images/platform/platform", false); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
BrowseUtils.browser(CloudCenter.getInstance().acquireUrlByKind("service.platform")); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package com.fr.design.mainframe.theme.processor; |
||||||
|
|
||||||
|
import com.fr.stable.fun.mark.API; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bruce.Deng |
||||||
|
* @version 11.0 |
||||||
|
* Created by Bruce.Deng on 2023/2/14 |
||||||
|
*/ |
||||||
|
@API(level = ThemePreviewPaneProcessor.CURRENT_LEVEL) |
||||||
|
public abstract class AbstractThemePreviewPaneProcessor implements ThemePreviewPaneProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int currentAPILevel() { |
||||||
|
return CURRENT_LEVEL; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int layerIndex() { |
||||||
|
return DEFAULT_LAYER_INDEX; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package com.fr.design.mainframe.theme.processor; |
||||||
|
|
||||||
|
import com.fr.base.theme.FormTheme; |
||||||
|
import com.fr.base.theme.ReportTheme; |
||||||
|
import com.fr.design.mainframe.theme.TemplateThemePreviewPane; |
||||||
|
import com.fr.stable.fun.mark.Immutable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 主题样式预览界面接口 |
||||||
|
* |
||||||
|
* @author Bruce.Deng |
||||||
|
* @version 11.0 |
||||||
|
* Created by Bruce.Deng on 2023/2/14 |
||||||
|
*/ |
||||||
|
public interface ThemePreviewPaneProcessor extends Immutable { |
||||||
|
|
||||||
|
String XML_TAG = "ThemePreviewPaneProcessor"; |
||||||
|
|
||||||
|
int CURRENT_LEVEL = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建报表主题样式预览界面 |
||||||
|
* |
||||||
|
* @return 报表主题样式预览界面 |
||||||
|
*/ |
||||||
|
TemplateThemePreviewPane<ReportTheme> createReportThemePreviewPane(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建决策报表主题样式预览界面 |
||||||
|
* |
||||||
|
* @return 决策报表主题样式预览界面 |
||||||
|
*/ |
||||||
|
TemplateThemePreviewPane<FormTheme> createFormThemePreviewPane(); |
||||||
|
|
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue