Browse Source

KERNEL-418 在线更新升级重构

persist/11.0
Bryant 5 years ago
parent
commit
6d28467587
  1. 118
      designer-base/src/main/java/com/fr/design/update/actions/FileDownloader.java
  2. 55
      designer-base/src/main/java/com/fr/design/update/actions/FileProcess.java
  3. 102
      designer-base/src/main/java/com/fr/design/update/domain/DownloadItem.java
  4. 195
      designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java

118
designer-base/src/main/java/com/fr/design/update/actions/FileDownloader.java

@ -1,118 +0,0 @@
package com.fr.design.update.actions;
import com.fr.design.update.domain.UpdateConstants;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.design.update.domain.DownloadItem;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.ExecutionException;
/**
* Created by XINZAI on 2018/8/21.
*/
public abstract class FileDownloader extends SwingWorker<Boolean, DownloadItem> {
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("Fine-Design_Updater_Download_Failed"),
InterProviderFactory.getProvider().getLocText("Fine-Design_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);
Thread.currentThread().interrupt();
} 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);
File tempFile = new File(StableUtils.pathJoin(saveDir, item.getName()));
StableUtils.makesureFileExist(tempFile);
try ( InputStream reader = connection.getInputStream();
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);
}
}
}
/**
* 下载成功
*/
public abstract void onDownloadSuccess();
/**
* 下载失败
*/
public abstract void onDownloadFailed();
public long getCompleteSize() {
return completeSize;
}
public void setCompleteSize(long completeSize) {
this.completeSize = completeSize;
}
}

55
designer-base/src/main/java/com/fr/design/update/actions/FileProcess.java

@ -0,0 +1,55 @@
package com.fr.design.update.actions;
import com.fr.decision.update.Info.UpdateCallBack;
import com.fr.decision.update.UpdateExecutor;
import com.fr.log.FineLoggerFactory;
import javax.swing.*;
import java.util.concurrent.ExecutionException;
/**
* @author Bryant
* @version 10.0
* Created by Bryant on 2019-09-12
*/
public abstract class FileProcess extends SwingWorker<Boolean, Void> {
private UpdateCallBack callBack;
public FileProcess(UpdateCallBack callBack) {
this.callBack = callBack;
}
@Override
protected Boolean doInBackground() throws Exception {
return UpdateExecutor.getInstance().execute(callBack);
}
@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();
}

102
designer-base/src/main/java/com/fr/design/update/domain/DownloadItem.java

@ -1,102 +0,0 @@
package com.fr.design.update.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();
}
}

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

@ -1,5 +1,7 @@
package com.fr.design.update.ui.dialog; package com.fr.design.update.ui.dialog;
import com.fr.decision.update.Info.UpdateCallBack;
import com.fr.decision.update.Info.UpdateProgressCallBack;
import com.fr.design.RestartHelper; import com.fr.design.RestartHelper;
import com.fr.design.constants.LayoutConstants; import com.fr.design.constants.LayoutConstants;
import com.fr.design.dialog.UIDialog; import com.fr.design.dialog.UIDialog;
@ -10,8 +12,7 @@ import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.update.actions.FileDownloader; import com.fr.design.update.actions.FileProcess;
import com.fr.design.update.domain.DownloadItem;
import com.fr.design.update.domain.UpdateConstants; import com.fr.design.update.domain.UpdateConstants;
import com.fr.design.update.domain.UpdateInfoCachePropertyManager; import com.fr.design.update.domain.UpdateInfoCachePropertyManager;
import com.fr.design.update.factory.DirectoryOperationFactory; import com.fr.design.update.factory.DirectoryOperationFactory;
@ -27,7 +28,6 @@ import com.fr.general.ComparatorUtils;
import com.fr.general.DateUtils; import com.fr.general.DateUtils;
import com.fr.general.GeneralContext; import com.fr.general.GeneralContext;
import com.fr.general.GeneralUtils; import com.fr.general.GeneralUtils;
import com.fr.general.IOUtils;
import com.fr.general.SiteCenter; import com.fr.general.SiteCenter;
import com.fr.general.http.HttpClient; import com.fr.general.http.HttpClient;
import com.fr.general.http.HttpToolbox; import com.fr.general.http.HttpToolbox;
@ -39,18 +39,10 @@ import com.fr.stable.EncodeConstants;
import com.fr.stable.ProductConstants; import com.fr.stable.ProductConstants;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.org.apache.commons.codec.digest.DigestUtils;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.sun.java.swing.plaf.motif.MotifProgressBarUI; import com.sun.java.swing.plaf.motif.MotifProgressBarUI;
import javax.swing.BorderFactory; import javax.swing.*;
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.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import javax.swing.table.TableRowSorter; import javax.swing.table.TableRowSorter;
@ -67,19 +59,14 @@ import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.text.ParsePosition; import java.text.ParsePosition;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
/** /**
@ -107,7 +94,6 @@ public class UpdateMainDialog extends UIDialog {
private static final SimpleDateFormat CHANGELOG_FORMAT = new SimpleDateFormat("M/d/y, h:m:s a", Locale.ENGLISH); 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 static final SimpleDateFormat UPDATE_INFO_TABLE_FORMAT = new SimpleDateFormat("yyyy.MM.dd");
private Set<DownloadItem> downloadItems = new HashSet<DownloadItem>();
private JSONObject downloadFileConfig; private JSONObject downloadFileConfig;
//最新版本标签 //最新版本标签
private LoadingLabel loadingLabel; private LoadingLabel loadingLabel;
@ -166,14 +152,12 @@ public class UpdateMainDialog extends UIDialog {
public void setAutoUpdateAfterInit() { public void setAutoUpdateAfterInit() {
autoUpdateAfterInit = true; autoUpdateAfterInit = true;
} }
private void initUpdateActionPane() { private void initUpdateActionPane() {
double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE}; double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE};
double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED}; double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED};
double[] columnUpdateSubContentPaneProgressSize = {TableLayout.FILL, TableLayout.PREFERRED}; double[] columnUpdateSubContentPaneProgressSize = {TableLayout.FILL, TableLayout.PREFERRED};
double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED}; double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED};
JPanel progressBarPane = new JPanel(new BorderLayout()); JPanel progressBarPane = new JPanel(new BorderLayout());
progressBar = new JProgressBar(); progressBar = new JProgressBar();
progressBar.setUI(new MotifProgressBarUI()); progressBar.setUI(new MotifProgressBarUI());
progressBar.setForeground(UpdateConstants.BAR_COLOR); progressBar.setForeground(UpdateConstants.BAR_COLOR);
@ -601,62 +585,6 @@ public class UpdateMainDialog extends UIDialog {
} }
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));
String currentMD5 = getCurrentJarMD5(currentJAR);
String downloadMD5 = jo.optString("md5");
boolean exist = currentJAR.exists() && ComparatorUtils.equals(currentJAR.length(), downloadSize) && ComparatorUtils.equals(currentMD5, downloadMD5);
if (exist) {
// 如果jar包存在且MD5值和大小与oss上的一致 不下载
continue;
}
}
downloadItems.add(new DownloadItem(downloadName, downloadUrl, downloadSize));
}
}
}
/**
* 获取当前jar的md5
*
* @param currentJAR
* @return
*/
private String getCurrentJarMD5(File currentJAR) {
String md5 = StringUtils.EMPTY;
FileInputStream input = null;
try {
input = new FileInputStream(currentJAR);
md5 = DigestUtils.md5Hex(input);
} catch (Exception ignore) {
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
return md5;
} }
/** /**
@ -669,31 +597,19 @@ public class UpdateMainDialog extends UIDialog {
if (updateSuccessful) { if (updateSuccessful) {
RestartHelper.restart(); RestartHelper.restart();
} else { } else {
progressBar.setVisible(true);
UpdateCallBack callBack = new UpdateProgressCallBack(progressBar);
deletePreviousPropertyFile(); deletePreviousPropertyFile();
updateButton.setEnabled(false); updateButton.setEnabled(false);
progressBar.setVisible(true);
updateLabel.setVisible(false); updateLabel.setVisible(false);
new FileProcess(callBack) {
new FileDownloader(
downloadItems.toArray(new DownloadItem[downloadItems.size()]),
StableUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DOWNLOAD_DIR)) {
@Override
protected void process(java.util.List<DownloadItem> chunks) {
DownloadItem fileInfo = chunks.get(chunks.size() - 1);
progressBar.setString(fileInfo.getName() + " " + fileInfo.getProgressString());
progressBar.setValue(fileInfo.getProgressValue());
}
@Override @Override
public void onDownloadSuccess() { public void onDownloadSuccess() {
updateButton.setEnabled(true); updateButton.setEnabled(true);
progressBar.setVisible(false); progressBar.setVisible(false);
backup();
putNewFiles();
updateSuccessful = true; updateSuccessful = true;
updateButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Restart_Designer")); updateButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Restart_Designer"));
} }
@Override @Override
public void onDownloadFailed() { public void onDownloadFailed() {
progressBar.setVisible(false); progressBar.setVisible(false);
@ -719,109 +635,12 @@ public class UpdateMainDialog extends UIDialog {
} }
} }
/**
* 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, List<String> files) {
for (String file : files) {
try {
IOUtils.copy(
new File(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, ProductConstants.getAppFolderName(), 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, List<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<String, String> map = new HashMap<String, String>();
java.util.List<String> list = new ArrayList<String>();
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<String, String> map, java.util.List<String> 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<String, String> map, java.util.List<String> list) {
for (String file : files) {
map.put(StableUtils.pathJoin(installHome, UpdateConstants.DOWNLOAD_DIR, file),
StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, ProductConstants.getAppFolderName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file));
list.add(StableUtils.pathJoin(installHome, UpdateConstants.APPS_FOLDER_NAME, ProductConstants.getAppFolderName(), ProjectConstants.WEBINF_NAME, ProjectConstants.LIB_NAME, file));
}
}
//获取备份目录 //获取备份目录
private String getBackupDirectory() { private String getBackupDirectory() {
return UpdateConstants.DESIGNER_BACKUP_DIR; return UpdateConstants.DESIGNER_BACKUP_DIR;
} }
//获取服务器jar包列表
private List<String> getJARList4Server() {
return UpdateConstants.JARS_FOR_SERVER_X;
}
//获取设计器jar包列表
private List<String> getJARList4Designer() {
return UpdateConstants.JARS_FOR_DESIGNER_X;
}
//获取服务器jar包下载列表
private String[] getDownLoadJAR4Server() {
ArrayList<String> jarList = new ArrayList<String>();
List<String> serverItems = getJARList4Server();
for (DownloadItem downloadItem : downloadItems) {
String downloadItemName = downloadItem.getName();
if (serverItems.contains(downloadItemName)) {
jarList.add(downloadItemName);
}
}
return jarList.toArray(new String[jarList.size()]);
}
//获取设计器jar包下载列表
private String[] getDownLoadJAR4Designer() {
ArrayList<String> jarList = new ArrayList<String>();
List<String> designerJarItems = getJARList4Designer();
for (DownloadItem downloadItem : downloadItems) {
String downloadItemName = downloadItem.getName();
if (designerJarItems.contains(downloadItemName)) {
jarList.add(downloadItemName);
}
}
return jarList.toArray(new String[jarList.size()]);
}
//获取更新日志缓存配置文件名 //获取更新日志缓存配置文件名
private String getUpdateCacheConfig() { private String getUpdateCacheConfig() {
return UpdateConstants.UPDATE_CACHE_CONFIG_X; return UpdateConstants.UPDATE_CACHE_CONFIG_X;

Loading…
Cancel
Save