Browse Source

Pull request #4454: REPORT-52525 设计器数据集查询界面增加复制传参后sql的功能

Merge in DESIGN/design from ~BRUCE.DENG/design:feature/10.0 to feature/10.0

* commit '188c446450aef515c386bee7db08f2c3589d021b':
  REPORT-52525 设计器数据集查询界面增加复制传参后sql的功能
  REPORT-52525 设计器数据集查询界面增加复制传参后sql的功能
feature/10.0
Bruce.Deng 3 years ago
parent
commit
e05ccd5f2c
  1. 277
      designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java
  2. 17
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  3. 17
      designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java
  4. 1
      designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java
  5. BIN
      designer-base/src/main/resources/com/fr/design/images/lookandfeel/TipIcon.png
  6. BIN
      designer-base/src/main/resources/com/fr/design/images/m_file/preview_sql.png

277
designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java

@ -0,0 +1,277 @@
package com.fr.design.data.datapane.preview.sql;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.base.ParameterMapNameSpace;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EscapeSqlHelper;
import com.fr.data.operator.DataOperator;
import com.fr.decision.webservice.v10.config.ConfigService;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.parameter.ParameterInputPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.injectable.PluginModule;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.TableDataProvider;
import com.fr.stable.plugin.ExtraClassManagerProvider;
import com.fr.stable.script.NameSpace;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Frame;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
public class PreviewPerformedSqlPane extends JDialog implements ActionListener {
private JPanel topPanel;
private JPanel centerPanel;
private JPanel bottomPanel;
private UILabel imageLabel;
public PreviewPerformedSqlPane(Frame frame, String sql) {
this(frame, sql, null, null, false);
}
public PreviewPerformedSqlPane(Frame frame, String sql, List<int[]> selectedSpecialCharIndex, String[] selectedSpecialChar, boolean highlight) {
super(frame, true);
// 提示信息
topPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
JPanel imagePanel = new JPanel();
JPanel messagePanel;
if (isShowSpecialCharSqlPane(selectedSpecialCharIndex)) {
imageLabel = new UILabel(UIManager.getIcon("OptionPane.warningIcon"));
messagePanel = new JPanel();
messagePanel.setLayout(FRGUIPaneFactory.createBorderLayout());
messagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
// 日韩取消超链,直接显示文字
if (isNotShowLink()) {
JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql_Message") + Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention") + Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Back_Message"));
messagePanel.add(label);
} else {
MessageWithLink message = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Front_Message"), Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention"), CloudCenter.getInstance().acquireConf(Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention_Help"), "https://help.fanruan.com/finereport/doc-view-2219.html"), Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Back_Message"));
messagePanel.add(message);
}
// 提示图标
JPanel tipPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
UILabel tipLabel = new UILabel(UIManager.getIcon("OptionPane.tipIcon"));
StringBuilder textBuilder = new StringBuilder();
textBuilder.append("<html>").append(Toolkit.i18nText("Fine-Design_Basic_Processed_Special_Char")).append("<br/>");
for (String sChar : selectedSpecialChar) {
textBuilder.append(sChar).append("<br/>");
}
textBuilder.append("</html>");
tipLabel.setToolTipText(textBuilder.toString());
tipPanel.add(tipLabel, BorderLayout.SOUTH);
topPanel.add(tipPanel, BorderLayout.EAST);
} else {
imageLabel = new UILabel(UIManager.getIcon("OptionPane.informationIcon"));
messagePanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql_Message"));
messagePanel.add(label);
}
imagePanel.add(imageLabel);
topPanel.add(imagePanel, BorderLayout.WEST);
topPanel.add(messagePanel, BorderLayout.CENTER);
topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,0,10));
//中间的SQL面板
centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
centerPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10));
JScrollPane scrollPane = new JScrollPane();
JTextArea checkArea = new JTextArea(sql);
checkArea.setEditable(false);
checkArea.setCursor(new Cursor(Cursor.TEXT_CURSOR));
if (highlight) {
Highlighter highLighter = checkArea.getHighlighter();
DefaultHighlighter.DefaultHighlightPainter p = new DefaultHighlighter.DefaultHighlightPainter(Color.ORANGE);
for (int[] specialCharIndex : selectedSpecialCharIndex) {
try {
highLighter.addHighlight(specialCharIndex[0], specialCharIndex[1], p);
} catch (BadLocationException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
scrollPane.setViewportView(checkArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
centerPanel.add(scrollPane);
//底部的按钮面板
UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
okButton.addActionListener(this);
bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
bottomPanel.add(okButton, BorderLayout.EAST);
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql"));
this.setResizable(false);
this.add(topPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
this.add(bottomPanel, BorderLayout.SOUTH);
this.setSize(600, 400);
GUICoreUtils.centerWindow(this);
}
private boolean isNotShowLink() {
return GeneralContext.getLocale().equals(Locale.JAPAN) || GeneralContext.getLocale().equals(Locale.KOREA);
}
public static void previewPerformedSql(DBTableData tableData) {
Calculator calculator = Calculator.createCalculator();
//参数
ParameterProvider[] parameters = DataOperator.getInstance().getTableDataParameters(tableData);
if (ArrayUtils.isEmpty(parameters)) {
parameters = tableData.getParameters(calculator);
}
Map<String, Object> parameterMap = new HashMap<>();
if (needInputParams(parameters)) {
showParaWindow(parameterMap, parameters);
} else {
for (ParameterProvider parameter : parameters) {
parameterMap.put(parameter.getName(), parameter.getValue());
}
}
boolean showOriginSql = true;
for (ParameterProvider parameter : DataOperator.getInstance().getTableDataParameters(tableData)) {
if (parameterMap.containsKey(parameter.getName())) {
Object value = parameterMap.get(parameter.getName());
if (value != null && !StringUtils.EMPTY.equals(value)) {
showOriginSql = false;
}
parameter.setValue(value);
}
}
String sql;
// 计算高亮文本位置
List<int[]> specialCharParamIndex = null;
boolean highlight = true;
if (showOriginSql) {
sql = tableData.getQuery();
} else {
NameSpace ns = ParameterMapNameSpace.create(parameterMap);
calculator.pushNameSpace(ns);
Parameter[] paras = processParameters(tableData, calculator);
// 所有被转义参数的集合
Set<String> specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras);
// 将参数转义等
Set<TableDataProvider> tableDataProviders = getTableDataProviders();
for (TableDataProvider provider : tableDataProviders) {
provider.processParametersBeforeAnalyzeSQL(paras, calculator);
}
if (!specialCharParam.isEmpty()) {
specialCharParamIndex = ParameterHelper.analyzeCurrentContextTableData4Template(tableData.getQuery(), paras, specialCharParam);
}
String oldSql = ParameterHelper.analyzeCurrentContextTableData4Templatee(tableData.getQuery(), paras);
sql = processExtraSQL(paras, oldSql, calculator, tableDataProviders);
if (!StringUtils.equals(oldSql, sql)) {
highlight = false;
}
}
// sql内容复制到剪切板
StringSelection selection = new StringSelection(sql);
java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
// 弹窗
PreviewPerformedSqlPane pane;
if (isShowSpecialCharSqlPane(specialCharParamIndex)) {
pane = new PreviewPerformedSqlPane(DesignerContext.getDesignerFrame(), sql, specialCharParamIndex, ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar(), highlight);
} else {
pane = new PreviewPerformedSqlPane(DesignerContext.getDesignerFrame(), sql);
}
pane.setVisible(true);
}
private static boolean isShowSpecialCharSqlPane(List<int[]> specialCharParamIndex) {
return specialCharParamIndex != null && !specialCharParamIndex.isEmpty();
}
private static Parameter[] processParameters(DBTableData tableData, Calculator calculator) {
ParameterProvider[] parameters = tableData.getParameters();
if (parameters == null || parameters.length == 0) {
tableData.setParameters(ParameterHelper.analyze4Parameters(tableData.getQuery(), false));
return new Parameter[0];
}
return Parameter.providers2Parameter(Calculator.processParameters(calculator, parameters));
}
private static String processExtraSQL(Parameter[] ps, String sql, Calculator ca, Set<TableDataProvider> tableDataProviders) {
for (TableDataProvider provider : tableDataProviders) {
String newSql = provider.processTableDataSQL(ps, sql, ca);
if (StringUtils.isNotEmpty(newSql)) {
sql = newSql;
}
}
return sql;
}
private static boolean needInputParams(ParameterProvider[] parameters) {
if (ArrayUtils.isNotEmpty(parameters)) {
return true;
}
for (ParameterProvider parameter : parameters) {
if (parameter.getValue() == null || StringUtils.EMPTY.equals(parameter.getValue())) {
return true;
}
}
return false;
}
private static void showParaWindow(final Map<String, Object> parameterMap, ParameterProvider[] inParameters) {
final ParameterInputPane pPane = new ParameterInputPane(inParameters);
pPane.showSmallWindow(new JFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
parameterMap.putAll(pPane.update());
}
}).setVisible(true);
}
private static Set<TableDataProvider> getTableDataProviders() {
ExtraClassManagerProvider classManagerProvider = PluginModule.getAgent(PluginModule.ExtraCore);
if (classManagerProvider == null) {
return new HashSet<>();
}
return classManagerProvider.getArray(TableDataProvider.XML_TAG, EscapeSqlHelper.getInstance());
}
@Override
public void actionPerformed(ActionEvent e) {
this.dispose();
}
}

17
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java

@ -16,6 +16,7 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
@ -35,6 +36,7 @@ import com.fr.design.menu.ToolBarDef;
import com.fr.design.utils.ParameterUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.general.sql.SqlUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.script.Calculator;
@ -227,6 +229,7 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
// p:工具栏.
ToolBarDef toolBarDef = new ToolBarDef();
toolBarDef.addShortCut(new PreviewAction());
toolBarDef.addShortCut(new PreviewPerformedSQLAction());
toolBarDef.addShortCut(SeparatorDef.DEFAULT);
toolBarDef.addShortCut(new EditPageQueryAction());
dbTableDataMenuHandler = ExtraDesignClassManager.getInstance().getSingle(DBTableDataMenuHandler.MARK_STRING);
@ -368,6 +371,20 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
}
}
private class PreviewPerformedSQLAction extends UpdateAction {
public PreviewPerformedSQLAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql"));
this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/m_file/preview_sql.png"));
}
@Override
public void actionPerformed(ActionEvent e) {
checkParameter();
PreviewPerformedSqlPane.previewPerformedSql(DBTableDataPane.this.updateBean());
}
}
private class EditPageQueryAction extends UpdateAction {
public EditPageQueryAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Page_Query"));

17
designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java

@ -3,13 +3,14 @@ package com.fr.design.dialog.link;
import com.fr.design.gui.ilable.UILabel;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.net.URI;
import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
/**
* 用来构建JOptionPane带超链的消息提示
@ -35,8 +36,16 @@ public class MessageWithLink extends JEditorPane {
this(message, linkName, link, color, LABEL.getFont());
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage) {
this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont());
}
public MessageWithLink(String message, String linkName, String link, Color color, Font font) {
super("text/html", "<html><body style=\"" + generateStyle(color, font) + "\">" + message + "<a href=\"" + link + "\">" + linkName + "</a>" + "</body></html>");
this(message, linkName, link, StringUtils.EMPTY, color, font);
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color color, Font font) {
super("text/html", "<html><body style=\"" + generateStyle(color, font) + "\">" + frontMessage + "<a href=\"" + link + "\">" + linkName + "</a>" + backMessage + "</body></html>");
initListener(link);
setEditable(false);
setBorder(null);

1
designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java

@ -177,6 +177,7 @@ public class UILookAndFeel extends MetalLookAndFeel {
table.put("OptionPane.narrow.down", loadIcon("Icon_Narrow_Down_16x16.png", this));
table.put("OptionPane.warningIcon", loadIcon("WarningIcon.png", this));
table.put("OptionPane.questionIcon", loadIcon("QuestionIcon.png", this));
table.put("OptionPane.tipIcon", loadIcon("TipIcon.png", this));
table.put("ScrollPane.border", new UIScrollPaneBorder());
table.put("ProgressBar.border", new UIProgressBarBorder());
table.put("Spinner.border", new UITextFieldBorder(new Insets(2, 2, 2, 2)));

BIN
designer-base/src/main/resources/com/fr/design/images/lookandfeel/TipIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

BIN
designer-base/src/main/resources/com/fr/design/images/m_file/preview_sql.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Loading…
Cancel
Save