You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
12 KiB
301 lines
12 KiB
package com.fr.design.data.datapane.connect; |
|
|
|
import com.fr.data.impl.JDBCDatabaseConnection; |
|
import com.fr.data.security.ssh.BaseSsh; |
|
import com.fr.data.security.ssh.Ssh; |
|
import com.fr.data.security.ssh.SshException; |
|
import com.fr.data.security.ssh.SshType; |
|
import com.fr.data.security.ssh.impl.KeyVerifySsh; |
|
import com.fr.data.security.ssh.impl.NormalSsh; |
|
import com.fr.data.security.ssl.SslUtils; |
|
import com.fr.design.border.UITitledBorder; |
|
import com.fr.design.constants.UIConstants; |
|
import com.fr.design.dialog.BasicPane; |
|
import com.fr.design.editor.editor.NotNegativeIntegerEditor; |
|
import com.fr.design.gui.ibutton.UIButton; |
|
import com.fr.design.gui.icheckbox.UICheckBox; |
|
import com.fr.design.gui.icombobox.UIComboBox; |
|
import com.fr.design.gui.ilable.UILabel; |
|
import com.fr.design.gui.ipasswordfield.UIPasswordFieldWithFixedLength; |
|
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.file.FILE; |
|
import com.fr.file.FILEChooserPane; |
|
import com.fr.file.filter.ChooseFileFilter; |
|
import com.fr.stable.StringUtils; |
|
import com.fr.third.guava.collect.HashBiMap; |
|
|
|
import javax.swing.ImageIcon; |
|
import javax.swing.JPanel; |
|
import javax.swing.JPasswordField; |
|
import javax.swing.SwingConstants; |
|
import java.awt.BorderLayout; |
|
import java.awt.Component; |
|
import java.awt.Dimension; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.KeyAdapter; |
|
import java.awt.event.KeyEvent; |
|
import java.util.regex.Matcher; |
|
import java.util.regex.Pattern; |
|
|
|
import static com.fr.design.i18n.Toolkit.i18nText; |
|
|
|
/** |
|
* @author xiqiu |
|
* @date 2021/12/23 |
|
* @description |
|
*/ |
|
public class SshPane extends BasicPane { |
|
private static HashBiMap<String, SshType> typeMap; |
|
|
|
static { |
|
typeMap = HashBiMap.create(); |
|
typeMap.put(Toolkit.i18nText("Fine-Design_Basic_Password"), SshType.NORMAL); |
|
typeMap.put(Toolkit.i18nText("Fine-Design_Basic_Ssh_Public_Key"), SshType.KEY); |
|
} |
|
|
|
private UICheckBox usingSsh = new UICheckBox(i18nText("Fine-Design_Basic_Ssh_Using")); |
|
private NotNegativeIntegerEditor port = new NotNegativeIntegerEditor(20); |
|
private UITextField ip = new UITextField(20); |
|
private UIComboBox type = new UIComboBox(); |
|
private UITextField user = new UITextField(20); |
|
private JPasswordField password = new UIPasswordFieldWithFixedLength(20); |
|
private JPasswordField secret = new UIPasswordFieldWithFixedLength(20); |
|
private KeyFileUITextField keyPath = new KeyFileUITextField(18); |
|
private JPanel contextPane; |
|
private Component[][] passwordComps; |
|
private Component[][] keyComps; |
|
private double p = TableLayout.PREFERRED; |
|
private double f = TableLayout.FILL; |
|
private JPanel jPanel; |
|
private UIButton fileChooserButton = new UIButton(); |
|
private double[] columnSize = new double[]{195, p}; |
|
|
|
public SshPane() { |
|
fileChooserButton.setIcon(new ImageIcon(UIConstants.ACCESSIBLE_EDITOR_DOT)); |
|
this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Ssh_Settings"))); |
|
this.setLayout(FRGUIPaneFactory.createLabelFlowLayout()); |
|
typeMap.keySet().forEach(key -> type.addItem(key)); |
|
type.setSelectedItem(typeMap.inverse().get(SshType.KEY)); |
|
jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
fileChooserButton.setPreferredSize(new Dimension(20, 20)); |
|
type.setEditable(false); |
|
type.setSelectedItem(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key")); |
|
JPanel filePanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{{keyPath, fileChooserButton}}, new double[]{p}, new double[]{f, 20}, 0); |
|
Component[] compIp = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Host") + ":", SwingConstants.RIGHT), ip}; |
|
Component[] compPort = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Port") + ":", SwingConstants.RIGHT), port}; |
|
Component[] compUserName = {new UILabel(Toolkit.i18nText("Fine-Design_Report_UserName") + ":", SwingConstants.RIGHT), user}; |
|
Component[] compMethod = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Verify_Method") + ":", SwingConstants.RIGHT), type}; |
|
Component[] compPassword = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Password") + ":", SwingConstants.RIGHT), password}; |
|
Component[] compKey = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key") + ":", SwingConstants.RIGHT), filePanel}; |
|
Component[] comSecret = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Secret") + ":", SwingConstants.RIGHT), secret}; |
|
|
|
passwordComps = new Component[][]{ |
|
compIp, |
|
compPort, |
|
compUserName, |
|
compMethod, |
|
compPassword |
|
}; |
|
keyComps = new Component[][]{ |
|
compIp, |
|
compPort, |
|
compUserName, |
|
compMethod, |
|
compKey, |
|
comSecret |
|
}; |
|
usingSsh.setSelected(true); |
|
contextPane = TableLayoutHelper.createGapTableLayoutPane(keyComps, new double[]{p, p, p, p, p, p}, columnSize, 11, 11); |
|
jPanel.add(usingSsh, BorderLayout.NORTH); |
|
jPanel.add(contextPane, BorderLayout.CENTER); |
|
this.add(jPanel); |
|
|
|
usingSsh.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
changePane(); |
|
} |
|
}); |
|
|
|
type.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
changePaneForType(); |
|
} |
|
}); |
|
fileChooserButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(SslUtils.PREFIX, new ChooseFileFilter(true), SslUtils.CERTIFICATES); |
|
int type = fileChooser.showOpenDialog(SshPane.this, StringUtils.EMPTY); |
|
if (type == FILEChooserPane.OK_OPTION) { |
|
final FILE file = fileChooser.getSelectedFILE(); |
|
if (file == null) { |
|
keyPath.setText(StringUtils.EMPTY); |
|
} else { |
|
keyPath.setText(file.getPath()); |
|
} |
|
} |
|
fileChooser.removeAllFilter(); |
|
fileChooser.removeTopPath(); |
|
} |
|
}); |
|
} |
|
|
|
|
|
private void changePane() { |
|
contextPane.setVisible(usingSsh.isSelected()); |
|
} |
|
|
|
private void changePaneForType() { |
|
contextPane.removeAll(); |
|
switch (typeMap.get(type.getSelectedItem())) { |
|
case NORMAL: |
|
TableLayoutHelper.addComponent2ResultPane(passwordComps, new double[]{p, p, p, p, p}, columnSize, contextPane); |
|
break; |
|
case KEY: |
|
TableLayoutHelper.addComponent2ResultPane(keyComps, new double[]{p, p, p, p, p, p}, columnSize, contextPane); |
|
break; |
|
default: |
|
throw new SshException("un support ssh type"); |
|
} |
|
jPanel.revalidate(); |
|
jPanel.repaint(); |
|
} |
|
|
|
|
|
@Override |
|
protected String title4PopupWindow() { |
|
return Toolkit.i18nText("Fine-Design_Basic_Ssh_Settings"); |
|
} |
|
|
|
|
|
public void populate(JDBCDatabaseConnection jdbcDatabase) { |
|
if (jdbcDatabase.getSsh() == null) { |
|
jdbcDatabase.setSsh(new NormalSsh()); |
|
} |
|
Ssh ssh = jdbcDatabase.getSsh(); |
|
switch (ssh.getSshType()) { |
|
case KEY: |
|
type.setSelectedItem(typeMap.inverse().get(ssh.getSshType())); |
|
KeyVerifySsh keyVerifySsh = (KeyVerifySsh) ssh; |
|
keyPath.setText(keyVerifySsh.getPrivateKeyPath()); |
|
secret.setText(keyVerifySsh.getSecret()); |
|
password.setText(StringUtils.EMPTY); |
|
setCommonConfig(keyVerifySsh); |
|
break; |
|
case NORMAL: |
|
type.setSelectedItem(typeMap.inverse().get(ssh.getSshType())); |
|
NormalSsh normalSsh = (NormalSsh) ssh; |
|
password.setText(normalSsh.getSecret()); |
|
keyPath.setText(StringUtils.EMPTY); |
|
secret.setText(StringUtils.EMPTY); |
|
setCommonConfig(normalSsh); |
|
break; |
|
default: |
|
throw new SshException("un support ssh type"); |
|
} |
|
usingSsh.setSelected(ssh.isUsingSsh()); |
|
changePane(); |
|
} |
|
|
|
private void setCommonConfig(BaseSsh baseSsh) { |
|
ip.setText(baseSsh.getIp()); |
|
port.setValue(baseSsh.getPort()); |
|
user.setText(baseSsh.getUser()); |
|
} |
|
|
|
public void update(JDBCDatabaseConnection jdbcDatabase) { |
|
Ssh ssh; |
|
switch (typeMap.get(type.getSelectedItem())) { |
|
case NORMAL: |
|
NormalSsh normalSsh = new NormalSsh(); |
|
normalSsh.setSecret(new String(password.getPassword()).trim()); |
|
getCommonConfig(normalSsh); |
|
ssh = normalSsh; |
|
break; |
|
case KEY: |
|
KeyVerifySsh keyVerifySsh = new KeyVerifySsh(); |
|
keyVerifySsh.setPrivateKeyPath(keyPath.getText().trim()); |
|
keyVerifySsh.setSecret(new String(secret.getPassword()).trim()); |
|
getCommonConfig(keyVerifySsh); |
|
ssh = keyVerifySsh; |
|
break; |
|
default: |
|
throw new SshException("un support ssh type"); |
|
} |
|
jdbcDatabase.setSsh(ssh); |
|
} |
|
|
|
private void getCommonConfig(BaseSsh baseSsh) { |
|
baseSsh.setUsingSsh(usingSsh.isSelected()); |
|
baseSsh.setIp(ip.getText().trim()); |
|
baseSsh.setPort(port.getValue()); |
|
baseSsh.setUser(user.getText().trim()); |
|
} |
|
|
|
public static class KeyFileUITextField extends UITextField { |
|
private static final Pattern ERROR_START = Pattern.compile("^([/\\\\.]+).*"); |
|
private static final Pattern MUTI_DOT = Pattern.compile("\\.+"); |
|
private static final String UPPER = ".."; |
|
|
|
public KeyFileUITextField(int columns) { |
|
this(); |
|
this.setColumns(columns); |
|
} |
|
|
|
|
|
public KeyFileUITextField() { |
|
super(); |
|
this.addKeyListener(new KeyAdapter() { |
|
@Override |
|
public void keyReleased(KeyEvent e) { |
|
String text = KeyFileUITextField.this.getTextOrigin(); |
|
if (!StringUtils.isEmpty(text)) { |
|
if (text.contains(UPPER)) { |
|
text = MUTI_DOT.matcher(text).replaceAll("."); |
|
KeyFileUITextField.this.setTextOrigin(text); |
|
} |
|
Matcher matcher = ERROR_START.matcher(text); |
|
if (matcher.matches()) { |
|
text = text.substring(matcher.group(1).length()); |
|
KeyFileUITextField.this.setTextOrigin(text); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
public String getTextOrigin() { |
|
return super.getText(); |
|
} |
|
|
|
public void setTextOrigin(String text) { |
|
super.setText(text); |
|
} |
|
|
|
@Override |
|
public String getText() { |
|
// 获取的时候,不为空,给他加上前缀就好了,否则还是空 |
|
if (!StringUtils.isEmpty(super.getText())) { |
|
return SslUtils.PREFIX + super.getText(); |
|
} |
|
return StringUtils.EMPTY; |
|
} |
|
|
|
@Override |
|
public void setText(String text) { |
|
// 设置的时候,不为空,说明文件指定了(文件需要是resource下),替换掉前缀 |
|
if (!StringUtils.isEmpty(text) && text.startsWith(SslUtils.PREFIX)) { |
|
super.setText(text.replaceFirst(SslUtils.PREFIX, "")); |
|
} else { |
|
super.setText(text); |
|
} |
|
} |
|
} |
|
}
|
|
|