Browse Source

Merge remote-tracking branch 'origin/fbp/release' into fbp/release

fbp/release
lemon 3 months ago
parent
commit
408d677e7c
  1. 5
      build.gradle
  2. 16
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  3. 25
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  4. 11
      designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java
  5. 23
      designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java
  6. 10
      designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java
  7. 10
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  8. 14
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java
  9. 1
      designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java
  10. 19
      designer-base/src/main/java/com/fr/design/data/datapane/connect/LocalConnectionSource.java
  11. 140
      designer-base/src/main/java/com/fr/design/data/datapane/preview/ConnectionInfoBeanHelper.java
  12. 198
      designer-base/src/main/java/com/fr/design/data/datapane/preview/TableDataBeanHelper.java
  13. 34
      designer-base/src/main/java/com/fr/design/data/tabledata/LocalTableDataSource.java
  14. 16
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java
  15. 42
      designer-base/src/main/java/com/fr/design/extra/LoginDialog.java
  16. 200
      designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java
  17. 54
      designer-base/src/main/java/com/fr/design/extra/LoginWebPane.java
  18. 2
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  19. 601
      designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java
  20. 112
      designer-base/src/main/java/com/fr/design/extra/PluginWebPane.java
  21. 32
      designer-base/src/main/java/com/fr/design/extra/QQLoginDialog.java
  22. 46
      designer-base/src/main/java/com/fr/design/extra/ShopDialog.java
  23. 31
      designer-base/src/main/java/com/fr/design/extra/ShopManagerPane.java
  24. 36
      designer-base/src/main/java/com/fr/design/extra/ShopPaneConfig.java
  25. 307
      designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java
  26. 4
      designer-base/src/main/java/com/fr/design/extra/exe/PluginLoginExecutor.java
  27. 10
      designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java
  28. 47
      designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java
  29. 6
      designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java
  30. 30
      designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginBrowserExecutor.java
  31. 3
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java
  32. 18
      designer-base/src/main/java/com/fr/design/login/message/NotificationActionType.java
  33. 8
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  34. 32
      designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java
  35. 55
      designer-base/src/main/java/com/fr/design/os/impl/SupportOSImpl.java
  36. 91
      designer-base/src/main/java/com/fr/design/ui/Assistant.java
  37. 135
      designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java
  38. 364
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  39. 55
      designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java
  40. 45
      designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java
  41. 11
      designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java
  42. 515
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  43. 122
      designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java
  44. 30
      designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java
  45. 3
      designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties
  46. 34
      designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/impl/ChartHyperPopAttrPane.java
  47. 2
      designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java
  48. 9
      designer-chart/src/main/java/com/fr/van/chart/designer/component/border/VanChartBorderWithShapePane.java
  49. 1
      designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java
  50. 4
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java
  51. 3
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java
  52. 2
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java
  53. 21
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java
  54. 5
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java
  55. 22
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java
  56. 5
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/cell/model/PluginModel.java
  57. 46
      designer-realize/src/main/java/com/fr/design/mainframe/bbs/BBSDialog.java
  58. 21
      designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java
  59. 20
      designer-realize/src/main/java/com/fr/design/report/RichTextPane.java
  60. 73
      designer-realize/src/main/java/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java
  61. 11
      designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java

5
build.gradle

@ -95,7 +95,6 @@ allprojects {
// messenger
implementation 'com.fr.messenger:fine-messenger:' + carinaVersion
implementation 'com.install4j:install4j-runtime:8.0.4'
implementation 'com.fr.third:jxbrowser:6.23'
implementation "com.fr.third:jxbrowser-v7:${jxBrowserVersion}"
implementation "com.fr.third:jxbrowser-swing-v7:${jxBrowserVersion}"
implementation 'com.fr.third.server:servlet-api:3.0'
@ -131,18 +130,14 @@ allprojects {
// mac_x64, mac_aarch64, windows_x64
if (OperatingSystem.current().isMacOsX() && "aarch64".equals(System.getProperty("os.arch"))) {
dependencies {
// jxbrowser 6.23M16.23jar还是需要留着
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-arm-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isMacOsX()) {
dependencies {
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation "com.fr.third:jxbrowser-mac-v7:${jxBrowserVersion}"
}
} else if (OperatingSystem.current().isWindows()) {
dependencies {
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation "com.fr.third:jxbrowser-win64-v7:${jxBrowserVersion}"
}
}

16
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -1020,22 +1020,6 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter, AsyncXmlReada
designerLoginConfigManager.setPluginRemindOnFirstLaunch(pluginRemindOnFirstLaunch);
}
public boolean isUseOldVersionLogin() {
return designerLoginConfigManager.isUseOldVersionLogin();
}
public void setUseOldVersionLogin(boolean useOldVersionLogin) {
designerLoginConfigManager.setUseOldVersionLogin(useOldVersionLogin);
}
public boolean isUseNewPluginFirst() {
return designerLoginConfigManager.isUseNewPluginFirst();
}
public void setUseNewPluginFirst(boolean useNewPluginFirst) {
designerLoginConfigManager.setUseNewPluginFirst(useNewPluginFirst);
}
/**
* 内置服务器是否使用时启动
*

25
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -310,10 +310,6 @@ public class PreferencePane extends BasicPane {
cell(createLengthPane()),
// 服务器设置
cell(createServerPane()),
// 插件管理设置
cell(createUpmSelectorPane()).with(it -> it.setVisible(!OperatingSystem.isLinux() && JdkVersion.LE_8.support())),
// 登录选项
cell(createLoginSelectorPane()).with(it -> it.setVisible(SupportOSImpl.DESIGNER_LOGIN.support())),
// Oracle设置
cell(createOraclePane()),
// 内存设置
@ -968,11 +964,7 @@ public class PreferencePane extends BasicPane {
this.portEditor.setValue(new Integer(designerEnvManager.getEmbedServerPort()));
if (useOptimizedUPMCheckbox != null) {
useOptimizedUPMCheckbox.setSelected(checkOptimizedUPMUse());
}
if (useNewVersionLoginCheckbox != null) {
useNewVersionLoginCheckbox.setSelected(!DesignerEnvManager.getEnvManager().isUseOldVersionLogin());
useOptimizedUPMCheckbox.setSelected(true);
}
useUniverseDBMCheckbox.setSelected(ServerPreferenceConfig.getInstance().isUseUniverseDBM());
@ -1011,15 +1003,6 @@ public class PreferencePane extends BasicPane {
this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled());
}
private boolean checkOptimizedUPMUse() {
//如果是没手动配置过则默认开启
//isUseNewPluginFirst如果为true说明没手动配置过,直接开启
//走到这里说明checkBox不为空,机型肯定符合
return DesignerEnvManager.getEnvManager().isUseNewPluginFirst()
|| ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter();
}
private int chooseCase(int sign) {
switch (sign) {
case 0:
@ -1086,8 +1069,6 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setImageCompress(this.imageCompressPanelCheckBox.isSelected());
boolean optimizedUPMFlag = this.useOptimizedUPMCheckbox != null && this.useOptimizedUPMCheckbox.isSelected();
designerEnvManager.setUseOptimizedUPM4Adapter(optimizedUPMFlag);
//只有取消掉使用新插件管理器这个选项才需要把useNewPluginFirst置false(意味着用户手动配置了,如果勾选着的话,这个useNewPluginFirst为true就行了)
designerEnvManager.setUseNewPluginFirst(optimizedUPMFlag);
boolean cloudDelayFlag = this.cloudAnalyticsDelayCheckBox.isSelected();
designerEnvManager.setCloudAnalyticsDelay(cloudDelayFlag);
// cloudDelayFlag默认为true,如果用户手动配置过才会是false,则后续的云端运维配置都按照用户意愿来
@ -1125,10 +1106,6 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setAutoPushUpdateEnabled(this.autoPushUpdateCheckBox.isSelected());
}
if (useNewVersionLoginCheckbox != null) {
designerEnvManager.setUseOldVersionLogin(!this.useNewVersionLoginCheckbox.isSelected());
}
designerEnvManager.setUndoLimit(maxUndoLimit.getSelectedIndex() * SELECTED_INDEX_5);
if (maxUndoLimit.getSelectedIndex() == SELECTED_INDEX_5) {
designerEnvManager.setUndoLimit(MAX_UNDO_LIMIT_50);

11
designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java

@ -8,7 +8,8 @@ import com.fr.design.DesignModelAdapter;
import com.fr.design.actions.UpdateAction;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.data.tabledata.tabledatapane.TableDataManagerPane;
import com.fr.design.dialog.BasicDialog;
@ -24,10 +25,8 @@ import com.fr.esd.event.DSMapping;
import com.fr.esd.event.DsNameTarget;
import com.fr.esd.event.StrategyEventsNotifier;
import com.fr.file.TableDataConfig;
import com.fr.report.LockItem;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
@ -85,11 +84,7 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS
// 锁定成功,执行后续操作
final DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
final List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, TableData> tableDataMap = new HashMap<>();
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);

23
designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java

@ -10,7 +10,7 @@ import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.design.data.BasicTableDataUtils;
import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.MapCompareUtils;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.controlpane.JListControlPane;
import com.fr.design.gui.controlpane.NameableCreator;
@ -261,13 +261,28 @@ public class TableDataPaneListPane extends JListControlPane implements TableData
try {
switch (entryEventKind) {
case REMOVED:
deleteDatas.add(TableDataBeanHelper.getServerDataSetBean(s, tabledata));
ServerDataSetBean remove = TableDataBeanHelper.getServerDataSetBean(s, tabledata);
if (StringUtils.isNotEmpty(remove.getDatasetData())) {
deleteDatas.add(remove);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", tabledata.getClass());
}
break;
case ADDED:
addDatas.add(TableDataBeanHelper.getServerDataSetBean(s, tabledata));
ServerDataSetBean add = TableDataBeanHelper.getServerDataSetBean(s, tabledata);
if (StringUtils.isNotEmpty(add.getDatasetData())) {
addDatas.add(add);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", tabledata.getClass());
}
break;
case UPDATED:
updateDatas.add(TableDataBeanHelper.getServerDataSetBean(s, tabledata));
ServerDataSetBean update = TableDataBeanHelper.getServerDataSetBean(s, tabledata);
if (StringUtils.isNotEmpty(update.getDatasetData())) {
updateDatas.add(update);
} else {
FineLoggerFactory.getLogger().error("Unable to find the corresponding processor : {}", tabledata.getClass());
}
break;
default:
break;

10
designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataComboBox.java

@ -6,7 +6,8 @@ import com.fr.data.impl.Connection;
import com.fr.data.impl.RecursionTableData;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.design.data.DesignTableDataManager;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.design.data.tabledata.wrapper.ServerTableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper;
@ -14,7 +15,6 @@ import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.icombobox.UIComboBoxRenderer;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
@ -71,11 +71,7 @@ public class TreeTableDataComboBox extends UIComboBox {
// 全局数据集
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
Map<String, TableData> map = new HashMap<>();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);
for (ServerDataSetBean bean : beans) {

10
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java

@ -7,6 +7,7 @@ import com.fr.data.impl.AbstractDatabaseConnection;
import com.fr.data.impl.Connection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.design.DesignerEnvManager;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.editlock.ConnectionLockChangeChecker;
import com.fr.design.editlock.EditLockUtils;
import com.fr.design.gui.ibutton.UIButton;
@ -28,6 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 选择数据连接的下拉框
@ -89,13 +91,13 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
if (noAuthConnections == null) {
return nameList.iterator();
}
List<ConnectionBean> beans = ConnectionRepository.getInstance().getAll();
for (ConnectionBean bean : beans) {
String conName = bean.getName();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
for (Map.Entry<String, Connection> connectionEntry : connectionMap.entrySet()) {
String conName = connectionEntry.getKey();
if (noAuthConnections.contains(conName)) {
continue;
}
filterConnection(bean.getConnection(), conName, nameList);
filterConnection(connectionEntry.getValue(), conName, nameList);
}
return nameList.iterator();
}

14
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java

@ -190,11 +190,11 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
public void populate(Map<String, Connection> connectionMap) {
List<NameObject> nameObjectList = new ArrayList<NameObject>();
populatedConnectionsSnapshot.clear();
List<com.fr.workspace.server.entity.connection.ConnectionBean> beans = ConnectionRepository.getInstance().getAll();
for (com.fr.workspace.server.entity.connection.ConnectionBean entry : beans) {
nameObjectList.add(new NameObject(entry.getName(), entry.getConnection()));
final Map<String, Connection> map = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
for (Map.Entry<String, Connection> entry : map.entrySet()) {
nameObjectList.add(new NameObject(entry.getKey(), entry.getValue()));
try {
populatedConnectionsSnapshot.put(entry.getName(), (Connection) entry.getConnection().clone());
populatedConnectionsSnapshot.put(entry.getKey(), (Connection) entry.getValue().clone());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -365,11 +365,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh
}
public static void showDialog(Window parent) {
List<ConnectionBean> beans = ConnectionRepository.getInstance().getAll();
Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : beans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() {
@Override
public void complete() {

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

@ -366,6 +366,7 @@ public class JDBCDefPane extends JPanel {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
driverLoaders = new HashMap<>();
}
driverLoaders.entrySet().removeIf(entry -> StringUtils.isEmpty(entry.getValue().getDriverClass()));
nameAndRepresent = getDriverLoaderAndRepresent(driverLoaders);
}

19
designer-base/src/main/java/com/fr/design/data/datapane/connect/LocalConnectionSource.java

@ -1,16 +1,21 @@
package com.fr.design.data.datapane.connect;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fr.data.driver.DriverClassNotFoundException;
import com.fr.data.impl.Connection;
import com.fr.decision.webservice.bean.datasource.ConnectionInfoBean;
import com.fr.decision.webservice.exception.general.DriverNotFoundException;
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.ConnectionProcessorFactory;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.workspace.engine.exception.DriverUnExistException;
import com.fr.workspace.server.repository.connection.BaseConnectionSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 本地Connection资源操作
@ -21,6 +26,20 @@ import java.sql.SQLException;
*/
public class LocalConnectionSource extends BaseConnectionSource {
@Override
public ConnectionInfoBean[] getAll(){
Map<String, Connection> map = ConnectionConfigProviderFactory.getConfigProvider().getConnections();
List<ConnectionInfoBean> beans = new ArrayList<>();
for (String name : map.keySet()) {
try {
beans.add(ConnectionInfoBeanHelper.createConnectionInfoBean(name, map.get(name)));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return beans.toArray(new ConnectionInfoBean[0]);
}
@Override
public void testConnection(ConnectionInfoBean database) throws Exception {
try {

140
designer-base/src/main/java/com/fr/design/data/datapane/preview/ConnectionInfoBeanHelper.java

@ -3,6 +3,7 @@ package com.fr.design.data.datapane.preview;
import com.fr.data.auth.AuthenticationType;
import com.fr.data.auth.kerberos.KerberosAuthentication;
import com.fr.data.auth.kerberos.KerberosUtils;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.data.impl.Connection;
import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.impl.NameDatabaseConnection;
@ -10,7 +11,9 @@ import com.fr.data.pool.DBCPConnectionPoolAttr;
import com.fr.data.security.ssh.BaseSsh;
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.BaseSsl;
import com.fr.data.security.ssl.Ssl;
import com.fr.data.security.ssl.SslType;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.decision.privilege.TransmissionTool;
@ -19,11 +22,21 @@ import com.fr.decision.webservice.bean.datasource.JDBCConnectionBean;
import com.fr.decision.webservice.utils.DecisionServiceConstants;
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.ConnectionProcessorFactory;
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.JDBCConnectionProcessor;
import com.fr.log.FineLoggerFactory;
import com.fr.module.tool.ActivatorToolBox;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import com.fr.third.fasterxml.jackson.core.JsonProcessingException;
import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
import com.fr.third.springframework.beans.BeanUtils;
import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.DataEncryptionHelper;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* 数据连接传输工具类
@ -34,6 +47,36 @@ import com.fr.workspace.server.repository.connection.ConnectionRepository;
*/
public class ConnectionInfoBeanHelper {
private static ObjectMapper objectMapper = new ObjectMapper();
private static final Map<String, Integer> FETCH_SIZE_MAP = ActivatorToolBox.sandbox(new HashMap<String, Integer>());
private static final int ORACLE_DEFAULT_FETCH_SIZE = 128;
private static final int DB2_DEFAULT_FETCH_SIZE = 50;
private static final int POSTGRE_DEFAULT_FETCH_SIZE = 10000;
static {
FETCH_SIZE_MAP.put("oracle", ORACLE_DEFAULT_FETCH_SIZE);
FETCH_SIZE_MAP.put("ibm-db2", DB2_DEFAULT_FETCH_SIZE);
FETCH_SIZE_MAP.put("postgresql", POSTGRE_DEFAULT_FETCH_SIZE);
}
/**
* 获取连接Map
*/
public static Map<String, Connection> createConnectionMap(ConnectionInfoBean[] beans) {
Map<String, Connection> ans = new HashMap<>();
for (ConnectionInfoBean infoBean : beans) {
try {
if (JDBCConnectionProcessor.KEY.acceptConnectionTypes().contains(infoBean.getConnectionType())) {
ans.put(infoBean.getConnectionName(), createJDBCConnection(infoBean));
} else {
ans.put(infoBean.getConnectionName(), ConnectionProcessorFactory.createConnection(infoBean, true));
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
return ans;
}
/**
* 创建数据连接Bean可自定义是否携带密码
@ -137,4 +180,101 @@ public class ConnectionInfoBeanHelper {
return TransmissionEncryptionManager.getInstance().getEncryption(WorkplaceConstants.getEncryptionMode()).encrypt(password, WorkplaceConstants.getEncryptionKey());
}
private static Connection createJDBCConnection(ConnectionInfoBean connectionInfoBean) throws Exception {
String name = connectionInfoBean.getConnectionName();
if (StringUtils.isNotEmpty(connectionInfoBean.getConnectionId())) {
name = connectionInfoBean.getConnectionId();
}
JDBCDatabaseConnection connection = new JDBCDatabaseConnection();
JDBCConnectionBean bean = objectMapper.readValue(connectionInfoBean.getConnectionData(), JDBCConnectionBean.class);
if (StringUtils.isNotEmpty(name)) {
bean.setConnectionName(name);
}
DBCPConnectionPoolAttr connectionPoolAttr = new DBCPConnectionPoolAttr();
BeanUtils.copyProperties(bean.getConnectionPoolAttr(), connectionPoolAttr);
connectionPoolAttr.setValidationQuery(DataEncryptionHelper.decrypt(connectionPoolAttr.getValidationQuery()));
connectionPoolAttr.setMinEvictableIdleTimeMillis(bean.getConnectionPoolAttr().getMinEvictableIdleTimeMillis() * Constants.MILLS_PER_SECOND);
connectionPoolAttr.setMaxEvictableIdleTimeMillis((long) bean.getConnectionPoolAttr().getMaxEvictableIdleTimeMillis() * Constants.MILLS_PER_SECOND);
connection.setDatabase(bean.getDatabase());
connection.setSchema(bean.getSchema());
connection.setDriver(bean.getDriver());
connection.setURL(bean.getUrl());
connection.setOriginalCharsetName(StringUtils.isEmpty(bean.getOriginalCharsetName()) ? null : bean.getOriginalCharsetName());
connection.setNewCharsetName(StringUtils.isEmpty(bean.getNewCharsetName()) ? null : bean.getNewCharsetName());
connection.setCreator(bean.getCreator());
connection.setDriverSource(bean.getDriverSource());
connection.setDbcpAttr(connectionPoolAttr);
if (StringUtils.isNotEmpty(bean.getAuthType())) {
connection.setAuthentication(new KerberosAuthentication(bean.getPrincipal(), bean.getKeyPath(), bean.isUseJaas()));
}
connection.setUser(bean.getUser());
TransmissionEncryptionManager.getInstance().setCurrentEncryptionMode(WorkplaceConstants.getDecryptionMode());
connection.setPassword(DataEncryptionHelper.decrypt(bean.getPassword()));
connection.setProperties(bean.getProperties());
setFetchSize(bean, connection);
if (bean.getIdentity() != null) {
connection.setIdentity(bean.getIdentity());
}
BaseSsh baseSsh;
String sshType = bean.getSshType();
if (SshType.KEY.toString().equals(sshType)) {
baseSsh = new KeyVerifySsh();
((KeyVerifySsh) baseSsh).setPrivateKeyPath(bean.getSshPrivateKeyPath());
} else {
baseSsh = new NormalSsh();
}
baseSsh.setIp(bean.getSshIp());
baseSsh.setUsingSsh(bean.isUsingSsh());
baseSsh.setPort(bean.getSshPort());
baseSsh.setUser(bean.getSshUser());
baseSsh.setRedirectIp(bean.getRedirectIp());
baseSsh.setRedirectPort(bean.getRedirectPort());
baseSsh.setSecret(DataEncryptionHelper.decrypt(bean.getSshSecret()));
baseSsh.setKeepAlive(bean.getSshKeepAlive());
baseSsh.setTimeOut(bean.getSshTimeOut());
connection.setSsh(baseSsh);
connection.setSsl(createSsl(bean));
return connection;
}
private static Ssl createSsl(JDBCConnectionBean bean) {
//目前只有NormalSsl
BaseSsl baseSsl = new NormalSsl();
if (SslType.NORMAL.toString().equals(bean.getSslType())) {
((NormalSsl) baseSsl).setVerifyCa(bean.isVerifyCa());
((NormalSsl) baseSsl).setCipher(bean.getSslCipher());
}
baseSsl.setUsingSsl(bean.isUsingSsl());
baseSsl.setClientCertificate(bean.getSslClientCertificate());
baseSsl.setClientPrivateKey(bean.getSslClientPrivateKey());
baseSsl.setCaCertificate(bean.getCaCertificate());
return baseSsl;
}
/**
* 前端客户设置了一个fetchSize
* 1. 如果是合法值(>0)就使用
* 2. 如果是非法值(<=0)
* 2.1 如果我们对这种数据库有默认的fetchSize就用默认的
* 2.2 如果没有默认值就不进行任何设置
* @param bean bean
* @param connection connection
*/
private static void setFetchSize(JDBCConnectionBean bean, Connection connection) {
int connectionBeanFetchSize = bean.getFetchSize();
String connectionBeanDatabaseName = bean.getDatabase();
if (DialectFactory.isValidFetchSize(connectionBeanFetchSize)) {
connection.setFetchSize(connectionBeanFetchSize);
} else if (FETCH_SIZE_MAP.containsKey(connectionBeanDatabaseName)) {
Optional.ofNullable(FETCH_SIZE_MAP.get(connectionBeanDatabaseName)).ifPresent(connection::setFetchSize);
}
FineLoggerFactory.getLogger().info("[Connection] fetchSize set to {} for connection {}", connection.getFetchSize(), bean.getConnectionName());
}
}

198
designer-base/src/main/java/com/fr/design/data/datapane/preview/TableDataBeanHelper.java

@ -0,0 +1,198 @@
package com.fr.design.data.datapane.preview;
import com.fr.base.DataSetProcessors;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.base.ParameterTypeHandler;
import com.fr.base.StoreProcedureParameter;
import com.fr.base.TableData;
import com.fr.data.impl.Connection;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.decision.fun.UniversalServerTableDataProvider;
import com.fr.decision.webservice.bean.dataset.ParameterBean;
import com.fr.decision.webservice.bean.dataset.ParameterExternal;
import com.fr.decision.webservice.bean.dataset.SQLDataSetBean;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.decision.webservice.bean.dataset.StoreProcedureBean;
import com.fr.decision.webservice.v10.datasource.dataset.processor.impl.SQLDataSetProcessor;
import com.fr.decision.webservice.v10.datasource.dataset.processor.impl.StoreProcedureProcessor;
import com.fr.general.GeneralUtils;
import com.fr.general.sql.SqlUtils;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.script.Calculator;
import com.fr.security.encryption.transmission.TransmissionEncryptionManager;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.DataEncryptionHelper;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 数据集bean工具类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2024/8/9
*/
public class TableDataBeanHelper {
/**
* 获取服务器数据集
*/
public static Map<String, TableData> getServerTableDatas() {
final List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
final Map<String, TableData> tableDataMap = new HashMap<>();
try {
TransmissionEncryptionManager.setTransEncryptionLevel(1);
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName() , TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
TransmissionEncryptionManager.removeTransEncryptionLevel();
}
return tableDataMap;
}
/**
* 根据序列化数据生成tabledata
*/
public static TableData getTableDataSet(Map<String, Connection> connectionMap, String type, String tableDataSetData) throws Exception {
if (DataSetProcessors.getProcessors().containsKey(type)) {
if (StringUtils.equals(SQLDataSetProcessor.TYPE, type)) {
return deserialize4SQL(connectionMap, null, new JSONObject(tableDataSetData));
} else if (StringUtils.equals(StoreProcedureProcessor.TYPE, type)) {
return deserialize4Procedure(connectionMap, null, new JSONObject(tableDataSetData));
} else {
UniversalServerTableDataProvider processor = DataSetProcessors.getProcessors().get(type);
return (TableData) processor.deserialize(null, new JSONObject(tableDataSetData));
}
}
return null;
}
private static TableData deserialize4Procedure(Map<String, Connection> connectionMap, DBTableData oldDataSet, JSONObject object) {
StoreProcedure storeProcedure = new StoreProcedure();
StoreProcedureBean bean = object.mapTo(StoreProcedureBean.class);
storeProcedure.setShare(bean.isShare());
storeProcedure.setMaxMemRowCount(bean.getMaxMemRowCount());
storeProcedure.setQuery(bean.getQuery());
if (StringUtils.isNotEmpty(bean.getDatabase())) {
Connection connection = connectionMap.get(bean.getDatabase());
if (connection != null) {
storeProcedure.setDatabaseConnection(new NameDatabaseConnection(bean.getDatabase()));
} else {
FineLoggerFactory.getLogger().info("not find conn by {}", bean.getDatabase());
}
}
Parameter[] parameters = new Parameter[bean.getParameters().size()];
for (int i = 0; i < parameters.length; i++) {
ParameterBean parameterBean = bean.getParameters().get(i);
parameters[i] = (Parameter) ParameterTypeHandler.getInstance().parseParameter(parameterBean, new Parameter(parameterBean.getName()));
}
List<ParameterExternal> externals = bean.getStoreProcedureParameterBeanList();
StoreProcedureParameter[] procedureParameters = new StoreProcedureParameter[bean.getParameters().size()];
for (int i = 0; i < procedureParameters.length; i++) {
StoreProcedureParameter storeProcedureParameter = new StoreProcedureParameter();
storeProcedureParameter.setName(parameters[i].getName());
storeProcedureParameter.setValue(parameters[i].getValue());
storeProcedureParameter.setSchema(externals.get(i).getSchema());
storeProcedureParameter.setType(externals.get(i).getTypeInt());
procedureParameters[i] = storeProcedureParameter;
}
storeProcedure.setParameters(procedureParameters);
return storeProcedure;
}
/**
* 获取服务器数据集传输的bean
*/
public static ServerDataSetBean getServerDataSetBean(String name, TableData tableData) {
for (UniversalServerTableDataProvider processor : DataSetProcessors.getProcessors().values()) {
if (SQLDataSetProcessor.KEY.classForTableData() == tableData.getClass()) {
return serialize4SQL(name, tableData);
} else if (processor.classForTableData() == tableData.getClass()) {
ServerDataSetBean bean = new ServerDataSetBean();
try {
bean.setDatasetData(processor.serialize(tableData).toString());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
bean.setDatasetData(StringUtils.EMPTY);
}
bean.setDatasetName(name);
bean.setDatasetId(name);
bean.setDatasetType(processor.nameForTableData());
return bean;
}
}
return new ServerDataSetBean(name);
}
private static ServerDataSetBean serialize4SQL(String name, TableData tableData) {
ServerDataSetBean bean = new ServerDataSetBean();
try {
bean.setDatasetData(serialize4SQL0((DBTableData) tableData).toString());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
bean.setDatasetData(StringUtils.EMPTY);
}
bean.setDatasetName(name);
bean.setDatasetId(name);
bean.setDatasetType(SQLDataSetProcessor.KEY.nameForTableData());
return bean;
}
private static Object serialize4SQL0(DBTableData dataSet) {
SQLDataSetBean bean = new SQLDataSetBean();
if (dataSet.getDatabase() instanceof NameDatabaseConnection) {
bean.setDatabase(((NameDatabaseConnection) dataSet.getDatabase()).getName());
}
bean.setQuery(DataEncryptionHelper.encrypt(dataSet.getQuery()));
List<ParameterBean> parameterBeans = new ArrayList<>();
ParameterProvider[] parameters = dataSet.getParameters(Calculator.createCalculator());
for (ParameterProvider parameter : parameters) {
parameterBeans.add(new ParameterBean(parameter.getValue().getClass().getSimpleName(), parameter.getName(), GeneralUtils.objectToString(parameter.getValue())));
}
bean.setParameters(parameterBeans);
return JSONObject.mapFrom(bean);
}
private static TableData deserialize4SQL(Map<String, Connection> connectionMap, DBTableData oldDataSet, JSONObject object) {
DBTableData tableData = new DBTableData();
SQLDataSetBean bean = object.mapTo(SQLDataSetBean.class);
tableData.setQuery(DataEncryptionHelper.decrypt(bean.getQuery()));
Connection connection = connectionMap.get(bean.getDatabase());
if (connection != null) {
tableData.setDatabase(new NameDatabaseConnection(bean.getDatabase()));
} else {
FineLoggerFactory.getLogger().info("not find conn by {}", bean.getDatabase());
}
String sql = SqlUtils.clearSqlComments(DataEncryptionHelper.decrypt(bean.getQuery()));
Parameter[] parameters = new Parameter[bean.getParameters().size()];
for (int i = 0; i < parameters.length; i++) {
ParameterBean parameterBean = bean.getParameters().get(i);
parameters[i] = (Parameter) ParameterTypeHandler.getInstance().parseParameter(parameterBean, new Parameter(parameterBean.getName()));
}
tableData.setParameters(ParameterHelper.analyzeAndUnionSameParameters(new String[]{sql}, parameters));
if (oldDataSet != null) {
tableData.setMaxMemRowCount(oldDataSet.getMaxMemRowCount());
tableData.setPageQuerySql(oldDataSet.getPageQuerySql());
tableData.setShare(oldDataSet.isShare());
tableData.setDataQueryProcessor(oldDataSet.getDataQueryProcessor());
}
return tableData;
}
}

34
designer-base/src/main/java/com/fr/design/data/tabledata/LocalTableDataSource.java

@ -1,13 +1,18 @@
package com.fr.design.data.tabledata;
import com.fanruan.config.impl.data.ConnectionConfigProviderFactory;
import com.fanruan.config.impl.data.TableDataConfigProviderFactory;
import com.fr.base.TableData;
import com.fr.decision.webservice.bean.dataset.FileDataSetBean;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.decision.webservice.bean.entry.FileNodeBean;
import com.fr.decision.webservice.v10.datasource.dataset.processor.impl.FileProcessor;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.repository.tabledata.BaseTableDataSource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -61,4 +66,33 @@ public class LocalTableDataSource extends BaseTableDataSource {
return false;
}
}
@Override
public List<ServerDataSetBean> getAllTableData() {
List<ServerDataSetBean> beans = new ArrayList<>();
TableData[] tableDatas = TableDataConfigProviderFactory.getInstance().getTableDatas().values().toArray(new TableData[0]);
for (TableData data : tableDatas) {
beans.add(TableDataBeanHelper.getServerDataSetBean(data.getName(), data));
}
return beans;
}
@Override
public void add(ServerDataSetBean bean) throws Exception {
TableDataConfigProviderFactory.getInstance().addTableData(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(ConnectionConfigProviderFactory.getConfigProvider().getConnections(), bean.getDatasetType(), bean.getDatasetData()));
}
@Override
public void delete(ServerDataSetBean bean) throws Exception {
TableDataConfigProviderFactory.getInstance().removeTableData(bean.getDatasetName());
}
@Override
public void update(ServerDataSetBean bean) throws Exception {
TableDataConfigProviderFactory.getInstance().updateTableData(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(ConnectionConfigProviderFactory.getConfigProvider().getConnections(), bean.getDatasetType(), bean.getDatasetData()));
}
}

16
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java

@ -15,6 +15,7 @@ import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.datacenters.tabledata.DCTableData;
import com.fr.decision.webservice.bean.dataset.ServerDataSetBean;
import com.fr.design.data.datapane.TableDataNameObjectCreator;
import com.fr.design.data.datapane.preview.ConnectionInfoBeanHelper;
import com.fr.design.data.tabledata.datacenter.DCTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane;
import com.fr.design.data.tabledata.tabledatapane.ClassTableDataPane;
@ -29,9 +30,8 @@ import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.entity.connection.ConnectionBean;
import com.fr.workspace.server.repository.connection.ConnectionRepository;
import com.fr.workspace.server.repository.tabledata.TableDataBeanHelper;
import com.fr.design.data.datapane.preview.TableDataBeanHelper;
import com.fr.workspace.server.repository.tabledata.TableDataRepository;
import javax.swing.Icon;
@ -205,11 +205,7 @@ public abstract class TableDataFactory {
clearAll();
try {
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
Map<String, TableData> tableDataMap = new HashMap<>();
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
@ -233,11 +229,7 @@ public abstract class TableDataFactory {
Map<String, TableData> tableDataMap = new HashMap<>();
try {
List<ServerDataSetBean> beans = TableDataRepository.getInstance().getAllTableData();
final List<ConnectionBean> connectionInfoBeans = ConnectionRepository.getInstance().getAll();
final Map<String, Connection> connectionMap = new HashMap<>();
for (ConnectionBean bean : connectionInfoBeans) {
connectionMap.put(bean.getName(), bean.getConnection());
}
final Map<String, Connection> connectionMap = ConnectionInfoBeanHelper.createConnectionMap(ConnectionRepository.getInstance().getAll());
for (ServerDataSetBean bean : beans) {
tableDataMap.put(bean.getDatasetName(), TableDataBeanHelper.getTableDataSet(connectionMap, bean.getDatasetType(), bean.getDatasetData()));
}

42
designer-base/src/main/java/com/fr/design/extra/LoginDialog.java

@ -1,42 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StableUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by vito on 2017/5/5.
*/
public class LoginDialog extends UIDialog {
private static final Dimension DEFAULT_SHOP = new Dimension(401, 301);
public LoginDialog(Frame frame, Component pane) {
super(frame);
init(pane);
}
public LoginDialog(Dialog dialog, Component pane) {
super(dialog);
init(pane);
}
private void init(Component pane) {
if (StableUtils.getMajorJavaVersion() >= 8) {
setUndecorated(true);
}
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT_SHOP);
GUICoreUtils.centerWindow(this);
setResizable(false);
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

200
designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java

@ -1,200 +0,0 @@
package com.fr.design.extra;
import com.fanruan.carina.Carina;
import com.fanruan.cloud.FanruanCloud;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.login.service.DesignerLoginClient;
import com.fr.design.login.service.DesignerLoginResult;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpClient;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author vito
*/
public class LoginWebBridge {
//最低消息的条数
private static final int MIN_MESSAGE_COUNT = 0;
//网络连接失败
private static final String NET_FAILED = "-4";
//用户名,密码为空
private static final String LOGIN_INFO_EMPTY = "-5";
private static final Color LOGIN_BACKGROUND = new Color(184, 220, 242);
private static LoginWebBridge helper;
//消息条数
private int messageCount;
private UIDialog uiDialog;
private UIDialog qqDialog;
private UILabel uiLabel;
private WebEngine webEngine;
private LoginWebBridge() {
}
public static LoginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (LoginWebBridge.class) {
if (helper == null) {
helper = new LoginWebBridge();
}
return helper;
}
}
public static LoginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setWebEngine(webEngine);
return helper;
}
public void setWebEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public int getMessageCount() {
return messageCount;
}
/**
* 设置获取的消息长度并设置显示
*
* @param count
*/
public void setMessageCount(int count) {
if (count == MIN_MESSAGE_COUNT) {
Carina.config(FineBBSConfigProvider.class).setBbsUsername(DesignerEnvManager.getEnvManager().getDesignerLoginUsername());
return;
}
this.messageCount = count;
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.BLANK).append(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())
.append("(").append(this.messageCount)
.append(")").append(StringUtils.BLANK);
Carina.config(FineBBSConfigProvider.class).setBbsUsername(sb.toString());
}
public void setQQDialog(UIDialog qqDialog) {
closeQQWindow();
this.qqDialog = qqDialog;
}
public void setDialogHandle(UIDialog uiDialog) {
closeWindow();
this.uiDialog = uiDialog;
}
public void setUILabel(UILabel uiLabel) {
this.uiLabel = uiLabel;
}
/**
* 测试论坛网络连接
*
* @return
*/
private boolean testConnection() {
HttpClient client = new HttpClient(CloudCenter.getInstance().acquireUrlByKind("bbs.test"));
return client.isServerAlive();
}
/**
* 注册页面
*/
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 忘记密码
*/
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @return 登录信息标志
*/
public void defaultLogin(String username, String password, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new PluginLoginExecutor(username, password));
ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("bbsDefaultLogin"));
es.submit(task);
es.shutdown();
}
/**
* 登录操作
*
* @param userInfo 登录信息
* @param password 密码
* @return 登录信息标志
*/
public String login(String userInfo, String password) {
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.login(userInfo, password);
int uid = result.getUid();
if (uid > 0) {
closeWindow();
}
return String.valueOf(uid);
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
}
/**
* 关闭QQ授权窗口
*/
public void closeQQWindow() {
if (qqDialog != null) {
qqDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
qqDialog.setVisible(false);
}
}
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
// do nothing
}
}

54
designer-base/src/main/java/com/fr/design/extra/LoginWebPane.java

@ -1,54 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.FineJOptionPane;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.*;
/**
* Created by zhaohehe on 16/7/26.
*/
public class LoginWebPane extends JFXPanel {
public LoginWebPane(final String installHome) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
LoginWebPane.this.setScene(scene);
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load("file:///" + installHome + "/scripts/login.html");
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
JSObject obj = (JSObject) webEngine.executeScript("window");
obj.setMember("LoginHelper", LoginWebBridge.getHelper(webEngine));
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}
});
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(LoginWebPane.this, message);
}
});
}
}

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

@ -30,13 +30,11 @@ import com.fr.plugin.view.PluginView;
import com.fr.plugin.xml.PluginElementName;
import com.fr.plugin.xml.PluginXmlElement;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSArray;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.File;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;

601
designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java

@ -1,601 +0,0 @@
package com.fr.design.extra;
import com.fanruan.carina.Carina;
import com.fanruan.cloud.FanruanCloud;
import com.fanruan.config.bbs.FineBBSConfigProvider;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.GetInstalledPluginsExecutor;
import com.fr.design.extra.exe.GetPluginCategoriesExecutor;
import com.fr.design.extra.exe.GetPluginFromStoreExecutor;
import com.fr.design.extra.exe.GetPluginPrefixExecutor;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.extra.exe.ReadUpdateOnlineExecutor;
import com.fr.design.extra.exe.SearchOnlineExecutor;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.DesignerLoginSource;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.concurrent.ThreadFactoryBuilder;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import javafx.concurrent.Task;
import javafx.scene.web.WebEngine;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 开放给Web组件的接口,用于安装,卸载,更新以及更改插件可用状态
*/
public class PluginWebBridge {
private static final String THREAD_NAME_TEMPLATE = "pluginbridge-thread-%s";
private static final String ACTION = "action";
private static final String KEYWORD = "keyword";
private static final String PLUGIN_INFO = "pluginInfo";
private static final int COREPOOLSIZE = 3;
private static final int MAXPOOLSIZE = 5;
private static PluginWebBridge helper;
private UIDialog uiDialog;
private ACTIONS actions;
private Map<String, Object> config;
private WebEngine webEngine;
private ExecutorService threadPoolExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXPOOLSIZE,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(COREPOOLSIZE),
new ThreadFactoryBuilder().setNameFormat(THREAD_NAME_TEMPLATE).build());
private PluginWebBridge() {
}
public static PluginWebBridge getHelper() {
if (helper != null) {
return helper;
}
synchronized (PluginWebBridge.class) {
if (helper == null) {
helper = new PluginWebBridge();
}
return helper;
}
}
public static PluginWebBridge getHelper(WebEngine webEngine) {
getHelper();
helper.setEngine(webEngine);
return helper;
}
/**
* 获取打开动作配置
*
* @return 配置信息
*/
public String getRunConfig() {
if (actions != null) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(ACTION, actions.getContext());
Set<String> keySet = config.keySet();
for (String key : keySet) {
jsonObject.put(key, config.get(key).toString());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return jsonObject.toString();
}
return StringUtils.EMPTY;
}
/**
* 配置打开动作
*
* @param action 动作
* @param config 参数
*/
public void setRunConfig(ACTIONS action, Map<String, Object> config) {
this.actions = action;
this.config = config;
}
/**
* 清楚打开动作
*/
public void clearRunConfig() {
this.actions = null;
this.config = null;
}
/**
* 打开时搜索
*
* @param keyword 关键词
*/
public void openWithSearch(String keyword) {
HashMap<String, Object> map = new HashMap<String, Object>(2);
map.put(KEYWORD, keyword);
setRunConfig(ACTIONS.SEARCH, map);
}
/**
* 根据插件信息跳转到应用中心
*
* @param keyword
* @param pluginInfo
*/
public void showResultInStore(String keyword, String pluginInfo) {
HashMap<String, Object> map = new HashMap<>();
map.put(KEYWORD, keyword);
map.put(PLUGIN_INFO, pluginInfo);
setRunConfig(ACTIONS.SHOW_RESULT, map);
}
public void setEngine(WebEngine webEngine) {
this.webEngine = webEngine;
}
public void setDialogHandle(UIDialog uiDialog) {
closeWindow();
this.uiDialog = uiDialog;
}
/**
* 从插件服务器上安装插件
*
* @param pluginInfo 插件的ID
* @param callback 回调函数
*/
public void installPluginOnline(final String pluginInfo, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
public void installPluginFromDisk(final String filePath, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback);
}
/**
* 卸载当前选中的插件
*
* @param pluginInfo 插件信息
*/
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
public void updatePluginOnline(JSObject pluginIDs, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
String[] pluginInfos = jsObjectToStringArray(pluginIDs);
List<PluginMarker> pluginMarkerList = new ArrayList<PluginMarker>();
for (int i = 0; i < pluginInfos.length; i++) {
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginInfos[i]));
}
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
public void updatePluginFromDisk(String filePath, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
public void setPluginActive(String pluginID, final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 已安装插件检查更新
*/
public void readUpdateOnline(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new ReadUpdateOnlineExecutor());
threadPoolExecutor.submit(task);
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
public String showFileChooserWithFilter(String des, String filter) {
FileChooser fileChooser = new FileChooser();
if (StringUtils.isNotEmpty(filter)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filter));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
public String showFileChooserWithFilters(String des, JSObject args) {
FileChooser fileChooser = new FileChooser();
String[] filters = jsObjectToStringArray(args);
if (ArrayUtils.isNotEmpty(filters)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(des, filters));
}
File selectedFile = fileChooser.showOpenDialog(new Stage());
if (selectedFile == null) {
return null;
}
return selectedFile.getAbsolutePath();
}
/**
* 获取已经安装的插件的数组
*
* @return 已安装的插件组成的数组
*/
public void getInstalledPlugins(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetInstalledPluginsExecutor());
threadPoolExecutor.submit(task);
}
private String[] jsObjectToStringArray(JSObject obj) {
if (obj == null) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
int len = (int) obj.getMember("length");
List<String> list = new ArrayList<>();
for (int i = 0; i < len; i++) {
list.add(obj.getSlot(i).toString());
}
return list.toArray(new String[len]);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
public void searchPlugin(String keyword, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new SearchOnlineExecutor(keyword));
threadPoolExecutor.submit(task);
}
/**
* 根据条件获取在线插件的
*
* @param category 分类
* @param seller 卖家性质
* @param fee 收费类型
* @param callback 回调函数
*/
public void getPluginFromStore(String category, String seller, String fee, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(category, seller, fee, ""));
threadPoolExecutor.submit(task);
}
/**
* 根据条件获取在线插件
*
* @param info 插件信息
* @param callback 回调函数
*/
public void getPluginFromStoreNew(String info, final JSObject callback) {
try {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginFromStoreExecutor(new JSONObject(info)));
threadPoolExecutor.submit(task);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
public void getPluginPrefix(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginPrefixExecutor());
threadPoolExecutor.submit(task);
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
public void getPluginCategories(final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new GetPluginCategoriesExecutor());
threadPoolExecutor.submit(task);
}
/**
* 展示一个重启的对话框(少用,莫名其妙会有bug)
*
* @param message 展示的消息
*/
public void showRestartMessage(String message) {
int rv = JOptionPane.showOptionDialog(
null,
message,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null,
new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Restart_Designer_Later")},
null
);
if (rv == JOptionPane.OK_OPTION) {
RestartHelper.restart();
}
}
/**
* 关闭窗口
*/
public void closeWindow() {
if (uiDialog != null) {
uiDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
uiDialog.setVisible(false);
}
if (uiDialog == DesignerPluginContext.getPluginDialog()) {
DesignerPluginContext.setPluginDialog(null);
}
}
/**
* 窗口是否无装饰(判断是否使用系统标题栏)
*/
public boolean isCustomTitleBar() {
if (uiDialog != null) {
return uiDialog.isUndecorated();
}
return false;
}
/**
* 获取系统登录的用户名
*
* @param callback
*/
public String getLoginInfo(final JSObject callback) {
registerLoginInfo(callback);
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
* 系统登录注册
*
* @param callback
*/
public void registerLoginInfo(final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.getLoginInfo(jsCallback);
}
/**
* 打开论坛消息界面
*/
public void getPriviteMessage() {
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
Desktop.getDesktop().browse(new URI(spaceMark.getValue()));
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
* 打开登录页面
*/
public void loginContent() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
UserLoginContext.fireLoginContextListener(DesignerLoginSource.NORMAL);
}
});
}
/**
* 在本地浏览器里打开url
* tips:重载的时候,需要给js调用的方法需要放在前面,否则可能不会被调用(此乃坑)
* 所以最好的是不要重载在js可以访问的接口文件中
*
* @param url 要打开的地址
*/
public void openShopUrlAtWebBrowser(String url) {
openUrlAtLocalWebBrowser(webEngine, url);
}
/**
* 在本地浏览器里打开url
*
* @param eng web引擎
* @param url 要打开的地址
*/
public void openUrlAtLocalWebBrowser(WebEngine eng, String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (NullPointerException e) {
//此为uri为空时抛出异常
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} catch (IOException e) {
//此为无法获取系统默认浏览器
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 注册页面
*/
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/*-------------------------------登录部分的处理----------------------------------*/
/**
* 忘记密码
*/
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @return 登录信息标志
*/
public void defaultLogin(String username, String password, final JSObject callback) {
Task<Void> task = new PluginTask<>(webEngine, callback, new PluginLoginExecutor(username, password));
threadPoolExecutor.submit(task);
}
/**
* 通过QQ登录后通知登录
*/
public void ucsynLogin(long uid, String username, String password, final JSONObject callback) {
}
/**
* 清除用户信息
*/
public void clearUserInfo() {
Carina.config(FineBBSConfigProvider.class).setBbsUsername(StringUtils.EMPTY);
}
public void getPackInfo(final JSObject callback){
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
jsCallback.execute(StringUtils.EMPTY);
}
/**
* 初始化设计器部分
*/
public void initExtraDiff(final JSObject callback) {
//todo 初始化设计器其他部分
}
/**
* 国际化(用来做兼容暂时不删)
*/
public String parseI18(final String key) {
return com.fr.design.i18n.Toolkit.i18nText(key);
}
/**
* 是否是在设计器中操作
*/
public boolean isDesigner() {
return true;
}
/**
* 动作枚举
*/
public enum ACTIONS {
SEARCH("search"), SHOW_RESULT("showResult");
private String context;
ACTIONS(String context) {
this.context = context;
}
public String getContext() {
return context;
}
}
}

112
designer-base/src/main/java/com/fr/design/extra/PluginWebPane.java

@ -1,112 +0,0 @@
package com.fr.design.extra;
import com.fr.base.TemplateUtils;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* Created by richie on 16/3/19.
*/
public class PluginWebPane extends JFXPanel {
private static final String RESOURCE_URL = "resourceURL";
private static final String LANGUAGE = "language";
private static final String URL_PLUS = "+";
private static final String URL_SPACING = "%20";
private static final String URL_PREFIX = "file:///";
private WebEngine webEngine;
public PluginWebPane(final String installHome, final String mainJs) {
Platform.setImplicitExit(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
BorderPane root = new BorderPane();
Scene scene = new Scene(root);
PluginWebPane.this.setScene(scene);
WebView webView = new WebView();
webEngine = webView.getEngine();
try{
String htmlString = getRenderedHtml(installHome, mainJs);
webEngine.loadContent(htmlString);
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
showAlert(event.getData());
}
});
JSObject obj = (JSObject) webEngine.executeScript("window");
obj.setMember("PluginHelper", PluginWebBridge.getHelper(webEngine));
webView.setContextMenuEnabled(false);//屏蔽右键
root.setCenter(webView);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
});
}
private String getRenderedHtml(String installHome, String mainJs) throws IOException {
InputStream inp = IOUtils.readResource(StableUtils.pathJoin(installHome, mainJs));
if (inp == null) {
throw new IOException("Not found template: " + mainJs);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inp, StableUtils.RESOURCE_ENCODER));
BufferedReader read = new BufferedReader(reader);
StringBuffer sb = new StringBuffer();
String line;
Map<String, Object> map4Tpl = new HashMap<String, Object>();
//URL中关于空格的编码与空格所在位置相关:空格被编码成+的情况只能在查询字符串部分出现,而被编码成%20则可以出现在路径和查询字符串中
//URLEncoder会将空格转成+,这边需要+转成%20
map4Tpl.put(RESOURCE_URL, URL_PREFIX + URLEncoder.encode(installHome, EncodeConstants.ENCODING_UTF_8).replace(URL_PLUS, URL_SPACING));
map4Tpl.put(LANGUAGE, GeneralContext.getLocale().toString());
while ((line = read.readLine()) != null) {
if (sb.length() > 0) {
sb.append('\n');
}
sb.append(line);
}
String htmlString = StringUtils.EMPTY;
try{
htmlString = TemplateUtils.renderParameter4Tpl(sb.toString(), map4Tpl);
}catch (Exception e){
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
reader.close();
inp.close();
return htmlString;
}
private void showAlert(final String message) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FineJOptionPane.showMessageDialog(PluginWebPane.this, message);
}
});
}
}

32
designer-base/src/main/java/com/fr/design/extra/QQLoginDialog.java

@ -1,32 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by zhaohehe on 16/7/28.
*/
public class QQLoginDialog extends UIDialog {
private static final Dimension DEFAULT_SHOP = new Dimension(700, 500);
public QQLoginDialog(Frame frame, Component pane) {
super(frame);
setUndecorated(true);
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT_SHOP);
GUICoreUtils.centerWindow(this);
setResizable(false);
setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager"));
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

46
designer-base/src/main/java/com/fr/design/extra/ShopDialog.java

@ -1,46 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.jdk.JdkVersion;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StableUtils;
import javax.swing.*;
import java.awt.*;
/**
* Created by vito on 16/4/18.
*/
public class ShopDialog extends UIDialog {
public ShopDialog(Frame frame, BasicPane pane) {
super(frame);
if (StableUtils.getMajorJavaVersion() >= 8) {
setUndecorated(true);
}
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(createDefaultDimension());
GUICoreUtils.centerWindow(this);
setResizable(false);
DesignerPluginContext.setPluginDialog(this);
}
private Dimension createDefaultDimension() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// jdk11 分辨率较低 缩放较大时 屏幕高度小于或接近设定的高度 需要调整下
if (JdkVersion.GE_9.support() && screenSize.height - 700 < 50) {
return new Dimension(900, screenSize.height - 100);
} else {
return new Dimension(900, 700);
}
}
@Override
public void checkValid() throws Exception {
// do nothing
}
}

31
designer-base/src/main/java/com/fr/design/extra/ShopManagerPane.java

@ -1,31 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import java.awt.BorderLayout;
import java.awt.Component;
/**
* @author richie
* @date 2015-03-09
* @since 8.0
* 应用中心的构建采用JavaScript代码来动态实现,但是不总是依赖于服务器端的HTML
* 采用JDK提供的JavaScript引擎,实际是用JavaScript语法实现Java端的功能,并通过JavaScript引擎动态调用
* JavaScript放在安装目录下的scripts/store目录下,检测到新版本的时候,可以通过更新这个目录下的文件实现热更新
* 不直接嵌入WebView组件的原因是什么呢?
* 因为如果直接嵌入WebView,和设计器的交互就需要预先设定好,这样灵活性会差很多,而如果使用JavaScript引擎,
* 就可以直接在JavaScript中和WebView组件做交互,而同时JavaScript中可以调用任何的设计器API.
*/
public class ShopManagerPane extends BasicPane {
public ShopManagerPane(Component webPane) {
setLayout(new BorderLayout());
add(webPane, BorderLayout.CENTER);
}
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager");
}
}

36
designer-base/src/main/java/com/fr/design/extra/ShopPaneConfig.java

@ -1,36 +0,0 @@
package com.fr.design.extra;
import javafx.embed.swing.JFXPanel;
/**
* Created by vito on 2016/9/28.
*/
public abstract class ShopPaneConfig {
private String mainJS;
private String scriptsId;
private JFXPanel webPane;
public ShopPaneConfig() {
this.mainJS = setMainJS();
this.scriptsId = setScriptsId();
this.webPane = setWebPane();
}
abstract String setMainJS();
abstract String setScriptsId();
abstract JFXPanel setWebPane();
public String getMainJS() {
return mainJS;
}
public String getScriptsId() {
return scriptsId;
}
public JFXPanel getWebPane() {
return webPane;
}
}

307
designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java

@ -1,307 +0,0 @@
package com.fr.design.extra;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.CloudCenter;
import com.fr.general.CommonIOUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.PluginStoreConfig;
import com.fr.plugin.PluginStoreConstants;
import com.fr.stable.CommonUtils;
import com.fr.stable.EnvChangedListener;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StableUtils;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.concurrent.ExecutionException;
/**
* 在合适的 jre 环境下创建带有 WebView 的窗口
*
* @author vito
* @date 2016/9/28
*/
public class WebViewDlgHelper {
private static final String LATEST = "latest";
private static final String SHOP_SCRIPTS = "shop_scripts";
private static final int VERSION_8 = 8;
private static String installHome = PluginStoreConstants.getLocalInstallHome();
private static final String MAIN_JS_PATH = "/scripts/plugin.html";
static {
GeneralContext.addEnvChangedListener(new EnvChangedListener() {
@Override
public void envChanged() {
installHome = PluginStoreConstants.getLocalInstallHome();
}
});
}
public static void createPluginDialog() {
if (StableUtils.getMajorJavaVersion() >= VERSION_8) {
String mainJsPath = StableUtils.pathJoin(installHome, MAIN_JS_PATH);
File file = new File(mainJsPath);
if (!file.exists()) {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(SHOP_SCRIPTS);
}
return;
}
// 检测更新前先刷新一下版本号
PluginStoreConstants.refreshProps();
String jarVersion = PluginStoreConfig.getInstance().getEnvVersion();
if (ComparatorUtils.equals(jarVersion, ProductConstants.VERSION)) {
updateShopScripts(SHOP_SCRIPTS);
showPluginDlg();
} else {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install_Version"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(SHOP_SCRIPTS);
deleteExtraFile(StableUtils.pathJoin(installHome, "plugin.html"));
}
}
} else {
BasicPane traditionalStorePane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager");
}
};
traditionalStorePane.setLayout(new BorderLayout());
traditionalStorePane.add(initTraditionalStore(), BorderLayout.CENTER);
UIDialog dlg = new ShopDialog(DesignerContext.getDesignerFrame(), traditionalStorePane);
dlg.setVisible(true);
}
}
/**
* 检查script文件夹中的plugin.html文件
*/
public static void checkAndCopyMainFile(String indexPath, String mainJsPath) {
File file = new File(indexPath);
if (!file.exists()) {
copyMainFile(mainJsPath);
}
}
/**
* 將script文件夹中的plugin.html文件复制到webreport下
*/
private static void copyMainFile(String mainJsPath) {
try {
CommonIOUtils.copy(new File(mainJsPath), new File(installHome));
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除9.0工程下无用的plugin.html文件
*
* @param filePath 待删除文件路径
*/
private static void deleteExtraFile(String filePath) {
CommonIOUtils.deleteFile(new File(filePath));
}
/**
* 以关键词打开设计器商店
*
* @param keyword 关键词
*/
public static void createPluginDialog(String keyword) {
PluginWebBridge.getHelper().openWithSearch(keyword);
createPluginDialog();
}
/**
* 以关键词打开设计器商店显示搜索结果
*
* @param keyword
* @param data
*/
@Deprecated
public static void showPluginInStore(String keyword, String data) {
PluginWebBridge.getHelper().showResultInStore(keyword, data);
createPluginDialog();
}
public static void createLoginDialog() {
if (StableUtils.getMajorJavaVersion() >= VERSION_8) {
File file = new File(StableUtils.pathJoin(installHome, "scripts"));
if (!file.exists()) {
confirmDownLoadShopJS();
} else {
showLoginDlg(DesignerContext.getDesignerFrame());
updateShopScripts(SHOP_SCRIPTS);
}
}
}
public static void createLoginDialog(Window parent) {
if (StableUtils.getMajorJavaVersion() >= VERSION_8) {
File file = new File(StableUtils.pathJoin(installHome, "scripts"));
if (!file.exists()) {
confirmDownLoadShopJS();
} else {
showLoginDlg(parent);
updateShopScripts(SHOP_SCRIPTS);
}
}
}
private static void confirmDownLoadShopJS() {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(SHOP_SCRIPTS);
}
}
private static void showPluginDlg() {
try {
Class<?> clazz = Class.forName("com.fr.design.extra.PluginWebPane");
Constructor constructor = clazz.getConstructor(String.class, String.class);
Component webPane = (Component) constructor.newInstance(installHome, MAIN_JS_PATH);
BasicPane managerPane = new ShopManagerPane(webPane);
UIDialog dlg = new ShopDialog(DesignerContext.getDesignerFrame(), managerPane);
PluginWebBridge.getHelper().setDialogHandle(dlg);
dlg.setVisible(true);
DesignerLoginUtils.showPluginRemindOnFirstLaunch(dlg);
} catch (Exception e) {
// ignored
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private static void showLoginDlg(Window window) {
try {
Class<?> clazz = Class.forName("com.fr.design.extra.LoginWebPane");
Constructor constructor = clazz.getConstructor(String.class);
Component webPane = (Component) constructor.newInstance(installHome);
UIDialog qqdlg;
if (window instanceof Dialog) {
qqdlg = new LoginDialog((Dialog) window, webPane);
} else {
qqdlg = new LoginDialog((Frame) window, webPane);
}
LoginWebBridge.getHelper().setDialogHandle(qqdlg);
qqdlg.setVisible(true);
} catch (Throwable ignored) {
// ignored
}
}
private static Component initTraditionalStore() {
UITabbedPane tabbedPane = new UITabbedPane();
PluginInstalledPane installedPane = new PluginInstalledPane();
tabbedPane.addTab(installedPane.tabTitle(), installedPane);
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Update"), new PluginUpdatePane(tabbedPane));
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_All_Plugins"), new PluginFromStorePane(tabbedPane));
return tabbedPane;
}
private static void downloadShopScripts(final String scriptsId) {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return PluginUtils.downloadShopScripts(scriptsId, new Process<Double>() {
@Override
public void process(Double integer) {
// 这个注释毫无意义,就是为了通过SonarQube
}
});
}
@Override
protected void done() {
try {
if (get()) {
File scriptZip = new File(StableUtils.pathJoin(PluginConstants.DOWNLOAD_PATH, PluginConstants.TEMP_FILE));
if (scriptZip.exists()) {
IOUtils.unzip(scriptZip, installHome);
CommonUtils.deleteFile(scriptZip);
}
PluginStoreConstants.refreshProps(); // 下载完刷新一下版本号等
FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Installed"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), JOptionPane.INFORMATION_MESSAGE);
}
} catch (InterruptedException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}.execute();
}
private static void updateShopScripts(final String scriptsId) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
String url = CloudCenter.getInstance().acquireUrlByKind("shop.plugin.update");
if (url != null) {
String text = HttpToolbox.get(url + "?" + PluginUtils.FR_VERSION + "=" + ProductConstants.VERSION + "&version=" + PluginStoreConfig.getInstance().getVersion());
JSONObject resultJSONObject = new JSONObject(text);
String isLatest = resultJSONObject.optString("result");
if (!ComparatorUtils.equals(isLatest, LATEST)) {
int rv = FineJOptionPane.showConfirmDialog(
null,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Update"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE
);
if (rv == JOptionPane.OK_OPTION) {
downloadShopScripts(scriptsId);
}
}
}
return null;
}
}.execute();
}
}

4
designer-base/src/main/java/com/fr/design/extra/exe/PluginLoginExecutor.java

@ -1,6 +1,5 @@
package com.fr.design.extra.exe;
import com.fr.design.extra.LoginWebBridge;
import com.fr.design.extra.Process;
import com.fr.design.login.service.DesignerPassportManager;
@ -36,9 +35,6 @@ public class PluginLoginExecutor implements Executor {
@Override
public void run(Process<String> process) {
int uid = DesignerPassportManager.getInstance().login(username, password);
if (uid > 0) {
LoginWebBridge.getHelper().closeWindow();
}
result = String.valueOf(uid);
}
}

10
designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java

@ -24,6 +24,9 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.math.BigDecimal;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.row;
/**
* For input Number.
*/
@ -43,16 +46,13 @@ public abstract class UnitInputPane extends BasicPane {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel centerPane = FRGUIPaneFactory.createTitledBorderPane("");
this.add(centerPane, BorderLayout.CENTER);
centerPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 30));
centerPane.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 30));
UILabel titleLabel = new UILabel(title + ":");
centerPane.add(titleLabel);
// Denny:在对话框中加入JSpinner对象
numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, MAX_NUM, 1));
GUICoreUtils.setColumnForSpinner(numberFieldSpinner, 24);
numberFieldSpinner.setPreferredSize(new Dimension(60, 20));
numberFieldSpinner.setMinimumSize(new Dimension(60, 20));
centerPane.add(numberFieldSpinner);
numberFieldSpinner.addChangeListener(new ChangeListener() {
@Override
@ -64,7 +64,7 @@ public abstract class UnitInputPane extends BasicPane {
});
unitLabel = new UILabel("");
centerPane.add(unitLabel);
centerPane.add(row(4, cell(numberFieldSpinner), cell(unitLabel)).getComponent());
}
public void setUnitText(String unit) {

47
designer-base/src/main/java/com/fr/design/jxbrowser/JxUIPane.java

@ -2,19 +2,17 @@ package com.fr.design.jxbrowser;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.ModernUIConstants;
import com.fr.design.ui.ModernUIPane;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import com.fr.stable.os.OperatingSystem;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.event.Observer;
import com.teamdev.jxbrowser.frame.Frame;
import com.teamdev.jxbrowser.js.JsObject;
@ -50,7 +48,7 @@ import static com.fr.design.ui.ModernUIConstants.WINDOW;
* @since 11.0
* Created on 2023-06-12
*/
public class JxUIPane<T> extends ModernUIPane<T> {
public class JxUIPane<T> extends BasicPane {
public static final ExecutorService DEFAULT_EXECUTOR =
Executors.newSingleThreadExecutor(new NamedThreadFactory("jx-simple", true));
@ -68,11 +66,9 @@ public class JxUIPane<T> extends ModernUIPane<T> {
private JxEngine jxEngine = JxEngine.getInstance();
private JxUIPane() {
super();
}
private JxUIPane(JxEngine jxEngine) {
super();
this.jxEngine = jxEngine;
}
@ -155,7 +151,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
*
* @param url 新的地址
*/
@Override
public void redirect(String url) {
browser.navigation().loadUrl(encodeWindowsPath(url));
}
@ -166,7 +161,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
* @param url 新的地址
* @param map 初始化参数
*/
@Override
public void redirect(String url, Map<String, String> map) {
setMap(map);
browser.navigation().loadUrl(encodeWindowsPath(url));
@ -186,7 +180,11 @@ public class JxUIPane<T> extends ModernUIPane<T> {
}
@Override
/**
* 更新数据到界面
*
* @param t 数据类
*/
public void populate(final T t) {
setInjectJsCallback(params -> {
executeJsObject(params.frame(), WINDOW + DOT + namespace)
@ -195,7 +193,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
});
}
@Override
@Nullable
public T update() {
if (browser.mainFrame().isPresent()) {
@ -283,7 +280,7 @@ public class JxUIPane<T> extends ModernUIPane<T> {
*
* @param <T> 参数
*/
public static class Builder<T> extends ModernUIPane.Builder<T> {
public static class Builder<T> {
private JxEngine jxEngine;
private String namespace;
private String variable;
@ -302,8 +299,6 @@ public class JxUIPane<T> extends ModernUIPane<T> {
private String html;
public Builder() {
// 为了兼容继承关系,但又不允许创建,用这个方式先处理一下
super((ModernUIPane<T>) null);
this.jxEngine = JxEngine.getInstance();
this.namespace = DEFAULT_NAMESPACE;
this.variable = DEFAULT_VARIABLE;
@ -342,24 +337,14 @@ public class JxUIPane<T> extends ModernUIPane<T> {
return this;
}
@Override
public Builder<T> prepareForV6(ScriptContextListener contextListener) {
return this;
}
@Override
public Builder<T> prepareForV6(LoadListener loadListener) {
return this;
}
@Override
public JxUIPane.Builder<T> prepareForV7(InjectJsCallback callback) {
prepare(callback);
return this;
}
@Override
public JxUIPane.Builder<T> prepareForV7(Class event, Observer listener) {
/**
* 注册一个监听器
*
* @param event 事件
* @param listener 监听器
* @return builder
*/
public JxUIPane.Builder<T> prepare(Class event, Observer listener) {
listenerPair = new Pair<>(event, listener);
return this;
}

6
designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java

@ -2,10 +2,8 @@ package com.fr.design.login;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.update.ui.dialog.UpdateMainDialog;
import com.fr.general.GeneralContext;
@ -47,10 +45,6 @@ public class DesignerLoginHelper {
}
public static void showLoginDialog(DesignerLoginSource source, Map<String, String> params, Window window) {
if (!SupportOSImpl.DESIGNER_LOGIN.support() || DesignerEnvManager.getEnvManager().isUseOldVersionLogin()) {
WebViewDlgHelper.createLoginDialog(window);
return;
}
boolean hasJxBrowser = true;
try {
Class.forName(JXBROWSER);

30
designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginBrowserExecutor.java

@ -1,30 +0,0 @@
package com.fr.design.login.executor;
import com.fr.design.bridge.exec.JSExecutor;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-18
*/
public class DesignerLoginBrowserExecutor implements JSExecutor {
public static DesignerLoginBrowserExecutor create(JSObject window, JSFunction callback) {
return new DesignerLoginBrowserExecutor(window, callback);
}
private JSObject window;
private JSFunction callback;
private DesignerLoginBrowserExecutor(JSObject window, JSFunction callback) {
this.window = window;
this.callback = callback;
}
@Override
public void executor(String newValue) {
callback.invoke(window, newValue);
}
}

3
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java

@ -43,8 +43,7 @@ public class DesignerGuideHelper {
if (!DesignerLoginUtils.isOnline()
|| !SupportOSImpl.DESIGNER_LOGIN.support()
|| !FRContext.isChineseEnv()
|| DesignerPushUpdateManager.getInstance().isShouldPopUp()
|| DesignerEnvManager.getEnvManager().isUseOldVersionLogin()) {
|| DesignerPushUpdateManager.getInstance().isShouldPopUp()) {
return;
}
if (isActivatedForOneWeek()) {

18
designer-base/src/main/java/com/fr/design/login/message/NotificationActionType.java

@ -1,20 +1,15 @@
package com.fr.design.login.message;
import com.fr.config.ServerPreferenceConfig;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.mainframe.BaseJForm;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.EastRegionContainerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.upm.UpmFinder;
import com.fr.design.utils.DesignUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.bridge.StableFactory;
import com.fr.stable.os.Arch;
import com.fr.stable.os.OperatingSystem;
/**
* @author Lanlan
@ -31,17 +26,10 @@ public enum NotificationActionType {
@Override
public void doClick() {
try {
if (Arch.getArch() == Arch.ARM || OperatingSystem.isLinux() || SupportOSImpl.MACOS_WEB_PLUGIN_MANAGEMENT.support()) {
DesignUtils.visitEnvServerByParameters("#management/plugin", null, null);
return;
}
if (ServerPreferenceConfig.getInstance().isUseOptimizedUPM() || SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()) {
UpmFinder.showUPMDialog();
} else {
WebViewDlgHelper.createPluginDialog();
}
} catch (Exception e) {
UpmFinder.showUPMDialog();
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
DesignUtils.visitEnvServerByParameters("#management/plugin", null, null);
}
}
}),

8
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -100,6 +100,7 @@ import com.fr.stable.core.UUID;
import com.fr.widgettheme.designer.WidgetThemeDisplayAction;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.TplOperator;
import com.fr.workspace.server.repository.WorkplaceConstants;
import com.fr.workspace.server.repository.template.TemplateRepository;
import javax.swing.BorderFactory;
@ -1748,10 +1749,9 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
private boolean checkJTemplateAuthority() {
// todo:微服务待调整
//if (!FSConfig.getInstance().getAuthorizeAttr().isDataConnectionAuthority()) {
// return true;
//}
if (!WorkplaceConstants.isConnectionEditAuth()) {
return true;
}
JTemplateAuthorityChecker jTemplateAuthorityChecker = new JTemplateAuthorityChecker(this);
if (jTemplateAuthorityChecker.isAuthority()) {
return true;

32
designer-base/src/main/java/com/fr/design/os/impl/PMDialogAction.java

@ -1,41 +1,31 @@
package com.fr.design.os.impl;
import com.fr.config.ServerPreferenceConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.jdk.JdkVersion;
import com.fr.design.upm.UpmFinder;
import com.fr.design.utils.DesignUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.os.Arch;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.os.OperatingSystem;
import com.fr.stable.os.support.OSBasedAction;
/**
* 插件管理窗口
*
* @author pengda
* @date 2019/10/9
*/
public class PMDialogAction implements OSBasedAction {
private static String PLUGIN_MANAGER_ROUTE = "#management/plugin";
@Override
public void execute(Object... objects) {
if(Arch.getArch() == Arch.ARM || OperatingSystem.isLinux() || SupportOSImpl.MACOS_WEB_PLUGIN_MANAGEMENT.support()){
DesignUtils.visitEnvServerByParameters( PLUGIN_MANAGER_ROUTE,null,null);
return;
}
if (checkUPMSupport()) {
if (OperatingSystem.isLinux()) {
DesignUtils.visitEnvServerByParameters(PLUGIN_MANAGER_ROUTE, null, null);
return;
}
try {
UpmFinder.showUPMDialog();
} else {
WebViewDlgHelper.createPluginDialog();
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
DesignUtils.visitEnvServerByParameters(PLUGIN_MANAGER_ROUTE, null, null);
}
}
private boolean checkUPMSupport() {
return ServerPreferenceConfig.getInstance().isUseOptimizedUPM()
|| SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()
|| DesignerEnvManager.getEnvManager().isUseOptimizedUPM4Adapter()
//默认开启
|| DesignerEnvManager.getEnvManager().isUseNewPluginFirst();
}
}

55
designer-base/src/main/java/com/fr/design/os/impl/SupportOSImpl.java

@ -2,7 +2,6 @@ package com.fr.design.os.impl;
import com.fr.base.FRContext;
import com.fr.design.config.DesignerProperties;
import com.fr.design.jdk.JdkVersion;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.json.JSON;
@ -31,30 +30,33 @@ public enum SupportOSImpl implements SupportOS {
* 屏蔽登录入口
*/
BBS_USER_LOGIN_PANE {
public boolean support(){
return Arch.getArch() != Arch.ARM && DesignerProperties.getInstance().isSupportLoginEntry();
@Override
public boolean support() {
return DesignerProperties.getInstance().isSupportLoginEntry();
}
},
/**
* Linux系统屏蔽透明度
*/
OPACITY{
public boolean support(){
OPACITY {
@Override
public boolean support() {
return !OperatingSystem.isLinux();
}
},
/**
* Linux系统屏蔽FineUI选项
*/
FINEUI{
public boolean support(){
FINEUI {
@Override
public boolean support() {
return !OperatingSystem.isLinux();
}
},
/**
* 自动更新推送
*/
AUTOPUSHUPDATE{
AUTOPUSHUPDATE {
@Override
public boolean support() {
boolean isLocalEnv = WorkContext.getCurrent().isLocal();
@ -75,7 +77,7 @@ public enum SupportOSImpl implements SupportOS {
/**
* BBS窗口
*/
BBSDIALOG{
BBSDIALOG {
@Override
public boolean support() {
return FRContext.isChineseEnv() && !OperatingSystem.isMacos() && Arch.getArch() != Arch.ARM;
@ -117,7 +119,6 @@ public enum SupportOSImpl implements SupportOS {
/**
* 原生文件选择器弹窗
* https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8019464 mac下原生弹窗国际化设置无效,jdk11中有修复
*
*/
NATIVE_CHOOSER {
@Override
@ -133,23 +134,7 @@ public enum SupportOSImpl implements SupportOS {
}
},
MACOS_NEW_PLUGIN_MANAGEMENT {
@Override
public boolean support() {
return JdkVersion.GE_9.support() && OperatingSystem.isMacos() && getMacOsVersion() < BIG_SUR_VERSION_NUMBER;
}
},
MACOS_WEB_PLUGIN_MANAGEMENT {
@Override
public boolean support() {
return JdkVersion.GE_9.support() && OperatingSystem.isMacos() && getMacOsVersion() >= BIG_SUR_VERSION_NUMBER;
}
},
OLD_STYLE_CHOOSER {
@Override
public boolean support() {
boolean javafxExist = true;
@ -196,23 +181,9 @@ public enum SupportOSImpl implements SupportOS {
DESIGNER_LOGIN {
@Override
public boolean support() {
if (OperatingSystem.isLinux()) {
return false;
}
return !OperatingSystem.isMacos() || getMacOsVersion() < BIG_SUR_VERSION_NUMBER;
}
};
private static final int BIG_SUR_VERSION_NUMBER = 16;
protected int getMacOsVersion() {
String version = System.getProperty("os.version");
String[] versionSlice = version.split("\\.");
try {
return Integer.parseInt(versionSlice[1]);
} catch (Exception ignored) {
return 0;
return !OperatingSystem.isLinux();
}
}
}

91
designer-base/src/main/java/com/fr/design/ui/Assistant.java

@ -1,91 +0,0 @@
package com.fr.design.ui;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserContext;
import com.teamdev.jxbrowser.chromium.BrowserPreferences;
import com.teamdev.jxbrowser.chromium.ProtocolService;
import com.teamdev.jxbrowser.chromium.URLResponse;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-07
*/
public class Assistant {
public static void addChromiumSwitches(String... switches) {
List<String> list = BrowserPreferences.getChromiumSwitches();
Collections.addAll(list, switches);
BrowserPreferences.setChromiumSwitches((list.toArray(new String[0])));
}
public static URLResponse inputStream2Response(InputStream inputStream, String filePath) throws Exception {
URLResponse response = new URLResponse();
DataInputStream stream = new DataInputStream(inputStream);
byte[] data = new byte[stream.available()];
stream.readFully(data);
response.setData(data);
String mimeType = getMimeType(filePath);
response.getHeaders().setHeader("Content-Type", mimeType);
return response;
}
private static String getMimeType(String path) {
if (StringUtils.isBlank(path)) {
return "text/html";
}
if (path.endsWith(".html")) {
return "text/html";
}
if (path.endsWith(".css")) {
return "text/css";
}
if (path.endsWith(".js")) {
return "text/javascript";
}
if (path.endsWith(".svg")) {
return "image/svg+xml";
}
// upm 文件夹中的图片如果返回 Content-type 为 image/png 时会显示异常
if (path.endsWith(".png") && !path.contains("/upm")) {
return "image/png";
}
if (path.endsWith(".woff")) {
return "font/woff";
}
if (path.endsWith(".ttf")) {
return "truetype";
}
if (path.endsWith(".eot")) {
return "embedded-opentype";
}
Path file = new File(path).toPath();
try {
return Files.probeContentType(file);
} catch (IOException e) {
return "text/html";
}
}
public static void setEmbProtocolHandler(Browser browser, EmbProtocolHandler handler) {
BrowserContext browserContext = browser.getContext();
ProtocolService protocolService = browserContext.getProtocolService();
// 支持读取jar包中文件的自定义协议————emb:/com/fr/design/images/bbs.png
protocolService.setProtocolHandler("emb", handler);
protocolService.setProtocolHandler("file", handler);
}
}

135
designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java

@ -1,135 +0,0 @@
package com.fr.design.ui;
import com.fr.base.TemplateUtils;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.codec.net.URLCodec;
import com.fr.third.org.apache.commons.io.FileUtils;
import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.web.struct.AssembleComponent;
import com.fr.web.struct.AtomBuilder;
import com.fr.web.struct.PathGroup;
import com.fr.web.struct.category.ScriptPath;
import com.fr.web.struct.category.StylePath;
import com.teamdev.jxbrowser.chromium.ProtocolHandler;
import com.teamdev.jxbrowser.chromium.URLRequest;
import com.teamdev.jxbrowser.chromium.URLResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-07
*/
public class EmbProtocolHandler implements ProtocolHandler {
private AssembleComponent component;
private Map<String, String> map;
public EmbProtocolHandler() {
}
public EmbProtocolHandler(AssembleComponent component) {
this.component = component;
}
public EmbProtocolHandler(AssembleComponent component, Map<String, String> map) {
this.component = component;
this.map = map;
}
public EmbProtocolHandler(Map<String, String> map) {
this.map = map;
}
@Override
public URLResponse onRequest(URLRequest req) {
InputStream inputStream = null;
try {
String path = req.getURL();
if (path.startsWith("file:")) {
String url = new URLCodec().decode(path);
String filePath = TemplateUtils.renderParameter4Tpl(url, map);
File file = new File(URI.create(filePath).getPath());
inputStream = IOUtils.readResource(file.getAbsolutePath());
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, map);
return Assistant.inputStream2Response(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), path);
} else if (path.startsWith("emb:dynamic")) {
URLResponse response = new URLResponse();
response.setData(htmlText(map).getBytes());
response.getHeaders().setHeader("Content-Type", "text/html");
return response;
} else {
int index = path.indexOf("=");
if (index > 0) {
path = path.substring(index + 1);
} else {
path = path.substring(4);
}
inputStream = IOUtils.readResource(path);
if (path.endsWith(".html")) {
String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8);
text = TemplateUtils.renderParameter4Tpl(text, map);
return Assistant.inputStream2Response(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), path);
}
return Assistant.inputStream2Response(inputStream, path);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
return null;
}
private String htmlText(Map<String, String> map) {
PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component);
StylePath[] stylePaths = pathGroup.toStylePathGroup();
StringBuilder styleText = new StringBuilder();
for (StylePath path : stylePaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
styleText.append("<link rel=\"stylesheet\" href=\"emb:");
styleText.append(path.toFilePath());
styleText.append("\"/>");
}
}
String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString());
ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup();
StringBuilder scriptText = new StringBuilder();
for (ScriptPath path : scriptPaths) {
if (StringUtils.isNotBlank(path.toFilePath())) {
scriptText.append("<script src=\"emb:");
scriptText.append(path.toFilePath());
scriptText.append("\"></script>");
}
}
result = result.replaceAll("##script##", scriptText.toString());
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
result = result.replaceAll("\\$\\{" + key + "}", value);
}
}
return result;
}
}

364
designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java

@ -1,364 +0,0 @@
package com.fr.design.ui;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.i18n.Toolkit;
import com.fr.design.ui.compatible.BuilderDiff;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.web.struct.AssembleComponent;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserType;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;
import com.teamdev.jxbrowser.event.Observer;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Map;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-03-04
* 用于加载html5的Swing容器可以在设计选项设置中打开调试窗口示例可查看com.fr.design.ui.ModernUIPaneTest
* @see {@link com.fr.design.jxbrowser.JxUIPane}
* @deprecated 主要用于jxbrowser6将在下个版本删除
*/
@Deprecated
public class ModernUIPane<T> extends BasicPane {
private Browser browser;
private String namespace = "Pool";
private String variable = "data";
private String expression = "update()";
private ModernUIPane(BrowserType browserType) {
initialize(browserType);
}
protected ModernUIPane() {
}
private void initialize(BrowserType browserType) {
if (browser == null) {
setLayout(new BorderLayout());
Assistant.addChromiumSwitches("--disable-google-traffic");
if (DesignerEnvManager.getEnvManager().isOpenDebug()) {
UIToolbar toolbar = new UIToolbar();
add(toolbar, BorderLayout.NORTH);
UIButton openDebugButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window"));
toolbar.add(openDebugButton);
UIButton reloadButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Reload"));
toolbar.add(reloadButton);
UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window"));
toolbar.add(closeButton);
openDebugButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showDebuggerDialog();
}
});
reloadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
browser.reloadIgnoringCache();
}
});
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.getWindowAncestor(ModernUIPane.this).setVisible(false);
}
});
Assistant.addChromiumSwitches("--remote-debugging-port=9222");
initializeBrowser(browserType);
add(new BrowserView(browser), BorderLayout.CENTER);
} else {
initializeBrowser(browserType);
add(new BrowserView(browser), BorderLayout.CENTER);
}
}
}
private void showDebuggerDialog() {
JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this));
Browser debugger = new Browser();
BrowserView debuggerView = new BrowserView(debugger);
dialog.add(debuggerView, BorderLayout.CENTER);
dialog.setSize(new Dimension(800, 400));
GUICoreUtils.centerWindow(dialog);
dialog.setVisible(true);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
debugger.loadURL(browser.getRemoteDebuggingURL());
}
private void initializeBrowser(BrowserType browserType) {
browser = new Browser(browserType);
// 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的
browser.addScriptContextListener(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
event.getBrowser().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace));
}
});
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
*/
public void redirect(String url) {
browser.loadURL(url);
}
/**
* 转向一个新的地址相当于重新加载
*
* @param url 新的地址
* @param map 初始化参数
*/
public void redirect(String url, Map<String, String> map) {
Assistant.setEmbProtocolHandler(browser, new EmbProtocolHandler(map));
browser.loadURL(url);
}
@Override
protected String title4PopupWindow() {
return "Modern";
}
public void populate(final T t) {
browser.addScriptContextListener(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace);
ns.asObject().setProperty(variable, t);
}
});
}
public T update() {
JSValue jsValue = browser.executeJavaScriptAndReturnValue("window." + namespace + "." + expression);
if (jsValue.isObject()) {
return (T) jsValue.asJavaObject();
}
return null;
}
public void disposeBrowser() {
if (browser != null) {
browser.dispose();
browser = null;
}
}
public void clearCache() {
if (browser != null) {
browser.getCacheStorage().clearCache();
File file = new File(browser.getContext().getCacheDir());
if (file.exists()) {
file.delete();
}
}
}
public void executeJavaScript(String javaScript) {
if (browser != null) {
browser.executeJavaScript(javaScript);
}
}
public JSValue executeJavaScriptAndReturnValue(String javaScript) {
if (browser != null) {
return browser.executeJavaScriptAndReturnValue(javaScript);
}
return null;
}
/**
* ModernUIPane 建造者
*
* @param <T>
*/
public static class Builder<T> implements BuilderDiff<T> {
private ModernUIPane<T> pane;
public Builder() {
this(BrowserType.HEAVYWEIGHT);
}
public Builder(BrowserType browserType) {
this.pane = new ModernUIPane<>(browserType);
}
public Builder(ModernUIPane<T> pane) {
this.pane = pane;
}
public Builder<T> prepare(ScriptContextListener contextListener) {
pane.browser.addScriptContextListener(contextListener);
return this;
}
public Builder<T> prepare(LoadListener loadListener) {
pane.browser.addLoadListener(loadListener);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public Builder<T> withEMB(final String path) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler());
pane.browser.loadURL("emb:" + path);
return this;
}
/**
* 加载jar包中的资源
*
* @param path 资源路径
*/
public Builder<T> withEMB(final String path, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(map));
pane.browser.loadURL("emb:" + path);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public Builder<T> withURL(final String url) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler());
pane.browser.loadURL(url);
return this;
}
/**
* 加载url指向的资源
*
* @param url 文件的地址
*/
public Builder<T> withURL(final String url, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(map));
pane.browser.loadURL(url);
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public Builder<T> withComponent(AssembleComponent component) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component));
pane.browser.loadURL("emb:dynamic");
return this;
}
/**
* 加载Atom组件
*
* @param component Atom组件
*/
public Builder<T> withComponent(AssembleComponent component, Map<String, String> map) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component, map));
pane.browser.loadURL("emb:dynamic");
return this;
}
/**
* 加载html文本内容
*
* @param html 要加载html文本内容
*/
public Builder<T> withHTML(String html) {
Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler());
pane.browser.loadHTML(html);
return this;
}
/**
* 设置该前端页面做数据交换所使用的对象
*
* @param namespace 对象名
*/
public Builder<T> namespace(String namespace) {
pane.namespace = namespace;
return this;
}
/**
* java端往js端传数据时使用的变量名字
*
* @param name 变量的名字
*/
public Builder<T> variable(String name) {
pane.variable = name;
return this;
}
/**
* js端往java端传数据时执行的函数表达式
*
* @param expression 函数表达式
*/
public Builder<T> expression(String expression) {
pane.expression = expression;
return this;
}
@Override
public Builder<T> prepareForV6(ScriptContextListener contextListener) {
return prepare(contextListener);
}
@Override
public Builder<T> prepareForV6(LoadListener loadListener) {
return prepare(loadListener);
}
@Override
public Builder<T> prepareForV7(InjectJsCallback callback) {
// do nothing
return this;
}
@Override
public Builder<T> prepareForV7(Class event, Observer listener) {
// do nothing
return this;
}
public ModernUIPane<T> build() {
return pane;
}
}
}

55
designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java

@ -1,55 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.browser.callback.InjectJsCallback;
import com.teamdev.jxbrowser.chromium.events.LoadListener;
import com.teamdev.jxbrowser.chromium.events.ScriptContextListener;
import com.teamdev.jxbrowser.event.Observer;
/**
* 封装jxbrwoser v6/v7的构建方式的差异
*
* @author hades
* @see {@link JxUIPane}
* @since 10.0
* Created on 2021/6/13
* @deprecated 6在下个版本弃用
*/
@Deprecated
public interface BuilderDiff<T> {
/**
* v6准备工作
*
* @param contextListener 上下文监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV6(ScriptContextListener contextListener);
/**
* v6准备工作
*
* @param loadListener 加载监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV6(LoadListener loadListener);
/**
* v7准备工作
*
* @param callback 注入js回调器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV7(InjectJsCallback callback);
/**
* v7准备工作
*
* @param event 事件
* @param listener 监听器
* @return 构造器
*/
ModernUIPane.Builder<T> prepareForV7(Class event, Observer listener);
}

45
designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java

@ -1,45 +0,0 @@
package com.fr.design.ui.compatible;
import com.fr.design.jxbrowser.JxUIPane;
import com.fr.design.ui.ModernUIPane;
/**
* 根据版本选择构造器
*
* @author hades
* @see {@link JxUIPane}
* @since 10.0
* Created on 2021/6/13
* @deprecated 6在下个版本弃用
*/
public class ModernUIPaneFactory {
/**
* 获取一个 JxBrowser pane 的构造器
*
* @param <T> 参数
* @return 构造器
*/
public static <T> ModernUIPane.Builder<T> modernUIPaneBuilder() {
if (isV7()) {
return new JxUIPane.Builder<>();
} else {
return new ModernUIPane.Builder<>();
}
}
/**
* 判断 JxBrowser 版本是否在7或之上
*
* @return 是否7或之上
*/
public static boolean isV7() {
boolean jxBrowserV7 = true;
try {
Class.forName("com.teamdev.jxbrowser.net.Scheme");
} catch (ClassNotFoundException e) {
jxBrowserV7 = false;
}
return jxBrowserV7;
}
}

11
designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java

@ -1,7 +1,6 @@
package com.fr.design.update.ui.dialog;
import com.fanruan.product.ProductConstants;
import com.fine.theme.utils.FineUIScale;
import com.fr.decision.update.data.UpdateConstants;
import com.fr.decision.update.info.UpdateCallBack;
import com.fr.decision.update.info.UpdateProgressCallBack;
@ -14,7 +13,6 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.DesignSizeI18nManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
@ -62,6 +60,7 @@ import java.util.*;
import java.util.List;
import java.util.concurrent.ExecutionException;
import static com.fine.theme.utils.FineUIScale.scale;
import static java.nio.charset.StandardCharsets.*;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
@ -72,11 +71,10 @@ public class UpdateMainDialog extends UIDialog {
public static final Dimension DEFAULT = new Dimension(660, 620);
private static final Dimension PROGRESSBAR = new Dimension(120, 15);
private static final Dimension UPDATE_BUTTON = new Dimension(80, 24);
private static final int UPDATE_PANE_ROW_SIZE = 30;
private static final int UPDATE_CONTENT_PANE_ROW_SIZE = 10;
private static final int UPDATE_CONTENT_PANE_COLUMN_SIZE = 10;
private static final int UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE = 100;
private static final int UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE = 120;
private static final int SEARCH_PANE_ROW_SIZE = 50;
private static final int SEARCH_PANE_TEXT_COLUMN = 130;
private static final int SEARCH_PANE_COLUMN_GAP = 3;
@ -159,7 +157,7 @@ public class UpdateMainDialog extends UIDialog {
progressBar.setForeground(UpdateConstants.BAR_COLOR);
progressBar.setVisible(false);
progressBar.setStringPainted(true);
progressBar.setPreferredSize(PROGRESSBAR);
progressBar.setPreferredSize(scale(PROGRESSBAR));
progressBarPane.add(GUICoreUtils.createBorderLayoutPane(
progressBar, BorderLayout.CENTER
@ -298,7 +296,6 @@ public class UpdateMainDialog extends UIDialog {
loadingLabel = new LoadingLabel();
loadingLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Checking_Jar_Update"));
updateButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Update"));
updateButton.setPreferredSize(FineUIScale.scale(UPDATE_BUTTON));
updateButton.setEnabled(false);
double[] rowSize = {TableLayout.PREFERRED};
@ -692,7 +689,7 @@ public class UpdateMainDialog extends UIDialog {
* 显示窗口
*/
public void showDialog() {
setSize(DEFAULT);
setSize(scale(DEFAULT));
setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_UpdateAndUpgrade"));
GUICoreUtils.centerWindow(this);
setVisible(true);

515
designer-base/src/main/java/com/fr/design/upm/UpmBridge.java

@ -1,515 +0,0 @@
package com.fr.design.upm;
import com.fr.config.ServerPreferenceConfig;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.extra.PluginUtils;
import com.fr.design.extra.exe.GetInstalledPluginsExecutor;
import com.fr.design.extra.exe.GetPluginCategoriesExecutor;
import com.fr.design.extra.exe.GetPluginFromStoreExecutor;
import com.fr.design.extra.exe.GetPluginPrefixExecutor;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.extra.exe.ReadUpdateOnlineExecutor;
import com.fr.design.extra.exe.SearchOnlineExecutor;
import com.fr.design.gui.ifilechooser.FileChooserArgs;
import com.fr.design.gui.ifilechooser.FileChooserFactory;
import com.fr.design.gui.ifilechooser.FileChooserProvider;
import com.fr.design.gui.ifilechooser.FileSelectionMode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.upm.event.DownloadEvent;
import com.fr.design.upm.exec.UpmBrowserExecutor;
import com.fr.design.upm.task.UpmTaskWorker;
import com.fr.design.utils.BrowseUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.GeneralUtils;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSArray;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
* @deprecated 用于jxbrowser6下版本删除
*/
@Deprecated
public class UpmBridge {
public static UpmBridge getBridge(Browser browser) {
return new UpmBridge(browser);
}
private JSObject window;
private UpmBridge(Browser browser) {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
}
protected UpmBridge() {
}
/**
* 更新插件管理中心资源文件这个方法仅仅是为了语义上的作用更新
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
public void update(final JSFunction callback) {
callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
try {
UpmResourceLoader.INSTANCE.download();
UpmResourceLoader.INSTANCE.install();
callback.invoke(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.UPDATE, "success");
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
callback.invoke(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
}
}
/**
* 下载并安装插件管理中心的资源文件
*
* @param callback 安装完成后的回调函数
*/
@JSBridge
public void startDownload(final JSFunction callback) {
callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start"));
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
UpmResourceLoader.INSTANCE.download();
UpmResourceLoader.INSTANCE.install();
return null;
}
@Override
protected void done() {
try {
get();
callback.invoke(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success"));
EventDispatcher.fire(DownloadEvent.SUCCESS, "success");
} catch (Exception e) {
callback.invoke(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error"));
FineLoggerFactory.getLogger().error(e.getMessage(), e);
EventDispatcher.fire(DownloadEvent.ERROR, "error");
}
}
}.execute();
}
/**
* 获取upm的版本信息
*
* @return 版本信息
*/
@JSBridge
public String getVersion() {
return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion();
}
@JSBridge
public String i18nText(String key) {
return Toolkit.i18nText(key);
}
@JSBridge
public void closeWindow() {
UIUtil.invokeLaterIfNeeded(UpmFinder::closeWindow);
}
@JSBridge
public boolean isDesigner() {
return true;
}
@JSBridge
public void getPackInfo(final JSFunction callback) {
callback.invoke(window, StringUtils.EMPTY);
}
@JSBridge
public void getPluginPrefix(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginPrefixExecutor());
task.execute();
}
/**
* 在线获取插件分类
*
* @param callback 回调函数
*/
@JSBridge
public void getPluginCategories(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginCategoriesExecutor());
task.execute();
}
/**
* 根据条件获取在线插件
*
* @param info 插件信息
* @param callback 回调函数
*/
@JSBridge
public void getPluginFromStoreNew(String info, final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginFromStoreExecutor(new JSONObject(info)));
task.execute();
}
/**
* 已安装插件检查更新
*/
@JSBridge
public void readUpdateOnline(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new ReadUpdateOnlineExecutor());
task.execute();
}
/**
* 获取已经安装的插件的数组
*/
@JSBridge
public void getInstalledPlugins(final JSFunction callback) {
UpmTaskWorker<Void> task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetInstalledPluginsExecutor());
task.execute();
}
/**
* 从插件服务器上更新选中的插件
*
* @param pluginIDs 插件集合
*/
@JSBridge
public void updatePluginOnline(Object pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
List<PluginMarker> pluginMarkerList = new ArrayList<>();
if (pluginIDs instanceof String) {
pluginMarkerList.add(PluginUtils.createPluginMarker(pluginIDs.toString()));
} else if (pluginIDs instanceof JSArray) {
JSArray pluginInfos = (JSArray) pluginIDs;
for (int i = 0, len = pluginInfos.length(); i < len; i++) {
String value = pluginInfos.get(i).asString().getValue();
pluginMarkerList.add(PluginUtils.createPluginMarker(value));
}
}
PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback);
}
/**
* 搜索在线插件
*
* @param keyword 关键字
*/
@JSBridge
public void searchPlugin(String keyword, final JSFunction callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new SearchOnlineExecutor(keyword));
worker.execute();
}
/**
* 从磁盘上选择插件安装包进行安装
*
* @param filePath 插件包的路径
*/
@JSBridge
public void installPluginFromDisk(final String filePath, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
File file = new File(filePath);
PluginOperateUtils.installPluginFromDisk(file, jsCallback);
}
/**
* 卸载当前选中的插件
*
* @param pluginInfo 插件信息
*/
@JSBridge
public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback);
}
/**
* 从插件服务器上安装插件
*
* @param pluginInfo 插件的ID
* @param callback 回调函数
*/
@JSBridge
public void installPluginOnline(final String pluginInfo, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback);
}
/**
* 从磁盘上选择插件安装包进行插件升级
*
* @param filePath 插件包的路径
*/
public void updatePluginFromDisk(String filePath, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
File file = new File(filePath);
PluginOperateUtils.updatePluginFromDisk(file, jsCallback);
}
/**
* 修改选中的插件的活跃状态
*
* @param pluginID 插件ID
*/
@JSBridge
public void setPluginActive(String pluginID, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 批量修改选中的插件的活跃状态
*
* @param pluginIDs 要处理的插件ID
* @param callback 回调函数
*/
@JSBridge
public void setAllPluginActive(JSArray pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
List<String> list = new ArrayList<>();
int len = pluginIDs.length();
for (int i = 0; i < len; i++) {
list.add(pluginIDs.get(i).asString().getValue());
}
PluginOperateUtils.setPluginActive(list, jsCallback);
}
/**
* 选择文件对话框
*
* @return 选择的文件的路径
*/
@JSBridge
public String showFileChooser() {
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param filter 文件的后缀
* @return 选择的文件的路径
* 这里换用JFileChooser会卡死,不知道为什么
*/
@JSBridge
public String showFileChooserWithFilter(final String des, final String filter) {
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() {
FileChooserProvider fileChooserProvider = FileChooserFactory.createFileChooser(
FileChooserArgs.newBuilder().
setFileSelectionMode(FileSelectionMode.FILE).
setFilter(des, filter).build());
int result = fileChooserProvider.showDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooserProvider.getSelectedFile().getAbsolutePath();
}
return null;
}
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
/**
* 选择文件对话框
*
* @param des 过滤文件描述
* @param args 文件的后缀
* @return 选择的文件的路径
*/
@JSBridge
public String showFileChooserWithFilters(final String des, final Object args) {
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() {
JFileChooser fileChooser = new JFileChooser();
List<String> filterList = new ArrayList<>();
if (args instanceof String) {
filterList.add(GeneralUtils.objectToString(args));
} else if (args instanceof JSArray) {
JSArray array = (JSArray) args;
for (int i = 0, len = array.length(); i < len; i++) {
filterList.add(array.get(i).getStringValue());
}
}
String[] filters = filterList.toArray(new String[0]);
if (ArrayUtils.isNotEmpty(filters)) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters));
fileChooser.setFileFilter(filter);
}
int result = fileChooser.showOpenDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
}
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
////////登录相关///////
/**
* 获取系统登录的用户名
*/
@JSBridge
public String getLoginInfo(final JSFunction callback) {
registerLoginInfo(callback);
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
* 系统登录注册
*
* @param callback 回调函数
*/
@JSBridge
public void registerLoginInfo(final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
String username = DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
if (StringUtils.isEmpty(username)) {
jsCallback.execute(StringUtils.EMPTY);
} else {
jsCallback.execute(username);
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @param callback 回调函数
*/
@JSBridge
public void defaultLogin(String username, String password, final JSFunction callback) {
UpmTaskWorker<Void> worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new PluginLoginExecutor(username, password));
worker.execute();
}
/**
* 清除用户信息
*/
@JSBridge
public void clearUserInfo() {
}
/**
* 打开论坛消息界面
*/
@JSBridge
public void getPriviteMessage() {
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(spaceMark.getValue());
BrowseUtils.browser(ssoUrl);
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
* 忘记密码
*/
@JSBridge
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 立即注册
*/
@JSBridge
public void registerHref() {
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 使用系统浏览器打开网页
*
* @param url 要打开的网页
*/
@JSBridge
public void openShopUrlAtWebBrowser(String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
}

122
designer-base/src/main/java/com/fr/design/upm/UpmBridgeV7.java

@ -1,5 +1,6 @@
package com.fr.design.upm;
import com.fr.config.ServerPreferenceConfig;
import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSBridge;
@ -13,13 +14,25 @@ import com.fr.design.extra.exe.GetPluginPrefixExecutor;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.extra.exe.ReadUpdateOnlineExecutor;
import com.fr.design.extra.exe.SearchOnlineExecutor;
import com.fr.design.gui.ifilechooser.FileChooserArgs;
import com.fr.design.gui.ifilechooser.FileChooserFactory;
import com.fr.design.gui.ifilechooser.FileChooserProvider;
import com.fr.design.gui.ifilechooser.FileSelectionMode;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.upm.event.CertificateEvent;
import com.fr.design.upm.event.DownloadEvent;
import com.fr.design.upm.exec.NewUpmBrowserExecutor;
import com.fr.design.upm.task.UpmTaskWorker;
import com.fr.design.utils.BrowseUtils;
import com.fr.event.EventDispatcher;
import com.fr.general.GeneralUtils;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
@ -29,24 +42,29 @@ import com.teamdev.jxbrowser.js.JsAccessible;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
import com.teamdev.jxbrowser.js.internal.JsArrayImpl;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.Desktop;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-12
* 桥接Java和JavaScript的类
*
* @author richie
* @since 10.0
* Created on 2019-04-12
*/
@JsAccessible
public class UpmBridgeV7 extends UpmBridge {
public class UpmBridgeV7 {
public static UpmBridgeV7 getBridge(JsObject jsObject) {
return new UpmBridgeV7(jsObject);
@ -117,30 +135,40 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public String getVersion() {
return super.getVersion();
return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion();
}
/**
* 国际化
*
* @param key 国际化key
* @return 国际化文本
*/
@JSBridge
@JsAccessible
@Override
public String i18nText(String key) {
return super.i18nText(key);
return Toolkit.i18nText(key);
}
/**
* 关闭窗口
*/
@JSBridge
@JsAccessible
@Override
public void closeWindow() {
super.closeWindow();
UIUtil.invokeLaterIfNeeded(UpmFinder::closeWindow);
}
/**
* 是否设计器
*
* @return 是否设计器
*/
@JSBridge
@JsAccessible
@Override
public boolean isDesigner() {
return super.isDesigner();
return true;
}
@JSBridge
@ -326,9 +354,8 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public String showFileChooser() {
return super.showFileChooser();
return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY);
}
/**
@ -341,9 +368,28 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public String showFileChooserWithFilter(final String des, final String filter) {
return super.showFileChooserWithFilter(des, filter);
RunnableFuture<String> future = new FutureTask<>(new Callable<String>() {
@Override
public String call() {
FileChooserProvider fileChooserProvider = FileChooserFactory.createFileChooser(
FileChooserArgs.newBuilder().
setFileSelectionMode(FileSelectionMode.FILE).
setFilter(des, filter).build());
int result = fileChooserProvider.showDialog(UpmFinder.getDialog());
if (result == JFileChooser.APPROVE_OPTION) {
return fileChooserProvider.getSelectedFile().getAbsolutePath();
}
return null;
}
});
SwingUtilities.invokeLater(future);
try {
return future.get();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null;
}
/**
@ -469,9 +515,7 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JsAccessible
@JSBridge
@Override
public void clearUserInfo() {
super.clearUserInfo();
}
/**
@ -479,9 +523,14 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void getPriviteMessage() {
super.getPriviteMessage();
try {
LocaleMark<String> spaceMark = LocaleCenter.getMark(BbsSpaceMark.class);
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(spaceMark.getValue());
BrowseUtils.browser(ssoUrl);
} catch (Exception exp) {
FineLoggerFactory.getLogger().info(exp.getMessage());
}
}
/**
@ -489,9 +538,13 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void forgetHref() {
super.forgetHref();
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
@ -499,9 +552,13 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void registerHref() {
super.registerHref();
try {
LocaleMark<String> registerMark = LocaleCenter.getMark(BbsRegisterMark.class);
Desktop.getDesktop().browse(new URI(registerMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
@ -511,8 +568,21 @@ public class UpmBridgeV7 extends UpmBridge {
*/
@JSBridge
@JsAccessible
@Override
public void openShopUrlAtWebBrowser(String url) {
super.openShopUrlAtWebBrowser(url);
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
}

30
designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java

@ -1,30 +0,0 @@
package com.fr.design.upm.exec;
import com.fr.design.bridge.exec.JSExecutor;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-18
*/
public class UpmBrowserExecutor implements JSExecutor {
public static UpmBrowserExecutor create(JSObject window, JSFunction callback) {
return new UpmBrowserExecutor(window, callback);
}
private JSObject window;
private JSFunction callback;
private UpmBrowserExecutor(JSObject window, JSFunction callback) {
this.window = window;
this.callback = callback;
}
@Override
public void executor(String newValue) {
callback.invoke(window, newValue);
}
}

3
designer-base/src/main/resources/com/fine/theme/light/ui/laf/FineLightLaf.properties

@ -1187,7 +1187,8 @@ South.SheetSelectedColor = #FFF
#---- North ----
North.userinfoLabel.borderMargins=2, 16, 2, 16
North.userinfoLabel.width=80
North.userinfoLabel.maxWidth=176
North.userinfoLabel.minWidth=80
North.userinfoLabel.height=24
North.border = $defaultBorderColor
North.messageLabel.foreground=$text.placeholder

34
designer-chart/src/main/java/com/fr/design/chart/series/SeriesCondition/impl/ChartHyperPopAttrPane.java

@ -1,5 +1,8 @@
package com.fr.design.chart.series.SeriesCondition.impl;
import com.fine.theme.utils.FineLayoutBuilder;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.fr.base.Parameter;
import com.fr.chart.chartattr.ChartCollection;
import com.fr.chart.web.ChartHyperPoplink;
@ -9,18 +12,13 @@ import com.fr.design.gui.ilable.BoldFontTextLabel;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.chart.AbstractChartAttrPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.ParameterProvider;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.util.List;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
/**
* 图表弹出超链, 悬浮窗属性设置界面.
@ -52,41 +50,31 @@ public class ChartHyperPopAttrPane extends AbstractChartAttrPane {
@Override
protected JPanel createContentPane() {
JPanel pane = new JPanel();
pane.setLayout(FRGUIPaneFactory.createBorderLayout());
pane.setLayout(FRGUIPaneFactory.createScaledBorderLayout(0, 10));
pane.setBorder(new ScaledEmptyBorder(10, 0, 0, 0));
titleField = new UITextField(15);
titleField.setPreferredSize(new Dimension(200, 20));
widthField = new UINumberField(4);
widthField.setColumns(10);
widthField.setPreferredSize(new Dimension(200, 20));
heightField = new UINumberField(4);
heightField.setColumns(10);
heightField.setPreferredSize(new Dimension(200, 20));
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = { p,f};
double[] rowSize = { p,p,p,p,p,p};
Component[][] components = new Component[][]{
new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title") + ":", SwingConstants.RIGHT), titleField},
new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Designer_Width") + ":", SwingConstants.RIGHT), widthField},
new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Height") + ":", SwingConstants.RIGHT), heightField},
new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title") + ":"), titleField},
new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Designer_Width") + ":"), widthField},
new Component[]{new BoldFontTextLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Height") + ":"), heightField},
};
widthField.setText(String.valueOf(DEFAULT_V_VALUE));
heightField.setText(String.valueOf(DEFAULT_H_VALUE));
JPanel northPane = TableLayoutHelper.createTableLayoutPane(components,rowSize,columnSize);
JPanel northPane = FineLayoutBuilder.compatibleTableLayout(10, components, new double[]{1.2, 3});
pane.add(northPane, BorderLayout.NORTH);
parameterViewPane = new ReportletParameterViewPane(paraType, valueEditorPane, valueRenderPane);
parameterViewPane.setBorder(GUICoreUtils.createTitledBorder(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter")));
parameterViewPane.setPreferredSize(new Dimension(200, 200));
pane.add(parameterViewPane, BorderLayout.CENTER);
pane.add(FineUIUtils.wrapComponentWithTitle(parameterViewPane,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter")), BorderLayout.CENTER);
return pane;
}

2
designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java

@ -40,7 +40,7 @@ public class ChartPropertyPane extends BaseChartPropertyPane {
protected void initComponent() {
this.setLayout(new BorderLayout());
this.setBorder(new ScaledEmptyBorder(10, 0, 0, 0));
this.setBorder(new ScaledEmptyBorder(10, 4, 0, 4));
}
@Override

9
designer-chart/src/main/java/com/fr/van/chart/designer/component/border/VanChartBorderWithShapePane.java

@ -27,6 +27,9 @@ import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
public class VanChartBorderWithShapePane extends BasicPane {
private static final int RECTANGULAR_INDEX = 0;
private static final int DIALOG_INDEX = 1;
@ -68,8 +71,7 @@ public class VanChartBorderWithShapePane extends BasicPane {
detailPane = createDetailPane();
this.add(createLineTypePane(), BorderLayout.CENTER);
this.add(detailPane, BorderLayout.SOUTH);
this.add(column(10, cell(createLineTypePane()), cell(detailPane)).getComponent());
initLineTypeListener();
initLineColorListener();
@ -137,8 +139,7 @@ public class VanChartBorderWithShapePane extends BasicPane {
JPanel panel = new JPanel(new BorderLayout());
panel.add(center, BorderLayout.CENTER);
panel.add(south, BorderLayout.SOUTH);
panel.add(column(10, cell(center), cell(south)).getComponent());
return panel;
}

1
designer-form/src/main/java/com/fr/design/mainframe/WidgetPropertyPane.java

@ -114,6 +114,7 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
this.createTabPane();
this.initTables();
revalidate();
}
/**

4
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java

@ -1,6 +1,5 @@
package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
/**
@ -9,15 +8,12 @@ import com.teamdev.jxbrowser.js.JsAccessible;
* Created by Starryi on 2021/12/20
*/
public class ComposedNativeBridges {
@JSAccessible
@JsAccessible
public final Object Browser;
@JSAccessible
@JsAccessible
public final Object Auth;
@JSAccessible
@JsAccessible
public final Object Product;

3
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java

@ -5,7 +5,6 @@ import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.login.DesignerLoginHelper;
import com.fr.design.login.DesignerLoginSource;
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.awt.Window;
@ -17,14 +16,12 @@ import java.util.HashMap;
* Created by Starryi on 2021/12/20
*/
public class NativeAuthBridge {
@JSAccessible
@JsAccessible
@JSBridge
public String getLoginUsername() {
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
@JSAccessible
@JsAccessible
@JSBridge
public void goLogin() {

2
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java

@ -2,7 +2,6 @@ package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.awt.Window;
@ -14,7 +13,6 @@ import java.awt.Window;
*/
public class NativeBrowserBridge {
@JSAccessible
@JsAccessible
@JSBridge
public void dispose() {

21
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java

@ -20,7 +20,6 @@ import com.fr.form.share.bean.OnlineShareWidget;
import com.fr.form.share.group.DefaultShareGroupManager;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import javax.swing.JOptionPane;
@ -55,13 +54,12 @@ public class NativeProductBridge {
this.window = window;
}
@JSAccessible
@JsAccessible
@JSBridge
public boolean isProductDownloaded(String uuid) {
for (Group group : DefaultShareGroupManager.getInstance().getAllGroup()) {
SharableWidgetProvider[] widgetProviderList = group.getAllBindInfoList();
for (SharableWidgetProvider widget: widgetProviderList) {
for (SharableWidgetProvider widget : widgetProviderList) {
if (StringUtils.equals(uuid, widget.getId())) {
return true;
}
@ -70,7 +68,6 @@ public class NativeProductBridge {
return false;
}
@JSAccessible
@JsAccessible
@JSBridge
public void addProductDownloadTaskStartListener(String json, Object function) {
@ -91,7 +88,6 @@ public class NativeProductBridge {
}
@JSAccessible
@JsAccessible
@JSBridge
public void removeProductDownloadTaskStartListener(String json, Object function) {
@ -110,7 +106,6 @@ public class NativeProductBridge {
downloadTaskGetters.put(uuid, startListeners);
}
@JSAccessible
@JsAccessible
@JSBridge
public Object getExecutingProductDownloadTask(String json) {
@ -128,7 +123,6 @@ public class NativeProductBridge {
return task;
}
@JSAccessible
@JsAccessible
@JSBridge
public Object createProductDownloadTask(String json) {
@ -155,7 +149,6 @@ public class NativeProductBridge {
}
}
@JSAccessible
@JsAccessible
@JSBridge
public void addThemeDownloadTaskStartListener(String themePath, Object function) {
@ -167,7 +160,6 @@ public class NativeProductBridge {
themeDownloadTaskStartListeners.put(themePath, startListeners);
}
@JSAccessible
@JsAccessible
@JSBridge
public void removeThemeDownloadTaskStartListener(String themePath, Object function) {
@ -179,7 +171,6 @@ public class NativeProductBridge {
themeDownloadTaskStartListeners.put(themePath, startListeners);
}
@JSAccessible
@JsAccessible
@JSBridge
public Object getExecutingThemeDownloadTask(String themePath) {
@ -190,7 +181,6 @@ public class NativeProductBridge {
return task;
}
@JSAccessible
@JsAccessible
@JSBridge
public Object createTemplateThemeDownloadTask(String themePath) {
@ -236,7 +226,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -256,7 +245,7 @@ public class NativeProductBridge {
"",
FineJOptionPane.OK_CANCEL_OPTION
);
allowedDownload = result == JOptionPane.OK_OPTION;
allowedDownload = result == JOptionPane.OK_OPTION;
}
if (allowedDownload) {
fireStartEvent(null);
@ -268,7 +257,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -341,7 +329,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -370,7 +357,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -412,6 +398,7 @@ public class NativeProductBridge {
private final NativeProductBridge env;
private final String themePath;
private final TemplateThemeInstallation action;
public TemplateThemeInstallationTask(NativeProductBridge env, Object window, String themePath) {
super(window);
this.env = env;
@ -436,7 +423,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override
@ -454,7 +440,6 @@ public class NativeProductBridge {
});
}
@JSAccessible
@JsAccessible
@JSBridge
@Override

5
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java

@ -3,7 +3,6 @@ package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.mainframe.share.mini.MiniShopNativeTask;
import com.fr.design.mainframe.share.mini.MiniShopNativeTaskManager;
import com.teamdev.jxbrowser.chromium.JSAccessible;
import com.teamdev.jxbrowser.js.JsAccessible;
import java.util.HashSet;
@ -32,21 +31,18 @@ public class NativeTaskBridge implements MiniShopNativeTask {
}
@JSBridge
@JSAccessible
@JsAccessible
public void addStatusCallback(Object cb) {
this.statusCbs.add(cb);
}
@JSBridge
@JSAccessible
@JsAccessible
public void removeStatusCallback(Object cb) {
this.statusCbs.remove(cb);
}
@JSBridge
@JSAccessible
@JsAccessible
@Override
public void execute() {
@ -56,7 +52,6 @@ public class NativeTaskBridge implements MiniShopNativeTask {
}
@JSBridge
@JSAccessible
@JsAccessible
@Override
public void cancel() {

22
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java

@ -1,7 +1,5 @@
package com.fr.design.mainframe.share.ui.online.mini.bridge;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.js.JsFunction;
import com.teamdev.jxbrowser.js.JsObject;
@ -16,29 +14,15 @@ public class SafeJSFunctionInvoker {
public static void invoke(Collection<Object> functions, Object instance, Object... args) {
if (functions != null) {
for (Object function: functions) {
for (Object function : functions) {
invoke(function, instance, args);
}
}
}
public static void invoke(Object function, Object instance, Object... args) {
if (function != null) {
if (function instanceof JSFunction && instance instanceof JSObject) {
invokeV6((JSFunction) function, (JSObject) instance, args);
} else if (function instanceof JsFunction && instance instanceof JsObject) {
invokeV7((JsFunction) function, (JsObject) instance, args);
}
}
}
private static void invokeV6(JSFunction function, JSObject instance, Object... args) {
if (!function.getContext().isDisposed()) {
function.invoke(instance, args);
if (function instanceof JsFunction && instance instanceof JsObject) {
((JsFunction) function).invoke((JsObject) instance, args);
}
}
private static void invokeV7(JsFunction function, JsObject instance, Object... args) {
function.invoke(instance, args);
}
}

5
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/cell/model/PluginModel.java

@ -1,8 +1,8 @@
package com.fr.design.mainframe.alphafine.cell.model;
import com.fr.design.actions.help.alphafine.AlphaFineCloudConstants;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.mainframe.alphafine.CellType;
import com.fr.design.upm.UpmFinder;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
@ -112,7 +112,8 @@ public class PluginModel extends AlphaCellModel {
* 方便埋点
*/
private void openPluginStore(String name) {
WebViewDlgHelper.createPluginDialog(name);
// 适配
UpmFinder.showUPMDialog();
}
@Override

46
designer-realize/src/main/java/com/fr/design/mainframe/bbs/BBSDialog.java

@ -1,12 +1,11 @@
package com.fr.design.mainframe.bbs;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.PluginWebBridge;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.CloudCenter;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.general.CloudCenter;
import com.fr.stable.StringUtils;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
@ -18,9 +17,14 @@ import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
import javax.swing.*;
import java.awt.*;
import javax.swing.JDialog;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Frame;
import java.io.IOException;
import java.net.URI;
/**
* @author richie
@ -99,7 +103,7 @@ public class BBSDialog extends UIDialog {
if (ComparatorUtils.equals(newValue, url) || ComparatorUtils.equals(newValue, CloudCenter.getInstance().acquireUrlByKind("bbs.mobile"))) {
return;
}
PluginWebBridge.getHelper().openUrlAtLocalWebBrowser(eng, newValue);
openUrlAtLocalWebBrowser(newValue);
}
});
eng.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
@ -116,6 +120,34 @@ public class BBSDialog extends UIDialog {
});
}
/**
* 在本地浏览器里打开url
*
* @param eng web引擎
* @param url 要打开的地址
*/
public void openUrlAtLocalWebBrowser(String url) {
if (StringUtils.isBlank(url)) {
return;
}
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (IOException e) {
//此为无法获取系统默认浏览器
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 提供给web页面调用的关闭窗口
*/

21
designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java

@ -3,7 +3,6 @@
*/
package com.fr.design.mainframe.bbs;
import com.fine.theme.utils.FineUIScale;
import com.fr.base.FRContext;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
@ -29,6 +28,8 @@ import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.fine.theme.utils.FineUIScale.scale;
/**
* @author neil
@ -63,12 +64,11 @@ public class UserInfoPane extends BasicPane {
* 构造函数
*/
private UserInfoPane() {
this.setPreferredSize(FineUIScale.scale(new Dimension(UIManager.getInt("North.userinfoLabel.width"), UIManager.getInt("North.userinfoLabel.height"))));
this.setLayout(new BorderLayout());
this.userInfoLabel = new UserInfoLabel(this);
Insets insets = UIManager.getInsets("North.userinfoLabel.borderMargins");
Insets scaledInsets = FineUIScale.scale(insets);
Insets scaledInsets = scale(insets);
this.userInfoLabel.setBorder(BorderFactory.createEmptyBorder(scaledInsets.top, scaledInsets.left, scaledInsets.bottom, scaledInsets.right));
this.markUnSignIn();
@ -105,6 +105,7 @@ public class UserInfoPane extends BasicPane {
public void markUnSignIn() {
this.userInfoLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Onclick"));
this.userInfoLabel.resetUserName();
fitSize();
}
/**
@ -115,6 +116,18 @@ public class UserInfoPane extends BasicPane {
public void markSignIn(String userName) {
this.userInfoLabel.setText(userName);
this.userInfoLabel.setUserName(userName);
fitSize();
}
private void fitSize() {
int height = UIManager.getInt("North.userinfoLabel.height");
int maxWidth = UIManager.getInt("North.userinfoLabel.maxWidth");
int minWidth = UIManager.getInt("North.userinfoLabel.minWidth");
int labelWidth = userInfoLabel.getPreferredSize().width;
// 自适应尺寸,并限制最大最小尺寸
int preferWidth = Math.min(Math.max(minWidth, labelWidth), maxWidth);
Dimension fitDimension = scale(new Dimension(preferWidth, height));
setPreferredSize(fitDimension);
}
@Override
@ -199,6 +212,4 @@ public class UserInfoPane extends BasicPane {
});
executorService.shutdown();
}
}

20
designer-realize/src/main/java/com/fr/design/report/RichTextPane.java

@ -1,11 +1,13 @@
package com.fr.design.report;
import com.fine.theme.utils.FineUIUtils;
import com.formdev.flatlaf.ui.FlatRoundBorder;
import com.fr.base.BaseFormula;
import com.fr.base.Style;
import com.fr.design.border.FineBorderFactory;
import com.fr.design.cell.editor.RichTextToolBar;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.DesignUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
@ -20,6 +22,7 @@ import com.fr.stable.Constants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import javax.swing.ScrollPaneConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
@ -32,8 +35,6 @@ import java.awt.Font;
import java.math.BigDecimal;
import java.util.Iterator;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
public class RichTextPane extends BasicPane {
@ -50,13 +51,16 @@ public class RichTextPane extends BasicPane {
}
protected void initComponents() {
this.setLayout(new BorderLayout());
this.setLayout(FRGUIPaneFactory.createScaledBorderLayout(0, 10));
textPane = new RichTextEditingPane();
textPane.setBorder(new FlatRoundBorder());
textPane.setBackground(FineUIUtils.getUIColor("background.normal", "background"));
textPane.setFont(DEFAUL_FONT);
toolBar = new RichTextToolBar(textPane);
this.add(column(10, cell(toolBar), cell(textPane).weight(1)).getComponent());
textPane.setFont(DEFAUL_FONT);
UIScrollPane scrollPane = new UIScrollPane(textPane,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBorder(FineBorderFactory.createWrappedRoundBorder());
toolBar = new RichTextToolBar(textPane);
this.add(toolBar, BorderLayout.NORTH);
this.add(scrollPane, BorderLayout.CENTER);
}
@Override

73
designer-realize/src/main/java/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java

@ -2,16 +2,12 @@ package com.fr.design.report.freeze;
import com.fine.theme.utils.FineUIStyle;
import com.fr.base.FRContext;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicPane;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.gui.frpane.FineTabbedPane;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.page.ReportPageAttrProvider;
import com.fr.stable.ColumnRow;
@ -19,12 +15,11 @@ import com.fr.stable.FT;
import com.fr.stable.bridge.StableFactory;
import com.fr.workspace.WorkContext;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.BorderLayout;
import java.awt.Color;
import static com.fine.swing.ui.layout.Layouts.cell;
import static com.fine.swing.ui.layout.Layouts.column;
@ -701,17 +696,6 @@ public class RepeatAndFreezeSettingPane extends BasicPane {
|| this.useRepeatFinisCCheckBox.isSelected();
}
/**
* 给内部的重复与冻结选项添加指定的边框
*
* @param jPanel 重复或冻结对应的界面
* @param title 边框的文字
*/
public static void addBorder(JPanel jPanel, String title) {
jPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createMatteBorder(1,0,0,0, UIConstants.TITLED_BORDER_COLOR), title));
jPanel.setPreferredSize(new Dimension(REPEAT_AND_FROZEN_WIDTH,REPEAT_AND_FROZEN_HEIGHT));
}
protected void updateRowPane(ReportPageAttrProvider attribute) {
// 重复标题行
int titleFrom = valid(useRepeatTitleRCheckBox, this.repeatTitleRowPane.updateBean().getFrom());
@ -766,55 +750,4 @@ public class RepeatAndFreezeSettingPane extends BasicPane {
return null;
}
private BoxCenterAligmentPane getURLActionLabel(final String text) {
ActionLabel actionLabel = new ActionLabel(text);
actionLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
//Desktop.getDesktop().browse(new URI(url));
WebViewDlgHelper.createPluginDialog();
RepeatAndFreezeSettingPane.this.getTopLevelAncestor().setVisible(false);
} catch (Exception exp) {
}
}
});
return new BoxCenterAligmentPane(actionLabel);
}
class BoxCenterAligmentPane extends JPanel {
private UILabel textLabel;
public BoxCenterAligmentPane(String text) {
this(new UILabel(text));
}
public BoxCenterAligmentPane(UILabel label) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel centerPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
this.add(centerPane, BorderLayout.CENTER);
UILabel label1 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Form_Frozen_Tip"));
label1.setForeground(new Color(255, 0, 0));
UILabel label2 = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Form_Forzen_Speed"));
label2.setForeground(new Color(255, 0, 0));
this.textLabel = label;
centerPane.add(label1);
centerPane.add(textLabel);
centerPane.add(label2);
}
public void setFont(Font font) {
super.setFont(font);
if (textLabel != null) {
textLabel.setFont(font);
}
}
}
}

11
designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java

@ -1,5 +1,6 @@
package com.fr.design.share.ui.generate;
import com.fanruan.product.ProductConstants;
import com.fr.design.DesignerEnvManager;
import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.BasicDialog;
@ -7,7 +8,6 @@ import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.event.ChangeEvent;
import com.fr.design.event.ChangeListener;
import com.fr.design.extra.LoginWebBridge;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.LazyComboBox;
@ -37,10 +37,10 @@ import com.fr.design.share.effect.EffectItemGroup;
import com.fr.design.share.utils.ShareDialogUtils;
import com.fr.file.FileCommonUtils;
import com.fr.form.share.DefaultSharableWidget;
import com.fr.form.share.Group;
import com.fr.form.share.bean.StyleThemeBean;
import com.fr.form.share.constants.ShareComponentConstants;
import com.fr.form.share.group.DefaultShareGroupManager;
import com.fr.form.share.Group;
import com.fr.json.JSON;
import com.fr.json.JSONArray;
import com.fr.json.JSONFactory;
@ -48,14 +48,9 @@ import com.fr.plugin.context.PluginContext;
import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.manage.PluginManager;
import com.fr.stable.ArrayUtils;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.combination.Pair;
import com.fr.stable.pinyin.PinyinHelper;
import java.awt.TextField;
import java.util.Collections;
import java.util.HashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
@ -88,6 +83,7 @@ import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
@ -505,7 +501,6 @@ public class ShareMainPane extends JPanel {
unLoginLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
LoginWebBridge.getHelper().setUILabel(hidden);
Dialog shareDialog = ShareDialogUtils.getInstance().getShareDialog();
//必须这样创建,不然窗口优先级不对
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), shareDialog);

Loading…
Cancel
Save