Browse Source
Merge in DESIGN/design from ~DESTINY.LIN/design:fbp-1.0 to fbp-1.0 * commit '61412e90c3f9aedd1ff2d2f517874053680863fd': KERNEL-19047 设计器远程设计适配数据连接配置读写分离 REPORT-126685 fbp设计器适配——数据连接存储位置研究 代码规范 REPORT-126685 fbp设计器适配——数据连接存储位置研究 REPORT-126723 新建的服务器数据集设计器重启后丢失 REPORT-126687 fbp设计器——单元格形态-条形码显示异常 REPORT-126694 预定义控件保存失败fbp-1.0
Destiny.Lin-林锦龙
5 months ago
24 changed files with 418 additions and 185 deletions
@ -0,0 +1,119 @@ |
|||||||
|
package com.fr.design; |
||||||
|
|
||||||
|
import com.fanruan.carina.Carina; |
||||||
|
import com.fanruan.product.ProductConstants; |
||||||
|
import com.fr.io.utils.ResourceIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.CommonUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import com.fr.workspace.Workspace; |
||||||
|
import com.fr.workspace.resource.ResourceIOException; |
||||||
|
|
||||||
|
|
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileReader; |
||||||
|
import java.io.IOException; |
||||||
|
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 TAIL = ".properties"; |
||||||
|
public static final String CONFIG = "confighelper"; |
||||||
|
public static final String ENV = "envconfig"; |
||||||
|
public static final String BASE = ProductConstants.getEnvHome() + File.separator + CONFIG + File.separator; |
||||||
|
public static final String BASE_PATH = BASE + "BaseProperties" + TAIL; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取基础的配置(工作环境无关的配置内容,所有工作环境共用一份) |
||||||
|
*/ |
||||||
|
public static Properties getBaseProperties() { |
||||||
|
return getProperties(BASE_PATH, null); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 获取对应环境配置 |
||||||
|
*/ |
||||||
|
public static Properties getEnvProperties(Workspace workspace) { |
||||||
|
return getProperties(getEnvPropertiesPath(workspace), getBaseProperties()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前环境配置 |
||||||
|
*/ |
||||||
|
public static Properties getEnvProperties() { |
||||||
|
return getProperties(getEnvPropertiesPath(null), getBaseProperties()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取对应环境配置的路径 |
||||||
|
*/ |
||||||
|
public static String getEnvPropertiesPath(Workspace workspace) { |
||||||
|
return CommonUtils.pathJoin(workspace == null ? WorkContext.getCurrent().getPath() : workspace.getPath(), ProjectConstants.ASSETS_NAME, CONFIG, ENV) + TAIL; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取当前环境配置的路径 |
||||||
|
*/ |
||||||
|
public static String getEnvPropertiesPath() { |
||||||
|
return getEnvPropertiesPath(null); |
||||||
|
} |
||||||
|
|
||||||
|
private static Properties getProperties(String path, Properties defaultValue){ |
||||||
|
Properties properties = new Properties(); |
||||||
|
if (defaultValue != null) { |
||||||
|
properties.putAll(defaultValue); |
||||||
|
} |
||||||
|
try { |
||||||
|
File file = new File(path); |
||||||
|
if (!file.exists()) { |
||||||
|
createFile(file); |
||||||
|
} |
||||||
|
properties.load(new BufferedReader(new FileReader(path))); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
|
||||||
|
return properties; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean createFile(File file) throws ResourceIOException { |
||||||
|
String parent = file.getParent(); |
||||||
|
if (StringUtils.isNotEmpty(parent)) { |
||||||
|
createDirectory(parent); |
||||||
|
} |
||||||
|
try { |
||||||
|
return file.createNewFile(); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new ResourceIOException("[Resource] Failed to create '" + file.getPath() + "'", e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean createDirectory(String dir) { |
||||||
|
File root = new File(dir); |
||||||
|
if (root.exists()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (!dir.endsWith(File.separator)) { |
||||||
|
dir = dir.concat(File.separator); |
||||||
|
} |
||||||
|
// 创建目录
|
||||||
|
return root.mkdirs() || new File(dir).mkdirs(); |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.fr.start; |
package com.fr.design.backup; |
||||||
|
|
||||||
import com.fanruan.carina.context.CarinaApplicationContext; |
import com.fanruan.carina.context.CarinaApplicationContext; |
||||||
import com.fanruan.carina.standard.PartitionManager; |
import com.fanruan.carina.standard.PartitionManager; |
@ -0,0 +1,117 @@ |
|||||||
|
package com.fr.design.backup; |
||||||
|
|
||||||
|
import com.fanruan.carina.Carina; |
||||||
|
import com.fanruan.config.realm.ConfigRepositoryFactory; |
||||||
|
import com.fanruan.config.realm.local.LocalConfigRepositoryBuilder; |
||||||
|
import com.fr.design.ConfigHelper; |
||||||
|
import com.fr.design.mem.MemConfigBackupManager; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import com.fr.workspace.Workspace; |
||||||
|
|
||||||
|
import java.util.Properties; |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换环境对应的帮助类,主要负责环境切换的备份与环境属性的设置 |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/7/12 |
||||||
|
*/ |
||||||
|
public class EnvBackupHelper { |
||||||
|
private static final EnvBackupHelper INSTANCE = new EnvBackupHelper(); |
||||||
|
private boolean swtiching = false; |
||||||
|
private boolean local = true; |
||||||
|
private Properties properties = null; |
||||||
|
private String path = null; |
||||||
|
private Workspace target; |
||||||
|
private Workspace origin; |
||||||
|
/** |
||||||
|
* 获取单例 |
||||||
|
*/ |
||||||
|
public static EnvBackupHelper getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 备份 |
||||||
|
* <p>切换前需要判断,为什么?——当前的配置框架需要在切换前做好备份,防止切换失败,失败的话要切回备份</p> |
||||||
|
*/ |
||||||
|
public void backup() { |
||||||
|
FineLoggerFactory.getLogger().info("[EnvBackup] 1.back start..."); |
||||||
|
this.swtiching = true; |
||||||
|
local = WorkContext.getCurrent().isLocal(); |
||||||
|
if (local) { |
||||||
|
properties = ConfigHelper.getEnvProperties(); |
||||||
|
path = ConfigHelper.getEnvPropertiesPath(); |
||||||
|
} |
||||||
|
origin = WorkContext.getCurrent(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换前的准备 |
||||||
|
* <p>设置目标环境</p> |
||||||
|
* <p>设置新的工程路径</p> |
||||||
|
*/ |
||||||
|
public void prepare4switch(Workspace workspace) { |
||||||
|
this.target = workspace; |
||||||
|
((DesignContext) Carina.getApplicationContext()).setDesignWebInfPath(workspace.getPath()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换 |
||||||
|
*/ |
||||||
|
public void do4Switch4Config() { |
||||||
|
FineLoggerFactory.getLogger().info("[EnvBackup] 2.do config switch"); |
||||||
|
// 切换环境的时候新配置框架启动前要先reset原来的
|
||||||
|
ConfigRepositoryFactory.getInstance().reset(); |
||||||
|
if (target.isLocal()) { |
||||||
|
//如果目标是本地,就清空然后重新注册新的本地配置
|
||||||
|
ConfigRepositoryFactory.getInstance().registerConfigRepositoryBuilder(new LocalConfigRepositoryBuilder(ConfigHelper.getEnvProperties(target), ConfigHelper.getEnvPropertiesPath(target))); |
||||||
|
} else { |
||||||
|
// 如果是切到远程,先暂时用备份的内存配置,成功后再转到新配置,失败则切回原内存配置
|
||||||
|
MemConfigBackupManager.getInstance().startSwitch(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换成功后的处理 |
||||||
|
*/ |
||||||
|
public void success() { |
||||||
|
FineLoggerFactory.getLogger().info("[EnvBackup] 3.switch all" ); |
||||||
|
//切换成功,如果原来是本地,则清空备份,不需要干别的,此时配置走的就是新环境的本地
|
||||||
|
if (local) { |
||||||
|
properties = null; |
||||||
|
path = null; |
||||||
|
} else { |
||||||
|
// 如果原来是远程,就把内存的新环境配置替换掉原来旧的,然后新配置清空
|
||||||
|
MemConfigBackupManager.getInstance().success(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换失败后的处理 |
||||||
|
*/ |
||||||
|
public void failed() { |
||||||
|
FineLoggerFactory.getLogger().info("[EnvBackup] 3.handle failed" ); |
||||||
|
((DesignContext) Carina.getApplicationContext()).setDesignWebInfPath(origin.getPath()); |
||||||
|
// 切换失败,如果原来是本地,则切回去
|
||||||
|
ConfigRepositoryFactory.getInstance().reset(); |
||||||
|
if (local) { |
||||||
|
ConfigRepositoryFactory.getInstance().registerConfigRepositoryBuilder(new LocalConfigRepositoryBuilder(properties, path)); |
||||||
|
} else { |
||||||
|
// 如果是远程,则新环境的配置全部弃用,直接走老的
|
||||||
|
MemConfigBackupManager.getInstance().failed(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSwtiching() { |
||||||
|
return swtiching; |
||||||
|
} |
||||||
|
|
||||||
|
public EnvBackupHelper setSwtiching(boolean swtiching) { |
||||||
|
this.swtiching = swtiching; |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
package com.fr.design.mem; |
||||||
|
|
||||||
|
import com.fanruan.config.realm.ConfigRepositoryProvider; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* 内存配置框架备份管理 |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/7/11 |
||||||
|
*/ |
||||||
|
public class MemConfigBackupManager { |
||||||
|
|
||||||
|
private static final MemConfigBackupManager INSTANCE = new MemConfigBackupManager(); |
||||||
|
|
||||||
|
private Map<String, ConfigRepositoryProvider> oldEnvConfig = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
private Map<String, ConfigRepositoryProvider> newEnvConfig = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
private boolean switching = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取备份 |
||||||
|
*/ |
||||||
|
public static MemConfigBackupManager getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取配置 |
||||||
|
*/ |
||||||
|
public ConfigRepositoryProvider get(String namespace) { |
||||||
|
if (switching) { |
||||||
|
return newEnvConfig.getOrDefault(namespace, null); |
||||||
|
} |
||||||
|
return oldEnvConfig.getOrDefault(namespace, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 放入配置 |
||||||
|
*/ |
||||||
|
public void put(String namespace, ConfigRepositoryProvider provider) { |
||||||
|
if (switching) { |
||||||
|
newEnvConfig.put(namespace, provider); |
||||||
|
} else { |
||||||
|
oldEnvConfig.put(namespace, provider); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 清理 |
||||||
|
*/ |
||||||
|
public void clear() { |
||||||
|
oldEnvConfig.clear(); |
||||||
|
newEnvConfig.clear(); |
||||||
|
switching = false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 切换成功则将切换过程中的配置移动到旧配置,新的切换过程中的配置置空 |
||||||
|
*/ |
||||||
|
public void success() { |
||||||
|
oldEnvConfig = new HashMap<>(newEnvConfig); |
||||||
|
newEnvConfig.clear(); |
||||||
|
switching = false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 失败处理 |
||||||
|
*/ |
||||||
|
public void failed() { |
||||||
|
newEnvConfig.clear(); |
||||||
|
switching = false; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSwitching() { |
||||||
|
return switching; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 开始切换 |
||||||
|
*/ |
||||||
|
public void startSwitch() { |
||||||
|
switching = true; |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.fanruan.boot.mem; |
package com.fr.design.mem; |
||||||
|
|
||||||
import com.fanruan.config.event.ConfigListener; |
import com.fanruan.config.event.ConfigListener; |
||||||
import com.fanruan.config.realm.ConfigRepositoryProvider; |
import com.fanruan.config.realm.ConfigRepositoryProvider; |
@ -0,0 +1,30 @@ |
|||||||
|
package com.fr.design.mem; |
||||||
|
|
||||||
|
import com.fanruan.config.realm.ConfigRepositoryBuilder; |
||||||
|
import com.fanruan.config.realm.ConfigRepositoryProvider; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 设计器MemConfigRepositoryBuilder |
||||||
|
* |
||||||
|
* @author Destiny.Lin |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/5/29 |
||||||
|
*/ |
||||||
|
public class MemConfigRepositoryBuilder implements ConfigRepositoryBuilder { |
||||||
|
@Override |
||||||
|
public ConfigRepositoryProvider build(String namespace) throws Exception { |
||||||
|
ConfigRepositoryProvider provider = MemConfigBackupManager.getInstance().get(namespace); |
||||||
|
if (provider != null) { |
||||||
|
// 如果备份中有说明就是当前要的配置
|
||||||
|
return provider; |
||||||
|
} else { |
||||||
|
// 如果没有,说明是全新的远程环境,新建一个
|
||||||
|
provider = new MemConfigRepository(namespace); |
||||||
|
// 备份也得放一个
|
||||||
|
MemConfigBackupManager.getInstance().put(namespace, provider); |
||||||
|
} |
||||||
|
return provider; |
||||||
|
} |
||||||
|
} |
@ -1,104 +0,0 @@ |
|||||||
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 com.fr.stable.StringUtils; |
|
||||||
|
|
||||||
|
|
||||||
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 TAIL = ".properties"; |
|
||||||
public static final String CONFIG = "confighelper"; |
|
||||||
public static final String BASE = ProductConstants.getEnvHome() + File.separator + CONFIG + File.separator; |
|
||||||
public static final String BASE_PATH = BASE + "BaseProperties" + TAIL; |
|
||||||
private static String path = StringUtils.EMPTY; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 获取基础的配置(工作环境无关的配置内容,所有工作环境共用一份) |
|
||||||
*/ |
|
||||||
public static Properties getBaseProperties() { |
|
||||||
return getProperties(BASE_PATH, null); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 获取当前环境配置 |
|
||||||
*/ |
|
||||||
public static Properties getEnvProperties() { |
|
||||||
return getProperties(getEnvPropertiesPath(), getBaseProperties()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取当前环境配置的路径 |
|
||||||
*/ |
|
||||||
public static String getEnvPropertiesPath() { |
|
||||||
return path + TAIL; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 规范化配置文件的路径,保证配置文件落在缓存文件夹(110)中 |
|
||||||
*/ |
|
||||||
public static String normalise(String path) { |
|
||||||
if (!path.startsWith(BASE)) { |
|
||||||
path = BASE + path.replace("\\", "_").replace("/", "_").replace(":", "_"); |
|
||||||
} |
|
||||||
return path; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 设置config路径 |
|
||||||
*/ |
|
||||||
public static void setPath(String path) { |
|
||||||
ConfigHelper.path = normalise(path); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 获取路径 |
|
||||||
*/ |
|
||||||
public static String getPath() { |
|
||||||
if (StringUtils.isEmpty(path)) { |
|
||||||
path = Carina.getApplicationContext().getWebInfPath(); |
|
||||||
} |
|
||||||
return path; |
|
||||||
} |
|
||||||
|
|
||||||
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; |
|
||||||
} |
|
||||||
} |
|
@ -1,20 +0,0 @@ |
|||||||
package com.fanruan.boot.mem; |
|
||||||
|
|
||||||
import com.fanruan.config.realm.ConfigRepositoryBuilder; |
|
||||||
import com.fanruan.config.realm.ConfigRepositoryProvider; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 设计器MemConfigRepositoryBuilder |
|
||||||
* |
|
||||||
* @author Destiny.Lin |
|
||||||
* @since 11.0 |
|
||||||
* Created on 2024/5/29 |
|
||||||
*/ |
|
||||||
public class MemConfigRepositoryBuilder implements ConfigRepositoryBuilder { |
|
||||||
@Override |
|
||||||
public ConfigRepositoryProvider build(String namespace) throws Exception { |
|
||||||
return new MemConfigRepository(namespace); |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue