Browse Source
Merge in DESIGN/design from ~DESTINY.LIN/design:mss/2.0 to mss/2.0 * commit '5d136679fdb1d7bc13c2d028302baa7cc90c0513': REPORT-114392 FR-FBP版本本地设计适配 部分代码规范+decision依赖去除 REPORT-114392 FR-FBP版本本地设计适配 代码规范 REPORT-114392 FR-FBP版本本地设计适配 设计器本地预览主体流程开发mss/2.0
Destiny.Lin-林锦龙
8 months ago
67 changed files with 3211 additions and 136 deletions
@ -0,0 +1,62 @@ |
|||||||
|
package com.fr.decision.update; |
||||||
|
|
||||||
|
import com.fr.decision.update.backup.Recover; |
||||||
|
import com.fr.decision.update.backup.RecoverForSync; |
||||||
|
import com.fr.decision.update.command.SyncCommandHandler; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.ProjectLibrary; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* SyncExecutor |
||||||
|
* |
||||||
|
* @author pengda |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2021/6/02 |
||||||
|
*/ |
||||||
|
public class SyncExecutor { |
||||||
|
private static final SyncExecutor INSTANCE = new SyncExecutor(); |
||||||
|
private SyncCommandHandler sycHandler; |
||||||
|
private Recover recoverForSync; |
||||||
|
|
||||||
|
private SyncExecutor() { |
||||||
|
sycHandler = SyncCommandHandler.getInstance(); |
||||||
|
recoverForSync = RecoverForSync.getInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取单例 |
||||||
|
*/ |
||||||
|
public static SyncExecutor getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 执行 |
||||||
|
*/ |
||||||
|
public boolean execute(UpdateCallBack callBack, String fullBuildNo) { |
||||||
|
String dir = StableUtils.pathJoin(ProjectLibrary.getInstance().getLibHome(),ProjectConstants.ASSIST_NAME, UpdateConstants.ENV_LIB); |
||||||
|
try { |
||||||
|
if (fullBuildNo != null) { |
||||||
|
if (recoverForSync.backup()) { |
||||||
|
if (sycHandler.execute(callBack, fullBuildNo)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
recoverForSync.recover(); |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return false; |
||||||
|
} finally { |
||||||
|
CommonIOUtils.deleteFile(new File(dir)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package com.fr.decision.update; |
||||||
|
|
||||||
|
import com.fr.decision.update.backup.Recover; |
||||||
|
import com.fr.decision.update.backup.RecoverHandler; |
||||||
|
import com.fr.decision.update.command.Command; |
||||||
|
import com.fr.decision.update.command.CommandHandler; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.io.utils.ResourceIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateExecutor |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class UpdateExecutor { |
||||||
|
|
||||||
|
|
||||||
|
private static final UpdateExecutor INSTANCE = new UpdateExecutor(); |
||||||
|
|
||||||
|
private Command updateHandler; |
||||||
|
|
||||||
|
private Recover recoverHandler; |
||||||
|
|
||||||
|
private UpdateExecutor() { |
||||||
|
updateHandler = CommandHandler.getInstance(); |
||||||
|
recoverHandler = RecoverHandler.getInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
public static UpdateExecutor getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
String dir = StableUtils.pathJoin(ProjectConstants.ASSIST_NAME,UpdateConstants.ENV_LIB); |
||||||
|
try { |
||||||
|
if (recoverHandler.backup()) { |
||||||
|
if (updateHandler.execute(callBack)) { |
||||||
|
return true; |
||||||
|
}else { |
||||||
|
recoverHandler.recover(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} finally { |
||||||
|
ResourceIOUtils.delete(dir); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.fr.decision.update.acquirer; |
||||||
|
|
||||||
|
import com.fanruan.product.ProductConstants; |
||||||
|
import com.fr.base.j2v8.J2V8Utils; |
||||||
|
import com.fr.decision.update.command.SyncCommandHandler; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
import com.fr.module.ModuleContext; |
||||||
|
import com.fr.stable.ProjectLibrary; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.os.AbstractOperatingSystem; |
||||||
|
import com.fr.stable.os.Arch; |
||||||
|
import com.fr.stable.os.OperatingSystem; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* AbstractAcquirer |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/4/24 |
||||||
|
*/ |
||||||
|
public abstract class AbstractAcquirer implements Acquirer { |
||||||
|
|
||||||
|
private static final AbstractOperatingSystem os = OperatingSystem.getOperatingSystem(); |
||||||
|
|
||||||
|
private static final Map<String, String> JS_PROPERTIES = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
protected Map<String, String> normalProperties() { |
||||||
|
Map<String, String> map = new HashMap<>(JS_PROPERTIES); |
||||||
|
map.put("$build", GeneralUtils.readFullBuildNO()); |
||||||
|
map.put("$version", ProductConstants.VERSION); |
||||||
|
map.put("$installHome", StableUtils.getInstallHome()); |
||||||
|
map.put("$envHome", envHome()); |
||||||
|
map.put("$os", os.getType().getName()); |
||||||
|
map.put("$arch", arch()); |
||||||
|
map.put("$type", type()); |
||||||
|
map.put("$engine", engine()); |
||||||
|
map.put("$time", getBranchTime()); |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
public static void registerJsProperties(String key, String value) { |
||||||
|
JS_PROPERTIES.put(key, value); |
||||||
|
} |
||||||
|
|
||||||
|
private static String arch() { |
||||||
|
if (os.getArch() == Arch.x86) { |
||||||
|
return UpdateConstants.ARCH_X86; |
||||||
|
} else if (os.getArch() == Arch.x86_64) { |
||||||
|
return UpdateConstants.ARCH_X86_64; |
||||||
|
} else if (os.getArch() == Arch.ARM) { |
||||||
|
return UpdateConstants.ARM; |
||||||
|
} else { |
||||||
|
return UpdateConstants.UNKNOWNOS; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static String type() { |
||||||
|
if (ModuleContext.isDesignerStartup()) { |
||||||
|
return UpdateConstants.DESIGNER; |
||||||
|
} else { |
||||||
|
return UpdateConstants.DECISION; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static String engine() { |
||||||
|
return J2V8Utils.SUPPORT_J2V8 ? UpdateConstants.J2V8 : UpdateConstants.NASHORN; |
||||||
|
} |
||||||
|
|
||||||
|
private static String envHome() { |
||||||
|
return ProjectLibrary.getInstance().getLibHome(); |
||||||
|
} |
||||||
|
|
||||||
|
private static String getBranchTime() { |
||||||
|
return SyncCommandHandler.getInstance().getBranchTime(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package com.fr.decision.update.acquirer; |
||||||
|
|
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
|
||||||
|
/** |
||||||
|
* 更新配置检查接口 |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/4/24 |
||||||
|
*/ |
||||||
|
public interface Acquirer { |
||||||
|
|
||||||
|
String OPERATE_ADD = "add"; |
||||||
|
|
||||||
|
String OPERATE_DELETE = "deletes"; |
||||||
|
|
||||||
|
String OPERATE_MODIFY = "modify"; |
||||||
|
|
||||||
|
String TYPE_SOURCE = "source"; |
||||||
|
|
||||||
|
String TYPE_TARGET = "target"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 准备运行环境 |
||||||
|
*/ |
||||||
|
void prepare(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取运行环境名称. |
||||||
|
* |
||||||
|
* @return 运行环境名称 |
||||||
|
*/ |
||||||
|
String getName(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据配置脚本,获取各类待处理的文件 |
||||||
|
* @param script 配置脚本 |
||||||
|
* @return 待处理文件集合 |
||||||
|
*/ |
||||||
|
FinallyObject execute(String script) throws IllegalStateException; |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.fr.decision.update.acquirer; |
||||||
|
|
||||||
|
import com.fr.concurrent.NamedThreadFactory; |
||||||
|
import com.fr.decision.update.operate.AcquirerTask; |
||||||
|
import com.fr.module.ModuleContext; |
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService; |
||||||
|
import java.util.concurrent.Future; |
||||||
|
|
||||||
|
/** |
||||||
|
* 任务执行服务管理器 |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/16 |
||||||
|
*/ |
||||||
|
public class AcquirerExecutorService { |
||||||
|
|
||||||
|
private static ExecutorService executorService = ModuleContext.getExecutor().newSingleThreadExecutor((new NamedThreadFactory("AcquirerExecutorService"))); |
||||||
|
|
||||||
|
public static Future<String> registerJob(AcquirerTask task) { |
||||||
|
return executorService.submit(task); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package com.fr.decision.update.acquirer; |
||||||
|
|
||||||
|
import com.fr.base.j2v8.J2V8Utils; |
||||||
|
import com.fr.decision.update.agent.EmbedConfigAcquirer; |
||||||
|
import com.fr.decision.update.agent.V8ConfigAcquirer; |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置读取器AcquirerSelector |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/4/24 |
||||||
|
*/ |
||||||
|
public class AcquirerSelector { |
||||||
|
|
||||||
|
public static final boolean SUPPORT_J2V8 = J2V8Utils.SUPPORT_J2V8; |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据情况选择不同的配置读取器 |
||||||
|
* |
||||||
|
* @return 配置读取器 |
||||||
|
*/ |
||||||
|
public static Acquirer select() { |
||||||
|
return J2V8Utils.SUPPORT_J2V8 ? new V8ConfigAcquirer() : new EmbedConfigAcquirer(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.fr.decision.update.acquirer; |
||||||
|
|
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.general.http.HttpToolbox; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.EncodeConstants; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* JSEngine |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class JSEngine { |
||||||
|
|
||||||
|
private static final JSEngine engine = new JSEngine(); |
||||||
|
|
||||||
|
private JSEngine() {} |
||||||
|
|
||||||
|
public static JSEngine getEngine() { |
||||||
|
return engine; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取JS引擎名称. |
||||||
|
* |
||||||
|
* @return JS引擎名称 |
||||||
|
*/ |
||||||
|
public static String getEngineName() { |
||||||
|
return AcquirerSelector.select().getName(); |
||||||
|
} |
||||||
|
|
||||||
|
public FinallyObject executeJS(String url) { |
||||||
|
try { |
||||||
|
Acquirer acquirer = AcquirerSelector.select(); |
||||||
|
acquirer.prepare(); |
||||||
|
InputStream in = HttpToolbox.download(url); |
||||||
|
String script = IOUtils.inputStream2String(in, EncodeConstants.ENCODING_UTF_8); |
||||||
|
FinallyObject finallyObject = null; |
||||||
|
try { |
||||||
|
finallyObject = acquirer.execute(script); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e,e.getMessage()); |
||||||
|
} |
||||||
|
return finallyObject; |
||||||
|
} catch (IOException e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
package com.fr.decision.update.acquirer; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 存储后台使用的JS引擎信息. |
||||||
|
* |
||||||
|
* @author Cloud.Liu |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2020/12/15 |
||||||
|
*/ |
||||||
|
public class JSEngineInfo { |
||||||
|
|
||||||
|
/** |
||||||
|
* JS引擎信息. |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* key: 模块<br> |
||||||
|
* value: 引擎名称 |
||||||
|
* </p> |
||||||
|
*/ |
||||||
|
private static final Map<String, String> INFO_MAP = new HashMap<>(); |
||||||
|
|
||||||
|
static { |
||||||
|
// 注册平台使用的JS引擎信息
|
||||||
|
registerJSEngineInfo("decision", JSEngine.getEngineName()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 注册JS引擎信息. |
||||||
|
* |
||||||
|
* @param module 模块名称 |
||||||
|
* @param engine 引擎名称 |
||||||
|
*/ |
||||||
|
public static void registerJSEngineInfo(String module, String engine) { |
||||||
|
INFO_MAP.put(module, engine); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取JS引擎信息. |
||||||
|
* |
||||||
|
* @return JS引擎信息 |
||||||
|
*/ |
||||||
|
public static Map<String, String> getInfoMap() { |
||||||
|
return Collections.unmodifiableMap(INFO_MAP); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
package com.fr.decision.update.agent; |
||||||
|
|
||||||
|
import com.fr.decision.update.acquirer.AbstractAcquirer; |
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
import com.fr.decision.update.script.Files; |
||||||
|
import com.fr.json.JSON; |
||||||
|
import com.fr.json.JSONArray; |
||||||
|
import com.fr.json.JSONFactory; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.script.Console; |
||||||
|
import com.fr.script.ScriptFactory; |
||||||
|
|
||||||
|
import javax.script.ScriptEngine; |
||||||
|
import javax.script.ScriptException; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* EmbedConfigAcquirer |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/4/24 |
||||||
|
*/ |
||||||
|
public class EmbedConfigAcquirer extends AbstractAcquirer { |
||||||
|
|
||||||
|
/** |
||||||
|
* 引擎名称. |
||||||
|
*/ |
||||||
|
public static final String ENGINE_NAME = "nashorn"; |
||||||
|
|
||||||
|
private ScriptEngine scriptEngine = null; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void prepare() { |
||||||
|
scriptEngine = ScriptFactory.newScriptEngine(); |
||||||
|
scriptEngine.put("console", new Console()); |
||||||
|
scriptEngine.put("files", new Files()); |
||||||
|
Map<String, String> globalVariables = normalProperties(); |
||||||
|
for (Map.Entry<String, String> entry : globalVariables.entrySet()) { |
||||||
|
scriptEngine.put(entry.getKey(), entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public FinallyObject execute(String script) throws IllegalStateException { |
||||||
|
try { |
||||||
|
FinallyObject finallyObject = FinallyObject.create(); |
||||||
|
JSONObject jsonObject = JSONFactory.createJSON(JSON.OBJECT, (String) scriptEngine.eval(script)); |
||||||
|
JSONObject jo; |
||||||
|
JSONArray array; |
||||||
|
|
||||||
|
array = jsonObject.getJSONArray(OPERATE_ADD); |
||||||
|
if (array != null) { |
||||||
|
for (int i=0; i<array.length(); i++) { |
||||||
|
jo = array.getJSONObject(i); |
||||||
|
finallyObject.registerAdd(jo.getString(TYPE_SOURCE),jo.getString(TYPE_TARGET)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
array = jsonObject.getJSONArray(OPERATE_MODIFY); |
||||||
|
if (array != null) { |
||||||
|
for (int i=0; i<array.length(); i++) { |
||||||
|
jo = array.getJSONObject(i); |
||||||
|
finallyObject.registerModify(jo.getString(TYPE_SOURCE),jo.getString(TYPE_TARGET)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
array = jsonObject.getJSONArray(OPERATE_DELETE); |
||||||
|
if (array != null) { |
||||||
|
for (int i=0; i<array.length(); i++) { |
||||||
|
finallyObject.registerDelete(array.getString(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
return finallyObject; |
||||||
|
} catch (ScriptException e) { |
||||||
|
throw new IllegalStateException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getName() { |
||||||
|
return ENGINE_NAME; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,107 @@ |
|||||||
|
package com.fr.decision.update.agent; |
||||||
|
|
||||||
|
import com.eclipsesource.v8.V8; |
||||||
|
import com.eclipsesource.v8.V8Array; |
||||||
|
import com.eclipsesource.v8.V8Object; |
||||||
|
import com.fr.decision.update.acquirer.AbstractAcquirer; |
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
import com.fr.decision.update.script.Files; |
||||||
|
import com.fr.general.GeneralUtils; |
||||||
|
import com.fr.script.Console; |
||||||
|
import com.fr.script.InvokeUtils; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* v8 实现 |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @version 10.0 |
||||||
|
* Created by richie on 2019-04-24 |
||||||
|
*/ |
||||||
|
public class V8ConfigAcquirer extends AbstractAcquirer { |
||||||
|
|
||||||
|
/** |
||||||
|
* 引擎名称. |
||||||
|
*/ |
||||||
|
public static final String ENGINE_NAME = "j2v8"; |
||||||
|
|
||||||
|
private V8 v8 = V8.createV8Runtime(); |
||||||
|
|
||||||
|
public void prepare() { |
||||||
|
v8.registerJavaMethod((v8Object, v8Array) -> { |
||||||
|
String className = v8Array.getString(0); |
||||||
|
try { |
||||||
|
GeneralUtils.classForName(className); |
||||||
|
return true; |
||||||
|
} catch (ClassNotFoundException | NoClassDefFoundError e) { |
||||||
|
return false; |
||||||
|
} finally { |
||||||
|
v8Array.release(); |
||||||
|
} |
||||||
|
}, "loadClass"); |
||||||
|
V8Object v8Console = new V8Object(v8); |
||||||
|
v8.add("console", v8Console); |
||||||
|
Console console = new Console(); |
||||||
|
InvokeUtils.registerJavaMethods(v8Console, console); |
||||||
|
v8Console.release(); |
||||||
|
V8Object v8Files = new V8Object(v8); |
||||||
|
v8.add("Files", v8Files); |
||||||
|
Files files = new Files(); |
||||||
|
InvokeUtils.registerJavaMethods(v8Files, files); |
||||||
|
v8Files.release(); |
||||||
|
Map<String, String> map = normalProperties(); |
||||||
|
for (Map.Entry<String, String> entry : map.entrySet()) { |
||||||
|
v8.add(entry.getKey(), entry.getValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public FinallyObject execute(String config) throws IllegalStateException { |
||||||
|
|
||||||
|
FinallyObject finallyObject = FinallyObject.create(); |
||||||
|
|
||||||
|
try { |
||||||
|
|
||||||
|
V8Object returnV8Object = v8.executeObjectScript(config); |
||||||
|
|
||||||
|
V8Array addArray = returnV8Object.getArray(OPERATE_ADD); |
||||||
|
if (!addArray.isUndefined()) { |
||||||
|
for (int i = 0, len = addArray.length(); i < len; i++) { |
||||||
|
V8Object addObject = addArray.getObject(i); |
||||||
|
finallyObject.registerAdd(addObject.getString(TYPE_SOURCE), addObject.getString(TYPE_TARGET)); |
||||||
|
addObject.release(); |
||||||
|
} |
||||||
|
addArray.release(); |
||||||
|
} |
||||||
|
|
||||||
|
V8Array deleteArray = returnV8Object.getArray(OPERATE_DELETE); |
||||||
|
if (!deleteArray.isUndefined()) { |
||||||
|
for (int i = 0, len = deleteArray.length(); i < len; i++) { |
||||||
|
finallyObject.registerDelete(deleteArray.getString(i)); |
||||||
|
} |
||||||
|
deleteArray.release(); |
||||||
|
} |
||||||
|
|
||||||
|
V8Array modifyArray = returnV8Object.getArray(OPERATE_MODIFY); |
||||||
|
if (!modifyArray.isUndefined()) { |
||||||
|
for (int i = 0, len = modifyArray.length(); i < len; i++) { |
||||||
|
V8Object modifyObject = modifyArray.getObject(i); |
||||||
|
finallyObject.registerModify(modifyObject.getString(TYPE_SOURCE), modifyObject.getString(TYPE_TARGET)); |
||||||
|
modifyObject.release(); |
||||||
|
} |
||||||
|
modifyArray.release(); |
||||||
|
} |
||||||
|
returnV8Object.release(); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new IllegalStateException(e); |
||||||
|
} finally { |
||||||
|
v8.release(true); |
||||||
|
} |
||||||
|
return finallyObject; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getName() { |
||||||
|
return ENGINE_NAME; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package com.fr.decision.update.backup; |
||||||
|
|
||||||
|
/** |
||||||
|
* 恢复备份接口 |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public interface Recover { |
||||||
|
//恢复
|
||||||
|
boolean recover(); |
||||||
|
//备份
|
||||||
|
boolean backup(); |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.fr.decision.update.backup; |
||||||
|
|
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.io.utils.ResourceIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.ProjectLibrary; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* RecoverForCommon |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class RecoverForCommon implements Recover { |
||||||
|
|
||||||
|
private String envHome; |
||||||
|
|
||||||
|
RecoverForCommon() { |
||||||
|
this.envHome = ProjectLibrary.getInstance().getLibHome(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean recover() { |
||||||
|
try{ |
||||||
|
//当出现一些奇怪的问题时,从备份的jar中还原所有jar
|
||||||
|
CommonIOUtils.copyFilesInDirByPath(StableUtils.pathJoin(envHome,ProjectConstants.ASSIST_NAME,UpdateConstants.ENV_LIB,UpdateConstants.BACKUPPATH), |
||||||
|
StableUtils.pathJoin(envHome,ProjectConstants.LIB_NAME)); |
||||||
|
FineLoggerFactory.getLogger().error("Recover down for common"); |
||||||
|
return true; |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage() , "Recover error for common", e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean backup() { |
||||||
|
try { |
||||||
|
String envLib = StableUtils.pathJoin(ProjectConstants.ASSIST_NAME, UpdateConstants.ENV_LIB); |
||||||
|
if (ResourceIOUtils.isDirectoryExist(envLib)) { |
||||||
|
ResourceIOUtils.delete(envLib); |
||||||
|
} |
||||||
|
ResourceIOUtils.createDirectory(envLib); |
||||||
|
ResourceIOUtils.createDirectory(StableUtils.pathJoin(envLib, UpdateConstants.DOWNLOADPATH)); |
||||||
|
//更新之前先备份原来的jar包(设计器与平台公用的lib)
|
||||||
|
ResourceIOUtils.copy(ProjectConstants.LIB_NAME, StableUtils.pathJoin(envLib, UpdateConstants.BACKUPPATH)); |
||||||
|
FineLoggerFactory.getLogger().error("Backup down for common yes"); |
||||||
|
return true; |
||||||
|
} catch (IOException e) { |
||||||
|
UpdateException exception = new UpdateException("BackUp Exception " + e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
package com.fr.decision.update.backup; |
||||||
|
|
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.ProjectLibrary; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* RecoverForSync |
||||||
|
* |
||||||
|
* @author pengda |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2021/6/02 |
||||||
|
*/ |
||||||
|
public class RecoverForSync implements Recover { |
||||||
|
private static final RecoverForSync recoverForSync = new RecoverForSync(); |
||||||
|
private String envHome; |
||||||
|
|
||||||
|
private RecoverForSync() { |
||||||
|
this.envHome = ProjectLibrary.getInstance().getLibHome(); |
||||||
|
} |
||||||
|
|
||||||
|
public static Recover getInstance() { |
||||||
|
return recoverForSync; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean recover() { |
||||||
|
try{ |
||||||
|
//当出现一些奇怪的问题时,从备份的jar中还原所有jar
|
||||||
|
CommonIOUtils.copyFilesInDirByPath(StableUtils.pathJoin(envHome, ProjectConstants.ASSIST_NAME, UpdateConstants.ENV_LIB,UpdateConstants.BACKUPPATH), |
||||||
|
StableUtils.pathJoin(envHome,ProjectConstants.LIB_NAME)); |
||||||
|
FineLoggerFactory.getLogger().error("Recover down for sync"); |
||||||
|
return true; |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage() , "Recover error for sync", e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean backup() { |
||||||
|
try { |
||||||
|
String envLib = StableUtils.pathJoin(envHome,ProjectConstants.ASSIST_NAME, UpdateConstants.ENV_LIB); |
||||||
|
File file = new File(envLib); |
||||||
|
if(file.exists()){ |
||||||
|
CommonIOUtils.deleteFile(file); |
||||||
|
} |
||||||
|
CommonIOUtils.copyFilesInDirByPath(StableUtils.pathJoin(envHome,ProjectConstants.LIB_NAME),StableUtils.pathJoin(envLib, UpdateConstants.BACKUPPATH)); |
||||||
|
FineLoggerFactory.getLogger().error("Backup down for Sync yes"); |
||||||
|
return true; |
||||||
|
} catch (IOException e) { |
||||||
|
UpdateException exception = new UpdateException("BackUp Exception " + e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.fr.decision.update.backup; |
||||||
|
/** |
||||||
|
* RecoverHandler |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class RecoverHandler implements Recover { |
||||||
|
|
||||||
|
private static final RecoverHandler recoverHandler = new RecoverHandler(); |
||||||
|
private Recover recoverManager; |
||||||
|
|
||||||
|
private RecoverHandler() { |
||||||
|
this.recoverManager = RecoverManager.getInstance(); |
||||||
|
RecoverManager.register(new RecoverForCommon()); |
||||||
|
} |
||||||
|
|
||||||
|
public static Recover getInstance() { |
||||||
|
// 不支持集群,设计器自用
|
||||||
|
return recoverHandler; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean recover() { |
||||||
|
return recoverManager.recover(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean backup() { |
||||||
|
return recoverManager.backup(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
package com.fr.decision.update.backup; |
||||||
|
|
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* RecoverManager |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class RecoverManager implements Recover { |
||||||
|
|
||||||
|
private static final Recover INSTANCE = new RecoverManager(); |
||||||
|
|
||||||
|
private RecoverManager() {} |
||||||
|
|
||||||
|
public static Recover getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
private static final List<Recover> recovers = new ArrayList<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 注册 |
||||||
|
*/ |
||||||
|
public static void register(Recover recover) { |
||||||
|
if (recover != null) { |
||||||
|
recovers.add(recover); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 清理 |
||||||
|
*/ |
||||||
|
public static void clear() { |
||||||
|
recovers.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean recover() { |
||||||
|
try { |
||||||
|
for (Recover recover : recovers) { |
||||||
|
if (!recover.recover()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error("recover in RecoverManager failed"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean backup() { |
||||||
|
try { |
||||||
|
for (Recover recover : recovers) { |
||||||
|
if (!recover.backup()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage() + "backup in RecoverManager failed"); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
package com.fr.decision.update.command; |
||||||
|
|
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
|
||||||
|
/** |
||||||
|
* Command |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public interface Command { |
||||||
|
|
||||||
|
//空的command,赋值失败 & 初始化时候使用,command异常时候execute无操作
|
||||||
|
Command EMPTY = new Command() { |
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
boolean execute(UpdateCallBack callBack); |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
package com.fr.decision.update.command; |
||||||
|
|
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.impl.AddCommand; |
||||||
|
import com.fr.decision.update.impl.RemoveCommand; |
||||||
|
import com.fr.decision.update.impl.delete.DeleteJars; |
||||||
|
import com.fr.decision.update.impl.delete.DeleteOtherFiles; |
||||||
|
import com.fr.decision.update.info.UpdateProcessBean; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* CommandFactory |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class CommandFactory { |
||||||
|
|
||||||
|
private CommandFactory() { |
||||||
|
} |
||||||
|
|
||||||
|
public static Command build(FinallyObject finallyObject) { |
||||||
|
UpdateProcessBean bean = new UpdateProcessBean(); |
||||||
|
List<Command> commandList = new ArrayList<>(); |
||||||
|
CommandGroup commands = new CommandGroup(commandList); |
||||||
|
//下载文件
|
||||||
|
if (finallyObject.getItemsForAdd() != null) { |
||||||
|
int length = finallyObject.getItemsForAdd().length; |
||||||
|
bean.setTotalFiles(length); |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
Command command = new AddCommand(finallyObject.getItemsForAdd()[i].getSource(), finallyObject.getItemsForAdd()[i].getTarget(), bean); |
||||||
|
commands.addCommands(command); |
||||||
|
} |
||||||
|
} |
||||||
|
//操作文件
|
||||||
|
if (finallyObject.getItemsForModify() != null) { |
||||||
|
int length = finallyObject.getItemsForModify().length; |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
Command command = new RemoveCommand(finallyObject.getItemsForModify()[i].getSource(), finallyObject.getItemsForModify()[i].getTarget()); |
||||||
|
commands.addCommands(command); |
||||||
|
} |
||||||
|
} |
||||||
|
//删除文件
|
||||||
|
if (finallyObject.getFilesForDelete() != null) { |
||||||
|
String[] fileList = finallyObject.getFilesForDelete(); |
||||||
|
for (String file : fileList) { |
||||||
|
commands.addCommands(buildDeleteCommand(file)); |
||||||
|
} |
||||||
|
} |
||||||
|
return commands; |
||||||
|
} |
||||||
|
|
||||||
|
private static Command buildDeleteCommand(String file) { |
||||||
|
Command command = Command.EMPTY; |
||||||
|
try { |
||||||
|
if (file.endsWith(UpdateConstants.JAR_FILE_SUFFIX)) { |
||||||
|
command = new DeleteJars(file); |
||||||
|
} else { |
||||||
|
command = new DeleteOtherFiles(file); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage() + "get file postfix error"); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
} |
||||||
|
|
||||||
|
return command; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package com.fr.decision.update.command; |
||||||
|
|
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* CommandGroup |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class CommandGroup implements Command{ |
||||||
|
|
||||||
|
private List<Command> commands; |
||||||
|
|
||||||
|
public CommandGroup(List<Command> commands) { |
||||||
|
this.commands = commands; |
||||||
|
} |
||||||
|
|
||||||
|
public void addCommands(Command command) { |
||||||
|
commands.add(command); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
try { |
||||||
|
for (Command command : commands) { |
||||||
|
if (!command.execute(callBack)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage() + "execute error in group"); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
package com.fr.decision.update.command; |
||||||
|
|
||||||
|
import com.fr.decision.update.acquirer.JSEngine; |
||||||
|
import com.fr.decision.update.config.UpdateConfigFactory; |
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* CommandHandler |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class CommandHandler implements Command { |
||||||
|
|
||||||
|
private String yunURL; |
||||||
|
|
||||||
|
private static final CommandHandler commandHandler = new CommandHandler(); |
||||||
|
|
||||||
|
private CommandHandler(){} |
||||||
|
|
||||||
|
public static Command getInstance() { |
||||||
|
// 不支持集群,设计器自用
|
||||||
|
return commandHandler; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
if (checkUpdate()) { |
||||||
|
return update(callBack); |
||||||
|
} else { |
||||||
|
FineLoggerFactory.getLogger().info("Not need to update"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查是否需要更新 |
||||||
|
*/ |
||||||
|
private boolean checkUpdate() { |
||||||
|
try { |
||||||
|
yunURL = UpdateConfigFactory.get().getJsUpdateUrl(); |
||||||
|
return yunURL != null && !yunURL.equals(StringUtils.EMPTY); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 进行更新 |
||||||
|
*/ |
||||||
|
private boolean update(UpdateCallBack callBack) { |
||||||
|
FinallyObject finallyObject = JSEngine.getEngine().executeJS(yunURL); |
||||||
|
//增删改在备份之后执行
|
||||||
|
if (finallyObject != null) { |
||||||
|
Command command = CommandFactory.build(finallyObject); |
||||||
|
return command.execute(callBack); |
||||||
|
} else { |
||||||
|
UpdateException exception = new UpdateException("finallyObject can not be null"); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), exception); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,162 @@ |
|||||||
|
package com.fr.decision.update.command; |
||||||
|
|
||||||
|
import com.fr.decision.update.acquirer.JSEngine; |
||||||
|
import com.fr.decision.update.data.FinallyObject; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.file.FileCommonUtils; |
||||||
|
import com.fr.general.CloudCenter; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.CommonUtils; |
||||||
|
import com.fr.stable.ProjectLibrary; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.text.ParsePosition; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* SyncCommandHandler |
||||||
|
* |
||||||
|
* @author pengda |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2021/6/02 |
||||||
|
*/ |
||||||
|
public class SyncCommandHandler { |
||||||
|
|
||||||
|
private String jsURL; |
||||||
|
private String branchTime; |
||||||
|
private String HYPHEN = "-"; |
||||||
|
private String localJarsDirName = null; |
||||||
|
|
||||||
|
private static final SyncCommandHandler syncCommandHandler = new SyncCommandHandler(); |
||||||
|
|
||||||
|
private SyncCommandHandler() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取单例 |
||||||
|
*/ |
||||||
|
public static SyncCommandHandler getInstance() { |
||||||
|
return syncCommandHandler; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 执行 |
||||||
|
*/ |
||||||
|
public boolean execute(UpdateCallBack callBack, String fullBuildNo) { |
||||||
|
branchTime = formatBranch(fullBuildNo); |
||||||
|
if (checkLocalJars(fullBuildNo) || checkSync()) { |
||||||
|
return syncJars(callBack); |
||||||
|
} else { |
||||||
|
FineLoggerFactory.getLogger().info("The condition of syncJars is not satisfied"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean checkSync() { |
||||||
|
try { |
||||||
|
jsURL = CloudCenter.getInstance().acquireUrlByKind("js11.sync"); |
||||||
|
return jsURL != null && !jsURL.equals(StringUtils.EMPTY); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean checkLocalJars(String fullBuildNo) { |
||||||
|
try { |
||||||
|
localJarsDirName = null; |
||||||
|
File backupDir = new File(CommonUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR)); |
||||||
|
StableUtils.mkdirs(backupDir); |
||||||
|
File[] versions = backupDir.listFiles(); |
||||||
|
if (versions != null) { |
||||||
|
for (File version : versions) { |
||||||
|
String libName = version.getName(); |
||||||
|
if (ComparatorUtils.equals(libName.substring(libName.lastIndexOf(HYPHEN) + 1), fullBuildNo.substring(fullBuildNo.lastIndexOf("-") + 1))) { |
||||||
|
File[] designerJars = new File(CommonUtils.pathJoin(FileCommonUtils.getAbsolutePath(version), UpdateConstants.DESIGNERBACKUPPATH)).listFiles(); |
||||||
|
File[] oldJars = new File(CommonUtils.pathJoin(FileCommonUtils.getAbsolutePath(version), UpdateConstants.BACKUPPATH)).listFiles(); |
||||||
|
if (designerJars != null && oldJars != null) { |
||||||
|
boolean result = designerJars.length > 0 && oldJars.length > 0; |
||||||
|
if (result) { |
||||||
|
localJarsDirName = version.getName(); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean syncJars(UpdateCallBack callBack) { |
||||||
|
FinallyObject finallyObject; |
||||||
|
if (localJarsDirName != null) { |
||||||
|
finallyObject = createLocalJarsFinallyObject(); |
||||||
|
} else { |
||||||
|
finallyObject = JSEngine.getEngine().executeJS(jsURL); |
||||||
|
} |
||||||
|
//增删改在备份之后执行
|
||||||
|
if (finallyObject != null) { |
||||||
|
Command command = CommandFactory.build(finallyObject); |
||||||
|
return command.execute(callBack); |
||||||
|
} else { |
||||||
|
FineLoggerFactory.getLogger().error("sync error : finallyObject can not be null"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private FinallyObject createLocalJarsFinallyObject() { |
||||||
|
FinallyObject finallyObject = FinallyObject.create(); |
||||||
|
File[] designerJars = new File(CommonUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR, localJarsDirName, UpdateConstants.DESIGNERBACKUPPATH)).listFiles(); |
||||||
|
File[] oldJars = new File(CommonUtils.pathJoin(StableUtils.getInstallHome(), UpdateConstants.DESIGNER_BACKUP_DIR, localJarsDirName, UpdateConstants.BACKUPPATH)).listFiles(); |
||||||
|
if (null == designerJars || null == oldJars) { |
||||||
|
return finallyObject; |
||||||
|
} |
||||||
|
String envLibPath = CommonUtils.pathJoin(ProjectLibrary.getInstance().getLibHome(), ProjectConstants.LIB_NAME); |
||||||
|
File file = new File(envLibPath); |
||||||
|
File[] files = file.listFiles(); |
||||||
|
Set<String> fileSet = new HashSet<>(); |
||||||
|
if (files != null) { |
||||||
|
for (File file1 : files) { |
||||||
|
if (file1.getName().startsWith(UpdateConstants.FINE) && file1.getName().endsWith(UpdateConstants.JAR_FILE_SUFFIX)) { |
||||||
|
fileSet.add(file1.getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
for (File designerJar : designerJars) { |
||||||
|
finallyObject.registerModify(FileCommonUtils.getAbsolutePath(designerJar), CommonUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LIB_NAME)); |
||||||
|
} |
||||||
|
for (File oldJar : oldJars) { |
||||||
|
finallyObject.registerModify(FileCommonUtils.getAbsolutePath(oldJar), envLibPath); |
||||||
|
fileSet.remove(oldJar.getName()); |
||||||
|
} |
||||||
|
for (String fileName : fileSet) { |
||||||
|
finallyObject.registerDelete(CommonUtils.pathJoin(envLibPath, fileName)); |
||||||
|
} |
||||||
|
return finallyObject; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取分支时间 |
||||||
|
*/ |
||||||
|
public String getBranchTime(){ |
||||||
|
return branchTime; |
||||||
|
} |
||||||
|
|
||||||
|
private String formatBranch(String buildNO) { |
||||||
|
Date jarDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(buildNO, new ParsePosition(buildNO.indexOf("-") + 1)); |
||||||
|
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); |
||||||
|
return df.format(jarDate); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package com.fr.decision.update.config; |
||||||
|
|
||||||
|
import com.fr.general.CloudCenter; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* AbstractUpdateConfig |
||||||
|
* |
||||||
|
* @author Smile.Chen |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2022/9/9 |
||||||
|
*/ |
||||||
|
public abstract class AbstractUpdateConfig implements UpdateConfig { |
||||||
|
@Override |
||||||
|
public String getUpdateUrl() { |
||||||
|
return CloudCenter.getInstance().acquireUrlByKind(getUpdateKey()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getVersionUrl() { |
||||||
|
return CloudCenter.getInstance().acquireUrlByKind(getVersionKey()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJsUpdateUrl() { |
||||||
|
return CloudCenter.getInstance().acquireUrlByKind(getJsUpdateKey()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getChangeLogUrl() { |
||||||
|
return CloudCenter.getInstance().acquireUrlByKind(getChangeLogKey()); |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract String getUpdateKey(); |
||||||
|
|
||||||
|
protected abstract String getVersionKey(); |
||||||
|
|
||||||
|
protected abstract String getJsUpdateKey(); |
||||||
|
|
||||||
|
protected abstract String getChangeLogKey(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] getLogTypeWhiteList() { |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] getProjectValues() { |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package com.fr.decision.update.config; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateConfig |
||||||
|
* |
||||||
|
* @author Smile.Chen |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2022/9/20 |
||||||
|
*/ |
||||||
|
public interface UpdateConfig { |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回更新信息URL |
||||||
|
*/ |
||||||
|
String getUpdateUrl(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回版本信息URL,接口中包含小版本 |
||||||
|
*/ |
||||||
|
String getVersionUrl(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回js更新脚本的URL。 |
||||||
|
*/ |
||||||
|
String getJsUpdateUrl(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回更新日志URL |
||||||
|
*/ |
||||||
|
String getChangeLogUrl(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 白名单,title会从这个String[]中匹配是否包含其中一个关键字,如果包含则展示 |
||||||
|
*/ |
||||||
|
String[] getLogTypeWhiteList(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 需要获取日志的模块 |
||||||
|
*/ |
||||||
|
String[] getProjectValues(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package com.fr.decision.update.config; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateConfig |
||||||
|
* |
||||||
|
* @author Smile.Chen |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2022/9/20 |
||||||
|
*/ |
||||||
|
public class UpdateConfigFactory { |
||||||
|
|
||||||
|
private static volatile UpdateConfig UPDATE_CONFIG_INFO = null; |
||||||
|
|
||||||
|
public static UpdateConfig get() { |
||||||
|
if (UPDATE_CONFIG_INFO == null) { |
||||||
|
synchronized (UpdateConfigFactory.class) { |
||||||
|
if (UPDATE_CONFIG_INFO == null) { |
||||||
|
UPDATE_CONFIG_INFO = new UpdateConfigInfo(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return UPDATE_CONFIG_INFO; |
||||||
|
} |
||||||
|
|
||||||
|
public synchronized static void setUpdateConfigInfo(UpdateConfig configInfo) { |
||||||
|
UPDATE_CONFIG_INFO = configInfo; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package com.fr.decision.update.config; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateConfig |
||||||
|
* |
||||||
|
* @author Smile.Chen |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2022/9/20 |
||||||
|
*/ |
||||||
|
public class UpdateConfigInfo extends AbstractUpdateConfig { |
||||||
|
|
||||||
|
//包含更新信息
|
||||||
|
public static final String JAR11_UPDATE = "jar11.update"; |
||||||
|
//包含小版本信息
|
||||||
|
public static final String JAR11_VERSION = "jar11.version"; |
||||||
|
public static final String JS11_UPDATE = "js11.update"; |
||||||
|
public static final String CHANGE_LOG = "changelog10"; |
||||||
|
|
||||||
|
//更新日志显示白名单
|
||||||
|
private static final String[] LOG_TYPE_WHITELIST = new String[]{ |
||||||
|
"DEC", "REPORT", "MOBILE", "DESIGN", "CHART" |
||||||
|
}; |
||||||
|
//日志路由project参数值
|
||||||
|
private static final String[] PROJECT_VALUES = new String[]{ |
||||||
|
"DEC", "REPORT", "VISUAL", "CORE", "DB", "CRON", "CHART", "DESIGN" |
||||||
|
}; |
||||||
|
|
||||||
|
protected String getUpdateKey() { |
||||||
|
return JAR11_UPDATE; |
||||||
|
} |
||||||
|
|
||||||
|
protected String getVersionKey() { |
||||||
|
return JAR11_VERSION; |
||||||
|
} |
||||||
|
|
||||||
|
protected String getJsUpdateKey() { |
||||||
|
return JS11_UPDATE; |
||||||
|
} |
||||||
|
|
||||||
|
protected String getChangeLogKey() { |
||||||
|
return CHANGE_LOG; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] getLogTypeWhiteList() { |
||||||
|
return LOG_TYPE_WHITELIST; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String[] getProjectValues() { |
||||||
|
return PROJECT_VALUES; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
package com.fr.decision.update.data; |
||||||
|
|
||||||
|
import com.fr.stable.AssistUtils; |
||||||
|
|
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Set; |
||||||
|
/** |
||||||
|
* FinallyObject |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/4/24 |
||||||
|
*/ |
||||||
|
public class FinallyObject { |
||||||
|
|
||||||
|
public static FinallyObject create() { |
||||||
|
return new FinallyObject(); |
||||||
|
} |
||||||
|
|
||||||
|
private Set<Item> waitingForAdd = new HashSet<Item>(); |
||||||
|
|
||||||
|
private Set<String> waitingForDelete = new HashSet<String>(); |
||||||
|
|
||||||
|
private Set<Item> waitingForModify = new HashSet<Item>(); |
||||||
|
|
||||||
|
private FinallyObject() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void registerAdd(String source, String target) { |
||||||
|
waitingForAdd.add(new Item(source, target)); |
||||||
|
} |
||||||
|
|
||||||
|
public void registerDelete(String path) { |
||||||
|
waitingForDelete.add(path); |
||||||
|
} |
||||||
|
|
||||||
|
public void registerModify(String source, String target) { |
||||||
|
waitingForModify.add(new Item(source, target)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取待添加的条目信息 |
||||||
|
* @return 待添加条目组成的数组 |
||||||
|
*/ |
||||||
|
public Item[] getItemsForAdd() { |
||||||
|
return waitingForAdd.toArray(new Item[0]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取待删除的文件组成的数组 |
||||||
|
* @return 待删除的文件数组 |
||||||
|
*/ |
||||||
|
public String[] getFilesForDelete() { |
||||||
|
return waitingForDelete.toArray(new String[0]); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取待修改的条目信息 |
||||||
|
* @return 待修改的条目组成的数组 |
||||||
|
*/ |
||||||
|
public Item[] getItemsForModify() { |
||||||
|
return waitingForModify.toArray(new Item[0]); |
||||||
|
} |
||||||
|
|
||||||
|
public static final class Item { |
||||||
|
private String source; |
||||||
|
private String target; |
||||||
|
|
||||||
|
public Item(String source, String target) { |
||||||
|
this.source = source; |
||||||
|
this.target = target; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSource() { |
||||||
|
return source; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTarget() { |
||||||
|
return target; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
|
return obj instanceof Item |
||||||
|
&& AssistUtils.equals(source, ((Item) obj).source) |
||||||
|
&& AssistUtils.equals(target, ((Item) obj).target); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
return AssistUtils.hashCode(source, target); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package com.fr.decision.update.data; |
||||||
|
|
||||||
|
import java.awt.*; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateConstants |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public interface UpdateConstants { |
||||||
|
|
||||||
|
String INSTALL_LIB = "installLib"; |
||||||
|
String ENV_LIB = "envLib"; |
||||||
|
String WEBAPPS = "webapps"; |
||||||
|
String ASPECTJRT = "aspectjrt"; |
||||||
|
String FINE = "fine"; |
||||||
|
String UPDATE_SERVICE = "update"; |
||||||
|
String BACKUPPATH = "OldJars"; |
||||||
|
String KB = "KB"; |
||||||
|
String DESIGNERBACKUPPATH = "designerJars"; |
||||||
|
String DESIGNER = "designer"; |
||||||
|
String ARCH_X86 = "x86"; |
||||||
|
String ARCH_X86_64 = "x86_64"; |
||||||
|
String ARM = "ARM"; |
||||||
|
String UNKNOWNOS = "Unknown"; |
||||||
|
String DECISION = "decision"; |
||||||
|
int BYTE = 8192; |
||||||
|
String DOWNLOADPATH = "NewJars"; |
||||||
|
String JAR_FILE_SUFFIX = ".jar"; |
||||||
|
Color BAR_COLOR = new Color(0x3384F0); |
||||||
|
String CHANGELOG_X_START = "2018-07-11"; |
||||||
|
String DEFAULT_APP_NAME = "FineReport"; |
||||||
|
String DESIGNER_BACKUP_DIR = "designerbackup"; |
||||||
|
String UPDATE_CACHE_CONFIG_X = "updateCacheConfig10"; |
||||||
|
String UPDATE_CACHE_INFO_X = "updateCacheInfo10"; |
||||||
|
String J2V8 = "v8"; |
||||||
|
String NASHORN = "nashorn"; |
||||||
|
List<String> LOG_TYPE = Collections.unmodifiableList(Arrays.asList(new String[]{ |
||||||
|
"REPORT", "MOBILE", "CHART", "PFC", "BI" |
||||||
|
})); |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.fr.decision.update.exception; |
||||||
|
|
||||||
|
import com.fr.intelligence.IntelligenceException; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateException |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class UpdateException extends IntelligenceException { |
||||||
|
|
||||||
|
private String errorMessage; |
||||||
|
|
||||||
|
public UpdateException(String errorMessage) { |
||||||
|
super(errorMessage); |
||||||
|
this.errorMessage = errorCode() + errorMessage; |
||||||
|
} |
||||||
|
|
||||||
|
public String getErrorMessage() { |
||||||
|
return errorMessage; |
||||||
|
} |
||||||
|
|
||||||
|
public void setErrorMessage(String errorMessage) { |
||||||
|
this.errorMessage = errorMessage; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 异常错误码,一般是一串数字,由产品经理确定并提供文档 |
||||||
|
* |
||||||
|
* @return 错误码 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String errorCode() { |
||||||
|
return "21300025 "; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,120 @@ |
|||||||
|
package com.fr.decision.update.impl; |
||||||
|
|
||||||
|
import com.fr.concurrent.NamedThreadFactory; |
||||||
|
import com.fr.decision.update.command.Command; |
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.decision.update.info.UpdateProcessBean; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.general.http.HttpToolbox; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||||
|
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||||
|
import com.fr.third.org.apache.http.client.methods.HttpGet; |
||||||
|
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.concurrent.SynchronousQueue; |
||||||
|
import java.util.concurrent.ThreadPoolExecutor; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* 提交任务 |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class AddCommand implements Command { |
||||||
|
|
||||||
|
private static final int TIME_OUT = 30 * 1000; |
||||||
|
|
||||||
|
private String source; |
||||||
|
private String target; |
||||||
|
private UpdateProcessBean bean; |
||||||
|
|
||||||
|
private final ThreadPoolExecutor updateProgressExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>()); |
||||||
|
|
||||||
|
public AddCommand(String source, String target, UpdateProcessBean bean) { |
||||||
|
this.source = source; |
||||||
|
this.target = target; |
||||||
|
this.bean = bean; |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
private void init() { |
||||||
|
//十几万次提交至状态服务器会有性能问题,因此用异步阻塞队列
|
||||||
|
updateProgressExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy()); |
||||||
|
updateProgressExecutor.setThreadFactory(new NamedThreadFactory("updateProgress", true)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
return downloadFile(source, callBack); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Http请求更新文件 |
||||||
|
* |
||||||
|
* @param urlStr 更新路由 |
||||||
|
* @param callBack 进度条回调 |
||||||
|
*/ |
||||||
|
private boolean downloadFile(String urlStr, UpdateCallBack callBack) { |
||||||
|
FileOutputStream fos = null; |
||||||
|
//http请求
|
||||||
|
CloseableHttpClient httpClient; |
||||||
|
CloseableHttpResponse httpResponse; |
||||||
|
HttpGet httpGet = new HttpGet(urlStr); |
||||||
|
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIME_OUT) |
||||||
|
.setConnectionRequestTimeout(TIME_OUT).setSocketTimeout(TIME_OUT).build(); |
||||||
|
httpGet.setConfig(requestConfig); |
||||||
|
httpClient = HttpToolbox.getHttpClient(urlStr); |
||||||
|
InputStream in = null; |
||||||
|
try { |
||||||
|
httpResponse = httpClient.execute(httpGet); |
||||||
|
if (httpResponse.getStatusLine().getStatusCode() != 200) { |
||||||
|
FineLoggerFactory.getLogger().error("download jar error : no file exists!"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
long totalSize = httpResponse.getEntity().getContentLength(); |
||||||
|
in = httpResponse.getEntity().getContent(); |
||||||
|
//保存文件
|
||||||
|
File saveDir = new File(target); |
||||||
|
StableUtils.makesureFileExist(saveDir); |
||||||
|
String fileName = source.substring(source.lastIndexOf('/') + 1); |
||||||
|
bean.setDownloadedFiles(bean.getDownloadedFiles() + 1); |
||||||
|
bean.setName(fileName); |
||||||
|
bean.setTotalLength((int) totalSize); |
||||||
|
bean.setDownloadLength(0); |
||||||
|
updateProgress(callBack, bean); |
||||||
|
fos = new FileOutputStream(saveDir); |
||||||
|
int bytesRead; |
||||||
|
int totalBytesRead = 0; |
||||||
|
byte[] getData = new byte[UpdateConstants.BYTE]; |
||||||
|
while ((bytesRead = in.read(getData)) != -1) { |
||||||
|
fos.write(getData, 0, bytesRead); |
||||||
|
getData = new byte[UpdateConstants.BYTE]; |
||||||
|
totalBytesRead += bytesRead; |
||||||
|
bean.setDownloadLength(totalBytesRead); |
||||||
|
updateProgress(callBack, bean); |
||||||
|
} |
||||||
|
FineLoggerFactory.getLogger().error("Updating Download " + target); |
||||||
|
return true; |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
} finally { |
||||||
|
CommonIOUtils.close(fos); |
||||||
|
CommonIOUtils.close(in); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private void updateProgress(UpdateCallBack callBack, UpdateProcessBean bean) { |
||||||
|
updateProgressExecutor.submit(() -> callBack.updateProgress(bean)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
package com.fr.decision.update.impl; |
||||||
|
|
||||||
|
import com.fr.decision.update.command.Command; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* RemoveCommand |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class RemoveCommand implements Command { |
||||||
|
|
||||||
|
private String source; |
||||||
|
private String target; |
||||||
|
|
||||||
|
public RemoveCommand(String source, String target) { |
||||||
|
this.source = source; |
||||||
|
this.target = target; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
try { |
||||||
|
File src = new File(source); |
||||||
|
File tar = new File(target); |
||||||
|
if (src.isDirectory()) { |
||||||
|
CommonIOUtils.copyFilesInDirByPath(source,target); |
||||||
|
FineLoggerFactory.getLogger().error("Updating move " + target); |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
IOUtils.copy(src,tar); |
||||||
|
FineLoggerFactory.getLogger().error("Updating move " + target); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
UpdateException exception = new UpdateException("Move files error " + e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
package com.fr.decision.update.impl.delete; |
||||||
|
|
||||||
|
import com.fr.decision.update.command.Command; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.util.jar.JarOutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除Jar包 |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class DeleteJars implements Command { |
||||||
|
|
||||||
|
private String file; |
||||||
|
|
||||||
|
public DeleteJars(String file) { |
||||||
|
this.file = file; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
FileOutputStream oldOutputStream = null; |
||||||
|
JarOutputStream jar = null; |
||||||
|
try { |
||||||
|
File oldFile = new File(file); |
||||||
|
oldOutputStream = new FileOutputStream(oldFile); |
||||||
|
jar = new JarOutputStream(oldOutputStream); |
||||||
|
FineLoggerFactory.getLogger().error("Updating delete jar"); |
||||||
|
return true; |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException("write jar error " + e.getMessage()); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
} finally { |
||||||
|
CommonIOUtils.close(jar); |
||||||
|
CommonIOUtils.close(oldOutputStream); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package com.fr.decision.update.impl.delete; |
||||||
|
|
||||||
|
import com.fr.decision.update.command.Command; |
||||||
|
import com.fr.decision.update.exception.UpdateException; |
||||||
|
import com.fr.decision.update.info.UpdateCallBack; |
||||||
|
import com.fr.general.CommonIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.CommonUtils; |
||||||
|
|
||||||
|
import java.io.BufferedOutputStream; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除其他文件 |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/25 |
||||||
|
*/ |
||||||
|
public class DeleteOtherFiles implements Command { |
||||||
|
|
||||||
|
private String file; |
||||||
|
|
||||||
|
public DeleteOtherFiles(String file) { |
||||||
|
this.file = file; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean execute(UpdateCallBack callBack) { |
||||||
|
FileOutputStream oldOutputStream = null; |
||||||
|
BufferedOutputStream buffer = null; |
||||||
|
try { |
||||||
|
File oldFile = new File(file); |
||||||
|
if (!CommonUtils.deleteFile(oldFile)) { |
||||||
|
oldOutputStream = new FileOutputStream(file); |
||||||
|
buffer = new BufferedOutputStream(oldOutputStream); |
||||||
|
return true; |
||||||
|
} |
||||||
|
FineLoggerFactory.getLogger().error("Updating delete files"); |
||||||
|
return true; |
||||||
|
} catch (Exception e) { |
||||||
|
UpdateException exception = new UpdateException(e.getMessage() + " Delete files Exception"); |
||||||
|
FineLoggerFactory.getLogger().error(exception.getErrorMessage(), e); |
||||||
|
return false; |
||||||
|
}finally { |
||||||
|
CommonIOUtils.close(buffer); |
||||||
|
CommonIOUtils.close(oldOutputStream); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package com.fr.decision.update.info; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateCallBack |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public interface UpdateCallBack { |
||||||
|
/** |
||||||
|
* 更新进度条 |
||||||
|
*/ |
||||||
|
void updateProgress(UpdateProcessBean bean); |
||||||
|
} |
@ -0,0 +1,109 @@ |
|||||||
|
package com.fr.decision.update.info; |
||||||
|
|
||||||
|
import com.fr.decision.update.data.UpdateConstants; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateProcessBean |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class UpdateProcessBean { |
||||||
|
//显示为百分比
|
||||||
|
private static final int PERCENTAGE_RATIO = 100; |
||||||
|
//显示kB
|
||||||
|
private static final int BYTETOKB_RATIO = 1000; |
||||||
|
|
||||||
|
private String name; |
||||||
|
private long size; |
||||||
|
|
||||||
|
private int totalLength; |
||||||
|
private int downloadLength; |
||||||
|
private int downloadedFiles; |
||||||
|
private int totalFiles; |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDownloadedFiles() { |
||||||
|
return downloadedFiles; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDownloadedFiles(int downloadedFiles) { |
||||||
|
this.downloadedFiles = downloadedFiles; |
||||||
|
} |
||||||
|
|
||||||
|
int getTotalFiles() { |
||||||
|
return totalFiles; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTotalFiles(int totalFiles) { |
||||||
|
this.totalFiles = totalFiles; |
||||||
|
} |
||||||
|
|
||||||
|
public long getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSize(long size) { |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTotalLength() { |
||||||
|
return totalLength; |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
String getProgressString() { |
||||||
|
return StableUtils.pathJoin(downloadLength / BYTETOKB_RATIO + UpdateConstants.KB, totalLength / BYTETOKB_RATIO + UpdateConstants.KB); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 转化为字符串 |
||||||
|
* |
||||||
|
* @return 字符串 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "name:" + name + ";download:" + getProgressString(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
|
return obj instanceof UpdateProcessBean |
||||||
|
&& ComparatorUtils.equals(((UpdateProcessBean) obj).name, name); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回一个hash码 |
||||||
|
* |
||||||
|
* @return hash码 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
return name.hashCode(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package com.fr.decision.update.info; |
||||||
|
|
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import javax.swing.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* UpdateProgressCallBack |
||||||
|
* |
||||||
|
* @author Bryant |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/9/20 |
||||||
|
*/ |
||||||
|
public class UpdateProgressCallBack implements UpdateCallBack { |
||||||
|
|
||||||
|
private static JProgressBar bar; |
||||||
|
|
||||||
|
public UpdateProgressCallBack(JProgressBar bar) { |
||||||
|
this.bar = bar; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void updateProgress(UpdateProcessBean bean) { |
||||||
|
bar.setString(bean.getName() + StringUtils.BLANK + bean.getProgressString()); |
||||||
|
bar.setValue(bean.getProgressValue()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
package com.fr.decision.update.operate; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置任务 |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/8/16 |
||||||
|
*/ |
||||||
|
public class AcquirerTask implements Callable<String> { |
||||||
|
|
||||||
|
private String info; |
||||||
|
|
||||||
|
public AcquirerTask(String info) { |
||||||
|
this.info = info; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String call() { |
||||||
|
return info; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
package com.fr.decision.update.script; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.third.guava.hash.Hashing; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 文件工具类 |
||||||
|
* |
||||||
|
* @author richie |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2019/4/24 |
||||||
|
*/ |
||||||
|
public class Files { |
||||||
|
|
||||||
|
public Files() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断一个文件是否存在 |
||||||
|
* @param path 文件路径 |
||||||
|
* @return 文件存在则返回true,否则返回false |
||||||
|
*/ |
||||||
|
public boolean exist(String path) { |
||||||
|
return new File(path).exists(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回文件的md5校验码 |
||||||
|
* @param file 文件路径 |
||||||
|
* @return md5校验码 |
||||||
|
*/ |
||||||
|
public String md5(String file) { |
||||||
|
try { |
||||||
|
return com.fr.third.guava.io.Files.hash(new File(file), Hashing.md5()).toString(); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回文件的sha256校验码 |
||||||
|
* @param file 文件路径 |
||||||
|
* @return sha256校验码 |
||||||
|
*/ |
||||||
|
public String sha256(String file) { |
||||||
|
try { |
||||||
|
return com.fr.third.guava.io.Files.hash(new File(file), Hashing.sha256()).toString(); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,180 @@ |
|||||||
|
package com.fr.design.carton; |
||||||
|
|
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.io.BufferedInputStream; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileInputStream; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.OutputStream; |
||||||
|
import java.nio.charset.Charset; |
||||||
|
import java.util.Enumeration; |
||||||
|
import java.util.zip.ZipEntry; |
||||||
|
import java.util.zip.ZipFile; |
||||||
|
import java.util.zip.ZipOutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* LogZipUtils |
||||||
|
* |
||||||
|
* @author Hoky |
||||||
|
* @since 10.0 |
||||||
|
* Created on 2021/4/28 |
||||||
|
*/ |
||||||
|
public class LogZipUtils { |
||||||
|
private static final int BUFFER_SIZE = 2 * 1024; |
||||||
|
/** |
||||||
|
* 是否保留原来的目录结构 |
||||||
|
* true: 保留目录结构; |
||||||
|
* false: 所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) |
||||||
|
*/ |
||||||
|
private static final boolean KEEP_DIR_STRUCTURE = true; |
||||||
|
public static final String GBK = "GBK"; |
||||||
|
public static final String STRING = "/"; |
||||||
|
public static final String REGEX = "\\*"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 压缩成ZIP |
||||||
|
* |
||||||
|
* @param outPathFile 压缩 文件/文件夹 输出路径+文件名 D:/xx.zip |
||||||
|
* @param isDelSrcFile 只需要压缩文件夹 |
||||||
|
*/ |
||||||
|
public static void compress(File[] sourceFiles, String outPathFile, boolean isDelSrcFile) throws Exception { |
||||||
|
if (sourceFiles.length == 0) { |
||||||
|
throw new NullSuchFileException("Not such zip file"); |
||||||
|
} |
||||||
|
byte[] buf = new byte[BUFFER_SIZE]; |
||||||
|
try (FileOutputStream out = new FileOutputStream(outPathFile); |
||||||
|
ZipOutputStream zos = new ZipOutputStream(out)) { |
||||||
|
for (File sourceFile : sourceFiles) { |
||||||
|
zos.putNextEntry(new ZipEntry(sourceFile.getName())); |
||||||
|
int len; |
||||||
|
InputStream in = new BufferedInputStream(new FileInputStream(sourceFile)); |
||||||
|
while ((len = in.read(buf)) != -1) { |
||||||
|
zos.write(buf, 0, len); |
||||||
|
} |
||||||
|
zos.closeEntry(); |
||||||
|
in.close(); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
throw new Exception("zip error from ZipUtils", e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 递归压缩方法 |
||||||
|
* |
||||||
|
* @param sourceFile 源文件 |
||||||
|
* @param zos zip输出流 |
||||||
|
* @param name 压缩后的名称 |
||||||
|
*/ |
||||||
|
private static void compress(File sourceFile, ZipOutputStream zos, String name) |
||||||
|
throws Exception { |
||||||
|
byte[] buf = new byte[BUFFER_SIZE]; |
||||||
|
if (!sourceFile.isDirectory()) { |
||||||
|
zos.putNextEntry(new ZipEntry(name)); |
||||||
|
int len; |
||||||
|
InputStream in = new BufferedInputStream(new FileInputStream(sourceFile)); |
||||||
|
while ((len = in.read(buf)) != -1) { |
||||||
|
zos.write(buf, 0, len); |
||||||
|
} |
||||||
|
zos.closeEntry(); |
||||||
|
in.close(); |
||||||
|
} else { |
||||||
|
File[] listFiles = sourceFile.listFiles(); |
||||||
|
if (listFiles == null || listFiles.length == 0) { |
||||||
|
if (KEEP_DIR_STRUCTURE) { |
||||||
|
zos.putNextEntry(new ZipEntry(name + STRING)); |
||||||
|
zos.closeEntry(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
for (File file : listFiles) { |
||||||
|
if (KEEP_DIR_STRUCTURE) { |
||||||
|
compress(file, zos, name + STRING + file.getName()); |
||||||
|
} else { |
||||||
|
compress(file, zos, file.getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 解压文件到指定目录 |
||||||
|
* |
||||||
|
* @param zipPath 解压源文件路径 |
||||||
|
* @param descDir 解压目标文件路径 |
||||||
|
*/ |
||||||
|
public static void unCompress(String zipPath, String descDir) throws IOException { |
||||||
|
long start = System.currentTimeMillis(); |
||||||
|
File zipFile = new File(zipPath); |
||||||
|
if (!zipFile.exists()) { |
||||||
|
throw new IOException("zip file not exist."); |
||||||
|
} |
||||||
|
File pathFile = new File(descDir); |
||||||
|
if (!pathFile.exists()) { |
||||||
|
pathFile.mkdirs(); |
||||||
|
} |
||||||
|
try (ZipFile zip = new ZipFile(zipFile, Charset.forName(GBK))) { |
||||||
|
for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) { |
||||||
|
ZipEntry entry = (ZipEntry) entries.nextElement(); |
||||||
|
String zipEntryName = entry.getName(); |
||||||
|
InputStream in = zip.getInputStream(entry); |
||||||
|
String outPath = (descDir + File.separator + zipEntryName).replaceAll(REGEX, STRING); |
||||||
|
// 判断路径是否存在,不存在则创建文件路径
|
||||||
|
File file = new File(outPath.substring(0, outPath.lastIndexOf('/'))); |
||||||
|
if (!file.exists()) { |
||||||
|
file.mkdirs(); |
||||||
|
} |
||||||
|
// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
|
||||||
|
if (new File(outPath).isDirectory()) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
// 输出文件路径信息
|
||||||
|
OutputStream out = new FileOutputStream(outPath); |
||||||
|
byte[] buf1 = new byte[1024]; |
||||||
|
int len; |
||||||
|
while ((len = in.read(buf1)) > 0) { |
||||||
|
out.write(buf1, 0, len); |
||||||
|
} |
||||||
|
in.close(); |
||||||
|
out.close(); |
||||||
|
} |
||||||
|
FineLoggerFactory.getLogger().info("file:{}. zip path:{}. finished. cost time:{}ms. ", zipPath, descDir, System.currentTimeMillis() - start); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
throw new IOException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 删除dir |
||||||
|
*/ |
||||||
|
public static void delDir(String dirPath) throws IOException { |
||||||
|
long start = System.currentTimeMillis(); |
||||||
|
try { |
||||||
|
File dirFile = new File(dirPath); |
||||||
|
if (!dirFile.exists()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (dirFile.isFile()) { |
||||||
|
dirFile.delete(); |
||||||
|
return; |
||||||
|
} |
||||||
|
File[] files = dirFile.listFiles(); |
||||||
|
if (files == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
for (int i = 0; i < files.length; i++) { |
||||||
|
delDir(files[i].toString()); |
||||||
|
} |
||||||
|
dirFile.delete(); |
||||||
|
FineLoggerFactory.getLogger().info("delete file:{}. cost:{}ms. ", dirPath, System.currentTimeMillis() - start); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().info("delete file:{}. exception:{}. cost:{}ms. ", dirPath, e, System.currentTimeMillis() - start); |
||||||
|
throw new IOException("delete file exception."); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.fr.design.carton; |
||||||
|
|
||||||
|
/** |
||||||
|
* NullSuchFileException |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/20 |
||||||
|
*/ |
||||||
|
public class NullSuchFileException extends NullPointerException { |
||||||
|
public NullSuchFileException(String s) { |
||||||
|
super(s); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,200 @@ |
|||||||
|
package com.fr.start.server; |
||||||
|
|
||||||
|
import com.fr.cbb.websocket.core.WebSocketEndpoint; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.module.ModuleRole; |
||||||
|
import com.fr.stable.EncodeConstants; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.third.guava.collect.Sets; |
||||||
|
import com.fr.third.springframework.web.SpringServletContainerInitializer; |
||||||
|
import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import org.apache.catalina.Context; |
||||||
|
import org.apache.catalina.LifecycleException; |
||||||
|
import org.apache.catalina.loader.WebappLoader; |
||||||
|
import org.apache.catalina.startup.Tomcat; |
||||||
|
import org.apache.catalina.webresources.StandardRoot; |
||||||
|
import org.apache.tomcat.websocket.server.WsSci; |
||||||
|
;import java.io.File; |
||||||
|
import java.nio.file.Files; |
||||||
|
import java.nio.file.LinkOption; |
||||||
|
import java.nio.file.Path; |
||||||
|
import java.nio.file.Paths; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Properties; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* 内置服务器工具类 |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/18 |
||||||
|
*/ |
||||||
|
public class DesignEmbedHelper { |
||||||
|
|
||||||
|
private static final String TOMCAT_MAX_HEADER_SIZE = "tomcat-maxHttpHeaderSize"; |
||||||
|
|
||||||
|
private static Tomcat tomcat; |
||||||
|
|
||||||
|
/** |
||||||
|
* 启动tomcat |
||||||
|
*/ |
||||||
|
public static synchronized void start() { |
||||||
|
|
||||||
|
try { |
||||||
|
FineEmbedServerMonitor.getInstance().reset(); |
||||||
|
//初始化tomcat
|
||||||
|
initTomcat(); |
||||||
|
tomcat.start(); |
||||||
|
|
||||||
|
} catch (LifecycleException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} finally { |
||||||
|
FineEmbedServerMonitor.getInstance().setComplete(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 停止tomcat |
||||||
|
*/ |
||||||
|
public static synchronized void stop() { |
||||||
|
|
||||||
|
try { |
||||||
|
stopSpring(); |
||||||
|
stopServerActivator(); |
||||||
|
stopTomcat(); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void initTomcat() { |
||||||
|
|
||||||
|
tomcat = new Tomcat(); |
||||||
|
|
||||||
|
tomcat.setPort(DesignerEnvManager.getEnvManager().getEmbedServerPort()); |
||||||
|
// 设置解码uri使用的字符编码
|
||||||
|
tomcat.getConnector().setURIEncoding(EncodeConstants.ENCODING_UTF_8); |
||||||
|
// 参考 https://jira.atlassian.com/browse/CONFSERVER-57582
|
||||||
|
// https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
|
||||||
|
// 8.5.x 请求参数带特殊字符被tomcat拒绝 []|{}^\`"<>
|
||||||
|
tomcat.getConnector().setProperty("relaxedQueryChars", "[]|{}^\`"<>"); |
||||||
|
setMaxPostSize(); |
||||||
|
setMaxHttpHeaderSize(); |
||||||
|
Paths.get(System.getProperty("user.dir")).getParent().toAbsolutePath().normalize().toString(); |
||||||
|
String docBase = new File(WorkContext.getCurrent().getPath()).getParent(); |
||||||
|
|
||||||
|
//内置的上下文使用工程目录比如webroot
|
||||||
|
String contextPath = "/" + getAppFolderName(); |
||||||
|
final Context context = tomcat.addContext(contextPath, docBase); |
||||||
|
context.setResources(new StandardRoot(context)); |
||||||
|
Tomcat.initWebappDefaults(context); |
||||||
|
//覆盖tomcat的WebAppClassLoader
|
||||||
|
context.setLoader(new FRTomcatLoader()); |
||||||
|
|
||||||
|
|
||||||
|
//直接指定initializer,tomcat就不用再扫描一遍了
|
||||||
|
SpringServletContainerInitializer initializer = new SpringServletContainerInitializer(); |
||||||
|
Set<Class<?>> classes = new HashSet<Class<?>>(); |
||||||
|
classes.add(EmbedWebApplicationInitializer.class); |
||||||
|
context.addServletContainerInitializer(initializer, classes); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取App文件夹名称 |
||||||
|
*/ |
||||||
|
public static String getAppFolderName() { |
||||||
|
String webApplication = new File(WorkContext.getCurrent().getPath()).getParent(); |
||||||
|
return webApplication == null |
||||||
|
? StringUtils.EMPTY |
||||||
|
: new File(webApplication).getName().replaceAll(".war", StringUtils.EMPTY); |
||||||
|
} |
||||||
|
|
||||||
|
// tomcat的maxPostSize会影响到post参数获取,默认2M
|
||||||
|
private static void setMaxPostSize() { |
||||||
|
|
||||||
|
if (System.getProperty("tomcat-maxPostSize") != null) { |
||||||
|
try { |
||||||
|
tomcat.getConnector().setMaxPostSize(Integer.parseInt(System.getProperty("tomcat-maxPostSize"))); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error("maxPostSize error: " + e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void setMaxHttpHeaderSize() { |
||||||
|
String value = System.getProperty(TOMCAT_MAX_HEADER_SIZE); |
||||||
|
if (StringUtils.isNotEmpty(value)) { |
||||||
|
try { |
||||||
|
tomcat.getConnector().setProperty("maxHttpHeaderSize", value); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static String getDocBase() { |
||||||
|
String path = Paths.get(System.getProperty("user.dir")).getParent().toAbsolutePath().normalize().toString(); |
||||||
|
boolean isBuildProject = false; |
||||||
|
String docBase = null; |
||||||
|
Path libPath = Paths.get(path, "lib"); |
||||||
|
Path buildPath = Paths.get(path, "serviceBuild"); |
||||||
|
if (!Files.exists(libPath, new LinkOption[0])) { |
||||||
|
if (Files.exists(buildPath, new LinkOption[0])) { |
||||||
|
isBuildProject = true; |
||||||
|
docBase = buildPath.toAbsolutePath().normalize().toString(); |
||||||
|
} else { |
||||||
|
buildPath = Paths.get(System.getProperty("user.dir"), "build"); |
||||||
|
if (Files.exists(buildPath, new LinkOption[0])) { |
||||||
|
isBuildProject = true; |
||||||
|
String base = buildPath.toAbsolutePath().normalize().toString(); |
||||||
|
docBase = base; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
docBase = libPath.toAbsolutePath().normalize().toString(); |
||||||
|
} |
||||||
|
|
||||||
|
return docBase; |
||||||
|
} |
||||||
|
private static String getContextPath(Properties carinaBootProp) { |
||||||
|
String contextPath = "/webroot"; |
||||||
|
return contextPath; |
||||||
|
} |
||||||
|
private static void stopServerActivator() { |
||||||
|
|
||||||
|
ModuleRole.ServerRoot.stop(); |
||||||
|
} |
||||||
|
|
||||||
|
private static void stopSpring() { |
||||||
|
|
||||||
|
AnnotationConfigWebApplicationContext context = ModuleRole.ServerRoot.findSingleton(AnnotationConfigWebApplicationContext.class); |
||||||
|
if (context != null) { |
||||||
|
context.stop(); |
||||||
|
context.destroy(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void stopTomcat() throws LifecycleException { |
||||||
|
|
||||||
|
tomcat.stop(); |
||||||
|
tomcat.destroy(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Created by juhaoyu on 2018/6/5. |
||||||
|
* 自定义的tomcat loader,主要用于防止内置服务器再加载一遍class |
||||||
|
*/ |
||||||
|
private static class FRTomcatLoader extends WebappLoader { |
||||||
|
|
||||||
|
@Override |
||||||
|
public ClassLoader getClassLoader() { |
||||||
|
|
||||||
|
return this.getClass().getClassLoader(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package com.fr.start.server; |
||||||
|
|
||||||
|
import com.fanruan.carina.Carina; |
||||||
|
import com.fanruan.carina.context.CarinaApplicationContext; |
||||||
|
import com.fanruan.carina.launch.XmlCarinaLauncher; |
||||||
|
|
||||||
|
import javax.servlet.ServletContext; |
||||||
|
import java.util.Properties; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 内置服务器launcher |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/18 |
||||||
|
*/ |
||||||
|
public class DesignEmbedLauncher extends XmlCarinaLauncher { |
||||||
|
public DesignEmbedLauncher() { |
||||||
|
super( |
||||||
|
Carina.getApplicationContext().getPartitionManager(), |
||||||
|
Carina.getApplicationContext().getServletContext(), |
||||||
|
Carina.getApplicationContext().getCarinaApplicationProperties(), |
||||||
|
"/com/fr/config/starter/designer-server.xml" |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected CarinaApplicationContext createApplicationContext(ServletContext servletContext, Properties carinaApplicationProperties) { |
||||||
|
return Carina.getApplicationContext(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.fr.start.server; |
||||||
|
|
||||||
|
import com.fanruan.carina.Carina; |
||||||
|
import com.fr.third.springframework.web.WebApplicationInitializer; |
||||||
|
|
||||||
|
import javax.servlet.ServletContext; |
||||||
|
import javax.servlet.ServletException; |
||||||
|
|
||||||
|
/** |
||||||
|
* 内置服务器WebApplicationInitializer |
||||||
|
* <p>用于FR服务的WebApplication初始化</p> |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/18 |
||||||
|
*/ |
||||||
|
public class EmbedWebApplicationInitializer implements WebApplicationInitializer { |
||||||
|
@Override |
||||||
|
public void onStartup(ServletContext servletContext) throws ServletException { |
||||||
|
if (Carina.getApplicationContext().getServletContext() instanceof ServletContextWrapper) { |
||||||
|
ServletContextWrapper wrapper = (ServletContextWrapper) Carina.getApplicationContext().getServletContext(); |
||||||
|
wrapper.update(servletContext); |
||||||
|
DesignEmbedLauncher launcher = new DesignEmbedLauncher(); |
||||||
|
try { |
||||||
|
launcher.launch(); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.fr.start; |
package com.fr.start.server; |
||||||
|
|
||||||
import com.fr.stable.StringUtils; |
import com.fr.stable.StringUtils; |
||||||
|
|
@ -0,0 +1,307 @@ |
|||||||
|
package com.fr.start.server; |
||||||
|
|
||||||
|
|
||||||
|
import javax.servlet.Filter; |
||||||
|
import javax.servlet.FilterRegistration; |
||||||
|
import javax.servlet.RequestDispatcher; |
||||||
|
import javax.servlet.Servlet; |
||||||
|
import javax.servlet.ServletContext; |
||||||
|
import javax.servlet.ServletException; |
||||||
|
import javax.servlet.ServletRegistration; |
||||||
|
import javax.servlet.SessionCookieConfig; |
||||||
|
import javax.servlet.SessionTrackingMode; |
||||||
|
import javax.servlet.descriptor.JspConfigDescriptor; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.net.MalformedURLException; |
||||||
|
import java.net.URL; |
||||||
|
import java.util.Enumeration; |
||||||
|
import java.util.EventListener; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* 内置服务器的ServletContext包装 |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/18 |
||||||
|
*/ |
||||||
|
public class ServletContextWrapper implements ServletContext { |
||||||
|
public static final ServletContext EMPTY = new EmptyServletContext(); |
||||||
|
private ServletContext context = EMPTY; |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getContextPath() { |
||||||
|
return context.getContextPath(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ServletContext getContext(String s) { |
||||||
|
return context.getContext(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getMajorVersion() { |
||||||
|
return context.getMajorVersion(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getMinorVersion() { |
||||||
|
return context.getMinorVersion(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getEffectiveMajorVersion() { |
||||||
|
return context.getEffectiveMajorVersion(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getEffectiveMinorVersion() { |
||||||
|
return context.getEffectiveMinorVersion(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getMimeType(String s) { |
||||||
|
return context.getMimeType(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Set<String> getResourcePaths(String s) { |
||||||
|
return context.getResourcePaths(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public URL getResource(String s) throws MalformedURLException { |
||||||
|
return context.getResource(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public InputStream getResourceAsStream(String s) { |
||||||
|
return context.getResourceAsStream(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public RequestDispatcher getRequestDispatcher(String s) { |
||||||
|
return context.getRequestDispatcher(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public RequestDispatcher getNamedDispatcher(String s) { |
||||||
|
return context.getNamedDispatcher(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Servlet getServlet(String s) throws ServletException { |
||||||
|
return context.getServlet(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Enumeration<Servlet> getServlets() { |
||||||
|
return context.getServlets(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Enumeration<String> getServletNames() { |
||||||
|
return context.getServletNames(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void log(String s) { |
||||||
|
context.log(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void log(Exception e, String s) { |
||||||
|
context.log(e, s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void log(String s, Throwable throwable) { |
||||||
|
context.log(s, throwable); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getRealPath(String s) { |
||||||
|
return context.getRealPath(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getServerInfo() { |
||||||
|
return context.getServerInfo(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getInitParameter(String s) { |
||||||
|
return context.getInitParameter(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Enumeration<String> getInitParameterNames() { |
||||||
|
return context.getInitParameterNames(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean setInitParameter(String s, String s1) { |
||||||
|
return context.setInitParameter(s, s1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object getAttribute(String s) { |
||||||
|
return context.getAttribute(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Enumeration<String> getAttributeNames() { |
||||||
|
return context.getAttributeNames(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setAttribute(String s, Object o) { |
||||||
|
context.setAttribute(s, o); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void removeAttribute(String s) { |
||||||
|
context.removeAttribute(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getServletContextName() { |
||||||
|
return context.getServletContextName(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ServletRegistration.Dynamic addServlet(String s, String s1) { |
||||||
|
return context.addServlet(s, s1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ServletRegistration.Dynamic addServlet(String s, Servlet servlet) { |
||||||
|
return context.addServlet(s, servlet); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ServletRegistration.Dynamic addServlet(String s, Class<? extends Servlet> aClass) { |
||||||
|
return context.addServlet(s, aClass); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public <T extends Servlet> T createServlet(Class<T> aClass) throws ServletException { |
||||||
|
return context.createServlet(aClass); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ServletRegistration getServletRegistration(String s) { |
||||||
|
return context.getServletRegistration(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, ? extends ServletRegistration> getServletRegistrations() { |
||||||
|
return context.getServletRegistrations(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public FilterRegistration.Dynamic addFilter(String s, String s1) { |
||||||
|
return context.addFilter(s, s1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public FilterRegistration.Dynamic addFilter(String s, Filter filter) { |
||||||
|
return context.addFilter(s, filter); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public FilterRegistration.Dynamic addFilter(String s, Class<? extends Filter> aClass) { |
||||||
|
return context.addFilter(s, aClass); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public <T extends Filter> T createFilter(Class<T> aClass) throws ServletException { |
||||||
|
return context.createFilter(aClass); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public FilterRegistration getFilterRegistration(String s) { |
||||||
|
return context.getFilterRegistration(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map<String, ? extends FilterRegistration> getFilterRegistrations() { |
||||||
|
return context.getFilterRegistrations(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SessionCookieConfig getSessionCookieConfig() { |
||||||
|
return context.getSessionCookieConfig(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setSessionTrackingModes(Set<SessionTrackingMode> set) { |
||||||
|
context.setSessionTrackingModes(set); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { |
||||||
|
return context.getDefaultSessionTrackingModes(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { |
||||||
|
return context.getEffectiveSessionTrackingModes(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addListener(String s) { |
||||||
|
context.addListener(s); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public <T extends EventListener> void addListener(T t) { |
||||||
|
context.addListener(t); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addListener(Class<? extends EventListener> aClass) { |
||||||
|
context.addListener(aClass); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public <T extends EventListener> T createListener(Class<T> aClass) throws ServletException { |
||||||
|
return context.createListener(aClass); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JspConfigDescriptor getJspConfigDescriptor() { |
||||||
|
return context.getJspConfigDescriptor(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ClassLoader getClassLoader() { |
||||||
|
return context.getClassLoader(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void declareRoles(String... strings) { |
||||||
|
context.declareRoles(strings); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getVirtualServerName() { |
||||||
|
return context.getVirtualServerName(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 重置 |
||||||
|
*/ |
||||||
|
public void reset() { |
||||||
|
context = EMPTY; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 更新context |
||||||
|
*/ |
||||||
|
public void update(ServletContext context) { |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
package com.fanruan.boot; |
||||||
|
|
||||||
|
import com.fanruan.carina.Carina; |
||||||
|
import com.fanruan.product.ProductConstants; |
||||||
|
import com.fr.io.utils.ResourceIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.Properties; |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置工具类 |
||||||
|
* <oi> |
||||||
|
* <li>1.获取基础配置</li> |
||||||
|
* <li>2.获取环境配置</li> |
||||||
|
* <li>3.基础的变量定义与对应环境配置路径获取</li> |
||||||
|
* </oi> |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/26 |
||||||
|
*/ |
||||||
|
public class ConfigHelper { |
||||||
|
public static final String BASE = ProductConstants.getEnvHome() + File.separator + ProductConstants.APP_NAME; |
||||||
|
public static final String TAIL = ".properties"; |
||||||
|
public static final String BASE_PATH = BASE + "BaseProperties" + TAIL; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取基础的配置(工作环境无关的配置内容,所有工作环境共用一份) |
||||||
|
*/ |
||||||
|
public static Properties getBaseProperties() { |
||||||
|
return getProperties(BASE_PATH, null); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前环境配置 |
||||||
|
*/ |
||||||
|
public static Properties getEnvProperties() { |
||||||
|
return getProperties(getEnvPropertiesPath(), getBaseProperties()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前环境配置的路径 |
||||||
|
*/ |
||||||
|
public static String getEnvPropertiesPath() { |
||||||
|
return BASE + Carina.getApplicationContext().getWebInfPath().replace("\\", "_").replace("/", "_").replace(":", "_") + TAIL; |
||||||
|
} |
||||||
|
|
||||||
|
private static Properties getProperties(String path, Properties defaultValue){ |
||||||
|
Properties properties = new Properties(); |
||||||
|
if (defaultValue != null) { |
||||||
|
properties.putAll(defaultValue); |
||||||
|
} |
||||||
|
try { |
||||||
|
if (!ResourceIOUtils.exist(path)) { |
||||||
|
ResourceIOUtils.createFile(path); |
||||||
|
} |
||||||
|
try (InputStream is = ResourceIOUtils.read(path)){ |
||||||
|
properties.load(is); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
return properties; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
package com.fanruan.boot.adaptation; |
||||||
|
|
||||||
|
import com.fanruan.carina.Carina; |
||||||
|
import com.fanruan.carina.annotions.FineComponent; |
||||||
|
import com.fanruan.carina.annotions.Start; |
||||||
|
import com.fr.general.I18nResource; |
||||||
|
import com.fr.general.InterProviderImpl; |
||||||
|
import com.fr.locale.InterMutableKey; |
||||||
|
import com.fr.locale.LocaleMarker; |
||||||
|
import com.fr.locale.LocaleScope; |
||||||
|
|
||||||
|
/** |
||||||
|
* 用于内置服务器检查并适配其他FR服务细节的模块 |
||||||
|
* <p>当前需要检查一下国际化,后续应该还有东西</p> |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/24 |
||||||
|
*/ |
||||||
|
@FineComponent(name = "fine_report_adaptation") |
||||||
|
public class ReportAdaptationComponent { |
||||||
|
|
||||||
|
/** |
||||||
|
* 启动 |
||||||
|
*/ |
||||||
|
@Start |
||||||
|
public void start() { |
||||||
|
checkI18n(); |
||||||
|
} |
||||||
|
|
||||||
|
private void checkI18n() { |
||||||
|
for (LocaleMarker marker : Carina.getApplicationContext().group(InterMutableKey.class).getAll()) { |
||||||
|
if (marker.match(LocaleScope.SERVER)) { |
||||||
|
// richie:服务器端国际化的文件进来
|
||||||
|
InterProviderImpl.getInstance().addResource(marker.getPath()); |
||||||
|
} |
||||||
|
if (marker.match(LocaleScope.WEB)) { |
||||||
|
//web端
|
||||||
|
I18nResource.getInstance().addResource(marker.getPath()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue