Browse Source

REPORT-14865 更新日志推送(部分)

research/10.0
plough 6 years ago
parent
commit
f1dd6f6fe5
  1. 127
      designer-base/src/main/java/com/fr/design/onlineupdate/push/DesignerPushUpdateDialog.java
  2. 101
      designer-base/src/main/java/com/fr/design/onlineupdate/push/DesignerPushUpdateManager.java
  3. 19
      designer-base/src/main/java/com/fr/design/onlineupdate/push/DesignerUpdateInfo.java
  4. 10
      designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java
  5. 179
      designer-base/src/main/resources/com/fr/design/ui/onlineupdate/push/pushUpdate.html
  6. 23
      designer-base/src/test/java/com/fr/design/onlineupdate/push/DesignerPushUpdateDialogTest.java
  7. 10
      designer-base/src/test/java/com/fr/design/onlineupdate/push/DesignerUpdateInfoTest.java
  8. 2
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

127
designer-base/src/main/java/com/fr/design/onlineupdate/push/DesignerPushUpdateDialog.java

@ -0,0 +1,127 @@
package com.fr.design.onlineupdate.push;
import com.fr.design.dialog.UIDialog;
import com.fr.design.ui.ModernUIPane;
import com.fr.design.utils.gui.GUICoreUtils;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
/**
* Created by plough on 2019/4/10.
*/
class DesignerPushUpdateDialog extends UIDialog {
public static final Dimension DEFAULT = new Dimension(640, 320);
private ModernUIPane<Model> jsPane;
private DesignerPushUpdateDialog(Frame parent) {
super(parent);
setModal(true);
initComponents();
}
static void createAndShow(Frame parent, DesignerUpdateInfo updateInfo) {
DesignerPushUpdateDialog dialog = new DesignerPushUpdateDialog(parent);
dialog.populate(updateInfo);
dialog.showDialog();
}
private void initComponents() {
JPanel contentPane = (JPanel) getContentPane();
contentPane.setLayout(new BorderLayout());
jsPane = new ModernUIPane.Builder<Model>()
.withEMB("/com/fr/design/ui/onlineupdate/push/pushUpdate.html").namespace("Pool").build();
contentPane.add(jsPane);
}
private void populate(DesignerUpdateInfo updateInfo) {
Model model = createModel(updateInfo);
jsPane.populate(model);
}
private Model createModel(DesignerUpdateInfo updateInfo) {
Model model = new Model();
model.setVersion(updateInfo.getPushVersion());
model.setContent(updateInfo.getPushContent());
model.setMoreInfoUrl(updateInfo.getMoreInfoUrl());
model.setBackgroundUrl(updateInfo.getBackgroundUrl());
return model;
}
@Override
public void checkValid() throws Exception {
// do nothing
}
/**
* 显示窗口
*/
private void showDialog() {
setSize(DEFAULT);
setUndecorated(true);
GUICoreUtils.centerWindow(this);
setVisible(true);
}
public class Model {
private String version;
private String content;
private String moreInfoUrl;
private String backgroundUrl;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMoreInfoUrl() {
return moreInfoUrl;
}
public void setMoreInfoUrl(String moreInfoUrl) {
this.moreInfoUrl = moreInfoUrl;
}
public String getBackgroundUrl() {
return backgroundUrl;
}
public void setBackgroundUrl(String backgroundUrl) {
this.backgroundUrl = backgroundUrl;
}
public void updateNow() {
DesignerPushUpdateManager.getInstance().doUpdate();
exit();
}
public void remindNextTime() {
exit();
}
public void skipThisVersion() {
DesignerPushUpdateManager.getInstance().skipCurrentPushVersion();
exit();
}
private void exit() {
DesignerPushUpdateDialog.this.dialogExit();
}
}
}

101
designer-base/src/main/java/com/fr/design/onlineupdate/push/DesignerPushUpdateManager.java

@ -1,16 +1,21 @@
package com.fr.design.onlineupdate.push; package com.fr.design.onlineupdate.push;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.general.CloudCenter; import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext; import com.fr.general.GeneralContext;
import com.fr.general.GeneralUtils; import com.fr.general.GeneralUtils;
import com.fr.general.http.HttpClient; import com.fr.general.http.HttpClient;
import com.fr.json.JSONObject; import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
/** /**
* Created by plough on 2019/4/8. * Created by plough on 2019/4/8.
*/ */
public class DesignerPushUpdateManager { public class DesignerPushUpdateManager {
private static final String SPLIT_CHAR = "-";
private static DesignerPushUpdateManager singleton; private static DesignerPushUpdateManager singleton;
private DesignerUpdateInfo updateInfo; private DesignerUpdateInfo updateInfo;
private DesignerPushUpdateConfigManager config; private DesignerPushUpdateConfigManager config;
@ -26,17 +31,31 @@ public class DesignerPushUpdateManager {
return singleton; return singleton;
} }
private void initUpdateInfo() { private void initUpdateInfo(String currentVersion, String latestVersion) {
String currentVersion = GeneralUtils.readFullBuildNO(); String lastIgnoredVersion = config.getLastIgnoredVersion();
String updatePushInfo = CloudCenter.getInstance().acquireUrlByKind("update.push");
JSONObject pushData = new JSONObject(updatePushInfo);
updateInfo = new DesignerUpdateInfo(currentVersion, latestVersion, lastIgnoredVersion, pushData);
}
// todo:耗时请求,可能需要优化 private String getFullLatestVersion() {
HttpClient hc = new HttpClient(CloudCenter.getInstance().acquireUrlByKind("jar10.update")); HttpClient hc = new HttpClient(CloudCenter.getInstance().acquireUrlByKind("jar10.update"));
String latestVersion = new JSONObject(hc.getResponseText()).optString("versionNO"); return new JSONObject(hc.getResponseText()).optString("buildNO");
}
String updatePushInfo = CloudCenter.getInstance().acquireUrlByKind("update.push"); private String getVersionByFullNO(String fullNO) {
JSONObject pushData = new JSONObject(updatePushInfo); if (fullNO.contains(SPLIT_CHAR)) {
fullNO = fullNO.substring(fullNO.lastIndexOf(SPLIT_CHAR) + 1);
}
return fullNO;
}
updateInfo = new DesignerUpdateInfo(currentVersion, latestVersion, pushData); private String getPrefixByFullNO(String fullNO) {
if (fullNO.contains(SPLIT_CHAR)) {
return fullNO.substring(0, fullNO.lastIndexOf(SPLIT_CHAR));
}
return StringUtils.EMPTY;
} }
/** /**
@ -57,18 +76,72 @@ public class DesignerPushUpdateManager {
/** /**
* 检查更新如果有合适的更新版本则弹窗 * 检查更新如果有合适的更新版本则弹窗
*/ */
public void popUpDialog() { public void checkAndPop() {
if (!shouldPopUp()) { new Thread() {
return; @Override
} public void run() {
// todo: do pop if (!shouldPopUp()) {
FineLoggerFactory.getLogger().debug("skip push update");
return;
}
// todo: do pop
final DesignerFrame designerFrame = DesignerContext.getDesignerFrame();
DesignerPushUpdateDialog.createAndShow(designerFrame, updateInfo);
}
}.start();
} }
private boolean shouldPopUp() { private boolean shouldPopUp() {
if (updateInfo == null) { if (updateInfo == null) {
initUpdateInfo(); String fullCurrentVersion = GeneralUtils.readFullBuildNO();
// todo: 开发测试用
if (!fullCurrentVersion.contains(SPLIT_CHAR)) {
fullCurrentVersion = "stable-2019.01.03.17.01.05.257";
}
String fullLatestVersion = getFullLatestVersion();
boolean isValidJarVersion = isValidJarVersion(fullCurrentVersion, fullLatestVersion);
if (!isValidJarVersion) {
FineLoggerFactory.getLogger().info("Jar version is not valid for push update.");
return false;
} else {
String currentVersion = getVersionByFullNO(fullCurrentVersion);
String latestVersion = getVersionByFullNO(fullLatestVersion);
initUpdateInfo(currentVersion, latestVersion);
}
} }
return isAutoPushUpdateSupported() && updateInfo.hasNewPushVersion(config.getLastIgnoredVersion()); return isAutoPushUpdateSupported() && updateInfo.hasNewPushVersion();
}
private boolean isValidJarVersion(String fullCurrentVersion, String fullLatestVersion) {
// todo: 目前设定的逻辑是 feature/release/stable 都弹,且不区分版本号。后期肯定要变的,注释代码先留着
// // 无效的情况:
// // 1. 版本号格式有误
// // 2. 当前用的是 release 或 feature 的 jar 包
// // 3. 代码启动的
// String prefix = getPrefixByFullNO(fullLatestVersion);
// return StringUtils.isNotEmpty(prefix) && fullCurrentVersion.startsWith(prefix);
// 无效的情况:
// 1. 版本号格式有误(正常情况下都有前缀,只有异常的时候才可能出现)
// 2. 代码启动的(fullCurrentVersion 为"不是安装版本")
String prefix = getPrefixByFullNO(fullLatestVersion);
return StringUtils.isNotEmpty(prefix) && fullCurrentVersion.contains(SPLIT_CHAR);
}
/**
* 跳转到更新升级窗口并自动开始更新
*/
void doUpdate() {
// todo
}
/**
* 跳过当前的推送版本
*/
void skipCurrentPushVersion() {
// todo
} }
} }

19
designer-base/src/main/java/com/fr/design/onlineupdate/push/DesignerUpdateInfo.java

@ -17,15 +17,17 @@ class DesignerUpdateInfo {
private final String currentVersion; // 当前版本 private final String currentVersion; // 当前版本
private final String latestVersion; // 最新版本 private final String latestVersion; // 最新版本
private final String lastIgnoredVersion; // 最近一次跳过的版本
private final String pushVersion; // 推送版本 private final String pushVersion; // 推送版本
private final String pushContent; // 推送更新内容 private final String pushContent; // 推送更新内容
private final String backgroundUrl; // 推送背景图片 url private final String backgroundUrl; // 推送背景图片 url
private final String moreInfoUrl; // 更多新特性 private final String moreInfoUrl; // 更多新特性
DesignerUpdateInfo(String currentVersion, String latestVersion, JSONObject pushData) { DesignerUpdateInfo(String currentVersion, String latestVersion, String lastIgnoredVersion, JSONObject pushData) {
this.currentVersion = currentVersion; this.currentVersion = currentVersion;
this.latestVersion = latestVersion; this.latestVersion = latestVersion;
this.lastIgnoredVersion = lastIgnoredVersion;
this.pushVersion = pushData.optString(KEY_VERSION); this.pushVersion = pushData.optString(KEY_VERSION);
this.pushContent = pushData.optString(KEY_CONTENT); this.pushContent = pushData.optString(KEY_CONTENT);
@ -39,6 +41,7 @@ class DesignerUpdateInfo {
} }
private boolean hasEmptyField() { private boolean hasEmptyField() {
// lastIgnoredVersion 可以为空
return StringUtils.isEmpty(currentVersion) return StringUtils.isEmpty(currentVersion)
|| StringUtils.isEmpty(latestVersion) || StringUtils.isEmpty(latestVersion)
|| StringUtils.isEmpty(pushVersion) || StringUtils.isEmpty(pushVersion)
@ -51,14 +54,18 @@ class DesignerUpdateInfo {
return currentVersion; return currentVersion;
} }
String getPushVersion() {
return pushVersion;
}
String getLatestVersion() { String getLatestVersion() {
return latestVersion; return latestVersion;
} }
public String getLastIgnoredVersion() {
return lastIgnoredVersion;
}
String getPushVersion() {
return pushVersion;
}
String getPushContent() { String getPushContent() {
return pushContent; return pushContent;
} }
@ -71,7 +78,7 @@ class DesignerUpdateInfo {
return moreInfoUrl; return moreInfoUrl;
} }
boolean hasNewPushVersion(String lastIgnoredVersion) { boolean hasNewPushVersion() {
boolean result = ComparatorUtils.compare(pushVersion, currentVersion) > 0 boolean result = ComparatorUtils.compare(pushVersion, currentVersion) > 0
&& ComparatorUtils.compare(pushVersion, latestVersion) <= 0; && ComparatorUtils.compare(pushVersion, latestVersion) <= 0;
if (StringUtils.isNotEmpty(lastIgnoredVersion)) { if (StringUtils.isNotEmpty(lastIgnoredVersion)) {

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

@ -75,13 +75,11 @@ public class ModernUIPane<T> extends BasicPane {
public void populate(final T t) { public void populate(final T t) {
browser.addLoadListener(new LoadAdapter() { browser.addScriptContextListener(new ScriptContextAdapter() {
@Override @Override
public void onFinishLoadingFrame(FinishLoadingEvent event) { public void onScriptContextCreated(ScriptContextEvent event) {
if (event.isMainFrame()) { JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace);
JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace); ns.asObject().setProperty(variable, t);
ns.asObject().setProperty(variable, t);
}
} }
}); });
} }

179
designer-base/src/main/resources/com/fr/design/ui/onlineupdate/push/pushUpdate.html

@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Push Update</title>
<link rel="stylesheet" href="emb:/com/fr/web/ui/fineui.min.css"/>
<script src="emb:/com/fr/web/ui/fineui.min.js"></script>
<style>
.title {
font-size: 30px;
}
.desc {
margin-top: 35px;
}
.moreInfo {
margin-top: 15px;
}
.buttonGroup {
margin-top: 35px;
}
.button-ignore {
}
body {
padding-left: 30px;
padding-top: 30px;
color: white;
}
</style>
</head>
<body>
<script>
// var EVENT_POPULATE = "EVENT_POPULATE";
// var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
//
// var observer = new MutationObserver(function(mutations) {
// mutations.forEach(function(mutation) {
// if (mutation.type === "attributes" && window.Pool) {
// console.log("attributes changed");
// window.fireEvent(EVENT_POPULATE);
// }
// });
// });
//
// observer.observe(window, {
// attributes: true //configure it to listen to attribute changes
// });
window.addEventListener("load", function (ev) {
// alert(window.Pool.data);
// todo: 开发临时方案
// setTimeout(function () {
console.log(window.Pool.data);
var title = BI.createWidget({
type: "bi.vertical",
items: [
{
type: "bi.label",
text: "发现新版本",
cls: "title",
textAlign: "left"
},
{
type: "bi.label",
text: Pool.data.getVersion(),
textAlign: "left"
}
]
});
var desc = BI.createWidget({
type: "bi.vertical",
cls: "desc",
items: [
{
type: "bi.label",
// text: "1) xxx",
text: Pool.data.getContent(),
textAlign: "left"
}
// {
// type: "bi.label",
// text: "2) ldsnvls df",
// textAlign: "left"
// }
]
});
var moreInfo = BI.createWidget({
type: "bi.text_button",
text: "更多信息",
cls: "moreInfo",
textAlign: "left"
});
var buttonGroup = BI.createWidget({
type: 'bi.left',
cls: "buttonGroup",
items: [
{
type: 'bi.button',
text: '立即更新',
level: 'common',
height: 30,
handler: function() {
Pool.data.updateNow();
}
},
{
el: {
type: 'bi.button',
text: '下次启动提醒我',
level: 'ignore',
height: 30,
handler: function() {
Pool.data.remindNextTime();
}
},
lgap: 10
},
{
el: {
type: 'bi.button',
text: '跳过此版本',
level: 'ignore',
height: 30,
handler: function() {
Pool.data.skipThisVersion();
}
},
lgap: 10
}
]
});
BI.createWidget({
type:"bi.vertical",
element: "body",
cls: "container",
items: [
title,
desc,
moreInfo,
buttonGroup
]
});
$(".container").css("background", "url(" + Pool.data.getBackgroundUrl() + ")");
$(".button-ignore").css({
"background-color": "white",
"border": "1px solid white"
});
// }, 2000);
// setTimeout(function() {
// // alert(Pool.data);
// alert(Pool.data.getName() + " " + Pool.data.getAge());
// }, 2000);
// Pool.update = function () {
// Pool.data.setAge(12);
// Pool.data.setName("Tom");
// return Pool.data;
// };
});
</script>
</body>
</html>

23
designer-base/src/test/java/com/fr/design/onlineupdate/push/DesignerPushUpdateDialogTest.java

@ -0,0 +1,23 @@
package com.fr.design.onlineupdate.push;
import com.fr.design.DesignerEnvManager;
import com.fr.json.JSONObject;
/**
* Created by plough on 2019/4/10.
*/
public class DesignerPushUpdateDialogTest {
public static void main(String[] args) {
DesignerEnvManager.getEnvManager().setOpenDebug(true);
JSONObject jo = JSONObject.create();
jo.put("version", "2019.03.06.04.02.43.6");
jo.put("content", "test content");
jo.put("more", "http://baidu.com");
jo.put("background", "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555043827901&di=fc266992abef5a7e13b4e0cb98975a75&imgtype=0&src=http%3A%2F%2Fi5.3conline.com%2Fimages%2Fpiclib%2F201203%2F20%2Fbatch%2F1%2F130280%2F1332249463721rez0li5fg0_medium.jpg");
DesignerUpdateInfo mockUpdateInfo = new DesignerUpdateInfo("111.22.11", "2211.231.1", "11.23.1", jo);
DesignerPushUpdateDialog.createAndShow(null, mockUpdateInfo);
}
}

10
designer-base/src/test/java/com/fr/design/onlineupdate/push/DesignerUpdateInfoTest.java

@ -18,6 +18,7 @@ import static org.junit.Assert.assertTrue;
public class DesignerUpdateInfoTest { public class DesignerUpdateInfoTest {
private static final String CURRENT_VERSION = "2018.09.03.xx"; private static final String CURRENT_VERSION = "2018.09.03.xx";
private static final String LATEST_VERSION = "2019.04.03.yy"; private static final String LATEST_VERSION = "2019.04.03.yy";
private static final String LAST_IGNORED_VERSION = "2019.02.03.yy";
private static final String PUSH_VERSION = "2019.01.03.21.11"; private static final String PUSH_VERSION = "2019.01.03.21.11";
private static final String PUSH_CONTENT = "the update desc content"; private static final String PUSH_CONTENT = "the update desc content";
private static final String PUSH_BACKGROUND = "http://image.fr.com/123.jpg"; private static final String PUSH_BACKGROUND = "http://image.fr.com/123.jpg";
@ -33,13 +34,14 @@ public class DesignerUpdateInfoTest {
pushData.put("background", PUSH_BACKGROUND); pushData.put("background", PUSH_BACKGROUND);
pushData.put("more", PUSH_MORE); pushData.put("more", PUSH_MORE);
updateInfo = new DesignerUpdateInfo(CURRENT_VERSION, LATEST_VERSION, pushData); updateInfo = new DesignerUpdateInfo(CURRENT_VERSION, LATEST_VERSION, LAST_IGNORED_VERSION, pushData);
} }
@Test @Test
public void testGetters() { public void testGetters() {
assertEquals(CURRENT_VERSION, updateInfo.getCurrentVersion()); assertEquals(CURRENT_VERSION, updateInfo.getCurrentVersion());
assertEquals(LATEST_VERSION, updateInfo.getLatestVersion()); assertEquals(LATEST_VERSION, updateInfo.getLatestVersion());
assertEquals(LAST_IGNORED_VERSION, updateInfo.getLastIgnoredVersion());
assertEquals(PUSH_VERSION, updateInfo.getPushVersion()); assertEquals(PUSH_VERSION, updateInfo.getPushVersion());
assertEquals(PUSH_CONTENT, updateInfo.getPushContent()); assertEquals(PUSH_CONTENT, updateInfo.getPushContent());
assertEquals(PUSH_BACKGROUND, updateInfo.getBackgroundUrl()); assertEquals(PUSH_BACKGROUND, updateInfo.getBackgroundUrl());
@ -79,14 +81,14 @@ public class DesignerUpdateInfoTest {
pushData.put("content", PUSH_CONTENT); pushData.put("content", PUSH_CONTENT);
pushData.put("background", PUSH_BACKGROUND); pushData.put("background", PUSH_BACKGROUND);
pushData.put("more", PUSH_MORE); pushData.put("more", PUSH_MORE);
DesignerUpdateInfo updateInfo = new DesignerUpdateInfo(Y, Z, pushData); DesignerUpdateInfo updateInfo = new DesignerUpdateInfo(Y, Z, X0, pushData);
return updateInfo.hasNewPushVersion(X0); return updateInfo.hasNewPushVersion();
} }
@Test @Test
public void testParameterValidation() { public void testParameterValidation() {
try { try {
DesignerUpdateInfo updateInfo = new DesignerUpdateInfo(null, null, new JSONObject()); DesignerUpdateInfo updateInfo = new DesignerUpdateInfo(null, null, null, new JSONObject());
Assert.fail("should not reach here!"); Assert.fail("should not reach here!");
} catch (InvalidParameterException e) { } catch (InvalidParameterException e) {
// do nothing // do nothing

2
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -53,6 +53,7 @@ import com.fr.design.mainframe.loghandler.DesignerLogAppender;
import com.fr.design.mainframe.loghandler.LogMessageBar; import com.fr.design.mainframe.loghandler.LogMessageBar;
import com.fr.design.mainframe.socketio.DesignerSocketIO; import com.fr.design.mainframe.socketio.DesignerSocketIO;
import com.fr.design.module.DesignModuleFactory; import com.fr.design.module.DesignModuleFactory;
import com.fr.design.onlineupdate.push.DesignerPushUpdateManager;
import com.fr.design.parameter.FormParameterReader; import com.fr.design.parameter.FormParameterReader;
import com.fr.design.parameter.ParameterPropertyPane; import com.fr.design.parameter.ParameterPropertyPane;
import com.fr.design.parameter.WorkBookParameterReader; import com.fr.design.parameter.WorkBookParameterReader;
@ -129,6 +130,7 @@ public class DesignerActivator extends Activator {
loadLogAppender(); loadLogAppender();
DesignerSocketIO.update(); DesignerSocketIO.update();
UserInfoPane.getInstance().updateBBSUserInfo(); UserInfoPane.getInstance().updateBBSUserInfo();
DesignerPushUpdateManager.getInstance().checkAndPop();
} }
private void loadLogAppender() { private void loadLogAppender() {

Loading…
Cancel
Save