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 74cebeb5a1..aa56e76b08 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 @@ -29,9 +29,6 @@ import java.awt.event.WindowEvent; */ public abstract class DatabaseConnectionPane extends BasicBeanPane { - // 编码转换. - private UIComboBox originalCharSetComboBox; - private UIComboBox newCharSetComboBox; private UILabel message; private UIButton okButton; private UIButton cancelButton; @@ -44,8 +41,6 @@ public abstract class DatabaseConnectionPane { + private static final int REPEAT_DOWNLOAD_TIMES = 3; + private DownloadItem[] files; + private String saveDir; + //已经完成的大小 + private long completeSize; + + public FileDownloader(DownloadItem[] files, String saveDir) { + this.files = files; + this.saveDir = saveDir; + } + + @Override + protected Boolean doInBackground() throws Exception { + if (ArrayUtils.isNotEmpty(files)) { + setCompleteSize(0L); + for (DownloadItem item : files) { + for (int i = 0; i < REPEAT_DOWNLOAD_TIMES; i++) { + item.setTotalLength(0); + item.setDownloadLength(0); + download(item); + if (item.getTotalLength() == item.getDownloadLength()) { + break; + } + } + if (item.getTotalLength() != item.getDownloadLength()) { + JOptionPane.showMessageDialog(null, + com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Download_Failed"), + com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Alert"), JOptionPane.ERROR_MESSAGE); + return false; + } else { + item.setDownloadLength(0); + completeSize += item.getTotalLength(); + } + } + } + return true; + } + + @Override + protected void done() { + boolean success = false; + try { + success = get(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (success) { + onDownloadSuccess(); + } else { + onDownloadFailed(); + } + } + + private void download(DownloadItem item) throws Exception { + URL url = new URL(item.getUrl()); + URLConnection connection = url.openConnection(); + int total = connection.getContentLength(); + item.setTotalLength(total); + InputStream reader = connection.getInputStream(); + File tempFile = new File(StableUtils.pathJoin(saveDir, item.getName())); + StableUtils.makesureFileExist(tempFile); + FileOutputStream writer = new FileOutputStream(tempFile); + byte[] buffer = new byte[UpdateConstants.BYTE]; + int bytesRead = 0; + int totalBytesRead = 0; + while ((bytesRead = reader.read(buffer)) != -1) { + writer.write(buffer, 0, bytesRead); + buffer = new byte[UpdateConstants.BYTE]; + totalBytesRead += bytesRead; + item.setDownloadLength(totalBytesRead); + publish(item); + } + reader.close(); + writer.close(); + } + + /** + * 下载成功 + */ + public abstract void onDownloadSuccess(); + + /** + * 下载失败 + */ + public abstract void onDownloadFailed(); + + public long getCompleteSize() { + return completeSize; + } + + public void setCompleteSize(long completeSize) { + this.completeSize = completeSize; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/actions/SoftwareUpdateAction.java b/designer-base/src/main/java/com/fr/design/onlineupdate/actions/SoftwareUpdateAction.java new file mode 100644 index 0000000000..eee2ab2f1b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/actions/SoftwareUpdateAction.java @@ -0,0 +1,34 @@ +package com.fr.design.onlineupdate.actions; + +import com.fr.base.BaseUtils; +import com.fr.design.actions.UpdateAction; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.onlineupdate.ui.dialog.UpdateMainDialog; +import com.fr.locale.InterProviderFactory; + +import java.awt.event.ActionEvent; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class SoftwareUpdateAction extends UpdateAction { + + + public SoftwareUpdateAction() { + setName(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_UpdateAndUpgrade")); + setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/update/update_new.png")); + + } + + /** + * 事件响应 + * + * @param e 事件 + */ + @Override + public void actionPerformed(ActionEvent e) { + UpdateMainDialog dialog = new UpdateMainDialog(DesignerContext.getDesignerFrame()); + dialog.showDialog(); + } +} + diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/domain/DownloadItem.java b/designer-base/src/main/java/com/fr/design/onlineupdate/domain/DownloadItem.java new file mode 100644 index 0000000000..6871190aab --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/domain/DownloadItem.java @@ -0,0 +1,102 @@ +package com.fr.design.onlineupdate.domain; + +import com.fr.general.ComparatorUtils; +import com.fr.json.JSONObject; + +import java.util.Date; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class DownloadItem { + + //显示为百分比 + private static final int PERCENTAGE_RATIO = 100; + //显示kB + private static final int BYTETOKB_RATIO = 1000; + + private String name; + private String url; + private long size; + + private int totalLength; + private int downloadLength; + + public DownloadItem(JSONObject json) { + this(json.optString("name"), json.optString("url"), json.optLong("size")); + } + + public DownloadItem(String name, String url, long size) { + this.name = name; + this.url = url; + this.size = size; + } + + public String getName() { + return name; + } + + public String getUrl() { + return url + "?v=" + new Date().getTime(); + } + + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public int getTotalLength() { + return totalLength; + } + + public int getDownloadLength() { + return downloadLength; + } + + public void setTotalLength(int totalLength) { + this.totalLength = totalLength; + } + + public void setDownloadLength(int downloadLength) { + this.downloadLength = downloadLength; + } + + public int getProgressValue() { + return (int) ((downloadLength / (double) totalLength) * PERCENTAGE_RATIO); + } + + public String getProgressString() { + return downloadLength / BYTETOKB_RATIO + "KB/" + totalLength / BYTETOKB_RATIO + "KB"; + } + + /** + * 转化为字符串 + * + * @return 字符串 + */ + @Override + public String toString() { + return "name:" + name + ";download:" + getProgressString(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DownloadItem + && ComparatorUtils.equals(((DownloadItem) obj).name, name) + && ComparatorUtils.equals(((DownloadItem) obj).url, url); + } + + /** + * 返回一个hash码 + * + * @return hash码 + */ + @Override + public int hashCode() { + return name.hashCode(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/domain/UpdateConstants.java b/designer-base/src/main/java/com/fr/design/onlineupdate/domain/UpdateConstants.java new file mode 100644 index 0000000000..5bd3605424 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/domain/UpdateConstants.java @@ -0,0 +1,55 @@ +package com.fr.design.onlineupdate.domain; + +/** + * Created by XINZAI on 2018/8/21. + */ + +import java.awt.Color; + +/** + * 更新升级的常量 + */ +public interface UpdateConstants { + + String APPS_FOLDER_NAME = "webapps"; + + int CONNECTION_TIMEOUT = 1000 * 5; + Color BAR_COLOR = new Color(0x3384F0); + + String CHANGELOG_X_START = "2018-07-11"; + + String DEFAULT_APP_NAME = "FineReport"; + String DOWNLOAD_DIR = "update"; + String DESIGNER_BACKUP_DIR = "designerbackup"; + + String UPDATE_CACHE_CONFIG_X = "updateCacheConfig10"; + String UPDATE_CACHE_INFO_X = "updateCacheInfo10"; + + + int BYTE = 153600; + + String[] JARS_FOR_SERVER_X = new String[]{ + "fine-activator-10.0.jar", + "fine-core-10.0.jar", + "fine-report-engine-10.0.jar", + "fine-decision-10.0.jar", + "fine-decision-report-10.0.jar", + "fine-schedule-10.0.jar", + "fine-schedule-report-10.0.jar", + "fine-swift-log-adaptor-10.0.jar", + "fine-webui-10.0.jar", + "fine-datasource-10.0.jar", + "fine-third-10.0.jar" + }; + + String[] JARS_FOR_DESIGNER_X = new String[]{ + "fine-report-designer-10.0.jar", + "aspectjrt.jar" + }; + + + String[] LOG_TYPE = new String[]{ + "REPORT", "MOBILE", "CHART", "PFC", "BI" + }; + +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/domain/UpdateInfoCachePropertyManager.java b/designer-base/src/main/java/com/fr/design/onlineupdate/domain/UpdateInfoCachePropertyManager.java new file mode 100644 index 0000000000..7895c69138 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/domain/UpdateInfoCachePropertyManager.java @@ -0,0 +1,41 @@ +package com.fr.design.onlineupdate.domain; + +import com.fr.log.FineLoggerFactory; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Properties; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class UpdateInfoCachePropertyManager { + private Properties prop; + private String filePath; + + public UpdateInfoCachePropertyManager(String filePath) { + this.filePath = filePath; + prop = new Properties(); + try { + prop.load(new FileInputStream(filePath)); + } catch (Exception ignored) { + + } + } + + public void updateProperty(String keyName, String keyValue) { + try { + OutputStream fos = new FileOutputStream(filePath); + prop.setProperty(keyName, keyValue); + prop.store(fos, null); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + + public String readProperty(String keyName) { + return prop.getProperty(keyName); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/factory/DirectoryOperationFactory.java b/designer-base/src/main/java/com/fr/design/onlineupdate/factory/DirectoryOperationFactory.java new file mode 100644 index 0000000000..9d929c095e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/factory/DirectoryOperationFactory.java @@ -0,0 +1,132 @@ +package com.fr.design.onlineupdate.factory; + +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StableUtils; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class DirectoryOperationFactory { + /** + * 新建一个目录 + * + * @param dirPath 目录路径 + */ + public static void createNewDirectory(String dirPath) { + try { + File newDirPath = new File(dirPath); + if (!newDirPath.exists()) { + StableUtils.mkdirs(newDirPath); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + + /** + * 删除目录 + * + * @param dirPath 目录路径 + */ + public static void deleteDirectory(String dirPath) { + try { + File dir = new File(dirPath); + if (dir.isDirectory()) { + File[] file = dir.listFiles(); + for (File fileTemp : file) { + deleteDirectory(fileTemp.toString()); + fileTemp.delete(); + } + } else { + dir.delete(); + } + dir.delete(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + + /** + * 复制目录 + * + * @param oldDirPath 被复制目录 + * @param newDirPath 新目录 + */ + public static void copyDirectory(String oldDirPath, String newDirPath) { + File oldDir = new File(oldDirPath); + if (oldDir.isDirectory()) { + StableUtils.mkdirs(new File(newDirPath)); + File[] files = oldDir.listFiles(); + for (File fileTemp : files) { + copyDirectory(fileTemp.toString(), newDirPath + "/" + fileTemp.getName()); + } + } else { + try { + copy(oldDirPath, newDirPath); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + } + + private static void copy(String path1, String path2) throws IOException { + DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(path1))); + DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path2))); + byte[] date = new byte[in.available()]; + + in.read(date); + out.write(date); + + in.close(); + out.close(); + } + + /** + * 移动目录 + * + * @param oldDirPath 被移动目录 + * @param newDirPath 新目录 + */ + public static void moveDirectory(String oldDirPath, String newDirPath) { + copyDirectory(oldDirPath, newDirPath); + deleteDirectory(oldDirPath); + } + + /** + * 列出过滤后的文件 + * + * @param installHome 安装目录 + * @param backupdir 备份目录 + * @return String数组 + */ + public static String[] listFilteredFiles(String installHome, String backupdir) { + File backupDir = new File(StableUtils.pathJoin(installHome, backupdir)); + StableUtils.mkdirs(backupDir); + File[] fileNames = backupDir.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.isDirectory(); + } + }); + String[] jarFileName = new String[fileNames.length]; + int j = 0; + for (File fileName : fileNames) { + if ((fileName.isDirectory()) && (ArrayUtils.getLength(fileName.listFiles()) > 0)) {//判断备份文件夹中是否为空,为空不显示 + jarFileName[j++] = fileName.getName(); + } + } + return Arrays.copyOf(jarFileName, j); + } +} diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/RestoreDialog.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/RestoreDialog.java new file mode 100644 index 0000000000..f197fd1821 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/RestoreDialog.java @@ -0,0 +1,122 @@ +package com.fr.design.onlineupdate.ui.dialog; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.onlineupdate.domain.UpdateConstants; +import com.fr.design.onlineupdate.factory.DirectoryOperationFactory; +import com.fr.design.onlineupdate.ui.widget.ColorfulCellRender; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.locale.InterProviderFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StableUtils; + +import javax.swing.BoxLayout; +import javax.swing.JDialog; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ScrollPaneConstants; +import java.awt.BorderLayout; +import java.awt.Dialog; +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.Arrays; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class RestoreDialog extends JDialog { + private static final int LISTCELLHEIGHT = 30; + private static final Dimension RESTOREJAR = new Dimension(523, 480); + private static final Dimension RESTOREJAR_NORTHPANE = new Dimension(500, 392); + //一个页面上最少显示13个元素 + private static final int NUMOFCELL_LEAST = 13; + + private UIButton okButton; + private UIButton cancelButton; + private JPanel buttonPanel; + private String jarSelected; + + public RestoreDialog(Dialog parent, boolean modal) { + super(parent, modal); + initComponents(); + } + + public RestoreDialog(Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + } + + private void initButton() { + okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Ok")); + cancelButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Cancel")); + + okButton.setEnabled(false); + okButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + RestoreResultDialog dialog = new RestoreResultDialog(DesignerContext.getDesignerFrame(), true, jarSelected); + dialog.showDialog(); + } + }); + cancelButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + } + + private void initComponents() { + + this.setResizable(false); + JPanel pane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + this.setContentPane(pane); + + initButton(); + + buttonPanel = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + buttonPanel.add(okButton); + buttonPanel.add(cancelButton); + pane.add(buttonPanel, BorderLayout.SOUTH); + + JPanel jarListPane = new JPanel(); + jarListPane.setLayout(new BoxLayout(jarListPane, BoxLayout.Y_AXIS)); + String[] jarBackupFiles = DirectoryOperationFactory.listFilteredFiles(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR); + + ArrayUtils.reverse(jarBackupFiles); + String[] jarFilesList = ((jarBackupFiles.length < NUMOFCELL_LEAST) ? Arrays.copyOf(jarBackupFiles, NUMOFCELL_LEAST) : jarBackupFiles); + final JList jarList = new JList(jarFilesList); + jarList.setFixedCellHeight(LISTCELLHEIGHT); + jarList.setCellRenderer(new ColorfulCellRender()); + jarList.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + jarSelected = (String) jarList.getSelectedValue(); + okButton.setEnabled((jarSelected != null)); + } + }); + + JScrollPane jsp = new JScrollPane(jarList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jsp.setPreferredSize(RESTOREJAR_NORTHPANE); + pane.add(jsp, BorderLayout.NORTH); + + } + + /** + * 显示窗口 + */ + public void showDialog() { + this.setSize(RESTOREJAR); + this.setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Jar_Restore")); + GUICoreUtils.centerWindow(this); + this.setVisible(true); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/RestoreResultDialog.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/RestoreResultDialog.java new file mode 100644 index 0000000000..da0401af95 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/RestoreResultDialog.java @@ -0,0 +1,182 @@ +package com.fr.design.onlineupdate.ui.dialog; + +import com.fr.base.FRContext; +import com.fr.design.RestartHelper; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.onlineupdate.domain.UpdateConstants; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.locale.InterProviderFactory; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class RestoreResultDialog extends JDialog { + private static final Dimension RESTORE = new Dimension(340, 100); + + private static final Dimension RESTORE_OLD_VERSION = new Dimension(340, 135); + + private String jarRestoreDir; + + public RestoreResultDialog(Dialog parent, boolean modal) { + super(parent, modal); + initCommonComponents(); + } + + public RestoreResultDialog(Frame parent, boolean modal, String jarDir) { + super(parent, modal); + this.jarRestoreDir = jarDir; + if (ComparatorUtils.equals(jarDir, com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Restore_Old_Version"))) { + initOldVersionRestoreComps(); + } else { + initCommonComponents(); + } + } + + private void initCommonComponents() { + this.setResizable(false); + JPanel pane = new JPanel(); + pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10)); + pane.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setContentPane(pane); + + UIButton restartButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restart_Designer")); + UIButton restartLaterButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Restart_Later")); + + restartButton.setFont(new Font("Default", Font.PLAIN, 12)); + restartButton.setEnabled(false); + restartButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + RestartHelper.restart(); + } + }); + restartLaterButton.setFont(new Font("Default", Font.PLAIN, 12)); + restartLaterButton.setEnabled(false); + restartLaterButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + JPanel buttonPane = new JPanel(); + buttonPane.add(restartLaterButton); + buttonPane.add(restartButton); + pane.add(buttonPane, BorderLayout.SOUTH); + + JPanel progressLabelPane = new JPanel(new BorderLayout()); + UILabel jarProgressLabel = new UILabel((com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restore_To")) + " " + jarRestoreDir + " " + (com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_WorksAfterRestart"))); + jarProgressLabel.setFont(new Font("Default", Font.PLAIN, 12)); + jarProgressLabel.setVisible(true); + progressLabelPane.add(jarProgressLabel); + pane.add(progressLabelPane, BorderLayout.CENTER); + + UpdateMainDialog.deletePreviousPropertyFile(); + + putJarBackupFiles(); + restartButton.setEnabled(true); + restartLaterButton.setEnabled(true); + this.setSize(RESTORE); + this.setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Jar_Restore")); + } + + private void initOldVersionRestoreComps() { + this.setResizable(false); + JPanel pane = new JPanel(); + pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10)); + pane.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setContentPane(pane); + + UIButton okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Ok")); + okButton.setFont(new Font("Default", Font.PLAIN, 12)); + okButton.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + + JPanel buttonPane = new JPanel(); + buttonPane.add(okButton); + pane.add(buttonPane, BorderLayout.SOUTH); + + JPanel infoPane = new JPanel(new BorderLayout()); + JTextArea jTextArea = new JTextArea( + com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Already_Backup_Old_Project") + + StringUtils.BLANK + + StableUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR) + + com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Unzip_Replace_Restore") + ); + jTextArea.setLineWrap(true); + jTextArea.setEditable(false); + jTextArea.setBackground(null); + jTextArea.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); + jTextArea.setFont(new Font("Default", Font.PLAIN, 12)); + infoPane.add(jTextArea); + pane.add(infoPane, BorderLayout.CENTER); + + this.setSize(RESTORE_OLD_VERSION); + this.setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Designer_Updater_Restore_to_V8")); + } + + + /** + * 显示窗口 + */ + public void showDialog() { + GUICoreUtils.centerWindow(this); + this.setVisible(true); + } + + private void putJarBackupFiles() { + Map map = new HashMap(); + java.util.List list = new ArrayList(); + String installHome = StableUtils.getInstallHome(); + + putJarBackupFilesToInstallLib(installHome, map, list); + putJarBackupFilesToInstallEnv(installHome, map, list); + RestartHelper.saveFilesWhichToMove(map); + RestartHelper.saveFilesWhichToDelete(list.toArray(new String[list.size()])); + } + + private void putJarBackupFilesToInstallLib(String installHome, Map map, java.util.List list) { + String[] files = UpdateConstants.JARS_FOR_DESIGNER_X; + String backupDir = UpdateConstants.DESIGNER_BACKUP_DIR; + for (String file : files) { + map.put(StableUtils.pathJoin(installHome, backupDir, jarRestoreDir, file), + StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); + list.add(StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); + } + } + + private void putJarBackupFilesToInstallEnv(String installHome, Map map, java.util.List list) { + String[] files = UpdateConstants.JARS_FOR_SERVER_X; + String backupDir = UpdateConstants.DESIGNER_BACKUP_DIR; + for (String file : files) { + map.put(StableUtils.pathJoin(installHome, backupDir, jarRestoreDir, file), + StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); + list.add(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/UpdateMainDialog.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/UpdateMainDialog.java new file mode 100644 index 0000000000..9ca0fccc0e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/dialog/UpdateMainDialog.java @@ -0,0 +1,821 @@ +package com.fr.design.onlineupdate.ui.dialog; + +import com.fr.base.FRContext; +import com.fr.design.RestartHelper; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.onlineupdate.actions.FileDownloader; +import com.fr.design.onlineupdate.domain.DownloadItem; +import com.fr.design.onlineupdate.domain.UpdateConstants; +import com.fr.design.onlineupdate.domain.UpdateInfoCachePropertyManager; +import com.fr.design.onlineupdate.factory.DirectoryOperationFactory; +import com.fr.design.onlineupdate.ui.widget.LoadingLabel; +import com.fr.design.onlineupdate.ui.widget.UpdateActionLabel; +import com.fr.design.onlineupdate.ui.widget.UpdateInfoTable; +import com.fr.design.onlineupdate.ui.widget.UpdateInfoTableCellRender; +import com.fr.design.onlineupdate.ui.widget.UpdateInfoTableModel; +import com.fr.design.onlineupdate.ui.widget.UpdateInfoTextAreaCellRender; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.DateUtils; +import com.fr.general.GeneralUtils; +import com.fr.general.IOUtils; +import com.fr.general.SiteCenter; +import com.fr.general.http.HttpClient; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; +import com.sun.java.swing.plaf.motif.MotifProgressBarUI; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.RowSorter; +import javax.swing.SortOrder; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.table.TableRowSorter; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +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.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +/** + * Created by XINZAI on 2018/8/21. + */ +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 SEARCH_PANE_ROW_SIZE = 50; + private static final int SEARCH_PANE_TEXT_COLUMN = 130; + private static final int SEARCH_PANE_COLUMN_GAP = 3; + private static final int UPDATE_INFO_TABLE_HEADER_TIME_WIDTH = 120; + private static final int UPDATE_CONTENT_PANE_BORDER_COLOR = 0xCCCCCC; + private static final int RESTORE_LABEL_COLOR = 0x3384F0; + + private static final String UPDATE_CACHE_STATE_FAIL = "fail"; + private static final String UPDATE_CACHE_STATE_SUCCESS = "success"; + + private static final SimpleDateFormat CHANGELOG_FORMAT = new SimpleDateFormat("M/d/y, h:m:s a", Locale.ENGLISH); + private static final SimpleDateFormat UPDATE_INFO_TABLE_FORMAT = new SimpleDateFormat("yyyy.MM.dd"); + + private Set downloadItems = new HashSet(); + private JSONObject downloadFileConfig; + //最新版本标签 + private LoadingLabel loadingLabel; + //更新按钮 + private UIButton updateButton; + //有新版本提示标签 + private UILabel updateLabel; + + //jar包版本信息面板,包括当前版本和最新版本 + private JPanel jarVersionInfoPane; + //jar包更新信息面板,包括每个版本更新的信息 + private JPanel jarUpdateInfoPane; + //jar包更新操作面板,包括更新重启按钮和进度条 + private JPanel updateActionPane; + //进度条 + private JProgressBar progressBar; + //更新版本提示面板 + private JPanel updateVersionReminderPane; + //jar包版本标签 + private UILabel jarCurrentLabel; + //jar包还原标签 + private UILabel jarRestoreLabel; + //更新信息搜索按钮 + private UIButton searchUpdateInfoBtn; + //搜索更新信息关键词文本框 + private UITextField searchUpdateInfoKeyword; + + private boolean updateSuccessful; + + private UpdateInfoTable updateInfoTable; + + private ArrayList updateInfoList; + + private boolean getUpdateInfoSuccess; + + private UpdateInfoCachePropertyManager cacheProperty; + private String lastUpdateCacheTime; + private String lastUpdateCacheState = UPDATE_CACHE_STATE_FAIL; + + public UpdateMainDialog(Dialog parent) { + super(parent); + initComponents(); + } + + public UpdateMainDialog(Frame parent) { + super(parent); + setModal(true); + initComponents(); + } + + private void initUpdateActionPane() { + double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE}; + double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED}; + double[] columnUpdateSubContentPaneProgressSize = {TableLayout.FILL, TableLayout.PREFERRED}; + double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED}; + JPanel progressBarPane = new JPanel(new BorderLayout()); + + progressBar = new JProgressBar(); + progressBar.setUI(new MotifProgressBarUI()); + progressBar.setForeground(UpdateConstants.BAR_COLOR); + progressBar.setVisible(false); + progressBar.setStringPainted(true); + progressBar.setPreferredSize(PROGRESSBAR); + + updateLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_New_Version_Available")); + updateLabel.setHorizontalAlignment(SwingConstants.RIGHT); + updateLabel.setVisible(false); + + progressBarPane.add(GUICoreUtils.createBorderLayoutPane( + progressBar, BorderLayout.CENTER, + updateLabel, BorderLayout.EAST + ), BorderLayout.CENTER); + + updateActionPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ + new Component[]{new UILabel(), new UILabel(), new UILabel()}, + new Component[]{new UILabel(), initPaneContent(getBackground(), rowUpdateContentPaneSize, columnUpdateSubContentPaneProgressSize, progressBarPane, updateButton), new UILabel()}, + new Component[]{new UILabel(), new UILabel(), new UILabel()} + }, rowUpdateSubContentPaneSize, columnUpdateSubContentPaneSize, LayoutConstants.VGAP_LARGE); + } + + private JPanel initPaneContent(Color color, double[] row, double[] column, Component... var) { + JPanel paneContent = TableLayoutHelper.createTableLayoutPane(new Component[][]{var}, row, column); + paneContent.setBackground(color); + return paneContent; + } + + private void initJarVersionInfoPane() { + double[] rowUpdatePaneSize = {UPDATE_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED}; + double[] columnUpdatePaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; + double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED}; + double[] columnUpdateContentPaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; + double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE}; + double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED}; + double[] columnUpdateSubContentPaneLabelSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED}; + + JPanel jarUpdateContentPane = new JPanel(); + jarUpdateContentPane.setLayout(new BorderLayout()); + jarUpdateContentPane.setBorder(BorderFactory.createLineBorder(new Color(UPDATE_CONTENT_PANE_BORDER_COLOR))); + + JPanel jarUpdateContentPane2 = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ + new Component[]{new UILabel(), new UILabel(), new UILabel()}, + new Component[]{new UILabel(), updateVersionReminderPane, new UILabel()}, + new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_JAR_Version")), jarCurrentLabel), new UILabel()}, + new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Latest_JAR")), loadingLabel), new UILabel()}, + new Component[]{new UILabel(), new UILabel(), new UILabel()} + }, rowUpdateSubContentPaneSize, columnUpdateSubContentPaneSize, LayoutConstants.VGAP_LARGE); + jarUpdateContentPane2.setBackground(Color.WHITE); + jarUpdateContentPane.add(jarUpdateContentPane2); + jarVersionInfoPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ + new Component[]{new UILabel(), new UILabel(), new UILabel()}, + new Component[]{new UILabel(), initPaneContent(getBackground(), rowUpdateContentPaneSize, columnUpdateContentPaneSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_JarUpdate")), new UILabel(), jarRestoreLabel), new UILabel()}, + new Component[]{new UILabel(), jarUpdateContentPane, new UILabel()} + }, rowUpdatePaneSize, columnUpdatePaneSize, LayoutConstants.VGAP_LARGE); + } + + private void initJarUpdateInfoPane() { + double[] rowUpdatePaneSize = {SEARCH_PANE_ROW_SIZE, TableLayout.FILL}; + double[] columnUpdatePaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; + + double[] searchRow = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, SEARCH_PANE_COLUMN_GAP * 2}; + double[] searchColumn = {TableLayout.FILL, SEARCH_PANE_TEXT_COLUMN, TableLayout.PREFERRED}; + initUpdateInfoSearchPane(); + JPanel searchPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ + new Component[]{new UILabel(), new UILabel(), new UILabel()}, + new Component[]{new UILabel(), searchUpdateInfoKeyword, searchUpdateInfoBtn}, + new Component[]{new UILabel(), new UILabel(), new UILabel()} + }, searchRow, searchColumn, LayoutConstants.VGAP_LARGE); + + String[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Date"), com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Content"), com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_SignHeader")}; + initUpdateInfoTable(columnNames); + + UIScrollPane uiScrollPane = new UIScrollPane(updateInfoTable); + jarUpdateInfoPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ + new Component[]{new UILabel(), searchPane, new UILabel()}, + new Component[]{new UILabel(), uiScrollPane, new UILabel()} + }, rowUpdatePaneSize, columnUpdatePaneSize, LayoutConstants.VGAP_LARGE); + } + + private void initUpdateInfoTable(String[] columnNames) { + int updateTimeColIndex = 0; + int updateTitleColIndex = 1; + int updateSignColIndex = 2; + + updateInfoTable = new UpdateInfoTable(columnNames); + + updateInfoTable.setShowGrid(false); + updateInfoTable.setCellSelectionEnabled(false); + TableRowSorter sorter = new TableRowSorter(updateInfoTable.getDataModel()); + sorter.setSortable(updateTimeColIndex, true); + sorter.setSortable(updateTitleColIndex, false); + sorter.setSortable(updateSignColIndex, false); + updateInfoTable.setRowSorter(sorter); + List sortKeys = new ArrayList(); + sortKeys.add(new RowSorter.SortKey(updateTimeColIndex, SortOrder.DESCENDING)); + sorter.setSortKeys(sortKeys); + + updateInfoTable.getTableHeader().setReorderingAllowed(false); + updateInfoTable.getColumnModel().getColumn(updateTimeColIndex).setMaxWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); + updateInfoTable.getColumnModel().getColumn(updateTimeColIndex).setMinWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); + updateInfoTable.getColumnModel().getColumn(updateSignColIndex).setMaxWidth(0); + updateInfoTable.getColumnModel().getColumn(updateSignColIndex).setMinWidth(0); + updateInfoTable.getTableHeader().getColumnModel().getColumn(updateSignColIndex).setMaxWidth(0); + updateInfoTable.getTableHeader().getColumnModel().getColumn(updateSignColIndex).setMinWidth(0); + updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Date")).setCellRenderer(new UpdateInfoTableCellRender()); + updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Content")).setCellRenderer(new UpdateInfoTextAreaCellRender()); + } + + private void initUpdateInfoSearchPane() { + searchUpdateInfoKeyword = new UITextField(); + searchUpdateInfoKeyword.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + } + + @Override + public void removeUpdate(DocumentEvent e) { + String keyword = searchUpdateInfoKeyword.getText(); + if (ComparatorUtils.equals(keyword, StringUtils.EMPTY) && getUpdateInfoSuccess) { + updateInfoList.clear(); + getUpdateInfo(keyword).execute(); + } + } + + @Override + public void changedUpdate(DocumentEvent e) { + } + }); + searchUpdateInfoBtn = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Search")); + searchUpdateInfoBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (getUpdateInfoSuccess) { + updateInfoList.clear(); + getUpdateInfo(searchUpdateInfoKeyword.getText()).execute(); + } + } + }); + } + + private void initButtonAndLabel() { + loadingLabel = new LoadingLabel(); + loadingLabel.setText(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Checking_Jar_Update")); + updateButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Update")); + updateButton.setPreferredSize(UPDATE_BUTTON); + updateButton.setEnabled(false); + + double[] rowSize = {TableLayout.PREFERRED}; + + double[] colSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED}; + updateVersionReminderPane = initPaneContent( + Color.WHITE, rowSize, colSize, + new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Designer-Updater_Designer_Version")), + new UILabel(UpdateConstants.DEFAULT_APP_NAME + StringUtils.BLANK + ProductConstants.VERSION) + ); + + + jarCurrentLabel = new UILabel(StringUtils.isEmpty(GeneralUtils.readBuildNO()) ? com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Not_Install_Version") : GeneralUtils.readBuildNO(), SwingConstants.CENTER); + UILabel noJarPreviousRevision = new UILabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_No_Previous_Version")); + UpdateActionLabel jarRestorePreviousRevision = new UpdateActionLabel(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restore"), false); + jarRestorePreviousRevision.setForeground(new Color(RESTORE_LABEL_COLOR)); + jarRestorePreviousRevision.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + RestoreDialog dialog = new RestoreDialog(DesignerContext.getDesignerFrame(), true); + dialog.showDialog(); + } + }); + //choose RestoreLabel to show + boolean isNeedRestore = ArrayUtils.isNotEmpty(DirectoryOperationFactory.listFilteredFiles(StableUtils.getInstallHome(), getBackupDirectory())); + jarRestoreLabel = isNeedRestore ? jarRestorePreviousRevision : noJarPreviousRevision; + } + + private void initComponents() { + JPanel contentPane = (JPanel) getContentPane(); + contentPane.setLayout(new BorderLayout()); + + + initButtonAndLabel(); + + initJarVersionInfoPane(); + initJarUpdateInfoPane(); + initUpdateActionPane(); + + add(jarVersionInfoPane, BorderLayout.NORTH); + add(jarUpdateInfoPane, BorderLayout.CENTER); + add(updateActionPane, BorderLayout.SOUTH); + + addActionListenerForUpdateBtn(); + + new SwingWorker() { + @Override + protected JSONObject doInBackground() throws Exception { + HttpClient hc = new HttpClient(SiteCenter.getInstance().acquireUrlByKind("jar10.update")); + hc.setTimeout(UpdateConstants.CONNECTION_TIMEOUT); + return new JSONObject(hc.getResponseText()); + } + + @Override + protected void done() { + try { + downloadFileConfig = get(); + showDownLoadInfo(); + } catch (InterruptedException e) { + stopLoading(); + } catch (ExecutionException e) { + stopLoading(); + } finally { + getUpdateInfo(StringUtils.EMPTY).execute(); + } + } + }.execute(); + } + + private SwingWorker getUpdateInfo(final String keyword) { + updateInfoList = new ArrayList(); + lastUpdateCacheTime = UpdateConstants.CHANGELOG_X_START; + String cacheConfigPath = getUpdateCacheConfig(); + cacheProperty = new UpdateInfoCachePropertyManager(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres", cacheConfigPath)); + String recordUpdateTime = cacheProperty.readProperty("updateTime"); + if (StringUtils.isNotEmpty(recordUpdateTime)) { + lastUpdateCacheTime = recordUpdateTime; + } + String recordUpdateState = cacheProperty.readProperty("updateState"); + if (StringUtils.isNotEmpty(recordUpdateState)) { + lastUpdateCacheState = recordUpdateState; + } + return new SwingWorker() { + @Override + protected JSONArray doInBackground() { + try { + getUpdateInfoSuccess = false; + //step1:read from cache file + getCachedUpdateInfo(keyword); + //step2:read from website,start from cacheRecordTime + if (downloadFileConfig == null) { + throw new Exception("network error."); + } + HttpClient hc = new HttpClient(SiteCenter.getInstance().acquireUrlByKind("changelog10") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr()); + hc.asGet(); + hc.setTimeout(UpdateConstants.CONNECTION_TIMEOUT * 2); + String responseText = hc.getResponseText(); + JSONArray array = JSONArray.create(); + //假如返回"-1",说明socket出错了 + if (!ComparatorUtils.equals(responseText, "-1")) { + array = new JSONArray(responseText); + } + hc.release(); + return array; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + return JSONArray.create(); + } + + @Override + protected void done() { + try { + JSONArray jsonArray = get(); + //step3:generateInfoTableList + updateInfoTable.getDataModel().populateBean(generateUpdateInfoList(jsonArray, keyword)); + + getUpdateInfoSuccess = true; + //step4:update cache file,start from cacheRecordTime,end latest server jartime + updateCachedInfoFile(jsonArray); + } catch (Exception e) { + getUpdateInfoSuccess = true; + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + }; + } + + //从文件中读取缓存的更新信息 + private void getCachedUpdateInfo(String keyword) throws Exception { + String cacheInfoPath = getUpdateCacheInfo(); + File cacheFile = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres", cacheInfoPath)); + if (!ComparatorUtils.equals(lastUpdateCacheState, "success")) { + cacheFile.delete(); + return; + } + if (cacheFile.exists()) { + FileReader reader = new FileReader(cacheFile); + BufferedReader br = new BufferedReader(reader); + String readStr, updateTimeStr; + + while ((readStr = br.readLine()) != null) { + String[] updateInfo = readStr.split("\\t"); + if (updateInfo.length == 2) { + updateTimeStr = updateInfo[0]; + Date updateTime = CHANGELOG_FORMAT.parse(updateTimeStr); + //形如 Build#release-2018.07.31.03.03.52.80 + String currentNO = GeneralUtils.readBuildNO(); + Date curJarDate = UPDATE_INFO_TABLE_FORMAT.parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); + if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY)) { + if (!containsKeyword(UPDATE_INFO_TABLE_FORMAT.format(updateTime), keyword) && !containsKeyword(updateInfo[1], keyword)) { + continue; + } + } + if (isValidLogInfo(updateInfo[1])) { + updateInfoList.add(new Object[]{UPDATE_INFO_TABLE_FORMAT.format(updateTime), updateInfo[1], updateTime.after(curJarDate)}); + } + } + } + br.close(); + reader.close(); + } + } + + private void updateCachedInfoFile(JSONArray jsonArray) throws Exception { + String cacheDirPath = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres"); + File cacheFileDir = new File(cacheDirPath); + if (!StableUtils.mkdirs(cacheFileDir)) { + FineLoggerFactory.getLogger().error("make dir error."); + return; + } + final File cacheFile = new File(StableUtils.pathJoin(cacheDirPath, getUpdateCacheInfo())); + if (!cacheFile.exists()) { + cacheFile.createNewFile(); + lastUpdateCacheTime = UpdateConstants.CHANGELOG_X_START; + lastUpdateCacheState = UPDATE_CACHE_STATE_FAIL; + } + if (downloadFileConfig == null) { + return; + } + String endTime = getLatestJARTimeStr(); + if (endTime.equals(lastUpdateCacheTime) || jsonArray.length() == 0 || ComparatorUtils.compare(endTime, lastUpdateCacheTime) <= 0) { + return; + } + FileWriter fileWriter = new FileWriter(cacheFile, true); + BufferedWriter bufferWriter = new BufferedWriter(fileWriter); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jo = (JSONObject) jsonArray.get(i); + bufferWriter.write((String) jo.get("update") + '\t' + jo.get("title")); + bufferWriter.newLine(); + bufferWriter.flush(); + } + bufferWriter.close(); + fileWriter.close(); + lastUpdateCacheState = UPDATE_CACHE_STATE_SUCCESS; + lastUpdateCacheTime = endTime; + cacheProperty.updateProperty("updateTime", lastUpdateCacheTime); + cacheProperty.updateProperty("updateState", lastUpdateCacheState); + } + + private ArrayList generateUpdateInfoList(JSONArray jsonArray, String keyword) throws Exception { + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jo = (JSONObject) jsonArray.get(i); + String updateTitle = (String) jo.get("title"); + String updateTimeStr = (String) jo.get("update"); + Date updateTime = CHANGELOG_FORMAT.parse(updateTimeStr); + //形如 Build#release-2018.07.31.03.03.52.80 + String currentNO = GeneralUtils.readBuildNO(); + Date curJarDate = UPDATE_INFO_TABLE_FORMAT.parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); + if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY)) { + if (!containsKeyword(UPDATE_INFO_TABLE_FORMAT.format(updateTime), keyword) && !containsKeyword(updateTitle, keyword)) { + continue; + } + } + if (isValidLogInfo(updateTitle)) { + updateInfoList.add(new Object[]{UPDATE_INFO_TABLE_FORMAT.format(updateTime), updateTitle, updateTime.after(curJarDate)}); + } + } + return new ArrayList(updateInfoList); + } + + private boolean containsKeyword(String str, String keyword) { + return str.toUpperCase().contains(keyword.toUpperCase()); + } + + private void stopLoading() { + loadingLabel.stopLoading(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Connect_VersionUpdateServer_Failed")); + } + + + private void showDownLoadInfo() { + //形如 Build#release-2018.07.31.03.03.52.80 + String buildNO = downloadFileConfig.optString("buildNO"); + Date jarDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(buildNO, new ParsePosition(buildNO.indexOf("-") + 1)); + String serverVersionNO = downloadFileConfig.optString("versionNO"); + String currentVersionNO = ProductConstants.RELEASE_VERSION; + String[] serverVersionSplitStr = serverVersionNO.split("\\."); + String[] currentVersionSplitStr = currentVersionNO.split("\\."); + int index = 0; + int compareResult; + int versionLength = Math.min(serverVersionSplitStr.length, currentVersionSplitStr.length); + + //形如 Build#release-2018.07.31.03.03.52.80 + String currentNO = GeneralUtils.readBuildNO(); + if (!".".equals(StableUtils.getInstallHome())) { + Date currentDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); + if (DateUtils.subtractDate(jarDate, currentDate, DateUtils.DAY) > 0) { + updateButton.setEnabled(true); + updateLabel.setVisible(true); + loadingLabel.stopLoading(buildNO.contains("-") ? buildNO.substring(buildNO.lastIndexOf("-") + 1) : buildNO); + } else { + loadingLabel.stopLoading(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Already_Latest_Version")); + } + } else { + updateButton.setEnabled(true); + updateLabel.setVisible(true); + loadingLabel.stopLoading(buildNO.contains("-") ? buildNO.substring(buildNO.lastIndexOf("-") + 1) : buildNO); + } + + while (index < versionLength) { + compareResult = serverVersionSplitStr[index].length() - currentVersionSplitStr[index].length(); + if (0 == compareResult) { + compareResult = serverVersionSplitStr[index].compareTo(currentVersionSplitStr[index]); + if (0 == compareResult) { + ++index; + continue; + } + break; + } + break; + } + + initMapWithInfo(downloadFileConfig); + } + + public void initMapWithInfo(JSONObject result) { + addJarNameToMap(result, "designer"); + addJarNameToMap(result, "server"); + } + + private void addJarNameToMap(JSONObject result, String category) { + JSONArray jsonArray = result.optJSONArray(category); + if (jsonArray != null) { + for (int i = 0, len = jsonArray.length(); i < len; i++) { + JSONObject jo = jsonArray.optJSONObject(i); + String downloadName = jo.optString("name"); + String downloadUrl = jo.optString("url"); + long downloadSize = jo.optLong("size"); + if (ComparatorUtils.equals(category, "server")) { + File currentJAR = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), ProjectConstants.LIB_NAME, downloadName)); + if (currentJAR.exists() && ComparatorUtils.equals(currentJAR.length(), downloadSize)) { + //假如大小一样的jar包就不要下载了 + continue; + } + } + downloadItems.add(new DownloadItem(downloadName, downloadUrl, downloadSize)); + } + } + } + + /** + * jar包更新按钮监听器 + */ + private void addActionListenerForUpdateBtn() { + updateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (updateSuccessful) { + RestartHelper.restart(); + } else { + deletePreviousPropertyFile(); + updateButton.setEnabled(false); + progressBar.setVisible(true); + updateLabel.setVisible(false); + + new FileDownloader( + downloadItems.toArray(new DownloadItem[downloadItems.size()]), + StableUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DOWNLOAD_DIR)) { + @Override + protected void process(java.util.List chunks) { + DownloadItem fileInfo = chunks.get(chunks.size() - 1); + progressBar.setString(fileInfo.getName() + " " + fileInfo.getProgressString()); + progressBar.setValue(fileInfo.getProgressValue()); + } + + @Override + public void onDownloadSuccess() { + updateButton.setEnabled(true); + progressBar.setVisible(false); + backup(); + putNewFiles(); + updateSuccessful = true; + updateButton.setText(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_Restart_Designer")); + } + + @Override + public void onDownloadFailed() { + progressBar.setVisible(false); + } + }.execute(); + } + } + }); + } + + /** + * 确保升级更新之前删除以前的配置文件 + */ + public static void deletePreviousPropertyFile() { + //在进行更新升级之前确保move和delete.properties删除 + File moveFile = new File(RestartHelper.MOVE_FILE); + File delFile = new File(RestartHelper.RECORD_FILE); + if ((moveFile.exists()) && (!moveFile.delete())) { + FineLoggerFactory.getLogger().error(RestartHelper.MOVE_FILE + "delete failed!"); + } + if ((delFile.exists()) && (!delFile.delete())) { + FineLoggerFactory.getLogger().error(RestartHelper.RECORD_FILE + "delete failed!"); + } + } + + /** + * JAR包更新的时候备份老的jar包,包括设计器相关的和服务器相关的几个 + */ + private void backup() { + String installHome = StableUtils.getInstallHome(); + //jar包备份文件的目录为"backup/"+jar包当前版本号 + String todayBackupDir = StableUtils.pathJoin(installHome, getBackupDirectory(), (GeneralUtils.readBuildNO())); + backupFilesFromInstallEnv(installHome, todayBackupDir, getJARList4Server()); + backupFilesFromInstallLib(installHome, todayBackupDir, getJARList4Designer()); + jarCurrentLabel.setText(downloadFileConfig.optString("buildNO")); + } + + private void backupFilesFromInstallEnv(String installHome, String todayBackupDir, String[] files) { + for (String file : files) { + try { + IOUtils.copy( + new File(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)), + new File(StableUtils.pathJoin(todayBackupDir))); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + } + + private void backupFilesFromInstallLib(String installHome, String todayBackupDir, String[] files) { + for (String file : files) { + try { + IOUtils.copy( + new File(StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)), + new File(StableUtils.pathJoin(todayBackupDir))); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage()); + } + } + } + + private void putNewFiles() { + Map map = new HashMap(); + java.util.List list = new ArrayList(); + String installHome = StableUtils.getInstallHome(); + putNewFilesToInstallLib(installHome, getDownLoadJAR4Designer(), map, list); + putNewFilesToInstallEnv(installHome, getDownLoadJAR4Server(), map, list); + RestartHelper.saveFilesWhichToMove(map); + RestartHelper.saveFilesWhichToDelete(list.toArray(new String[list.size()])); + } + + private void putNewFilesToInstallLib(String installHome, String[] files, Map map, java.util.List list) { + for (String file : files) { + map.put(StableUtils.pathJoin(installHome, UpdateConstants.DOWNLOAD_DIR, file), + StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); + list.add(StableUtils.pathJoin(installHome, ProjectConstants.LIB_NAME, file)); + } + } + + private void putNewFilesToInstallEnv(String installHome, String[] files, Map map, java.util.List list) { + for (String file : files) { + map.put(StableUtils.pathJoin(installHome, UpdateConstants.DOWNLOAD_DIR, file), + StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); + list.add(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, FRContext.getCommonOperator().getAppName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file)); + } + } + + //获取备份目录 + private String getBackupDirectory() { + return UpdateConstants.DESIGNER_BACKUP_DIR; + } + + //获取服务器jar包列表 + private String[] getJARList4Server() { + return UpdateConstants.JARS_FOR_SERVER_X; + } + + //获取设计器jar包列表 + private String[] getJARList4Designer() { + return UpdateConstants.JARS_FOR_DESIGNER_X; + } + + //获取服务器jar包下载列表 + private String[] getDownLoadJAR4Server() { + ArrayList jarList = new ArrayList(); + for (DownloadItem downloadItem : downloadItems) { + String downloadItemName = downloadItem.getName(); + if (ArrayUtils.contains(getJARList4Server(), downloadItemName)) { + jarList.add(downloadItemName); + } + } + return jarList.toArray(new String[jarList.size()]); + } + + //获取设计器jar包下载列表 + private String[] getDownLoadJAR4Designer() { + ArrayList jarList = new ArrayList(); + for (DownloadItem downloadItem : downloadItems) { + String downloadItemName = downloadItem.getName(); + if (ArrayUtils.contains(getJARList4Designer(), downloadItemName)) { + jarList.add(downloadItemName); + } + } + return jarList.toArray(new String[jarList.size()]); + } + + //获取更新日志缓存配置文件名 + private String getUpdateCacheConfig() { + return UpdateConstants.UPDATE_CACHE_CONFIG_X; + } + + //获取更新日志缓存内容文件名 + private String getUpdateCacheInfo() { + return UpdateConstants.UPDATE_CACHE_INFO_X; + } + + //获取最新的jar包时间字符串 + private String getLatestJARTimeStr() { + if (downloadFileConfig == null) { + return StringUtils.EMPTY; + } + String buildNO = downloadFileConfig.optString("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 boolean isValidLogInfo(String logContent) { + String log = logContent.toUpperCase(); + for (String s : UpdateConstants.LOG_TYPE) { + if (log.startsWith(s)) { + return true; + } + } + return false; + } + + /** + * 显示窗口 + */ + public void showDialog() { + setSize(DEFAULT); + setTitle(com.fr.design.i18n.Toolkit.i18nText("FR-Desinger-Updater_UpdateAndUpgrade")); + GUICoreUtils.centerWindow(this); + setVisible(true); + } + + /** + * 检查有效性 + * + * @throws Exception + */ + @Override + public void checkValid() throws Exception { + + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/ColorfulCellRender.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/ColorfulCellRender.java new file mode 100644 index 0000000000..461489839a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/ColorfulCellRender.java @@ -0,0 +1,65 @@ +package com.fr.design.onlineupdate.ui.widget; + +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.Graphics; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class ColorfulCellRender extends JPanel implements ListCellRenderer { + private static int CELLCOLOR_DARK = 0xf6f6f6; + private static int CELLCOLOR_LIGHT = 0xffffff; + private static int CELLCOLOR_SELECTED = 0xdfecfd; + private static int TEXT_COORDINATE_X = 10; + private static int TEXT_COORDINATE_Y = 20; + private static final int LISTFONTSIZE = 12; + private Color[] colors = new Color[]{new Color(CELLCOLOR_DARK), new Color(CELLCOLOR_LIGHT)}; + + private String text; + + public ColorfulCellRender() { + setOpaque(true); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + text = ((null != value) ? (value.toString()) : null); + + Color background; + Color foreground = Color.BLACK; + //当前Renderer是否是拖拽目标 + JList.DropLocation dropLocation = list.getDropLocation(); + if (dropLocation != null + && !dropLocation.isInsert() + && dropLocation.getIndex() == index) { + + background = new Color(CELLCOLOR_SELECTED); + //当前Renderer是否被选中 + } else if (isSelected) { + background = new Color(CELLCOLOR_SELECTED); + } else { + background = colors[index % 2]; + } + + setBackground(background); + setForeground(foreground); + + return this; + } + + @Override + public void paintComponent(Graphics g) { + g.setColor(getBackground()); + g.fillRect(0, 0, getWidth(), getHeight()); + g.setColor(getForeground()); + g.setFont(new Font("Default", Font.PLAIN, LISTFONTSIZE)); + if (text != null) { + g.drawString(text, TEXT_COORDINATE_X, TEXT_COORDINATE_Y); + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/LoadingLabel.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/LoadingLabel.java new file mode 100644 index 0000000000..a21d67e462 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/LoadingLabel.java @@ -0,0 +1,48 @@ +package com.fr.design.onlineupdate.ui.widget; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.general.IOUtils; + +import javax.swing.Icon; +import javax.swing.SwingConstants; +import javax.swing.Timer; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class LoadingLabel extends UILabel { + private Icon[] busyIcons = new Icon[15]; + private Timer busyIconTimer; + private int busyIconIndex; + + public LoadingLabel() { + for (int i = 0; i < busyIcons.length; i++) { + busyIcons[i] = IOUtils.readIcon("/com/fr/design/images/update/busy-icon" + i + ".png"); + } + int busyAnimationRate = 30; + + busyIconTimer = new Timer(busyAnimationRate, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + busyIconIndex = (busyIconIndex + 1) % busyIcons.length; + setIcon(busyIcons[busyIconIndex]); + setHorizontalAlignment(SwingConstants.CENTER); + } + }); + busyIconTimer.start(); + } + + /** + * 停止加载,并显示 + * + * @param text 要显示的字段 + */ + public void stopLoading(String text) { + busyIconTimer.stop(); + setIcon(null); + setText(text); + } + +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateActionLabel.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateActionLabel.java new file mode 100644 index 0000000000..74c2b6ae57 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateActionLabel.java @@ -0,0 +1,95 @@ +package com.fr.design.onlineupdate.ui.widget; + +import com.fr.design.gui.ilable.UILabel; + +import javax.swing.event.MouseInputAdapter; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class UpdateActionLabel extends UILabel { + private ActionListener actionListener; + private boolean drawLine = true; + + public UpdateActionLabel(String text, boolean drawUnderLine) { + super(text); + this.drawLine = drawUnderLine; + this.setForeground(Color.BLUE); + this.addMouseListener(mouseInputAdapter); + this.addMouseMotionListener(mouseInputAdapter); + } + + /** + * 增加事件监听 + * + * @param actionListener 监听器 + */ + public void addActionListener(ActionListener actionListener) { + this.actionListener = actionListener; + } + + /** + * Repaints the text. + */ + public void paintComponent(Graphics _gfx) { + super.paintComponent(_gfx); + + _gfx.setColor(Color.BLUE); + if (drawLine) { + _gfx.drawLine(0, this.getHeight() - 1, this.getWidth(), this.getHeight() - 1); + } + } + + private MouseInputAdapter mouseInputAdapter = new MouseInputAdapter() { + public void mouseClicked(MouseEvent e) { + } + + public void mousePressed(MouseEvent e) { + } + + public void mouseReleased(MouseEvent evt) { + Object source = evt.getSource(); + + if (source instanceof UILabel) { + //Action. + if (actionListener != null) { + ActionEvent actionEvent = new ActionEvent(source, 99, ""); + actionListener.actionPerformed(actionEvent); + } + } + } + + public void mouseEntered(MouseEvent evt) { + Object source = evt.getSource(); + + if (source instanceof UILabel) { + ((UILabel) source).setCursor(new Cursor(Cursor.HAND_CURSOR)); + } + } + + public void mouseExited(MouseEvent evt) { + Object source = evt.getSource(); + + if (source instanceof UILabel) { + ((UILabel) source).setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + } + + public void mouseDragged(MouseEvent e) { + } + + public void mouseMoved(MouseEvent evt) { + Object source = evt.getSource(); + + if (source instanceof UILabel) { + ((UILabel) source).setCursor(new Cursor(Cursor.HAND_CURSOR)); + } + } + }; +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTable.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTable.java new file mode 100644 index 0000000000..f94a514ad3 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTable.java @@ -0,0 +1,46 @@ +package com.fr.design.onlineupdate.ui.widget; + +import javax.swing.JTable; +import javax.swing.table.TableModel; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class UpdateInfoTable extends JTable { + private UpdateInfoTableModel dataModel; + + public UpdateInfoTable(TableModel dm) { + super(dm); + dataModel = (UpdateInfoTableModel) dm; + } + + public UpdateInfoTable() { + } + + public UpdateInfoTable(String[] columnNames) { + this(new UpdateInfoTableModel(columnNames, new ArrayList())); + } + + public UpdateInfoTable(List data, String[] columnNames) { + this(new UpdateInfoTableModel(columnNames, data)); + } + + public UpdateInfoTable(Vector rowData, Vector columnNames) { + super(rowData, columnNames); + } + + public UpdateInfoTable(int numRows, int numColumns) { + super(numRows, numColumns); + } + + public UpdateInfoTableModel getDataModel() { + return dataModel; + } + + public void setDataModel(UpdateInfoTableModel dataModel) { + this.dataModel = dataModel; + } +} diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTableCellRender.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTableCellRender.java new file mode 100644 index 0000000000..22c603c86f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTableCellRender.java @@ -0,0 +1,48 @@ +package com.fr.design.onlineupdate.ui.widget; + +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.Color; +import java.awt.Component; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class UpdateInfoTableCellRender extends DefaultTableCellRenderer { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + cell.setBackground((row & 1) != 0 ? new Color(0xf0f0f0) : Color.WHITE); + if ((Boolean) table.getValueAt(row, 2)) { + cell.setBackground(new Color(0xdfecfd)); + } + if (column == 0) { + //设置首列日期居中显示 + setHorizontalAlignment(JLabel.CENTER); + + for (int i = 1; row - i >= 0; i++) { + if (ComparatorUtils.equals(table.getValueAt(row - i, 0), value)) { + //调用的父类JLabel的setText,table本身的值不变 + setText(StringUtils.EMPTY); + break; + } + } + } + return cell; + } + + @Override + public void setForeground(Color c) { + super.setForeground(c); + } + + @Override + public void setBackground(Color c) { + super.setBackground(c); + } +} diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTableModel.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTableModel.java new file mode 100644 index 0000000000..147f88a299 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTableModel.java @@ -0,0 +1,65 @@ +package com.fr.design.onlineupdate.ui.widget; + +import javax.swing.table.AbstractTableModel; +import java.util.List; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class UpdateInfoTableModel extends AbstractTableModel { + private String[] titles; + private List data; + + public UpdateInfoTableModel(String[] titles, List data) { + this.titles = titles; + this.data = data; + } + + public void populateBean(List data) { + if (data == null) { + return; + } + clear(); + this.data = data; + fireTableDataChanged(); + } + + public void clear() { + data.clear(); + } + + public List updateBean() { + return data; + } + + @Override + public int getRowCount() { + return data.size(); + } + + @Override + public int getColumnCount() { + return titles.length; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return data.get(rowIndex)[columnIndex]; + } + + @Override + public String getColumnName(int column) { + return titles[column]; + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return false; + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + super.setValueAt(aValue, rowIndex, columnIndex); + } +} + diff --git a/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTextAreaCellRender.java b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTextAreaCellRender.java new file mode 100644 index 0000000000..1e3cebdf81 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/onlineupdate/ui/widget/UpdateInfoTextAreaCellRender.java @@ -0,0 +1,43 @@ +package com.fr.design.onlineupdate.ui.widget; + +import javax.swing.BorderFactory; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.table.TableCellRenderer; +import java.awt.Color; +import java.awt.Component; +import java.awt.Insets; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class UpdateInfoTextAreaCellRender extends JTextArea implements TableCellRenderer { + public UpdateInfoTextAreaCellRender() { + setMargin(new Insets(2, 2, 2, 2)); + setLineWrap(true); + setWrapStyleWord(true); + setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + // 计算当前行的最佳高度 + int maxPreferredHeight = 0; + for (int i = 0; i < table.getColumnCount(); i++) { + setText("" + table.getValueAt(row, i)); + setSize(table.getColumnModel().getColumn(column).getWidth(), 0); + maxPreferredHeight = Math.max(maxPreferredHeight, getPreferredSize().height); + } + + if (table.getRowHeight(row) != maxPreferredHeight) { + table.setRowHeight(row, maxPreferredHeight); + } + + setText(value == null ? "" : value.toString()); + setBackground((row & 1) != 0 ? new Color(0xf0f0f0) : Color.WHITE); + if ((Boolean) table.getValueAt(row, 2)) { + setBackground(new Color(0xdfecfd)); + } + return this; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/env/EnvListPane.java b/designer-base/src/main/java/com/fr/env/EnvListPane.java index 59eaea4e6e..30b4b76f12 100644 --- a/designer-base/src/main/java/com/fr/env/EnvListPane.java +++ b/designer-base/src/main/java/com/fr/env/EnvListPane.java @@ -53,7 +53,7 @@ public class EnvListPane extends JListControlPane { */ @Override public NameableCreator[] createNameableCreators() { - NameableCreator local = new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("FR-Engine-Local_Workspace"), "com/fr/design/images/data/bind/localconnect.png", + NameableCreator local = new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Local_Workspace"), "com/fr/design/images/data/bind/localconnect.png", LocalDesignerWorkspaceInfo.class, LocalEnvPane.class); NameableCreator remote = new NameObjectCreator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Env_Remote_Server"), "com/fr/design/images/data/bind/distanceconnect.png", RemoteDesignerWorkspaceInfo.class, RemoteEnvPane.class); diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon0.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon0.png new file mode 100644 index 0000000000..242c0c85bc Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon0.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon1.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon1.png new file mode 100644 index 0000000000..9f6f63438e Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon1.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon10.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon10.png new file mode 100644 index 0000000000..c4ef4a1fc6 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon10.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon11.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon11.png new file mode 100644 index 0000000000..6eca1f5e4e Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon11.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon12.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon12.png new file mode 100644 index 0000000000..e447ee8ac2 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon12.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon13.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon13.png new file mode 100644 index 0000000000..848a6f1a41 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon13.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon14.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon14.png new file mode 100644 index 0000000000..7b3561df21 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon14.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon2.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon2.png new file mode 100644 index 0000000000..c866e62a7c Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon2.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon3.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon3.png new file mode 100644 index 0000000000..9be22fa586 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon3.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon4.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon4.png new file mode 100644 index 0000000000..f07c20dc44 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon4.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon5.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon5.png new file mode 100644 index 0000000000..653fc9c3be Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon5.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon6.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon6.png new file mode 100644 index 0000000000..703557264f Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon6.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon7.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon7.png new file mode 100644 index 0000000000..49fbc6ec54 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon7.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon8.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon8.png new file mode 100644 index 0000000000..e1a5a40938 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon8.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/busy-icon9.png b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon9.png new file mode 100644 index 0000000000..827801235b Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/busy-icon9.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/update/update_new.png b/designer-base/src/main/resources/com/fr/design/images/update/update_new.png new file mode 100644 index 0000000000..c4b2b231c0 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/update/update_new.png differ diff --git a/designer-realize/src/main/java/com/fr/onlineupdate/actions/FileDownloader.java b/designer-realize/src/main/java/com/fr/onlineupdate/actions/FileDownloader.java new file mode 100644 index 0000000000..152dbd9d4f --- /dev/null +++ b/designer-realize/src/main/java/com/fr/onlineupdate/actions/FileDownloader.java @@ -0,0 +1,7 @@ +package com.fr.onlineupdate.actions; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class FileDownloader { +} diff --git a/designer-realize/src/main/java/com/fr/onlineupdate/domain/DownloadItem.java b/designer-realize/src/main/java/com/fr/onlineupdate/domain/DownloadItem.java new file mode 100644 index 0000000000..25cfff1f7d --- /dev/null +++ b/designer-realize/src/main/java/com/fr/onlineupdate/domain/DownloadItem.java @@ -0,0 +1,7 @@ +package com.fr.onlineupdate.domain; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class DownloadItem { +} diff --git a/designer-realize/src/main/java/com/fr/onlineupdate/factory/DirectoryOperationFactory.java b/designer-realize/src/main/java/com/fr/onlineupdate/factory/DirectoryOperationFactory.java new file mode 100644 index 0000000000..97e979c350 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/onlineupdate/factory/DirectoryOperationFactory.java @@ -0,0 +1,7 @@ +package com.fr.onlineupdate.factory; + +/** + * Created by XINZAI on 2018/8/21. + */ +public class DirectoryOperationFactory { +}