Browse Source

Merge pull request #5546 in DESIGN/design from release/10.0 to release/11.0

* commit '99d6581338700aefb706e25cd2d92423b750c7ea':
  REPORT-57590 选中参数面板模后板上方的工具栏也要禁用剪切复制
  REPORT-57898  代码回退
  REPORT-57816 REPORT-57816
  REPORT-57449 【FR11回归】【开发者预览支持调整模板布局】新自适应-远程环境模板进入开发者调试后,设计器端此模板没有显示已锁定,双击模板会弹出已锁定的弹窗,但会打开一个空白模板,且此时模板才显示“已锁定”
  REPORT-56047 修改下判断是否为安版本的标准
  REPORT-57568 解决目录树展开收起触发打开模板的逻辑
  REPORT-57898 【权限编辑】进入权限编辑时打开frm/大屏模板/版本管理,再回到原模板,无法退出权限编辑状态
  REPORT-57590 表单参数面板剪切复制按钮禁用
  REPORT-55048 fix调整下逻辑
  REPORT-57490 websocket断开时弹窗位置问题
  REPORT-55048 https远程连接时,设计器上无法获取服务器推送过来的eventhread线程日志 fix npe问题
  REPORT-55048 https远程连接时,设计器上无法获取服务器推送过来的eventhread线程日志
  REPORT-57561 远程版本不一致功能不可用的提示-启动时连接远程目录
  REPORT-57979  前面=赋值了,set没意义,删掉
  REPORT-57872 数据集-数据库查询时候,列名之间的分隔符没了
fix-lag
superman 3 years ago
parent
commit
2052e147d9
  1. 2
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  2. 1
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java
  3. 16
      designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java
  4. 20
      designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java
  5. 3
      designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java
  6. 5
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  7. 10
      designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java
  8. 5
      designer-form/src/main/java/com/fr/design/designer/beans/actions/CopyAction.java
  9. 3
      designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java
  10. 6
      designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java
  11. 16
      designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CopyableEnable.java
  12. 16
      designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CutableEnable.java
  13. 16
      designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/DeletableEnable.java
  14. 8
      designer-form/src/main/java/com/fr/design/form/parameter/FormParaDesigner.java
  15. 25
      designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java
  16. 131
      designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java
  17. 4
      designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java

2
designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java

@ -8,6 +8,7 @@ import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.env.DesignerWorkspaceGenerator; import com.fr.design.env.DesignerWorkspaceGenerator;
import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceInfoContext;
import com.fr.design.env.DesignerWorkspaceType; import com.fr.design.env.DesignerWorkspaceType;
import com.fr.design.env.RemoteDesignerWorkspaceInfo; import com.fr.design.env.RemoteDesignerWorkspaceInfo;
import com.fr.design.env.RemoteWorkspace; import com.fr.design.env.RemoteWorkspace;
@ -105,6 +106,7 @@ public class EnvChangeEntrance {
private boolean switch2Env(final String envName, PopTipStrategy strategy) { private boolean switch2Env(final String envName, PopTipStrategy strategy) {
DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); DesignerEnvManager envManager = DesignerEnvManager.getEnvManager();
DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName);
DesignerWorkspaceInfoContext.setWorkspaceInfo(selectedEnv);
WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection();
try { try {

1
designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java

@ -511,7 +511,6 @@ public class JDBCDefPane extends JPanel {
this.dbtypeComboBox.setSelectedItem(OTHER_DB); this.dbtypeComboBox.setSelectedItem(OTHER_DB);
} }
} }
this.jdbcDatabase.setIdentity(jdbcDatabase.getIdentity());
// jdbcDatabase.getDriverSource() 只会是空或者是有值,但是为了保险起见,还是应该做个处理 // jdbcDatabase.getDriverSource() 只会是空或者是有值,但是为了保险起见,还是应该做个处理
String driverSource = jdbcDatabase.getDriverSource(); String driverSource = jdbcDatabase.getDriverSource();
if (driverSource == null) { if (driverSource == null) {

16
designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java

@ -48,9 +48,17 @@ public class CopyableJTable extends SortableJTable {
boolean mouseDrag = false; boolean mouseDrag = false;
boolean headerSelect = false; boolean headerSelect = false;
DefaultTableCellRenderer tableHeaderCellRenderer = new DefaultTableCellRenderer() {
class CopyableTableHeaderCellRenderer implements TableCellRenderer {
TableCellRenderer tableCellRenderer;
CopyableTableHeaderCellRenderer(TableCellRenderer tableCellRenderer) {
this.tableCellRenderer = tableCellRenderer;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); JComponent comp = (JComponent) this.tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (isChoose(row, column)) { if (isChoose(row, column)) {
comp.setBackground(selectBackGround); comp.setBackground(selectBackGround);
} else { } else {
@ -58,13 +66,13 @@ public class CopyableJTable extends SortableJTable {
} }
return comp; return comp;
} }
}; }
public CopyableJTable(TableSorter tableModel) { public CopyableJTable(TableSorter tableModel) {
super(tableModel); super(tableModel);
initListener(); initListener();
this.getTableHeader().setDefaultRenderer(tableHeaderCellRenderer); this.getTableHeader().setDefaultRenderer(new CopyableTableHeaderCellRenderer(this.getTableHeader().getDefaultRenderer()));
} }
private void initListener() { private void initListener() {

20
designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java vendored

@ -0,0 +1,20 @@
package com.fr.design.env;
/**
*
* @author hades
* @version 10.0
* Created by hades on 2021/8/24
*/
public class DesignerWorkspaceInfoContext {
private static DesignerWorkspaceInfo workspaceInfo;
public static DesignerWorkspaceInfo getWorkspaceInfo() {
return workspaceInfo;
}
public static void setWorkspaceInfo(DesignerWorkspaceInfo workspaceInfo) {
DesignerWorkspaceInfoContext.workspaceInfo = workspaceInfo;
}
}

3
designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java vendored

@ -3,6 +3,7 @@ package com.fr.design.env;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils; import com.fr.general.GeneralUtils;
import com.fr.locale.InterProviderFactory; import com.fr.locale.InterProviderFactory;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants; import com.fr.stable.project.ProjectConstants;
@ -107,7 +108,7 @@ public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo {
File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR)); File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR));
// 非安装版本允许自由切换 // 非安装版本允许自由切换
boolean notExistLib = !ComparatorUtils.equals(GeneralUtils.readFullBuildNO(), InterProviderFactory.getProvider().getLocText("Fine-Core_Basic_About_No_Build")) boolean notExistLib = !CoreConstants.DOT.equals(StableUtils.getInstallHome())
&& !engineLib.exists(); && !engineLib.exists();
if (notExistLib) { if (notExistLib) {
throw new MainVersionNotMatchException(); throw new MainVersionNotMatchException();

5
designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java

@ -3,6 +3,7 @@ package com.fr.design.gui.controlpane;
import com.fr.design.constants.UIConstants; import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.controlpane.shortcutfactory.ShortCutFactory; import com.fr.design.gui.controlpane.shortcutfactory.ShortCutFactory;
import com.fr.design.gui.ifilechooser.JavaFxNativeFileChooser;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itoolbar.UIToolBarUI; import com.fr.design.gui.itoolbar.UIToolBarUI;
import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.gui.itoolbar.UIToolbar;
@ -277,6 +278,10 @@ public abstract class UIControlPane extends JControlPane {
this.requestFocus(); this.requestFocus();
return; return;
} }
if (JavaFxNativeFileChooser.isShowDialogState()) {
JavaFxNativeFileChooser.setShowDialogState(false);
return;
}
saveSettings(); saveSettings();
setVisible(false); setVisible(false);
PopupDialogSaveAction saveAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); PopupDialogSaveAction saveAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);

10
designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java

@ -24,6 +24,7 @@ import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
public class JavaFxNativeFileChooser implements FileChooserProvider { public class JavaFxNativeFileChooser implements FileChooserProvider {
private static boolean showDialogState = false;
private File[] selectedFiles = new File[0]; private File[] selectedFiles = new File[0];
private FileSelectionMode fileSelectionMode = FileSelectionMode.FILE; private FileSelectionMode fileSelectionMode = FileSelectionMode.FILE;
private String title = Toolkit.i18nText("Fine-Design_Basic_Open"); private String title = Toolkit.i18nText("Fine-Design_Basic_Open");
@ -43,8 +44,17 @@ public class JavaFxNativeFileChooser implements FileChooserProvider {
return null; return null;
} }
public static boolean isShowDialogState() {
return showDialogState;
}
public static void setShowDialogState(boolean showDialogState) {
JavaFxNativeFileChooser.showDialogState = showDialogState;
}
@Override @Override
public int showDialog(Component parent) { public int showDialog(Component parent) {
setShowDialogState(true);
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
PlatformImpl.startup(() -> { PlatformImpl.startup(() -> {
}); });

5
designer-form/src/main/java/com/fr/design/designer/beans/actions/CopyAction.java

@ -1,8 +1,7 @@
package com.fr.design.designer.beans.actions; package com.fr.design.designer.beans.actions;
import com.fr.design.base.mode.DesignModeContext; import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.designer.beans.actions.behavior.ComponentEnable; import com.fr.design.designer.beans.actions.behavior.CopyableEnable;
import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormDesigner;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
@ -18,7 +17,7 @@ public class CopyAction extends FormWidgetEditAction {
this.setMnemonic('C'); this.setMnemonic('C');
this.setSmallIcon("/com/fr/design/images/m_edit/copy"); this.setSmallIcon("/com/fr/design/images/m_edit/copy");
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER));
setUpdateBehavior(new ComponentEnable()); setUpdateBehavior(new CopyableEnable());
this.setEnabled(!DesignModeContext.isBanCopyAndCut()); this.setEnabled(!DesignModeContext.isBanCopyAndCut());
} }

3
designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java

@ -3,6 +3,7 @@ package com.fr.design.designer.beans.actions;
import com.fr.design.base.mode.DesignModeContext; import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.designer.beans.actions.behavior.ComponentEnable; import com.fr.design.designer.beans.actions.behavior.ComponentEnable;
import com.fr.design.designer.beans.actions.behavior.CutableEnable;
import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormDesigner;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
@ -18,7 +19,7 @@ public class CutAction extends FormWidgetEditAction {
this.setMnemonic('T'); this.setMnemonic('T');
this.setSmallIcon("/com/fr/design/images/m_edit/cut"); this.setSmallIcon("/com/fr/design/images/m_edit/cut");
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER));
this.setUpdateBehavior(new ComponentEnable()); this.setUpdateBehavior(new CutableEnable());
this.setEnabled(!DesignModeContext.isBanCopyAndCut()); this.setEnabled(!DesignModeContext.isBanCopyAndCut());
} }

6
designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java

@ -7,9 +7,7 @@ import java.awt.event.KeyEvent;
import javax.swing.*; import javax.swing.*;
import com.fr.design.designer.beans.actions.behavior.DeletableEnable;
import com.fr.design.designer.beans.actions.behavior.ComponentEnable;
import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormDesigner;
/** /**
@ -26,7 +24,7 @@ public class FormDeleteAction extends FormWidgetEditAction {
// Richie:删除菜单图标 // Richie:删除菜单图标
this.setSmallIcon("/com/fr/design/images/m_report/delete"); this.setSmallIcon("/com/fr/design/images/m_report/delete");
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0)); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0));
this.setUpdateBehavior(new ComponentEnable()); this.setUpdateBehavior(new DeletableEnable());
} }
@Override @Override

16
designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CopyableEnable.java

@ -0,0 +1,16 @@
package com.fr.design.designer.beans.actions.behavior;
import com.fr.design.designer.beans.actions.FormWidgetEditAction;
import com.fr.design.mainframe.FormDesigner;
public class CopyableEnable implements UpdateBehavior<FormWidgetEditAction> {
@Override
public void doUpdate(FormWidgetEditAction action) {
FormDesigner designer = action.getEditingComponent();
if (designer == null) {
action.setEnabled(false);
return;
}
action.setEnabled(designer.isCurrentComponentCopyable());
}
}

16
designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CutableEnable.java

@ -0,0 +1,16 @@
package com.fr.design.designer.beans.actions.behavior;
import com.fr.design.designer.beans.actions.FormWidgetEditAction;
import com.fr.design.mainframe.FormDesigner;
public class CutableEnable implements UpdateBehavior<FormWidgetEditAction> {
@Override
public void doUpdate(FormWidgetEditAction action) {
FormDesigner designer = action.getEditingComponent();
if (designer == null) {
action.setEnabled(false);
return;
}
action.setEnabled(designer.isCurrentComponentCutable());
}
}

16
designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/DeletableEnable.java

@ -0,0 +1,16 @@
package com.fr.design.designer.beans.actions.behavior;
import com.fr.design.designer.beans.actions.FormWidgetEditAction;
import com.fr.design.mainframe.FormDesigner;
public class DeletableEnable implements UpdateBehavior<FormWidgetEditAction> {
@Override
public void doUpdate(FormWidgetEditAction action) {
FormDesigner designer = action.getEditingComponent();
if (designer == null) {
action.setEnabled(false);
return;
}
action.setEnabled(designer.isCurrentComponentDeletable());
}
}

8
designer-form/src/main/java/com/fr/design/form/parameter/FormParaDesigner.java

@ -745,5 +745,13 @@ public class FormParaDesigner extends FormDesigner implements ParameterDesignerP
return false; return false;
} }
@Override
public boolean isCurrentComponentCutable() {
return !isRootSelected();
}
@Override
public boolean isCurrentComponentCopyable() {
return !isRootSelected();
}
} }

25
designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java

@ -110,6 +110,10 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_M_Edit_Delete")}) Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_M_Edit_Delete")})
); );
protected static final ArrayList<String> PARAMETER_TOOLAR_BAN_LIST = new ArrayList<String>(
Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy")})
);
private double scale = 1.0D; private double scale = 1.0D;
//底层容器的默认大小 //底层容器的默认大小
@ -1267,6 +1271,11 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
return isForm || isRoot(getSelectionModel().getSelection().getSelectedCreator()); return isForm || isRoot(getSelectionModel().getSelection().getSelectedCreator());
} }
public boolean isParameterSelected() {
XCreator xCreator = getSelectionModel().getSelection().getSelectedCreator();
return xCreator != null && xCreator.acceptType(XWParameterLayout.class);
}
/** /**
* 显示权限编辑界面 * 显示权限编辑界面
*/ */
@ -1300,6 +1309,10 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
protected void setToolbarButtons() { protected void setToolbarButtons() {
//自适应布局和底层都不能删除 //自适应布局和底层都不能删除
DesignerContext.getDesignerFrame().checkCombineUp(!isRootSelected(), NAME_ARRAY_LIST); DesignerContext.getDesignerFrame().checkCombineUp(!isRootSelected(), NAME_ARRAY_LIST);
if (isParameterSelected()) {
DesignerContext.getDesignerFrame().checkCombineUp(false, PARAMETER_TOOLAR_BAN_LIST);
}
} }
private void invalidateLayout() { private void invalidateLayout() {
@ -1385,6 +1398,18 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
} }
} }
public boolean isCurrentComponentCutable() {
return !(isRootSelected() || isParameterSelected());
}
public boolean isCurrentComponentCopyable() {
return !(isRootSelected() || isParameterSelected());
}
public boolean isCurrentComponentDeletable() {
return !isRootSelected();
}
// 当前选中控件可以上移一层吗? // 当前选中控件可以上移一层吗?
public boolean isCurrentComponentMovableUp() { public boolean isCurrentComponentMovableUp() {
XCreator creator = getSelectionModel().getSelection().getSelectedCreator(); XCreator creator = getSelectionModel().getSelection().getSelectedCreator();

131
designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java

@ -5,29 +5,40 @@ import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.design.DesignerEnvManager; import com.fr.design.DesignerEnvManager;
import com.fr.design.EnvChangeEntrance; import com.fr.design.EnvChangeEntrance;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceInfoContext;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.loghandler.DesignerLogger; import com.fr.design.mainframe.loghandler.DesignerLogger;
import com.fr.design.ui.util.UIUtil; import com.fr.design.ui.util.UIUtil;
import com.fr.event.Event;
import com.fr.event.EventDispatcher; import com.fr.event.EventDispatcher;
import com.fr.event.Listener; import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.report.RemoteDesignConstants; import com.fr.report.RemoteDesignConstants;
import com.fr.serialization.SerializerHelper; import com.fr.serialization.SerializerHelper;
import com.fr.stable.ArrayUtils; import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.third.apache.log4j.spi.LoggingEvent; import com.fr.third.apache.log4j.spi.LoggingEvent;
import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
import com.fr.third.org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import com.fr.third.org.apache.http.ssl.SSLContexts;
import com.fr.web.WebSocketConfig;
import com.fr.web.socketio.WebSocketProtocol;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace; import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import com.fr.workspace.base.WorkspaceConstants; import com.fr.workspace.base.WorkspaceConstants;
import com.fr.workspace.connect.WorkspaceConnection; import com.fr.workspace.connect.WorkspaceConnection;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.server.socket.SocketInfoOperator; import com.fr.workspace.server.socket.SocketInfoOperator;
import io.socket.client.IO; import io.socket.client.IO;
import io.socket.client.Socket; import io.socket.client.Socket;
import io.socket.emitter.Emitter; import io.socket.emitter.Emitter;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.Arrays; import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.swing.*; import javax.swing.*;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -37,26 +48,14 @@ import java.util.TimerTask;
public class DesignerSocketIO { public class DesignerSocketIO {
static {
EventDispatcher.listen(WorkspaceEvent.LostConnect, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
// 远程设计websocket不支持wss 所以断开无法提醒
// 使用远程设计的心跳断开来提醒断开
if (DesignerEnvManager.getEnvManager().isHttps()) {
showConnectionLostDialog();
}
}
});
}
enum Status { enum Status {
Connected, Connected,
Disconnected, Disconnected,
Disconnecting Disconnecting
} }
private static final String HTTPS = "https";
private static final String HTTP = "http";
private static Socket socket = null; private static Socket socket = null;
private static Status status = Status.Disconnected; private static Status status = Status.Disconnected;
private static Timer disConnectHintTimer = null; private static Timer disConnectHintTimer = null;
@ -65,6 +64,8 @@ public class DesignerSocketIO {
private static String[] uri; private static String[] uri;
//维护一个关于uri列表的计数器 //维护一个关于uri列表的计数器
private static int count; private static int count;
// 当前webSocket选择的协议
private static String currentProtocol;
public static void close() { public static void close() {
@ -95,7 +96,7 @@ public class DesignerSocketIO {
//根据uri和计数器建立连接,并注册监听 //根据uri和计数器建立连接,并注册监听
try { try {
if (count < uri.length) { if (count < uri.length) {
socket = IO.socket(new URI(uri[count])); socket = IO.socket(new URI(uri[count]), createOptions());
socket.on(WorkspaceConstants.WS_LOGRECORD, printLog); socket.on(WorkspaceConstants.WS_LOGRECORD, printLog);
socket.on(WorkspaceConstants.CONFIG_MODIFY, modifyConfig); socket.on(WorkspaceConstants.CONFIG_MODIFY, modifyConfig);
socket.on(Socket.EVENT_CONNECT_ERROR, failRetry); socket.on(Socket.EVENT_CONNECT_ERROR, failRetry);
@ -112,15 +113,58 @@ public class DesignerSocketIO {
} }
} }
private static IO.Options createOptions() {
IO.Options options = new IO.Options();
try {
if (ComparatorUtils.equals(currentProtocol, HTTPS)) {
options.sslContext = getSSLContext();
options.hostnameVerifier = NoopHostnameVerifier.INSTANCE;
options.secure = true;
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return options;
}
private static SSLContext getSSLContext() throws Exception {
WorkspaceConnectionInfo connection = getConnectionInfo();
String certPath = connection.getCertPath();
String certSecretKey = connection.getCertSecretKey();
if (StringUtils.isBlank(certPath) || StringUtils.isBlank(certSecretKey)) {
return SSLContexts.createDefault();
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream keystore = new FileInputStream(new File(certPath))) {
trustStore.load(keystore, certSecretKey.toCharArray());
}
return SSLContexts.custom()
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
.build();
}
private static WorkspaceConnectionInfo getConnectionInfo() {
if (DesignerWorkspaceInfoContext.getWorkspaceInfo() == null) {
String currentName = DesignerEnvManager.getEnvManager().getCurEnvName();
DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(currentName);
return info.getConnection();
} else {
return DesignerWorkspaceInfoContext.getWorkspaceInfo().getConnection();
}
}
private static String[] getSocketUri() throws IOException { private static String[] getSocketUri() throws IOException {
Workspace current = WorkContext.getCurrent(); Workspace current = WorkContext.getCurrent();
URL url = new URL(current.getPath()); URL url = new URL(current.getPath());
Integer[] ports = current.get(SocketInfoOperator.class).getPort(); Integer[] ports = current.get(SocketInfoOperator.class).getPort();
WorkspaceConnection connection = current.getConnection(); WorkspaceConnection connection = current.getConnection();
// 服务器配置https webSocket可能是wss也可能是ws webSocket的协议可以单独配置
WebSocketProtocol webSocketProtocol = WebSocketConfig.getInstance().getProtocol();
currentProtocol = webSocketProtocol == WebSocketProtocol.PLAIN ? HTTP : HTTPS;
String[] result = new String[ports.length]; String[] result = new String[ports.length];
for (int i = 0; i < ports.length; i++) { for (int i = 0; i < ports.length; i++) {
result[i] = String.format("%s://%s:%s%s?%s=%s&%s=%s", result[i] = String.format("%s://%s:%s%s?%s=%s&%s=%s",
url.getProtocol(), currentProtocol,
url.getHost(), url.getHost(),
ports[i], ports[i],
WorkspaceConstants.WS_NAMESPACE, WorkspaceConstants.WS_NAMESPACE,
@ -129,6 +173,7 @@ public class DesignerSocketIO {
RemoteDesignConstants.USER_LOCK_ID, RemoteDesignConstants.USER_LOCK_ID,
connection.getId()); connection.getId());
} }
FineLoggerFactory.getLogger().error("Available ports: {}, current Protocol: {}", Arrays.toString(ports), currentProtocol);
return result; return result;
} }
@ -136,7 +181,7 @@ public class DesignerSocketIO {
private static final Emitter.Listener failRetry = new Emitter.Listener() { private static final Emitter.Listener failRetry = new Emitter.Listener() {
@Override @Override
public void call(Object... args) { public void call(Object... args) {
FineLoggerFactory.getLogger().warn("failed args: {}", Arrays.toString(args)); printLog(args, PrintEventLogImpl.WARN, "failed args: {}");
status = Status.Disconnecting; status = Status.Disconnecting;
socket.close(); socket.close();
count++; count++;
@ -183,7 +228,7 @@ public class DesignerSocketIO {
* todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒 * todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上切换成心跳断开之后进行提醒
* socket 只用推日志和通知配置变更 * socket 只用推日志和通知配置变更
*/ */
FineLoggerFactory.getLogger().error("disConnected args: {}", Arrays.toString(objects)); printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}");
if (status != Status.Disconnecting) { if (status != Status.Disconnecting) {
showConnectionLostDialog(); showConnectionLostDialog();
} }
@ -199,7 +244,7 @@ public class DesignerSocketIO {
private static void showConnectionLostDialog() { private static void showConnectionLostDialog() {
try { try {
UIUtil.invokeAndWaitIfNeeded(new Runnable() { UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override @Override
public void run() { public void run() {
FineJOptionPane.showMessageDialog( FineJOptionPane.showMessageDialog(
@ -226,4 +271,46 @@ public class DesignerSocketIO {
} }
}; };
private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) {
for (Object object : objects) {
if (object instanceof Throwable) {
Throwable throwable = (Throwable) object;
printEventLog.printThrowable(throwable);
} else {
printEventLog.print(prefix, object);
}
}
}
interface PrintEventLog {
void printThrowable(Throwable throwable);
void print(String s, Object ...object);
}
enum PrintEventLogImpl implements PrintEventLog {
ERROR {
@Override
public void printThrowable(Throwable throwable) {
FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable);
}
@Override
public void print(String s, Object... object) {
FineLoggerFactory.getLogger().error(s, object);
}
},
WARN {
@Override
public void printThrowable(Throwable throwable) {
FineLoggerFactory.getLogger().warn(throwable.getMessage(), throwable);
}
@Override
public void print(String s, Object... object) {
FineLoggerFactory.getLogger().warn(s, object);
}
};
}
} }

4
designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java

@ -62,12 +62,12 @@ public class DesignerWorkspaceProvider extends Activator {
} else { } else {
WorkContext.switchTo(workspace); WorkContext.switchTo(workspace);
//在设计器完全启动完成后,对初始环境进行一次服务检测,对主要功能无影响,异常仅做日志提示即可 //在设计器完全启动完成后,对初始环境进行一次服务检测,对主要功能无影响,异常仅做日志提示即可
final DesignerWorkspaceInfo selectEnv = workspaceInfo; final String selectEnv = current;
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() { EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override @Override
public void on(Event event, Null aNull) { public void on(Event event, Null aNull) {
try { try {
VersionCheckUtils.showVersionCheckDialog(selectEnv.getName()); VersionCheckUtils.showVersionCheckDialog(selectEnv);
} catch (Exception e) { } catch (Exception e) {
FineLoggerFactory.getLogger().warn("Check Service Failed"); FineLoggerFactory.getLogger().warn("Check Service Failed");
} }

Loading…
Cancel
Save