diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index 5196c783a..c5a4a7dd2 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -22,6 +22,7 @@ import com.fr.env.CheckServiceDialog; import com.fr.env.EnvListPane; import com.fr.env.RemoteWorkspaceURL; import com.fr.env.TestConnectionResult; +import com.fr.env.VersionCheckMessageDialog; import com.fr.exit.DesignerExiter; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralUtils; @@ -96,6 +97,7 @@ public class EnvChangeEntrance { */ public void switch2Env(final String envName) { switch2Env(envName, PopTipStrategy.LATER); + VersionCheckUtils.showVersionCheckDialog(envName); } /** @@ -145,7 +147,6 @@ public class EnvChangeEntrance { if (template != null) { template.refreshToolArea(); } - showServiceDialog(selectedEnv); pluginErrorRemind(); } catch (WorkspaceAuthException | RegistEditionException e) { // String title = Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Auth_Failed"); @@ -294,8 +295,7 @@ public class EnvChangeEntrance { if(StringUtils.isEmpty(areaText)){ return; } - CheckServiceDialog dialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), areaText, localBranch, remoteBranch); - dialog.setVisible(true); + } } } diff --git a/designer-base/src/main/java/com/fr/design/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/VersionCheckUtils.java new file mode 100644 index 000000000..17dcd51a1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/VersionCheckUtils.java @@ -0,0 +1,339 @@ +package com.fr.design; + +import com.fr.base.FRContext; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceType; +import com.fr.design.env.RemoteWorkspace; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.env.VersionCheckMessageDialog; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralUtils; +import com.fr.invoke.Reflect; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.locale.InterProviderFactory; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.context.PluginMarker; +import com.fr.plugin.manage.PluginManager; +import com.fr.plugin.manage.control.PluginControllerHelper; +import com.fr.plugin.manage.control.PluginTaskCallback; +import com.fr.plugin.manage.control.PluginTaskResult; +import com.fr.plugin.manage.control.ProgressCallback; +import com.fr.rpc.Result; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import com.fr.workspace.base.WorkspaceAPI; +import com.fr.workspace.connect.WorkspaceConnectionInfo; +import com.fr.workspace.engine.base.FineObjectPool; +import com.fr.workspace.engine.channel.http.FunctionalHttpRequest; +import com.fr.workspace.engine.exception.WorkspaceConnectionException; +import com.fr.workspace.engine.rpc.WorkspaceProxyPool; +import java.lang.reflect.Method; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author pengda + * @version 10.0 + * Created on 2021-06-02 + */ +public class VersionCheckUtils { + public static final String INCONSISTENCY = "inconsistency"; + public static final String MISSING = "missing"; + private static final String ID = "id"; + private static final String VERSION = "version"; + private static final String NAME = "name"; + + + public static boolean versionCheck(String envName) { + return checkLocalAndRemoteJartime(envName) && checkLocalAndRemotePlugin().size() == 0; + } + + public static boolean versionCheck(DesignerWorkspaceInfo selectedEnv) { + return checkLocalAndRemoteJartime(selectedEnv) && checkLocalAndRemotePlugin().size() == 0; + } + + public static void showVersionCheckDialog(String envName) { + if (!VersionCheckUtils.versionCheck(envName)) { + VersionCheckMessageDialog versionCheckMessageDialog = new VersionCheckMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Check_Brief_Info"), envName); + versionCheckMessageDialog.setVisible(true); + } + } + + public static boolean checkLocalAndRemoteJartime(String envName) { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + return checkLocalAndRemoteJartime(selectedEnv); + } + + public static boolean checkLocalAndRemoteJartime(DesignerWorkspaceInfo selectedEnv) { + //是否需要做服务校验 + if (needCheckBranch(selectedEnv)) { + String localBranch; + String remoteBranch = getRemoteBranch(selectedEnv); + localBranch = GeneralUtils.readFullBuildNO(); + //通过是否包含#来避免当前版本为非安装版本(主要是内部开发版本) + if (localBranch.contains("#") && ComparatorUtils.equals(localBranch, remoteBranch)) { + //说明版本一致,仅做日志记录 + FineLoggerFactory.getLogger().info("Remote Designer version consistency"); + return true; + } else { + return false; + } + } + return true; + } + + public static List getNoExistServiceDescription(String envName) { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); + List noExistServiceDescription = new ArrayList<>(); + Set noExistServiceSet = getNoExistServiceSet(connectionInfo); + for (Class clazz : noExistServiceSet) { + WorkspaceAPI workspaceAPI = (WorkspaceAPI) clazz.getAnnotation(WorkspaceAPI.class); + if (workspaceAPI == null) { + FineLoggerFactory.getLogger().info("workspace service {} get annotation failed", clazz); + continue; + } + if (workspaceAPI.ignore()) { + continue; + } + String descriptionOfCN = InterProviderFactory.getProvider().getLocText(workspaceAPI.description()); + noExistServiceDescription.add(descriptionOfCN); + } + return noExistServiceDescription; + } + + public static String getRemoteBranch(String envName) { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + return getRemoteBranch(selectedEnv); + } + + public static String getRemoteBranch(DesignerWorkspaceInfo selectedEnv) { + String remoteBranch = StringUtils.EMPTY; + WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); + try { + remoteBranch = new FunctionalHttpRequest(connectionInfo).getServerBranch(); + } catch (WorkspaceConnectionException e) { + remoteBranch = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old") + formatBranch(GeneralUtils.readFullBuildNO()); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return remoteBranch; + } + + /** + * 获取不存在的服务列表 + * + * @param info 环境连接信息 + * @return 以Set形式返回不存在的服务 + */ + public static Set getNoExistServiceSet(WorkspaceConnectionInfo info) { + Set noExistServiceSet = new HashSet(); + Set remoteServiceSet = new HashSet(); + Set localServiceSet = FineObjectPool.getInstance().getServerPool().keySet(); + + try { + JSONArray serviceArray = new FunctionalHttpRequest(info).getServiceList(); + for (int i = 0; i < serviceArray.size(); i++) { + try { + Class clazz = Class.forName((String) serviceArray.get(i)); + remoteServiceSet.add(clazz); + } catch (Exception e) { + continue; + } + } + noExistServiceSet.addAll(localServiceSet); + noExistServiceSet.removeAll(remoteServiceSet); + return noExistServiceSet; + } catch (WorkspaceConnectionException e) { + FineLoggerFactory.getLogger().info(e.getMessage()); + //根据本地的服务列表做逐一检测 + for (Class clazz : localServiceSet) { + Method testMethod = Reflect.on(Method.class).create(clazz, "connectTest", new Class[0], String.class, new Class[0], 1025, 8, null, null, null, null).get(); + WorkspaceProxyPool proxyPool = (WorkspaceProxyPool) (((RemoteWorkspace) WorkContext.getCurrent()).getClient()).getPool(); + Result result = proxyPool.testInvoker(testMethod); + Exception invokeException = (Exception) result.getException(); + if (invokeException != null) { + Exception cause = (Exception) invokeException.getCause(); + //获取被包装最底层的异常 + while (cause != null) { + invokeException = cause; + cause = (Exception) invokeException.getCause(); + } + //该异常表示服务不存在 + if (invokeException instanceof ClassNotFoundException) { + noExistServiceSet.add(clazz); + } + } + } + return noExistServiceSet; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return noExistServiceSet; + } + } + + /** + * 格式化分支版本号 + * + * @param buildNO 初始的分支版本号 + * @return 格式化后的版本号 + */ + private static String formatBranch(String buildNO) { + Date jarDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(buildNO, new ParsePosition(buildNO.indexOf("-") + 1)); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + return df.format(jarDate); + } + + private static boolean needCheckBranch(DesignerWorkspaceInfo selectedEnv) { + if (selectedEnv.getType() == DesignerWorkspaceType.Remote) { + return true; + } + return false; + } + + public static JSONArray checkLocalAndRemotePlugin() { + JSONArray differentPlugins = new JSONArray(); + JSONArray remotePlugins = FRContext.getCommonOperator().getPluginStatus(); + Map localPluginsMap = new HashMap<>(); + List localPlugins = PluginManager.getContexts(); + for (PluginContext pluginContext : localPlugins) { + localPluginsMap.put(pluginContext.getID(), pluginContext); + } + JSONObject remotePlugin; + for (int i = 0; i < remotePlugins.size(); i++) { + remotePlugin = remotePlugins.getJSONObject(i); + if (localPluginsMap.containsKey(remotePlugin.getString(ID))) { + if (ComparatorUtils.equals(localPluginsMap.get(remotePlugin.getString(ID)).getVersion(), remotePlugin.getString(VERSION))) { + continue; + } else { + if (remotePlugin.getString(NAME) == null) { + remotePlugin.put(NAME, localPluginsMap.get(remotePlugin.getString(ID)).getName()); + } + remotePlugin.put("type", INCONSISTENCY); + } + } + remotePlugin.put("type", MISSING); + if (remotePlugin.getString(NAME) == null) { + remotePlugin.put(NAME, remotePlugin.getString("id")); + } + differentPlugins.put(remotePlugin); + } + return differentPlugins; + } + + public static JSONArray syncPlugins(JSONArray differentPlugins) { + Set uninstallFailed = uninstallPlugins(differentPlugins); + List plugins = getSyncPlugins(differentPlugins, uninstallFailed); + installPlugins(plugins); + return getPluginsSyncFailed(differentPlugins); + } + + private static List getSyncPlugins(JSONArray differentPlugins, Set uninstallFailed) { + JSONObject differentPlugin; + String id; + String version; + List plugins = new ArrayList<>(); + if (differentPlugins != null) { + for (int i = 0; i < differentPlugins.size(); i++) { + differentPlugin = differentPlugins.getJSONObject(i); + id = differentPlugin.getString(ID); + if (uninstallFailed.contains(id)) { + continue; + } + version = differentPlugin.getString(VERSION); + plugins.add(PluginMarker.create(id, version)); + } + } + return plugins; + } + + private static Set uninstallPlugins(JSONArray differentPlugins) { + Set pluginsNeedUninstall = new HashSet<>(); + Map localPluginsMap = new HashMap<>(); + List localPlugins = PluginManager.getContexts(); + for (PluginContext pluginContext : localPlugins) { + localPluginsMap.put(pluginContext.getID(), pluginContext); + } + for (int i = 0; i < differentPlugins.size(); i++) { + String id = differentPlugins.getJSONObject(i).getString(ID); + if (localPluginsMap.containsKey(id)) { + pluginsNeedUninstall.add(localPluginsMap.get(id).getMarker()); + } + } + Set uninstallFailedID = new HashSet<>(); + CountDownLatch latch = new CountDownLatch(pluginsNeedUninstall.size()); + for (PluginMarker pluginMarker : pluginsNeedUninstall) { + PluginManager.getController().uninstall(pluginMarker, true, new PluginTaskCallback() { + @Override + public void done(PluginTaskResult result) { + latch.countDown(); + if (!result.isSuccess()) { + uninstallFailedID.add(pluginMarker.getPluginID()); + } + } + }); + } + try { + latch.await(5000, TimeUnit.MILLISECONDS); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return uninstallFailedID; + } + + private static JSONArray getPluginsSyncFailed(JSONArray differentPlugins){ + JSONArray pluginsNeedSync = JSONArray.create(); + List localPlugins = PluginManager.getContexts(); + Map localPluginsInfo = new HashMap<>(); + for (int i = 0; i < localPlugins.size(); i++) { + localPluginsInfo.put(localPlugins.get(i).getID(), localPlugins.get(i).getVersion()); + } + for (int i = 0; i < differentPlugins.size(); i++) { + JSONObject plugin = differentPlugins.getJSONObject(i); + String id = plugin.getString(ID); + if (localPluginsInfo.containsKey(id) && ComparatorUtils.equals(plugin.getString(VERSION), localPluginsInfo.get(id))) { + continue; + } + pluginsNeedSync.add(plugin); + } + return pluginsNeedSync; + } + + private static void installPlugins(List plugins) { + CountDownLatch latch = new CountDownLatch(plugins.size()); + for (int i = 0; i < plugins.size(); i++) { + PluginControllerHelper.installOnline(plugins.get(i), new ProgressCallback() { + @Override + public void updateProgress(String description, double progress) { + + } + + @Override + public void done(PluginTaskResult result) { + latch.countDown(); + } + }); + } + try { + latch.await(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java index 18f4d9440..f3a97ffb1 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java @@ -136,8 +136,8 @@ public abstract class DatabaseConnectionPane selectedSpecialCharIndex, String[] selectedSpecialChar, boolean highlight) { + super(frame, true); + // 提示信息 + topPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + JPanel imagePanel = new JPanel(); + JPanel messagePanel; + + if (isShowSpecialCharSqlPane(selectedSpecialCharIndex)) { + imageLabel = new UILabel(UIManager.getIcon("OptionPane.warningIcon")); + messagePanel = new JPanel(); + messagePanel.setLayout(FRGUIPaneFactory.createBorderLayout()); + messagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0)); + // 日韩取消超链,直接显示文字 + if (isNotShowLink()) { + JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql_Message") + Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention") + Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Back_Message")); + messagePanel.add(label); + } else { + MessageWithLink message = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Front_Message"), Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention"), CloudCenter.getInstance().acquireConf(Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention_Help"), "https://help.fanruan.com/finereport/doc-view-2219.html"), Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Back_Message")); + messagePanel.add(message); + } + // 提示图标 + JPanel tipPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + UILabel tipLabel = new UILabel(UIManager.getIcon("OptionPane.tipIcon")); + StringBuilder textBuilder = new StringBuilder(); + textBuilder.append("").append(Toolkit.i18nText("Fine-Design_Basic_Processed_Special_Char")).append("
"); + for (String sChar : selectedSpecialChar) { + textBuilder.append(sChar).append("
"); + } + textBuilder.append(""); + tipLabel.setToolTipText(textBuilder.toString()); + tipPanel.add(tipLabel, BorderLayout.SOUTH); + topPanel.add(tipPanel, BorderLayout.EAST); + } else { + imageLabel = new UILabel(UIManager.getIcon("OptionPane.informationIcon")); + messagePanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); + JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql_Message")); + messagePanel.add(label); + } + imagePanel.add(imageLabel); + + topPanel.add(imagePanel, BorderLayout.WEST); + topPanel.add(messagePanel, BorderLayout.CENTER); + topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,0,10)); + + //中间的SQL面板 + centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + centerPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); + JScrollPane scrollPane = new JScrollPane(); + JTextArea checkArea = new JTextArea(sql); + checkArea.setEditable(false); + checkArea.setCursor(new Cursor(Cursor.TEXT_CURSOR)); + if (highlight) { + Highlighter highLighter = checkArea.getHighlighter(); + DefaultHighlighter.DefaultHighlightPainter p = new DefaultHighlighter.DefaultHighlightPainter(Color.ORANGE); + for (int[] specialCharIndex : selectedSpecialCharIndex) { + try { + highLighter.addHighlight(specialCharIndex[0], specialCharIndex[1], p); + } catch (BadLocationException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + scrollPane.setViewportView(checkArea); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + centerPanel.add(scrollPane); + + //底部的按钮面板 + UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK")); + okButton.addActionListener(this); + bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + bottomPanel.add(okButton, BorderLayout.EAST); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql")); + this.setResizable(false); + this.add(topPanel, BorderLayout.NORTH); + this.add(centerPanel, BorderLayout.CENTER); + this.add(bottomPanel, BorderLayout.SOUTH); + this.setSize(600, 400); + + GUICoreUtils.centerWindow(this); + } + + private boolean isNotShowLink() { + return GeneralContext.getLocale().equals(Locale.JAPAN) || GeneralContext.getLocale().equals(Locale.KOREA); + } + + public static void previewPerformedSql(DBTableData tableData) { + Calculator calculator = Calculator.createCalculator(); + //参数 + ParameterProvider[] parameters = DataOperator.getInstance().getTableDataParameters(tableData); + if (ArrayUtils.isEmpty(parameters)) { + parameters = tableData.getParameters(calculator); + } + Map parameterMap = new HashMap<>(); + if (needInputParams(parameters)) { + showParaWindow(parameterMap, parameters); + } else { + for (ParameterProvider parameter : parameters) { + parameterMap.put(parameter.getName(), parameter.getValue()); + } + } + boolean showOriginSql = true; + for (ParameterProvider parameter : DataOperator.getInstance().getTableDataParameters(tableData)) { + if (parameterMap.containsKey(parameter.getName())) { + Object value = parameterMap.get(parameter.getName()); + if (value != null && !StringUtils.EMPTY.equals(value)) { + showOriginSql = false; + } + parameter.setValue(value); + } + } + String sql; + // 计算高亮文本位置 + List specialCharParamIndex = null; + boolean highlight = true; + if (showOriginSql) { + sql = tableData.getQuery(); + } else { + NameSpace ns = ParameterMapNameSpace.create(parameterMap); + calculator.pushNameSpace(ns); + Parameter[] paras = processParameters(tableData, calculator); + // 所有被转义参数的集合 + Set specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras); + // 将参数转义等 + Set tableDataProviders = getTableDataProviders(); + for (TableDataProvider provider : tableDataProviders) { + provider.processParametersBeforeAnalyzeSQL(paras, calculator); + } + + if (!specialCharParam.isEmpty()) { + specialCharParamIndex = ParameterHelper.analyzeCurrentContextTableData4Template(tableData.getQuery(), paras, specialCharParam); + } + String oldSql = ParameterHelper.analyzeCurrentContextTableData4Templatee(tableData.getQuery(), paras); + sql = processExtraSQL(paras, oldSql, calculator, tableDataProviders); + if (!StringUtils.equals(oldSql, sql)) { + highlight = false; + } + } + // sql内容复制到剪切板 + StringSelection selection = new StringSelection(sql); + java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); + // 弹窗 + PreviewPerformedSqlPane pane; + if (isShowSpecialCharSqlPane(specialCharParamIndex)) { + pane = new PreviewPerformedSqlPane(DesignerContext.getDesignerFrame(), sql, specialCharParamIndex, ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar(), highlight); + } else { + pane = new PreviewPerformedSqlPane(DesignerContext.getDesignerFrame(), sql); + } + pane.setVisible(true); + } + + private static boolean isShowSpecialCharSqlPane(List specialCharParamIndex) { + return specialCharParamIndex != null && !specialCharParamIndex.isEmpty(); + } + + private static Parameter[] processParameters(DBTableData tableData, Calculator calculator) { + ParameterProvider[] parameters = tableData.getParameters(); + if (parameters == null || parameters.length == 0) { + tableData.setParameters(ParameterHelper.analyze4Parameters(tableData.getQuery(), false)); + return new Parameter[0]; + } + return Parameter.providers2Parameter(Calculator.processParameters(calculator, parameters)); + } + + private static String processExtraSQL(Parameter[] ps, String sql, Calculator ca, Set tableDataProviders) { + for (TableDataProvider provider : tableDataProviders) { + String newSql = provider.processTableDataSQL(ps, sql, ca); + if (StringUtils.isNotEmpty(newSql)) { + sql = newSql; + } + } + return sql; + } + + private static boolean needInputParams(ParameterProvider[] parameters) { + if (ArrayUtils.isNotEmpty(parameters)) { + return true; + } + for (ParameterProvider parameter : parameters) { + if (parameter.getValue() == null || StringUtils.EMPTY.equals(parameter.getValue())) { + return true; + } + } + return false; + } + + private static void showParaWindow(final Map parameterMap, ParameterProvider[] inParameters) { + final ParameterInputPane pPane = new ParameterInputPane(inParameters); + pPane.showSmallWindow(new JFrame(), new DialogActionAdapter() { + @Override + public void doOk() { + parameterMap.putAll(pPane.update()); + } + }).setVisible(true); + } + + private static Set getTableDataProviders() { + ExtraClassManagerProvider classManagerProvider = PluginModule.getAgent(PluginModule.ExtraCore); + if (classManagerProvider == null) { + return new HashSet<>(); + } + return classManagerProvider.getArray(TableDataProvider.XML_TAG, EscapeSqlHelper.getInstance()); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.dispose(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java index 6065d0485..fecf9c079 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java @@ -16,6 +16,7 @@ import com.fr.design.constants.UIConstants; import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane; import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener; import com.fr.design.data.datapane.preview.PreviewTablePane; +import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane; import com.fr.design.data.datapane.sqlpane.SQLEditPane; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; @@ -35,6 +36,7 @@ import com.fr.design.menu.ToolBarDef; import com.fr.design.utils.ParameterUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; import com.fr.general.sql.SqlUtils; import com.fr.log.FineLoggerFactory; import com.fr.script.Calculator; @@ -227,6 +229,7 @@ public class DBTableDataPane extends AbstractTableDataPane { // p:工具栏. ToolBarDef toolBarDef = new ToolBarDef(); toolBarDef.addShortCut(new PreviewAction()); + toolBarDef.addShortCut(new PreviewPerformedSQLAction()); toolBarDef.addShortCut(SeparatorDef.DEFAULT); toolBarDef.addShortCut(new EditPageQueryAction()); dbTableDataMenuHandler = ExtraDesignClassManager.getInstance().getSingle(DBTableDataMenuHandler.MARK_STRING); @@ -368,6 +371,20 @@ public class DBTableDataPane extends AbstractTableDataPane { } } + private class PreviewPerformedSQLAction extends UpdateAction { + + public PreviewPerformedSQLAction() { + this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql")); + this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/m_file/preview_sql.png")); + } + + @Override + public void actionPerformed(ActionEvent e) { + checkParameter(); + PreviewPerformedSqlPane.previewPerformedSql(DBTableDataPane.this.updateBean()); + } + } + private class EditPageQueryAction extends UpdateAction { public EditPageQueryAction() { this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Page_Query")); diff --git a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java index 889a0c3c9..f73ec77df 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java +++ b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java @@ -3,13 +3,14 @@ package com.fr.design.dialog.link; import com.fr.design.gui.ilable.UILabel; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; + +import javax.swing.JEditorPane; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; import java.awt.Color; import java.awt.Desktop; import java.awt.Font; import java.net.URI; -import javax.swing.JEditorPane; -import javax.swing.event.HyperlinkEvent; -import javax.swing.event.HyperlinkListener; /** * 用来构建JOptionPane带超链的消息提示 @@ -35,8 +36,16 @@ public class MessageWithLink extends JEditorPane { this(message, linkName, link, color, LABEL.getFont()); } + public MessageWithLink(String frontMessage, String linkName, String link, String backMessage) { + this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont()); + } + public MessageWithLink(String message, String linkName, String link, Color color, Font font) { - super("text/html", "" + message + "" + linkName + "" + ""); + this(message, linkName, link, StringUtils.EMPTY, color, font); + } + + public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color color, Font font) { + super("text/html", "" + frontMessage + "" + linkName + "" + backMessage + ""); initListener(link); setEditable(false); setBorder(null); diff --git a/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java b/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java index 4dbbc1af3..6d1a729d9 100644 --- a/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java +++ b/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java @@ -177,6 +177,7 @@ public class UILookAndFeel extends MetalLookAndFeel { table.put("OptionPane.narrow.down", loadIcon("Icon_Narrow_Down_16x16.png", this)); table.put("OptionPane.warningIcon", loadIcon("WarningIcon.png", this)); table.put("OptionPane.questionIcon", loadIcon("QuestionIcon.png", this)); + table.put("OptionPane.tipIcon", loadIcon("TipIcon.png", this)); table.put("ScrollPane.border", new UIScrollPaneBorder()); table.put("ProgressBar.border", new UIProgressBarBorder()); table.put("Spinner.border", new UITextFieldBorder(new Insets(2, 2, 2, 2))); diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java index 6e0313ec7..bb7fee0a3 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java @@ -12,6 +12,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.widget.EventCreator; import com.fr.form.event.Listener; import com.fr.form.ui.Widget; +import com.fr.general.FRFont; import com.fr.general.NameObject; import com.fr.report.web.util.ReportEngineEventMapping; import com.fr.stable.ArrayUtils; @@ -26,10 +27,13 @@ import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Constructor; @@ -456,7 +460,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements L getHelper().popupEditDialog(null, this.selectNameEdList, this); } - protected String getWrapperLabelText(){ + protected String getWrapperLabelText() { return StringUtils.EMPTY; } @@ -466,9 +470,18 @@ public abstract class UIListGroupControlPane extends UIControlPane implements L public ListWrapperPane(String labelText, UINameEdList nameEdList) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - UILabel label = new UILabel(labelText + getWrapperLabelText()); + UILabel label = new UILabel(labelText + getWrapperLabelText()) { + @Override + public void paint(Graphics g) { + ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f)); + super.paint(g); + } + }; label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); - label.setBackground(Color.decode("#FFFFFF")); + label.setOpaque(true); + label.setBackground(Color.WHITE); + label.setForeground(Color.decode("#333334")); + label.setFont(label.getFont().deriveFont(10F)); label.setPreferredSize(new Dimension(224, 26)); this.nameEdList = nameEdList; this.add(label, BorderLayout.NORTH); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java index e55f9a481..7757ea2f4 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java @@ -4,12 +4,14 @@ import com.fr.base.BaseUtils; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; import com.fr.design.worker.save.CallbackSaveWorker; import com.fr.file.FILE; import com.fr.file.FileNodeFILE; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.rpc.ExceptionHandler; import com.fr.rpc.RPCInvokerExceptionInfo; @@ -21,7 +23,6 @@ import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; -import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -40,7 +41,7 @@ public class CheckButton extends UIButton { private UILabel message; private UIButton okButton; private JDialog dialog; - private UILabel uiLabel; + private UILabel imageLabel; public CheckButton() { this.setIcon(BaseUtils.readIcon("/com/fr/design/images/buttonicon/check.png")); @@ -71,7 +72,7 @@ public class CheckButton extends UIButton { } if (set.isEmpty()) { okButton.setEnabled(true); - uiLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/correct.png")); + imageLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/correct.png")); message.setText("" + Toolkit.i18nText("Fine_Designer_Check_Font_Success") + ""); } else { if (dialog != null) { @@ -161,7 +162,6 @@ public class CheckButton extends UIButton { }); checkThread.execute(); dialog.setVisible(true); - dialog.dispose(); } }; @@ -171,7 +171,7 @@ public class CheckButton extends UIButton { @Override public Void callHandler(RPCInvokerExceptionInfo rpcInvokerExceptionInfo) { - uiLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/error.png")); + imageLabel.setIcon(BaseUtils.readIcon("com/fr/design/images/error.png")); message.setText("" + Toolkit.i18nText("Fine_Designer_Check_Font_Upgrade") + ""); okButton.setEnabled(true); return null; @@ -183,7 +183,7 @@ public class CheckButton extends UIButton { private void initDialogPane() { message = new UILabel(); message.setText(Toolkit.i18nText("Fine-Designer_Check_Font_Checking") + "..."); - uiLabel = new UILabel(); + imageLabel = new UILabel(); okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK")); okButton.setEnabled(false); okButton.addActionListener(new ActionListener() { @@ -194,13 +194,13 @@ public class CheckButton extends UIButton { dialog = new JDialog(); dialog.setTitle(Toolkit.i18nText("Fine_Designer_Check_Font")); dialog.setModal(true); - dialog.setSize(new Dimension(268, 118)); + dialog.setSize(DesignSizeI18nManager.getInstance().i18nDimension(this.getClass().getName())); JPanel jp = new JPanel(); JPanel upPane = new JPanel(); JPanel downPane = new JPanel(); - uiLabel = new UILabel(BaseUtils.readIcon("com/fr/design/images/waiting.png")); + imageLabel = new UILabel(IOUtils.readIcon("com/fr/design/images/waiting.png")); upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10)); - upPane.add(uiLabel); + upPane.add(imageLabel); upPane.add(message); downPane.setLayout(new FlowLayout(FlowLayout.CENTER, 6, 0)); downPane.add(okButton); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java index 0d5771a49..0671ed1b6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/check/CheckFontInfoDialog.java @@ -3,11 +3,11 @@ package com.fr.design.mainframe.check; import com.fr.design.dialog.link.MessageWithLink; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.CloudCenter; -import com.fr.general.GeneralContext; import com.fr.general.IOUtils; import javax.swing.BorderFactory; @@ -17,13 +17,11 @@ import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; import java.awt.BorderLayout; -import java.awt.Dimension; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.Locale; /** * 字体缺失检测的具体结果对话框 @@ -52,7 +50,7 @@ public class CheckFontInfoDialog extends JDialog implements ActionListener { MessageWithLink linkMessage = new MessageWithLink(Toolkit.i18nText("Fine_Designer_Check_Font_Message"), Toolkit.i18nText("Fine_Designer_Check_Font_Install_Font"), CloudCenter.getInstance().acquireUrlByKind("help.install.font", "https://help.fanruan.com/finereport/doc-view-3999.html")); - linkMessage.setPreferredSize(new Dimension(380, 31)); + linkMessage.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink")); messagePanel.add(linkMessage); // 查看详情按钮 @@ -89,11 +87,11 @@ public class CheckFontInfoDialog extends JDialog implements ActionListener { public void mouseClicked(MouseEvent e) { if (hiddenPanel.isVisible()) { hiddenPanel.setVisible(false); - CheckFontInfoDialog.this.setSize(new Dimension(380, 185)); + CheckFontInfoDialog.this.setSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.check.CheckFontInfoDialog.collapse")); detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); } else { - CheckFontInfoDialog.this.setSize(new Dimension(380, 280)); + CheckFontInfoDialog.this.setSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.check.CheckFontInfoDialog.unfold")); hiddenPanel.setVisible(true); detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail")); directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); @@ -114,7 +112,7 @@ public class CheckFontInfoDialog extends JDialog implements ActionListener { this.add(topPanel, BorderLayout.NORTH); this.add(hiddenPanel, BorderLayout.CENTER); this.add(bottomPanel, BorderLayout.SOUTH); - this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US)? 400:380, 185)); + this.setSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.mainframe.check.CheckFontInfoDialog.collapse")); GUICoreUtils.centerWindow(this); } diff --git a/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java b/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java index 526280027..1d8e73e84 100644 --- a/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java +++ b/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java @@ -83,7 +83,7 @@ public class ContentReplaceUtil { private static String replaceFormulaContent4TableDataName0(String content, String oldName, String newName) { content = getFormulaPureContent(content); FRFormulaTransformer frFormulaTransformer = new FRFormulaTransformer(); - frFormulaTransformer.addRenamedWidget(oldName, newName); + frFormulaTransformer.addRenamedDataset(oldName, newName); return EQ_STRING + frFormulaTransformer.transform(content); } diff --git a/designer-base/src/main/java/com/fr/design/mod/ModClassFilter.java b/designer-base/src/main/java/com/fr/design/mod/ModClassFilter.java index 7caa88ac4..6ed0b367f 100644 --- a/designer-base/src/main/java/com/fr/design/mod/ModClassFilter.java +++ b/designer-base/src/main/java/com/fr/design/mod/ModClassFilter.java @@ -17,6 +17,8 @@ public class ModClassFilter implements Filter { private static final Filter INSTANCE = new ModClassFilter(); + private static final String DESIGN_PREFIX = "com.fr.design"; + public static Filter getInstance() { return INSTANCE; } @@ -27,10 +29,11 @@ public class ModClassFilter implements Filter { FILTER_SET.add("com.fr.poly.creator.ECBlockCreator"); FILTER_SET.add("io.netty.channel.nio.SelectedSelectionKeySet"); FILTER_SET.add("com.fr.form.ui.ElementCaseImage"); + FILTER_SET.add("this$0"); } @Override public boolean accept(String s) { - return FILTER_SET.contains(s); + return FILTER_SET.contains(s) || s.startsWith(DESIGN_PREFIX); } } diff --git a/designer-base/src/main/java/com/fr/design/update/actions/SyncFileProcess.java b/designer-base/src/main/java/com/fr/design/update/actions/SyncFileProcess.java new file mode 100644 index 000000000..1614d1084 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/update/actions/SyncFileProcess.java @@ -0,0 +1,50 @@ +package com.fr.design.update.actions; + +import com.fr.decision.update.SyncExecutor; +import com.fr.decision.update.info.UpdateCallBack; +import com.fr.log.FineLoggerFactory; +import java.util.concurrent.ExecutionException; +import javax.swing.SwingWorker; + +public abstract class SyncFileProcess extends SwingWorker { + private UpdateCallBack callBack; + private String buildNo; + + public SyncFileProcess(UpdateCallBack callBack,String buildNo) { + this.callBack = callBack; + this.buildNo = buildNo; + } + + @Override + protected Boolean doInBackground() throws Exception { + return SyncExecutor.getInstance().execute(callBack,buildNo); + } + + @Override + protected void done() { + boolean success = false; + try { + success = get(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (success) { + onDownloadSuccess(); + } else { + onDownloadFailed(); + } + } + + /** + * 下载成功 + */ + public abstract void onDownloadSuccess(); + + /** + * 下载失败 + */ + public abstract void onDownloadFailed(); +} diff --git a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java index efee9bfdf..3a4612699 100644 --- a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java +++ b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java @@ -1,32 +1,67 @@ package com.fr.env; -import com.fr.design.DesignerEnvManager; -import com.fr.design.env.RemoteDesignerWorkspaceInfo; +import com.fr.decision.update.data.UpdateConstants; +import com.fr.decision.update.info.UpdateCallBack; +import com.fr.decision.update.info.UpdateProgressCallBack; +import com.fr.design.RestartHelper; +import com.fr.design.VersionCheckUtils; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.update.actions.SyncFileProcess; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.env.utils.DisplayUtils; +import com.fr.general.CloudCenter; +import com.fr.general.CloudCenterConfig; +import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.GeneralContext; import com.fr.general.IOUtils; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.process.engine.core.FineProcessContext; +import com.fr.process.engine.core.FineProcessEngineEvent; +import com.fr.stable.CommonUtils; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; +import com.sun.java.swing.plaf.motif.MotifProgressBarUI; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.File; +import java.util.List; +import java.util.concurrent.ExecutionException; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JDialog; +import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JTextArea; -import javax.swing.JTextPane; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.Locale; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingWorker; +import javax.swing.UIManager; + + +import static javax.swing.JOptionPane.QUESTION_MESSAGE; /** * @author: Maksim @@ -36,11 +71,34 @@ import java.util.Locale; public class CheckServiceDialog extends JDialog implements ActionListener { private JPanel topPanel; private JPanel centerPanel; - private JPanel bottomPanel; - private UICheckBox remindBox; + private UIButton ignoreButton; + private UIButton syncButton; + private JProgressBar progressBar; + private String remoteBuildNo; + private static final Dimension PROGRESSBAR = new Dimension(120, 15); + private JSONArray differentPlugins; + private UILabel affectedFunctionsLabel; + private UILabel jarCheckResultLabel; + private UILabel jarCheckTitleLabel; + private UILabel pluginCheckTitleLabel; + + private JPanel affectedFunctionsDetailsPane; + private JPanel pluginsCheckResultPanel; + private JPanel detailsInnerPane; + private JPanel detailsPane; + private JScrollPane jScrollPane; + private Component[][] detailsComponents; + private Component[][] hideAffectedFunctionsComponents; + private boolean showAffectedFunctions = true; + private boolean jarConsistency; + private double p = TableLayout.PREFERRED; + private double f = TableLayout.FILL; - public CheckServiceDialog(Frame parent, String areaText, String localBranch, String remoteBranch){ - super(parent,true); + public CheckServiceDialog(Frame parent, String localBranch, String remoteBranch, List noExistServiceDescription) { + super(parent, true); + this.remoteBuildNo = remoteBranch; + this.differentPlugins = VersionCheckUtils.checkLocalAndRemotePlugin(); + this.jarConsistency = ComparatorUtils.equals(localBranch, remoteBranch); //上面的标签面板 topPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); JPanel imagePanel = new JPanel(); @@ -49,90 +107,318 @@ public class CheckServiceDialog extends JDialog implements ActionListener { JLabel imageLabel = new JLabel(); imageLabel.setIcon(icon); imagePanel.add(imageLabel); - imagePanel.setPreferredSize(new Dimension(110,100)); + imagePanel.setPreferredSize(new Dimension(110, 100)); JPanel verticalPanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); FRFont font = FRFont.getInstance(); font = font.applySize(15).applyStyle(1); - JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Inconsistency")); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Branch_Inconsistency")); label.setFont(font); - label.setPreferredSize(new Dimension(650,30)); - - String text = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Local_Designer") + localBranch - + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Remote_Server") + - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old") + - localBranch; - String delimiter = DisplayUtils.getDisplayLength(text) > 70? "
":"/"; - JLabel label2 = new JLabel(""+Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Local_Designer") - + localBranch + delimiter + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Remote_Server") + - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old")+ localBranch +""); - label2.setPreferredSize(new Dimension(600,30)); - - JTextPane tipsPane = new JTextPane(); - tipsPane.setEditable(false); - tipsPane.setBackground(verticalPanel.getBackground()); - tipsPane.setPreferredSize(new Dimension(500,40)); - tipsPane.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Need_Update")); + label.setPreferredSize(new Dimension(650, 30)); + UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Inconsistency_Risk")); + label2.setPreferredSize(new Dimension(600, 30)); verticalPanel.add(label); verticalPanel.add(label2); - verticalPanel.add(tipsPane); - topPanel.add(imagePanel,BorderLayout.WEST); - topPanel.add(verticalPanel,BorderLayout.CENTER); - topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,0,10)); + topPanel.add(imagePanel, BorderLayout.WEST); + topPanel.add(verticalPanel, BorderLayout.CENTER); + topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); //中间的文本域面板 centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - centerPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); - centerPanel.setPreferredSize(new Dimension(480,320)); - - JLabel titleLabel = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Affected_Function")); - titleLabel.setPreferredSize(new Dimension(400,40)); - JTextArea checkArea = new JTextArea(areaText); - checkArea.setEnabled(false); - centerPanel.add(titleLabel,BorderLayout.NORTH); - centerPanel.add(checkArea,BorderLayout.CENTER); - - //下面的按钮面板 - remindBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Remind_Show")); - remindBox.addActionListener(remindCheckboxListener); - UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Button_Confirm")); - JPanel buttonPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - buttonPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); - buttonPanel.add(remindBox, BorderLayout.WEST); - buttonPanel.add(okButton,BorderLayout.EAST); - okButton.addActionListener(this ); - bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - bottomPanel.add(buttonPanel); + centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + centerPanel.setPreferredSize(new Dimension(480, 320)); + + UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Details")); + titleLabel.setPreferredSize(new Dimension(400, 40)); + //详情面板 + detailsPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); + detailsPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); + detailsPane.setBackground(Color.WHITE); + + jarCheckTitleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_JAR_Check_title")); + jarCheckTitleLabel.setBackground(Color.WHITE); + + + //插件的检测结果相关面板 + pluginCheckTitleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Check_title")); + pluginCheckTitleLabel.setBackground(Color.WHITE); + initPluginsCheckResultPanel(differentPlugins); + + //jar包检测结果相关面板 + initJarCheckResultPanel(remoteBranch, noExistServiceDescription); + + double[] detailsRowSize; + double[] detailsColumnSize = {f}; + + detailsComponents = new Component[][]{{jarCheckTitleLabel}, {jarCheckResultLabel}, {affectedFunctionsLabel}, {affectedFunctionsDetailsPane}, {pluginCheckTitleLabel}, {pluginsCheckResultPanel}}; + hideAffectedFunctionsComponents = new Component[][]{{jarCheckTitleLabel}, {jarCheckResultLabel}, {affectedFunctionsLabel}, {pluginCheckTitleLabel}, {pluginsCheckResultPanel}}; + if (noExistServiceDescription.size() > 0 && !ComparatorUtils.equals(remoteBranch, localBranch)) { + detailsRowSize = new double[]{p, p, p, p,p,p}; + detailsInnerPane = TableLayoutHelper.createTableLayoutPane(detailsComponents, detailsRowSize, detailsColumnSize); + } else { + detailsRowSize = new double[]{p, p, 0, 0, p, p}; + detailsInnerPane = TableLayoutHelper.createTableLayoutPane(detailsComponents, detailsRowSize, detailsColumnSize); + } + detailsInnerPane.setBackground(Color.WHITE); + jScrollPane = new JScrollPane(detailsInnerPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jScrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + detailsPane.add(jScrollPane); + centerPanel.add(titleLabel, BorderLayout.NORTH); + centerPanel.add(detailsPane, BorderLayout.CENTER); + JPanel buttonPanel = FRGUIPaneFactory.createBorderLayout_M_Pane(); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + if (isOnline()) { + ignoreButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_Ignore")); + ignoreButton.addActionListener(this); + syncButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local")); + syncButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local_Tip")); + syncButton.addMouseListener(syncButtonClickListener); + progressBar = new JProgressBar(); + progressBar.setUI(new MotifProgressBarUI()); + progressBar.setForeground(UpdateConstants.BAR_COLOR); + progressBar.setVisible(false); + progressBar.setStringPainted(true); + progressBar.setPreferredSize(PROGRESSBAR); + buttonPanel.add(ignoreButton, BorderLayout.WEST); + buttonPanel.add(progressBar, BorderLayout.CENTER); + buttonPanel.add(syncButton, BorderLayout.EAST); + } else { + UILabel adviceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Suggestion")); + centerPanel.add(adviceLabel, BorderLayout.SOUTH); + UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Button_Confirm")); + okButton.addActionListener(this); + buttonPanel.add(okButton, BorderLayout.EAST); + } this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Title_Hint")); this.setResizable(false); - - this.add(topPanel,BorderLayout.NORTH); + this.add(topPanel, BorderLayout.NORTH); this.add(centerPanel, BorderLayout.CENTER); - this.add(buttonPanel,BorderLayout.SOUTH); - this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US)? 750:600, 500)); - + this.add(buttonPanel, BorderLayout.SOUTH); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 750 : 600, 500)); GUICoreUtils.centerWindow(this); } + + /** + * 插件检测的结果 + */ + private void initPluginsCheckResultPanel(JSONArray differentPlugins) { + + if (differentPlugins.size() > 0) { + int size = differentPlugins.size(); + Component[][] pluginCheckResultComponents = new Component[size][1]; + double[] pluginCheckResultColumnSize = new double[size]; + for (int i = 0; i < size; i++) { + JSONObject plugin = differentPlugins.getJSONObject(i); + JLabel pluginLabel; + if (ComparatorUtils.equals(VersionCheckUtils.INCONSISTENCY, plugin.getString("type"))) { + pluginLabel = new JLabel("\"" + plugin.getString("name") + "\"" + Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Inconsistency_Info") + plugin.getString("version")); + } else if (ComparatorUtils.equals(VersionCheckUtils.MISSING, plugin.getString("type"))) { + pluginLabel = new JLabel("\"" + plugin.getString("name") + "\"" + Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Missing_Info") + plugin.getString("version")); + } else { + continue; + } + pluginLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/fail.png")); + pluginCheckResultComponents[i][0] = pluginLabel; + pluginCheckResultColumnSize[i] = p; + } + double[] pluginCheckResultRowSize = {f}; + pluginsCheckResultPanel = TableLayoutHelper.createTableLayoutPane(pluginCheckResultComponents, pluginCheckResultColumnSize, pluginCheckResultRowSize); + } else { + UILabel pluginCheckResultLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Consistency")); + pluginCheckResultLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/success.png")); + pluginsCheckResultPanel = TableLayoutHelper.createTableLayoutPane(new Component[][]{{pluginCheckResultLabel}}, new double[]{p}, new double[]{f}); + } + pluginsCheckResultPanel.setBackground(Color.WHITE); + } + + /** + * jar包检测的结果 + */ + private void initJarCheckResultPanel(String remoteBranch, List noExistServiceDescription) { + jarCheckResultLabel = new UILabel(); + jarCheckResultLabel.setBackground(Color.WHITE); + if (jarConsistency) { + jarCheckResultLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Sync_JAR_Consistency")); + jarCheckResultLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/success.png")); + } else { + jarCheckResultLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Sync_JAR_Inconsistency_Info") + remoteBranch); + jarCheckResultLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/fail.png")); + Component[][] noExistServiceComponents; + int noExistService = noExistServiceDescription.size(); + if (noExistService > 0) { + affectedFunctionsLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Affected_Function")); + affectedFunctionsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + affectedFunctionsLabel.setBackground(Color.WHITE); + affectedFunctionsLabel.addMouseListener(affectedFunctionsClickListener); + noExistServiceComponents = new Component[noExistServiceDescription.size()][1]; + double[] noExistServiceColumnSize = new double[noExistService]; + for (int i = 0; i < noExistService; i++) { + JLabel noExitServiceLabel = new JLabel(" " + noExistServiceDescription.get(i)); + noExistServiceComponents[i][0] = noExitServiceLabel; + noExistServiceColumnSize[i] = p; + } + double[] noExistServiceRowSize = {f}; + affectedFunctionsDetailsPane = TableLayoutHelper.createTableLayoutPane(noExistServiceComponents, noExistServiceColumnSize, noExistServiceRowSize); + affectedFunctionsDetailsPane.setBackground(Color.WHITE); + } + } + } + @Override public void actionPerformed(ActionEvent e) { this.dispose(); } + private boolean isOnline() { + if (CloudCenterConfig.getInstance().isOnline()) { + String ping = CloudCenter.getInstance().acquireConf("ping", StringUtils.EMPTY); + if (StringUtils.isNotEmpty(ping)) { + try { + return StringUtils.isEmpty(HttpToolbox.get(ping)); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + } + return false; + } - private ActionListener remindCheckboxListener = new ActionListener() { + private MouseListener affectedFunctionsClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (showAffectedFunctions) { + showAffectedFunctions = false; + detailsInnerPane.removeAll(); + affectedFunctionsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + TableLayoutHelper.addComponent2ResultPane(hideAffectedFunctionsComponents, new double[]{p, p, p, p, p}, new double[]{f}, detailsInnerPane); + jScrollPane.validate(); + jScrollPane.repaint(); + } else { + showAffectedFunctions = true; + detailsInnerPane.removeAll(); + affectedFunctionsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + TableLayoutHelper.addComponent2ResultPane(detailsComponents, new double[]{p, p, p, p, p, p}, new double[]{f}, detailsInnerPane); + jScrollPane.validate(); + jScrollPane.repaint(); + } + } + }; + private MouseListener syncButtonClickListener = new MouseAdapter() { @Override - public void actionPerformed(ActionEvent e) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - String remindTime = format.format(new Date()); - //环境已切换,通过当前环境获取,一定是远程环境 - String currentEnvName = DesignerEnvManager.getEnvManager().getCurEnvName(); - RemoteDesignerWorkspaceInfo currentEnv = (RemoteDesignerWorkspaceInfo)DesignerEnvManager.getEnvManager().getWorkspaceInfo(currentEnvName); - currentEnv.setRemindTime(remindBox.isSelected()? remindTime : ""); + public void mouseClicked(MouseEvent e) { + String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; + int a = FineJOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Basic_Sync_Info_Information"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, IOUtils.readIcon("com/fr/design/icon/versioncheck/question.png"), option, 1); + if (0 == a) { + //jar包一致的话只更新插件 + UpdateCallBack callBack = new UpdateProgressCallBack(progressBar); + progressBar.setVisible(true); + progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message")); + syncButton.setEnabled(false); + if (!jarConsistency) { + deletePreviousPropertyFile(); + final String installLib = StableUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LOGS_NAME, UpdateConstants.INSTALL_LIB); + final JFrame frame = DesignerContext.getDesignerFrame(); + final RestartHelper helper = new RestartHelper(); + FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY); + new SyncFileProcess(callBack, remoteBuildNo) { + @Override + public void onDownloadSuccess() { + deleteForDesignerUpdate(installLib); + //主jar下载成功之后再卸载安装插件 + progressBar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); + progressBar.setValue(0); + new SwingWorker() { + + @Override + protected JSONArray doInBackground() { + return VersionCheckUtils.syncPlugins(differentPlugins); + } + + @Override + protected void done() { + progressBar.setVisible(false); + JSONArray syncFailedPlugins = null; + try { + syncFailedPlugins = get(); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + if (syncFailedPlugins != null && syncFailedPlugins.size() > 0) { + SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(DesignerContext.getDesignerFrame(), syncFailedPlugins); + syncFailedPluginsDialog.setVisible(true); + } + helper.restartForUpdate(frame); + } + }.execute(); + } + + @Override + public void onDownloadFailed() { + progressBar.setVisible(false); + deleteForDesignerUpdate(installLib); + ErrorDialog errorDialog = new ErrorDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Fail")); + errorDialog.setVisible(true); + helper.restartForUpdate(frame); + } + }.execute(); + } else { + //到这边说明主jar是一致的,就只尝试同步插件 + progressBar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); + progressBar.setValue(0); + new SwingWorker() { + + @Override + protected JSONArray doInBackground() { + return VersionCheckUtils.syncPlugins(differentPlugins); + } + + @Override + protected void done() { + progressBar.setVisible(false); + JSONArray syncFailedPlugins = null; + try { + syncFailedPlugins = get(); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + if (syncFailedPlugins != null && syncFailedPlugins.size() > 0) { + SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(DesignerContext.getDesignerFrame(), syncFailedPlugins); + syncFailedPluginsDialog.setVisible(true); + } else { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Sync_Success"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + FineJOptionPane.INFORMATION_MESSAGE); + } + close(); + } + }.execute(); + } + } } }; + private boolean deletePreviousPropertyFile() { + File moveFile = new File(RestartHelper.MOVE_FILE); + File delFile = new File(RestartHelper.RECORD_FILE); + if (StableUtils.mkdirs(moveFile) && StableUtils.mkdirs(delFile)) { + return StableUtils.deleteFile(moveFile) && StableUtils.deleteFile(delFile); + } + return false; + } + + private void close() { + this.dispose(); + } + + private void deleteForDesignerUpdate(String installLib) { + File dir = new File(installLib); + CommonUtils.deleteFile(dir); + } } diff --git a/designer-base/src/main/java/com/fr/env/ErrorDialog.java b/designer-base/src/main/java/com/fr/env/ErrorDialog.java new file mode 100644 index 000000000..be91955f2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/ErrorDialog.java @@ -0,0 +1,73 @@ +package com.fr.env; + +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.CloudCenter; +import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; + +/** + * 主jar下载失败的弹出框 + * + * */ + +public class ErrorDialog extends JDialog implements ActionListener { + public ErrorDialog(Frame parent, String message) { + super(parent, true); + init(message); + } + + private void init(String message){ + //主体内容 + JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + //带超链的提示信息 + JPanel messagePanel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + messagePanel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); + + MessageWithLink messageWithLink = new MessageWithLink(message + ",", Toolkit.i18nText("Fine-Design_Basic_Sync_Help"), CloudCenter.getInstance().acquireUrlByKind("help.replacejars", "https://help.fanruan.com/finereport/doc-view-3268.html")); + messageWithLink.setPreferredSize(new Dimension(108, 20)); + JPanel messageLinkPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + messageLinkPane.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 0)); + messageLinkPane.add(messageWithLink); + + //错误提示图标 + UILabel imageLabel = new UILabel(IOUtils.readIcon("com/fr/design/icon/versioncheck/bigfail.png")); + messagePanel.add(imageLabel); + messagePanel.add(messageLinkPane); + + //确定按钮 + UIButton ok = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Button_OK")); + ok.addActionListener(this); + ok.setSize(new Dimension(44, 20)); + JPanel okPanel = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + okPanel.add(ok); + + centerPanel.add(messagePanel, BorderLayout.CENTER); + centerPanel.add(okPanel, BorderLayout.SOUTH); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")); + this.setResizable(false); + this.add(centerPanel, BorderLayout.CENTER); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 282 : 262, 118)); + GUICoreUtils.centerWindow(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.dispose(); + } +} diff --git a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java new file mode 100644 index 000000000..b9046e153 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java @@ -0,0 +1,119 @@ +package com.fr.env; + +import com.fr.design.RestartHelper; +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextarea.UITextArea; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.CloudCenter; +import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.stable.StringUtils; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.UIManager; + +/** + * @author pengda + * @version 10.0 + * Created on 2021-06-02 + */ +public class SyncFailedPluginsDialog extends JDialog { + private UILabel detailsLabel; + private JScrollPane scrollPane; + public SyncFailedPluginsDialog(Frame parent, JSONArray syncFailedPlugins) { + super(parent, true); + JPanel body = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + JPanel northPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + northPane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); + JPanel imagePanel = new JPanel(); + Icon icon = IOUtils.readIcon("com/fr/design/icon/versioncheck/warning.png"); + JLabel imageLabel = new JLabel(); + imageLabel.setIcon(icon); + imagePanel.add(imageLabel); + imagePanel.setPreferredSize(new Dimension(20, 20)); + + JPanel messagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + MessageWithLink messageWithLink = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Fail_Suggestion"),Toolkit.i18nText("Fine-Design_Basic_Sync_Deal_Immediately"), + CloudCenter.getInstance().acquireUrlByKind("help.installplugins", "https://help.fanruan.com/finereport/doc-view-2198.html")); + messageWithLink.setPreferredSize(new Dimension(316, 20)); + + messagePane.add(messageWithLink); + messagePane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); + + northPane.add(imageLabel, BorderLayout.WEST); + northPane.add(messagePane, BorderLayout.CENTER); + + JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + detailsLabel = new UILabel(Toolkit.i18nText("Fine_Designer_Look_Detail")); + detailsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + detailsLabel.addMouseListener(detailsLabelClickListener); + JPanel detailsTitlePanel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + detailsTitlePanel.add(detailsLabel); + detailsTitlePanel.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); + + UITextArea detailsTextArea = new UITextArea(); + StringBuilder detailsText = new StringBuilder(StringUtils.EMPTY); + for (int i = 0; i < syncFailedPlugins.size(); i++) { + JSONObject plugin = syncFailedPlugins.getJSONObject(i); + detailsText.append(plugin.getString("name")).append(",").append(Toolkit.i18nText("Fine-Design_Basic_Sync_Server_Version")).append(plugin.getString("version")).append("\n"); + } + detailsTextArea.setText(detailsText.toString()); + scrollPane = new JScrollPane(detailsTextArea); + centerPanel.add(detailsTitlePanel,BorderLayout.NORTH); + centerPanel.add(scrollPane,BorderLayout.CENTER); + + JPanel southPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + UIButton restartButton = new UIButton(Toolkit.i18nText("Fine-Design_Updater_Restart_Designer")); + restartButton.addMouseListener(restartButtonClickListener); + southPane.add(restartButton); + + body.add(northPane,BorderLayout.NORTH); + body.add(centerPanel,BorderLayout.CENTER); + body.add(southPane,BorderLayout.SOUTH); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")); + this.setResizable(false); + this.add(body, BorderLayout.CENTER); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 400 : 380, 225)); + GUICoreUtils.centerWindow(this); + } + + private MouseListener detailsLabelClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if(scrollPane.isVisible()){ + scrollPane.setVisible(false); + detailsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + }else{ + scrollPane.setVisible(true); + detailsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + } + } + }; + + private MouseListener restartButtonClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + RestartHelper.restartForUpdate(DesignerContext.getDesignerFrame()); + } + }; +} diff --git a/designer-base/src/main/java/com/fr/env/VersionCheckMessageDialog.java b/designer-base/src/main/java/com/fr/env/VersionCheckMessageDialog.java new file mode 100644 index 000000000..657b13e0a --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/VersionCheckMessageDialog.java @@ -0,0 +1,105 @@ +package com.fr.env; + +import com.fr.design.VersionCheckUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; +import com.fr.general.GeneralUtils; +import com.fr.general.IOUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; + +/** + * @author pengda + * @version 10.0 + * Created on 2021-06-02 + */ +public class VersionCheckMessageDialog extends JDialog implements ActionListener { + private UILabel imageLabel; + private UILabel detailLabel; + private JPanel centerPanel; + private JPanel detailPanel; + private JPanel body; + private String envName; + + public VersionCheckMessageDialog(Frame parent, String message, String envName) { + super(parent, true); + this.envName = envName; + init(message); + } + + private void init(String message) { + JPanel imagePanel = new JPanel(); + imageLabel = new UILabel(IOUtils.readIcon("com/fr/design/images/warnings/warning32.png")); + imagePanel.add(imageLabel); + JPanel messagePanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); + UILabel messageText = new UILabel(); + messageText.setText("" + message + ""); + messagePanel.add(messageText); + + centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + centerPanel.setBorder(BorderFactory.createEmptyBorder(15, 10, 10, 10)); + centerPanel.add(imagePanel, BorderLayout.WEST); + centerPanel.add(messagePanel, BorderLayout.CENTER); + + detailLabel = new UILabel(); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + detailLabel.setForeground(Color.BLUE); + + detailPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + detailPanel.add(detailLabel, BorderLayout.EAST); + + String localBranch = GeneralUtils.readFullBuildNO(); + String remoteBranch = VersionCheckUtils.getRemoteBranch(envName); + List noExistServiceDescription; + if(ComparatorUtils.equals(localBranch,remoteBranch)) { + noExistServiceDescription = new ArrayList<>(); + }else{ + noExistServiceDescription = VersionCheckUtils.getNoExistServiceDescription(this.envName); + } + + detailPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + hideDialog(); + CheckServiceDialog checkServiceDialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), localBranch, remoteBranch, noExistServiceDescription); + checkServiceDialog.setVisible(true); + } + }); + + body = FRGUIPaneFactory.createBorderLayout_S_Pane(); + body.add(centerPanel, BorderLayout.CENTER); + body.add(detailPanel, BorderLayout.SOUTH); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Sync_Prompt")); + this.setResizable(false); + this.add(body, BorderLayout.NORTH); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 300 : 280, 135)); + GUICoreUtils.centerWindow(this); + } + + private void hideDialog(){ + this.dispose(); + } + + @Override + public void actionPerformed(ActionEvent e) { + hideDialog(); + } +} diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties index 1cafa6d35..23abf1ba4 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties @@ -1 +1,5 @@ +com.fr.design.mainframe.check.CheckButton=305*118 +com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=630*185 +com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=630*31 +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=630*280 com.fr.design.report.ReportColumnsPane=800*600 diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties index e69de29bb..97c7a38b6 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties @@ -0,0 +1,4 @@ +com.fr.design.mainframe.check.CheckButton=280*118 +com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=610*185 +com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=610*31 +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=610*280 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties index e69de29bb..4ebb3e1ed 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties @@ -0,0 +1,4 @@ +com.fr.design.mainframe.check.CheckButton=230*118 +com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=490*185 +com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=490*31 +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=490*280 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties index 69c2fcef4..85eb5c552 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties @@ -1 +1,5 @@ # \u9ED8\u8BA4\u4E3A\u7C7B\u7684\u5168\u9650\u5B9A\u540D\uFF08\u53EF\u81EA\u5B9A\u4E49key\uFF09= width * height +com.fr.design.mainframe.check.CheckButton=250*118 +com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=385*185 +com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=385*31 +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=385*280 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties index e69de29bb..d6bdbbc64 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties @@ -0,0 +1,4 @@ +com.fr.design.mainframe.check.CheckButton=250*118 +com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=385*185 +com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=385*31 +com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=385*280 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/arrowright.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/arrowright.png new file mode 100644 index 000000000..faa3f898d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/arrowright.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/bigfail.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/bigfail.png new file mode 100644 index 000000000..0f09b2cba Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/bigfail.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/fail.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/fail.png new file mode 100644 index 000000000..611cab720 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/fail.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/question.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/question.png new file mode 100644 index 000000000..cf46cd468 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/question.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/success.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/success.png new file mode 100644 index 000000000..f88e68ece Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/success.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/warning.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/warning.png new file mode 100644 index 000000000..4d2a189b6 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/warning.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/TipIcon.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/TipIcon.png new file mode 100644 index 000000000..5c9492502 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/TipIcon.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/m_file/preview_sql.png b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_sql.png new file mode 100644 index 000000000..ba62d487a Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/m_file/preview_sql.png differ diff --git a/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java b/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java index 07a1d54f8..090838fd0 100644 --- a/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java +++ b/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java @@ -60,7 +60,7 @@ public class EnvChangeEntranceTest { EasyMock.replay(request, selectedEnv, connectionInfo); PowerMock.replayAll(); - entrance.showServiceDialog(selectedEnv); + //entrance.showServiceDialog(selectedEnv); }catch (Exception e){ Assert.fail(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index 3cd33d6c3..01d53f850 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -5,11 +5,13 @@ package com.fr.design.designer.creator; import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.UpdateAction; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.fun.ShareWidgetUIProcessor; import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.layout.FRGUIPaneFactory; @@ -298,6 +300,10 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo @Override public JComponent createToolPane(BaseJForm jform, FormDesigner formEditor) { if (!DesignerMode.isAuthorityEditing()) { + ShareWidgetUIProcessor exportProcessor = ExtraDesignClassManager.getInstance().getSingle(ShareWidgetUIProcessor.MARK_STRING); + if (exportProcessor != null) { + return exportProcessor.createToolPane(this, jform, formEditor); + } if (isDedicateContainer() && this.getComponentCount() > 0) { // 图表块和报表块由于控件树处不显示,但对应的属性表要显示,此处处理下 XCreator child = ((XLayoutContainer) this).getXCreator(0); @@ -789,7 +795,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo public boolean isTopable() { return true; } - + } diff --git a/designer-form/src/main/java/com/fr/design/fun/ShareWidgetUIProcessor.java b/designer-form/src/main/java/com/fr/design/fun/ShareWidgetUIProcessor.java new file mode 100644 index 000000000..510b2cddd --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/fun/ShareWidgetUIProcessor.java @@ -0,0 +1,29 @@ +package com.fr.design.fun; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.BaseJForm; +import com.fr.design.mainframe.FormDesigner; +import com.fr.stable.fun.mark.Immutable; + +import javax.swing.JComponent; + + +/** + * Created by kerry on 5/28/21 + */ +public interface ShareWidgetUIProcessor extends Immutable { + + String MARK_STRING = "ShareWidgetUIProcessor"; + + int CURRENT_LEVEL = 1; + + /** + * 生成属性配置界面 + * + * @param xCreator 选中的Xcreator + * @param formDesigner 表单设计器 + * @return 属性配置界面 + */ + JComponent createToolPane(XCreator xCreator, BaseJForm jform, FormDesigner formDesigner); + +} diff --git a/designer-form/src/main/java/com/fr/design/fun/impl/AbstractShareWidgetUIProcessor.java b/designer-form/src/main/java/com/fr/design/fun/impl/AbstractShareWidgetUIProcessor.java new file mode 100644 index 000000000..e0eddd09d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/fun/impl/AbstractShareWidgetUIProcessor.java @@ -0,0 +1,19 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.ShareWidgetUIProcessor; +import com.fr.stable.fun.mark.API; + +/** + * Created by kerry on 5/28/21 + */ +@API(level = ShareWidgetUIProcessor.CURRENT_LEVEL) +public abstract class AbstractShareWidgetUIProcessor implements ShareWidgetUIProcessor { + + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index 170704aa6..8fbc4d06d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -4,6 +4,7 @@ import com.fr.base.BaseUtils; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; @@ -89,7 +90,7 @@ public class FormWidgetDetailPane extends FormDockView{ cardLayout.show(centerPane, paneList.get(newSelectedIndex).getTitle()); } }; - headGroup.setSelectedIndex(ONLINE_TAB); + headGroup.setSelectedIndex(ComponentReuseNotificationInfo.getInstance().isClickedWidgetLib() ? 0 : ONLINE_TAB); this.add(headGroup, BorderLayout.NORTH); this.add(centerPane, BorderLayout.CENTER); } @@ -105,12 +106,11 @@ public class FormWidgetDetailPane extends FormDockView{ } - public void enterWidgetLib() { + public void enterWidgetLib() { EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); ComponentReuseNotifyUtil.enterWidgetLibExtraAction(false); } - /** * 定位 * diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java index 0a572e672..4c759822b 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java @@ -2,6 +2,7 @@ package com.fr.start.module; import com.fr.design.DesignerEnvManager; import com.fr.design.EnvChangeEntrance; +import com.fr.design.VersionCheckUtils; import com.fr.design.constants.DesignerLaunchStatus; import com.fr.design.editlock.ConnectionLockChangeChecker; import com.fr.design.editlock.ServerTableDataLockChangeChecker; @@ -69,7 +70,7 @@ public class DesignerWorkspaceProvider extends Activator { @Override public void on(Event event, Null aNull) { try { - EnvChangeEntrance.getInstance().showServiceDialog(selectEnv); + VersionCheckUtils.showVersionCheckDialog(selectEnv.getName()); } catch (Exception e) { FineLoggerFactory.getLogger().warn("Check Service Failed"); }