这些文件不是我创建的,不知道为啥会在我这……

This commit is contained in:
joylink_zhangsai 2022-12-08 09:21:34 +08:00
parent f82e500572
commit 4cb965ce71
3 changed files with 406 additions and 0 deletions

View File

@ -0,0 +1,88 @@
package club.joylink.rtss.iscs.proto.model;
import club.joylink.iscs.model.data.DataModelMapProto;
import club.joylink.iscs.model.data.DataModelProto;
import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.InvalidProtocolBufferException;
import java.lang.reflect.Method;
import java.util.Map;
public interface ModelMemory {
/**
* 获取模型数据的引用
*/
DataModelProto.ModelRef.Builder refFrom(GeneratedMessageV3 model) throws Exception;
/**
* 获取引用引用的模型实例数据
*/
<T extends GeneratedMessageV3> T modelFrom(DataModelProto.ModelRef.Builder ref) throws Exception;
/**
* 获取引用引用的模型实例数据
*/
<T extends GeneratedMessageV3> T modelFrom(DataModelProto.ModelRef ref) throws Exception;
/**
* 获取所有模型数据的副本
*/
DataModelMapProto.DataModelMap allDataModels();
/**
* 从已有数据恢复模型数据
*/
void recoverFrom(DataModelMapProto.DataModelMap modelsData);
/**
* 从已有数据恢复模型数据
*/
void recoverFrom(byte[] modelsData) throws InvalidProtocolBufferException;
public static ModelMemory create(byte[] modelsData) throws InvalidProtocolBufferException {
ModelMemoryImpl impl = new ModelMemoryImpl();
impl.recoverFrom(modelsData);
return impl;
}
/**
* 获取模型的身份信息
*/
public static DataModelProto.DataModel identityFrom(GeneratedMessageV3 model) throws Exception {
//getIdentity
Method getIdentity = getDeclaredMethod(model.getClass(), "getIdentity");
if (null != getIdentity) {
return (DataModelProto.DataModel) getIdentity.invoke(model);
}
//遍历
final Method[] mds = model.getClass().getMethods();
int count = 0;
for (Method md : mds) {
if (DataModelProto.DataModel.class.equals(md.getReturnType())) {
getIdentity = md;
count++;
}
}
if (count > 1) {
throw new Exception(String.format("%s 中 表示身份信息DataModelProto.DataModel有多个可以将其中一个命名为'identity'表示身份信息", model.getClass().getSimpleName()));
}
if (count < 1) {
throw new Exception(String.format("%s 中 没有表示身份信息DataModelProto.DataModel可以添加一个命名为'identity'", model.getClass().getSimpleName()));
}
return (DataModelProto.DataModel) getIdentity.invoke(model);
}
/**
* 根据模型类型获取该类模型的集合,可以通过遍历该集合来遍历该类的所有模型数据
*/
public <M extends GeneratedMessageV3> Map<String, M> getModelMap(Class<M> modelClass) throws Exception;
static Method getDeclaredMethod(Class cls, String name, Class<?>... parameterTypes) {
try {
return cls.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
}
return null;
}
}

View File

@ -0,0 +1,203 @@
package club.joylink.rtss.iscs.proto.model;
import club.joylink.iscs.model.data.DataModelMapProto;
import club.joylink.iscs.model.data.DataModelProto;
import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* 模型数据存储实现
*/
@Slf4j
public class ModelMemoryImpl implements ModelMemory {
/**
* 模型数据存储空间
*/
private DataModelMapProto.DataModelMap.Builder dmmBuilder = DataModelMapProto.DataModelMap.newBuilder();
/**
* 模型分类查找实现
*/
private final Map<DataModelProto.ModelType, Method> refMethodMap = new HashMap<>();
/**
* 快速存储模型数据实现
*/
private final Map<Class<? extends GeneratedMessageV3>, Method> putMethodMap = new HashMap<>();
/**
* 快速通过模型类获取模型的集合
*/
private final Map<Class<? extends GeneratedMessageV3>, Method> modelMap = new HashMap<>();
public ModelMemoryImpl() {
}
/**
* 获取模型数据的引用
*/
public synchronized DataModelProto.ModelRef.Builder refFrom(GeneratedMessageV3 model) throws Exception {
final DataModelProto.DataModel identify = ModelMemory.identityFrom(model);
this.putModelData(identify, model);
return DataModelProto.ModelRef.newBuilder().setType(identify.getType()).setId(identify.getId());
}
/**
* 获取引用引用的模型实例数据
*/
public synchronized <T extends GeneratedMessageV3> T modelFrom(DataModelProto.ModelRef.Builder ref) throws Exception {
return (T) findFromMap(ref.build());
}
/**
* 获取引用引用的模型实例数据
*/
public synchronized <T extends GeneratedMessageV3> T modelFrom(DataModelProto.ModelRef ref) throws Exception {
return (T) findFromMap(ref);
}
/**
* 获取所有模型数据的副本
*/
public synchronized DataModelMapProto.DataModelMap allDataModels() {
return this.dmmBuilder.build();
}
/**
* 从已有数据恢复模型数据
*/
public synchronized void recoverFrom(DataModelMapProto.DataModelMap modelsData) {
this.dmmBuilder = DataModelMapProto.DataModelMap.newBuilder(modelsData);
}
/**
* 从已有数据恢复模型数据
*/
public synchronized void recoverFrom(byte[] modelsData) throws InvalidProtocolBufferException {
this.dmmBuilder = DataModelMapProto.DataModelMap.newBuilder(DataModelMapProto.DataModelMap.parseFrom(modelsData));
}
/**
* 根据模型类型获取该类模型的集合,可以通过遍历该集合来遍历该类的所有模型数据
*/
public synchronized <M extends GeneratedMessageV3> Map<String, M> getModelMap(Class<M> modelClass) throws Exception {
final Map<String, M> rt = doFindByModelClass(modelClass);
if (null != rt) {
return rt;
}
//遍历所有集合查找
Method[] mds = dmmBuilder.getClass().getMethods();
for (Method md : mds) {
final String mdName = md.getName();
if (mdName.startsWith("get") && mdName.endsWith("Map")) {
final Map map = (Map) md.invoke(dmmBuilder);
for (Object v : map.values()) {
if (v.getClass().equals(modelClass)) {
this.modelMap.put(modelClass, md);
show("==>>遍历获取模型的集合modelClass = " + modelClass.getSimpleName());
return map;
}
}
}
}
return new HashMap<>();
}
//////////////////////////////////////////////////////////////////////////////////////////////////
/**
* 存储实例
*/
private void putModelData(final DataModelProto.DataModel identify, final GeneratedMessageV3 model) throws Exception {
final Method putModelMethod = this.putMethodMap.get(model.getClass());
if (null != putModelMethod) {
putModelMethod.invoke(this.dmmBuilder, identify.getId(), model);
show("==>>存储方法存在直接存储type = " + identify.getType() + " code = " + identify.getId());
} else {
final Method[] putMds = this.dmmBuilder.getClass().getMethods();
for (Method putMd : putMds) {
final String putMdName = putMd.getName();
if (putMdName.startsWith("put")) {
final Class<?>[] pts = putMd.getParameterTypes();
if (null != pts && pts.length == 2) {
if (pts[0].equals(String.class) && pts[1].equals(model.getClass())) {
if (!this.putMethodMap.containsKey(model.getClass())) {
this.putMethodMap.put(model.getClass(), putMd);
}
putMd.invoke(this.dmmBuilder, identify.getId(), model);
show("==>>存储方法不存在储遍历存储type = " + identify.getType() + " code = " + identify.getId());
break;
}
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private GeneratedMessageV3 findFromMap(DataModelProto.ModelRef ref) throws Exception {
return this.doFindFromMap(ref);
}
private Map doFindByModelClass(Class modelClass) throws Exception {
Method md = this.modelMap.get(modelClass);
if (null != md) {
final Map map = (Map) md.invoke(dmmBuilder);
show("==>>直接获取模型的集合modelClass = " + modelClass.getSimpleName());
return map;
}
return null;
}
/**
* 遍历所有map来查找ref对应的model实例
*/
private GeneratedMessageV3 doFindFromMap(DataModelProto.ModelRef ref) throws Exception {
//优先通过类型来查找
GeneratedMessageV3 model = this.doFindByType(ref);
if (null != model) {
show("==>>优先通过类型找到type = " + ref.getType() + " code = " + ref.getId());
return model;
}
//遍历所有集合查找
Method[] mds = dmmBuilder.getClass().getMethods();
for (Method md : mds) {
final String mdName = md.getName();
if (mdName.startsWith("get") && mdName.endsWith("Map")) {
Map map = (Map) md.invoke(dmmBuilder);
model = (GeneratedMessageV3) map.get(ref.getId());
if (null != model) {
if (!DataModelProto.ModelType.Any.equals(ref.getType())) {
if (!refMethodMap.containsKey(ref.getType())) {
refMethodMap.put(ref.getType(), md);
show("==>>保存类型查找信息type = " + ref.getType() + " getMapMethod = " + mdName);
}
}
show("==>>通过遍历所有集合找到type = " + ref.getType() + " code = " + ref.getId());
return model;
}
}
}
return null;
}
/**
* 通过类型来查找模型实例
*/
private GeneratedMessageV3 doFindByType(DataModelProto.ModelRef ref) throws Exception {
//getXXXMap()
final Method getMapMethod = refMethodMap.get(ref.getType());
if (null != getMapMethod) {
final Map map = (Map) getMapMethod.invoke(dmmBuilder);
return (GeneratedMessageV3) map.get(ref.getId());
}
return null;
}
private static void show(String msg) {
log.debug(msg);
}
}

View File

@ -0,0 +1,115 @@
package club.joylink.rtss.iscs.services;
import club.joylink.rtss.iscs.dao.IscsModelDataDAO;
import club.joylink.rtss.iscs.entity.IscsModelData;
import club.joylink.rtss.iscs.entity.IscsModelDataExample;
import club.joylink.rtss.iscs.proto.model.ModelMemory;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* iscs模型使用业务实现<br>
* iscs的所有页面的模型数据
*/
@Service
public class IscsModelMemoryService {
@Autowired
private IscsModelDataDAO modelDataDao;
/**
* key : iscs的类型<br>
* value : iscs的所有页面的模型数据<br>
*/
private final Map<String, Map<ModelMemoryIndex, ModelMemory>> modelMemoryMap = new ConcurrentHashMap<>();
/**
* iscs启动时加载模型数据
*/
@Transactional(readOnly = true)
public void loadModelData() throws Exception {
final List<ModelMemoryIndex> mmiList = this.findAllModelMemoryIndex(ISCS_DEFAULT_TYPE);
for (ModelMemoryIndex mmi : mmiList) {
final Map<ModelMemoryIndex, ModelMemory> map = getIscsModelMap(mmi.type);
map.put(mmi, this.loadModelMemory(mmi));
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
private synchronized Map<ModelMemoryIndex, ModelMemory> getIscsModelMap(String iscsType) {
Map<ModelMemoryIndex, ModelMemory> map = modelMemoryMap.get(iscsType);
if (null == map) {
map = new ConcurrentHashMap<>();
modelMemoryMap.put(iscsType, map);
}
return map;
}
private List<ModelMemoryIndex> findAllModelMemoryIndex(String iscsType) {
final List<ModelMemoryIndex> rt = new ArrayList<>();
//
final IscsModelDataExample example = new IscsModelDataExample();
final List<IscsModelData> list = modelDataDao.selectByExample(example);
if (null != list) {
list.forEach(md -> {
rt.add(new ModelMemoryIndex(md.getSystem(), md.getView(), md.getPlace()));
});
}
return rt;
}
private ModelMemory loadModelMemory(ModelMemoryIndex mmi) throws Exception {
IscsModelDataExample example = new IscsModelDataExample();
example.createCriteria().andSystemEqualTo(mmi.system).andViewEqualTo(mmi.view).andPlaceEqualTo(mmi.place);
List<IscsModelData> list = modelDataDao.selectByExampleWithBLOBs(example);
return ModelMemory.create(list.get(0).getData());
}
///////////////////////////////////////////////////////////////////////////////////////////////
/**
* 模型数据的索引(页面id)
*/
@Getter
@Setter
public static class ModelMemoryIndex {
//iscs 类型(扩展用暂时默认值)
private String type = ISCS_DEFAULT_TYPE;
//iscs 系统(一级菜单)
private String system;
//iscs 视图(二级菜单)
private String view;
//iscs 场所(车站变电所)(三级菜单)
private String place;
public ModelMemoryIndex() {
}
public ModelMemoryIndex(String system, String view, String place) {
this.system = system;
this.view = view;
this.place = place;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ModelMemoryIndex that = (ModelMemoryIndex) o;
return type.equals(that.type) && system.equals(that.system) && view.equals(that.view) && place.equals(that.place);
}
@Override
public int hashCode() {
return Objects.hash(type, system, view, place);
}
}
public static final String ISCS_DEFAULT_TYPE = "FAST_TRAIN";
}