Commit 384e48ae by s_guodong

init

parent 14e06dfc
.gradle/
build/
target/
bin/
logs/
# Eclipse Project Files
.classpath
.project
.settings/
# IntelliJ IDEA Files
*.iml
*.ipr
*.iws
*.idea
*.class
*.factorypath
*.springBeans
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.brilliance</groupId>
<artifactId>gjjs-bd-runtime</artifactId>
<version>0.0.1</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<druid.spring.boot.starter.version>1.1.10</druid.spring.boot.starter.version>
<spring.version>2.4.5</spring.version>
<jackson.version>2.11.4</jackson.version>
<dom4j.version>2.1.1</dom4j.version>
<jaxen.version>1.2.0</jaxen.version>
<itextpdf.version>5.5.13</itextpdf.version>
<itext-asian.version>5.2.0</itext-asian.version>
<xmlworker.version>5.5.8</xmlworker.version>
<mybatis.spring.boot.starter.version>2.1.4</mybatis.spring.boot.starter.version>
<mysql.connector.java.version>5.1.29</mysql.connector.java.version>
<poi.ooxml.version>4.1.0</poi.ooxml.version>
<commons.io.version>2.6</commons.io.version>
<commons.codec.version>1.10</commons.codec.version>
<commons.beanutils.version>1.9.3</commons.beanutils.version>
<commons.compress.version>1.18</commons.compress.version>
<guava.version>30.1.1-jre</guava.version>
<lombok.version>1.18.20</lombok.version>
<gson.version>2.8.5</gson.version>
<javax.persistence.api.version>2.2</javax.persistence.api.version>
<velocity.version>1.7</velocity.version>
<velocity.tools.version>2.0</velocity.tools.version>
<jackson.databind.version>2.11.4</jackson.databind.version>
<commons.lang3.version>3.3.2</commons.lang3.version>
<validation.api.version>1.1.0.Final</validation.api.version>
<commons.text.version>1.9</commons.text.version>
<kryo5.version>5.3.0</kryo5.version>
<jackson.annotations.version>2.9.0</jackson.annotations.version>
<slf4j.api.version>1.7.25</slf4j.api.version>
<spring.context.version>5.2.9.RELEASE</spring.context.version>
<fastjson.version>1.2.53</fastjson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.brilliance</groupId>
<artifactId>gjjs-mda</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.annotations.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind.version}</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons.beanutils.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.ooxml.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.api.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.context.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.starter.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>${dom4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.lang3.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo5</artifactId>
<version>${kryo5.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.2</version>
<scope>system</scope>
<systemPath>${pom.basedir}/lib/ojdbc6-12.1.0.2.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>brilliance-virtual</id>
<name>brilliance-virtual</name>
<url>http://114.115.138.98:9620/artifactory/gjjs-bd-runtime/</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>brilliance-virtual</id>
<name>brilliance-virtual</name>
<url>http://114.115.138.98:9620/artifactory/brilliance-virtual/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</project>
\ No newline at end of file
package com.brilliance.mda.runtime.mda.driver;
import com.brilliance.mda.runtime.mda.I18n;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale;
import java.util.ResourceBundle;
public class I18NImpl implements I18n {
private static Logger log = LoggerFactory.getLogger(I18NImpl.class);
public String getString(Locale locale, String resourceName, String resourceKey, int index) {
return getString(locale, resourceName, (index == 0) ? resourceKey : (String.valueOf(resourceKey) + index));
}
public String getString(Locale locale, String resourceName, String resourceKey) {
if (locale == null)
locale = Locale.getDefault();
try {
ResourceBundle rb = ResourceBundle.getBundle("i18n/" + resourceName, locale);
return rb.getString(resourceKey);
} catch (Exception e) {
return "???" + resourceKey + "???";
}
}
public String getString(Locale locale, String i18nStr) {
return getString(locale, i18nStr, 0);
}
public String getString(Locale locale, String i18nStr, int index) {
if (i18nStr == null || !i18nStr.startsWith("/"))
return i18nStr;
String[] values = i18nStr.split("/");
if (values.length != 3)
return i18nStr;
return getString(locale, values[1], values[2], index);
}
}
package com.brilliance.mda.runtime.mda.driver;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.impl.AbstractDaoSession;
import com.brilliance.mda.runtime.mda.impl.EnvConfig;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class MdaEnv {
private static String encoding = "UTF-8";
public static String LANG = "CN";
private static Locale locale = Locale.SIMPLIFIED_CHINESE;
private static Map<String, Map<String, List<Object>>> sessionContext = new ConcurrentHashMap<>();
// public static ApplicationContext appContext = null;
public static ConfigurableListableBeanFactory beanFactory = null;
private static ThreadLocal<IContext> tl = new ThreadLocal<IContext>();
private static ThreadLocal<IAuthInfo> tl_infos = new ThreadLocal<IAuthInfo>();
private static ThreadLocal<Map<String, Object>> tl_gridEtyData = new ThreadLocal<>();
private static ThreadLocal<String> moduleListCheckErrorItem = new ThreadLocal<>();
public static <T> T getBean(String beanId, Class<T> clazz) {
return beanFactory.getBean(beanId, clazz);
}
public static <T> T getBean(Class<T> clazz) {
return beanFactory.getBean(clazz);
}
public static Object getBean(String beanId) {
Object bean = null;
try {
bean = beanFactory.getBean(beanId);
} catch (Exception e) {
}
return bean;
}
public static void setContext(IContext ctx) {
//取消设置默认语言,因由TD决定
//ctx.storeData("LANG",LANG);
tl.set(ctx);
}
public static IContext getContext() {
return tl.get();
}
public static void rmContext() {
tl.remove();
AbstractDaoSession daoSession = beanFactory.getBean(AbstractDaoSession.class);
if (daoSession != null && daoSession.isOpenTrans()) {
//防止有未关闭的事务
daoSession.dbRollback();
}
}
public static void clearContext() {
rmContext();
tl_infos.remove();
}
public static void clear(Object object) {
if (object == null)
return;
if ((object instanceof IBaseObject)) {
((IBaseObject) object).clear();
} else if ((object instanceof Collection)) {
((Collection) object).clear();
} else if ((object instanceof Map)) {
((Map) object).clear();
}
}
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Object obj) {
if (obj == null)
return true;
if (obj instanceof String)
return ((String) obj).length() == 0 || ((String) obj).equals(" ");
if (obj instanceof BigDecimal)
return ((BigDecimal) obj).doubleValue() == 0.0D;
if ((obj instanceof Number)) {
return ((Number) obj).doubleValue() == 0.0D;
}
if ((obj instanceof Collection)) {
return ((Collection) obj).isEmpty();
}
if ((obj instanceof Map)) {
return ((Map) obj).isEmpty();
}
if (obj instanceof IModule) {
return isEmpty(MdaDriver.getDatafield((IModule) obj, "inr"));
}
if (obj instanceof IDatafield)
return isEmpty(((IDatafield) obj).getValue());
return false;
}
public static void setAuthInfo(IAuthInfo authInfo) {
tl_infos.set(authInfo);
}
public static IAuthInfo getAuthInfo() {
return tl_infos.get();
}
public static String getLoginUser() {
//结合具体环境,从tl_infos中获取
return tl_infos.get().getUserId();
}
public static String getEncoding() {
return encoding;
}
public static void setEncoding(String encoding) {
MdaEnv.encoding = encoding;
}
public static String getLang() {
String lang = (String) getContext().restoreData("LANG");
return lang;
}
public static <T> T getSessionContextValue(String key) {
String uid = MdaEnv.getAuthInfo().getUserId();
if (!sessionContext.containsKey(uid)) {
return null;
}
if (!sessionContext.get(uid).containsKey(key)) {
MdaEnv.getContext().setErrorCode(111);
return null;
}
return (T) sessionContext.get(uid).get(key).get(0);
}
public static void setSessionContext(String key, Object... obj) {
if (key == null) return;
String uid = MdaEnv.getAuthInfo().getUserId();
if (!sessionContext.containsKey(uid)) {
sessionContext.put(uid, new ConcurrentHashMap<String, List<Object>>());
}
sessionContext.get(uid).put(key, Arrays.asList(obj));
}
/**
* 该方法需在用户登录时先调用一次,保证把之前的缓存清除
*
* @param uid
*/
public static void clearSessionContext(String uid) {
if (sessionContext.containsKey(uid)) {
sessionContext.get(uid).clear();
}
}
public static String getRootPath() {
return getBean(EnvConfig.class).getRootPath();
}
public static void removeAuthInfo() {
tl_infos.remove();
}
private static ThreadLocal<Map<String, Object>> attrs = new ThreadLocal<>();
public static void removeAttrs() {
attrs.remove();
}
public static void setAttribute(String key, Object obj) {
if (attrs.get() == null) {
attrs.set(new HashMap<String, Object>());
}
attrs.get().put(key, obj);
}
public static Object getAttribute(String key) {
if (key == null) return null;
return attrs.get().get(key);
}
public static String getSessionId() {
String sessionId = (String) attrs.get().get("sessionId");
if (sessionId != null) {
return sessionId;
}
return "";
}
public static void setGridData(String title, String columns, IStream vals) {
Map<String, Object> data = new HashMap<>();
data.put("title", title);
data.put("columns", columns);
data.put("vals", vals);
tl_gridEtyData.set(data);
}
public static Map<String, Object> getGridData() {
return tl_gridEtyData.get();
}
public static void removeGridData() {
tl_gridEtyData.remove();
}
public static Locale getLocale() {
if (locale == null)
locale = Locale.SIMPLIFIED_CHINESE;
return locale;
}
public static void setLocale(Locale temp_locale) {
locale = temp_locale;
}
public static String getModuleListCheckErrorItem() {
return moduleListCheckErrorItem.get();
}
/**
* ModuleList 执行checkAll时,记录 module 的 path + index,方便前端页面显示错误信息
*
* @param prefix
*/
public static void setModuleListCheckItem(String prefix) {
moduleListCheckErrorItem.set(prefix);
}
public static void removeModuleListCheckErrorItem() {
moduleListCheckErrorItem.remove();
}
}
package com.brilliance.mda.runtime.mda.driver.compile;
import com.brilliance.mda.runtime.annotation.Module;
import com.brilliance.mda.runtime.annotation.Transaction;
import com.brilliance.mda.runtime.mda.driver.MdaScanner;
import com.brilliance.mda.runtime.mda.driver.compile.processor.ModuleAnnotationProcess;
import com.brilliance.mda.runtime.mda.driver.compile.processor.TransAnnotationProcessor;
import com.brilliance.mda.support.td.ModuleInfoManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Component
public class EmitterFactory implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Value("${envconfig.emitter.scanPackages:com.ceb.gjjs.mda.manager,com.ceb.gjjs.mda.bo}")
private String scanPackage;
@Autowired
private MdaScanner scanner;
public void buildEmitter(String... transPack){
try {
log.debug("prepare to walk transaction");
Map<Class<?>, Set<Class<?>>> map = new HashMap<>();
for (String pack : transPack) {
scanner.doScan(map, pack.trim().replaceAll("\\.", "/"), Module.class, Transaction.class);
}
log.debug("get all modules and transactions");
Set<Class<?>> moduleSet = map.get(Module.class);
moduleSet.forEach(item -> {
try {
ModuleInfoManager.getModuleInfo(item.getSimpleName());
ModuleInfoManager.loadModuleInfo(item);
} catch (Exception ignore) {
}
});
Set<Class<?>> transSet = map.get(Transaction.class);
transSet.forEach(item->new TransAnnotationProcessor().buildTransEmitter(item,scanner.getBeanDefinitionRegistry()));
ModuleAnnotationProcess.reduceCache();
TransAnnotationProcessor.getProcessQueue().clear();
log.debug("walk transaction finished");
//log.info("注册TableMeta {}个", TableMetaManager.getTableMetaCount());
log.info("注册ModuleInfo {}个", ModuleInfoManager.getModuleInfoCount());
log.info("注册Transaction {}个", transSet.size());
} catch (Exception e) {
log.error("动态Emitter扫描包发生错误", e);
}
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("动态Emitter扫描包:{}", scanPackage);
String[] scanPackages = scanPackage.split(",");
this.buildEmitter(scanPackages);
}
}
package com.brilliance.mda.runtime.mda.driver.compile;
import com.brilliance.mda.support.td.ModuleInfoManager;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EmitterManager {
private final static Logger log = LoggerFactory.getLogger(ModuleInfoManager.class);
private static final ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
private static final Map<String, Map<String, String>> initIgnoreMap = new HashMap<>();
private static final Map<String, Map<String, String>> defaultIgnoreMap = new HashMap<>();
private static final Map<String, Map<String, String>> ruleIgnoreMap = new HashMap<>();
private static final Map<String, Map<String, String>> checkIgnoreMap = new HashMap<>();
public static void loadEmitterIgnoreInfo(Class<?> aClass) {
try {
String moduleName = aClass.getSimpleName();
String filename = aClass.getSimpleName() + ".txt";
Resource[] resources = resourceResolver.getResources("classpath:ignoreRule/" + filename);
// File file = resources[0].getFile();
InputStream stream2 = resources[0].getInputStream();
log.info("加载ignoreRule:{}", filename);
List<String> lines = IOUtils.readLines(stream2, Charsets.toCharset(StandardCharsets.UTF_8));
for (String line : lines) {
String[] fields = line.split("\t");
// log.info("加载ignoreRule-line:{},fields.length:{}", line, fields.length);
if (fields.length < 2)
continue;
String target = fields[0].trim();
String field1 = fields[1].trim();
String methodExpress = field1;
methodExpress = methodExpress.substring(methodExpress.indexOf("(") + 1);
methodExpress = methodExpress.substring(0, methodExpress.lastIndexOf(")")).trim();
String[] methodExpresses = methodExpress.split(",");
if (methodExpresses.length < 3)
continue;
String order = methodExpresses[0].trim();
String path = methodExpresses[1].trim().replaceAll("\"", "");
String method = methodExpresses[2].substring(methodExpresses[2].lastIndexOf("::") + 2);
String expression = String.format("%s#%s#%s#%s", target, path, method, order);
if (field1.startsWith("execCheckItem")) {
log.info("加载ignoreRule.check方法:{}", expression);
Map<String, String> map = checkIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
map.put(expression, line);
} else if (field1.startsWith("execRuleItem")) {
Map<String, String> map = ruleIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
map.put(expression, line);
} else if (field1.startsWith("execDefaultItem")) {
Map<String, String> map = defaultIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
map.put(expression, line);
} else if (field1.startsWith("execInitItem")) {
Map<String, String> map = initIgnoreMap.computeIfAbsent(moduleName, k -> new HashMap<>());
map.put(expression, line);
}
}
} catch (FileNotFoundException ignore) {
log.warn("[这是提示信息,不影响运行]从resources/ignoreRule下查找文件失败。{}",ignore.getMessage());
} catch (Exception e) {
log.error("从resources/ignoreRule下查找文件失败", e);
throw new IllegalArgumentException(e.getCause());
}
}
public static boolean isIgnoreInitMethod(String moduleName, String methodName) {
Map<String, String> ignoreMap = initIgnoreMap.getOrDefault(moduleName, null);
return ignoreMap != null && ignoreMap.containsKey(methodName);
}
public static boolean isIgnoreCheckMethod(String moduleName, String methodName) {
Map<String, String> ignoreMap = checkIgnoreMap.getOrDefault(moduleName, null);
return ignoreMap != null && ignoreMap.containsKey(methodName);
}
public static boolean isIgnoreRuleMethod(String moduleName, String methodName) {
Map<String, String> ignoreMap = ruleIgnoreMap.getOrDefault(moduleName, null);
return ignoreMap != null && ignoreMap.containsKey(methodName);
}
public static boolean isIgnoreDefaultMethod(String moduleName, String methodName) {
Map<String, String> ignoreMap = defaultIgnoreMap.getOrDefault(moduleName, null);
return ignoreMap != null && ignoreMap.containsKey(methodName);
}
public static String getMethodNameByRule(String target, String path, String method, int order) {
return String.format("%s#%s#%s#%s", target, path, method, order);
}
}
package com.brilliance.mda.runtime.mda.driver.compile;
import com.brilliance.mda.runtime.annotation.Check;
import com.brilliance.mda.runtime.annotation.Default;
import com.brilliance.mda.runtime.annotation.Init;
import com.brilliance.mda.runtime.annotation.Rule;
import com.brilliance.mda.runtime.mda.FieldHolder;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.IModuleList;
import com.brilliance.mda.runtime.mda.ModuleHolder;
import com.brilliance.mda.runtime.mda.driver.compile.component.FieldInfo;
import com.brilliance.mda.runtime.mda.driver.compile.component.RuleItem;
import com.brilliance.mda.runtime.mda.driver.compile.processor.ModuleAnnotationProcess;
import com.brilliance.mda.runtime.response.ResponseSet;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/model/view")
public class ModelViewer {
private static Map<String, Object> cache = new ConcurrentHashMap<>();
@GetMapping("/{modelClass}")
public Object viewModelData(@PathVariable String modelClass) {
//根据交易名获取数据结构列表
try {
if (cache.containsKey(modelClass)) {
return ResponseSet.simpleSuccess(cache.get(modelClass));
}
Class modelClazz = Class.forName(modelClass);
Object classDesc = outModelClazz(modelClazz);
cache.put(modelClass, classDesc);
return ResponseSet.simpleSuccess(classDesc);
} catch (Exception e) {
e.printStackTrace();
}
return ResponseSet.fail("没有找到对应的模型");
}
private Map<String, Object> outModelClazz(Class modelClazz) {
List<FieldInfo> fields = new ArrayList<>();
Map<String, Object> methods = new LinkedHashMap<>();
List<Method> skipLocals = new ArrayList<>();
Arrays.stream(modelClazz.getDeclaredFields()).forEach(field -> {
if (Modifier.isStatic(field.getModifiers())) {
return;
}
FieldInfo fieldInfo = new FieldInfo();
fieldInfo.setName(field.getName());
fieldInfo.setTypeName(field.getType().getCanonicalName());
if (IModuleList.class.isAssignableFrom(field.getType())) {
fieldInfo.setType(2);
fieldInfo.setTypeName(field.getType().getCanonicalName());
if (field.getGenericType() instanceof ParameterizedTypeImpl) {
//取出泛型
String typeName = ((ParameterizedTypeImpl) field.getGenericType()).getActualTypeArguments()[0].getTypeName();
fieldInfo.setTypeName(typeName);
}
} else if (IModule.class == field.getType()) {
fieldInfo.setType(3);
fieldInfo.setTypeName(field.getType().getCanonicalName());
} else if (IModule.class.isAssignableFrom(field.getType())) {
fieldInfo.setType(1);
fieldInfo.setTypeName(field.getType().getCanonicalName());
} else if (ModuleHolder.class.isAssignableFrom(field.getType())) {
fieldInfo.setType(3);
fieldInfo.setTypeName(field.getType().getCanonicalName());
if (field.getGenericType() instanceof ParameterizedTypeImpl) {
//取出泛型
String typeName = ((ParameterizedTypeImpl) field.getGenericType()).getActualTypeArguments()[0].getTypeName();
fieldInfo.setTypeName(typeName);
}
} else if (FieldHolder.class.isAssignableFrom(field.getType())) {
fieldInfo.setType(4);
fieldInfo.setTypeName(field.getType().getCanonicalName());
if (field.getGenericType() instanceof ParameterizedTypeImpl) {
//取出泛型
String typeName = ((ParameterizedTypeImpl) field.getGenericType()).getActualTypeArguments()[0].getTypeName();
fieldInfo.setTypeName(typeName);
}
} else {
fieldInfo.setTypeName(field.getType().getCanonicalName());
}
fields.add(fieldInfo);
//找到get,set 方法
Method setter = ModuleAnnotationProcess.getSetterMethod(field);
Method getter = ModuleAnnotationProcess.getGetterMethod(field);
if (setter != null) {
skipLocals.add(setter);
}
if (getter != null) {
skipLocals.add(getter);
}
});
List<Object> initList = new ArrayList<>();
List<Object> checkList = new ArrayList<>();
List<Object> localList = new ArrayList<>();
List<Object> defaultList = new ArrayList<>();
List<Object> staticList = new ArrayList<>();
List<Object> ruleList = new ArrayList<>();
List<Object> globalList = new ArrayList<>();
methods.put("initList", initList);
methods.put("localList", localList);
methods.put("checkList", checkList);
methods.put("defaultList", defaultList);
methods.put("staticList", staticList);
methods.put("ruleList", ruleList);
methods.put("globalList", globalList);
Arrays.stream(modelClazz.getDeclaredMethods()).forEach(method -> {
String target = null;
String belongPath = "";
int order = 0;
//屏蔽特殊方法
if ((method.getName().equals("setArgument") && method.getParameters().length == 0) || method.getName().startsWith("lambda$")) {
return;
}
if (method.isAnnotationPresent(Rule.class)) {
Rule rule = method.getAnnotation(Rule.class);
target = rule.target();
order = rule.order();
String[] multiTarget = rule.value();
if (multiTarget == null || multiTarget.length == 0) {
multiTarget = new String[]{target};
}
buildRuleItem(ruleList, RuleItem.RULE, multiTarget, method, order);
} else if (method.isAnnotationPresent(Check.class)) {
Check check = method.getAnnotation(Check.class);
target = check.target();
order = check.order();
String[] multiTarget = check.value();
if (multiTarget == null || multiTarget.length == 0) {
multiTarget = new String[]{target};
}
buildRuleItem(checkList, RuleItem.CHECK, multiTarget, method, order);
} else if (method.isAnnotationPresent(Default.class)) {
Default defaultAno = method.getAnnotation(Default.class);
target = defaultAno.target();
order = defaultAno.order();
String[] multiTarget = defaultAno.value();
if (multiTarget == null || multiTarget.length == 0) {
multiTarget = new String[]{target};
}
buildRuleItem(defaultList, RuleItem.DEFAULT, multiTarget, method, order);
} else if (method.isAnnotationPresent(Init.class)) {
Init init = method.getAnnotation(Init.class);
order = init.order();
buildRuleItem(initList, RuleItem.INIT, new String[0], method, order);
} else if (Modifier.isStatic(method.getModifiers())) {
buildRuleItem(globalList, RuleItem.GLOBAL, new String[0], method, order);
} else if (!skipLocals.contains(method)) {
buildRuleItem(localList, RuleItem.LOCAL, new String[0], method, order);
}
});
Map<String, Object> descriptions = new LinkedHashMap<>();
descriptions.put("fields", fields);
descriptions.put("rules", methods);
return descriptions;
}
private void buildRuleItem(List<Object> seriesRule, String ruleType, String[] multiTarget, Method method, int order) {
RuleItem ruleItem = new RuleItem();
ruleItem.setRuleType(ruleType);
ruleItem.setOrder(order);
ruleItem.setMethod(method);
ruleItem.setDotPath(Arrays.stream(multiTarget).reduce(new StringJoiner(","), (s, i) -> s.add(i), (a, b) -> a.add(b.toString())).toString());
seriesRule.add(ruleItem);
}
@GetMapping("/all")
public Object viewAllTrans() {
//根据交易名获取数据结构列表
List<String> rs = ModuleAnnotationProcess.cache.entrySet().stream().filter(entry -> {
return entry.getValue().isTrans();
}).map(entry -> entry.getKey()).collect(Collectors.toList());
return ResponseSet.simpleSuccess(rs);
}
}
package com.brilliance.mda.runtime.mda.driver.compile.component;
import com.brilliance.mda.runtime.annotation.Default;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.DCR;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.driver.compile.processor.ModuleAnnotationProcess;
import com.brilliance.mda.runtime.mda.impl.AbstractRuleEmitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
public abstract class AbstractAutoCompileEmitter extends AbstractRuleEmitter {
private static Logger log = LoggerFactory.getLogger(AbstractAutoCompileEmitter.class);
private boolean executeRuleList(String ruleType,String target,int order){
return executeRuleList(ruleType,target,order,false);
}
private boolean executeRuleList(String ruleType,String target,int order,boolean verifyHead){
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null){
return false;
}
if(target != null){
target = getRealPath(target);
// if(target.charAt(0) == '.' || target.charAt(0) == '\\') {
// target = target.substring(1);
// }
MdaEnv.getContext().pushEventPath(target);
}
List<RuleItem> ruleItemList = null;
switch (ruleType){
case RuleItem.INIT:ruleItemList = moduleRuleContext.getInitList();break;
case RuleItem.RULE:ruleItemList = moduleRuleContext.getEventRule().get(target);break;
case RuleItem.CHECK:ruleItemList = moduleRuleContext.getCheckRule().get(target);break;
case RuleItem.DEFAULT:ruleItemList = moduleRuleContext.getDefaultRule().get(target);break;
}
if(ruleItemList == null){
return false;
}
//开始执行RuleChain
for (int i = 0; i < ruleItemList.size(); i++) {
RuleItem ruleItem = ruleItemList.get(i);
log.debug("executeRule {}.{}.{}{}",MdaEnv.getContext().getTransName(),ruleItem.getDotPath(),ruleItem.getRuleType(),ruleItem.getOrder());
//校验函数头,当是复合型的rule声明时,需要第一个target为当前target时才会被ExecuteDefaultRule执行
if(verifyHead && !verifyMethodHead(this,ruleItem,target,ruleType)){
continue;
}
try {
switch (ruleItem.getRuleType()) {
case RuleItem.INIT:
execInitItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, MdaEnv.getContext().getRoot()));
break;
case RuleItem.CHECK:
execCheckItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, MdaEnv.getContext().getRoot()));
break;
case RuleItem.DEFAULT:
execDefaultItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, MdaEnv.getContext().getRoot()));
break;
case RuleItem.RULE:
execRuleItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, MdaEnv.getContext().getRoot()));
break;
}
} catch (Exception e) {
log.error("execute Rule Exception",e);
throw e;
} finally {
this.printSlowExecutionLog();
}
}
this.printSlowExecutionLog();
return true;
}
public static boolean verifyMethodHead(IRuleEmitter emitter,RuleItem ruleItem, String target, String ruleType){
if(ruleItem.getMethod() instanceof Method && ruleType.equals(RuleItem.DEFAULT)){
Method method = (Method) ruleItem.getMethod();
Default defaultAno = method.getAnnotation(Default.class);
if(defaultAno.value()!=null && defaultAno.value().length > 1){
String firstTarget = defaultAno.value()[0];
String path = null;;
if(firstTarget.startsWith(".")){
path = firstTarget;
}else {
path = ruleItem.getDotPath()+"."+ firstTarget;
}
path = emitter.getRealPath(path);
//复合声明,仅与第一个路径相等时,才触发
if(!target.equals(path)){
return false;
}
}
}
return true;
}
public boolean invokeRuleList(String ruleType,String target,int order){
return invokeRuleList(ruleType,target,order,false);
}
public boolean invokeRuleList(String ruleType,String target,int order,boolean verifyHead){
IContext ctx = MdaEnv.getContext();
try {
//ctx.pushEventPath(target);
return executeRuleList(ruleType,target,order,verifyHead);
} catch (Exception e) {
if(e.getCause() instanceof RuleExitException)
throw (RuleExitException) e.getCause();
else if(e instanceof RuleExitException){
throw (RuleExitException) e;
}else if(e.getCause() instanceof RulePromptException){
throw (RulePromptException) e.getCause();
}else if(e instanceof RulePromptException){
throw (RulePromptException) e;
}
else if(e.getCause() instanceof RuleExecuteException){
throw (RuleExecuteException) e.getCause();
}else if(e instanceof RuleExecuteException){
throw (RuleExecuteException) e;
}
else
throw new RuntimeException(e);
}finally {
if(!RuleItem.INIT.equals(ruleType)) {
ctx.popEventPath();
}
}
}
@Override
public boolean executeInit(int order) {
return invokeRuleList(RuleItem.INIT,null,order);
}
//执行Rule
public boolean executeRule(String target, int order)
{
return invokeRuleList(RuleItem.RULE,target,order);
}
//执行Check
public boolean executeCheck( String target, int order)
{
target = getRealPath(target);
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null){
return true;
}
for(Map.Entry<String,List<RuleItem>> entry:moduleRuleContext.getCheckRule().entrySet()){
if(!checkPathMatch(entry.getKey(),target))
continue;
boolean result = invokeRuleList(RuleItem.CHECK,entry.getKey(),order);
if(!result) {
log.warn(String.format("execute @Check[%s,%d] return false", entry.getKey(), order));
}
}
return true;
}
//执行Default
public boolean executeDefault( String target, int order) {
boolean result;
try {
result = invokeRuleList(RuleItem.DEFAULT,target,order);
}catch (Exception ex)
{
DCR.emptyDefaultQueue();
throw new RuleExecuteException("Rule执行异常",ex);
}finally {
}
return result;
}
//执行Post 的default,因为它需要验证复合声明的头
public boolean executePostDefault(String target){
return invokeRuleList(RuleItem.DEFAULT,target,-1,true);
}
public String getModuleName(){
return relatedTransaction().getCanonicalName();
}
@Override
public Map<String, Integer> getDefaultQueue() {
Map<String,Integer> defaultQueue = super.getDefaultQueue();
if(defaultQueue.isEmpty()){
synchronized (defaultQueue){
if(defaultQueue.isEmpty()){
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
//设置默认的DefaultQueue,但要排除ModuleList
if(moduleRuleContext != null){
moduleRuleContext.getDefaultRule().entrySet().forEach(stringListEntry -> {
if(!(stringListEntry.getValue().size() == 1
&& stringListEntry.getValue().get(0).getMethodName().equals("executeDefault"))) {
defaultQueue.put(stringListEntry.getKey(), 0);
}
});
}
}
}
}
return defaultQueue;
}
@Override
public boolean executeDefaultAll(){
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null){
return false;
}
moduleRuleContext.getDefaultRule().entrySet().forEach(stringListEntry -> {
executeRuleList(RuleItem.DEFAULT,stringListEntry.getKey(),-1);
});
return true;
}
}
package com.brilliance.mda.runtime.mda.driver.compile.component;
import com.brilliance.mda.runtime.mda.IContext;
import com.brilliance.mda.runtime.mda.RuleExecuteException;
import com.brilliance.mda.runtime.mda.RuleExitException;
import com.brilliance.mda.runtime.mda.RulePromptException;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.driver.compile.processor.ModuleAnnotationProcess;
import com.brilliance.mda.runtime.mda.impl.AbstractScopeEmitter;
import java.util.List;
import java.util.Map;
import static com.brilliance.mda.runtime.mda.driver.compile.component.AbstractAutoCompileEmitter.verifyMethodHead;
public abstract class AbstractAutoCompileScopeEmitter extends AbstractScopeEmitter {
private boolean executeRuleList(String ruleType,String target,int order){
return executeRuleList(ruleType,target,order,false);
}
private boolean executeRuleList(String ruleType,String target,int order,boolean verifyHead){
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null){
return false;
}
if(target != null){
target = getRealPath(target);
if(target.charAt(0) == '.' || target.charAt(0) == '\\') {
target = target.substring(1);
}
MdaEnv.getContext().pushEventPath(target);
}
List<RuleItem> ruleItemList = null;
switch (ruleType){
case RuleItem.INIT:ruleItemList = moduleRuleContext.getInitList();break;
case RuleItem.RULE:ruleItemList = moduleRuleContext.getEventRule().get(target);break;
case RuleItem.CHECK:ruleItemList = moduleRuleContext.getCheckRule().get(target);break;
case RuleItem.DEFAULT:ruleItemList = moduleRuleContext.getDefaultRule().get(target);break;
}
if(ruleItemList == null){
return false;
}
//开始执行RuleChain
for (int i = 0; i < ruleItemList.size(); i++) {
RuleItem ruleItem = ruleItemList.get(i);
//校验函数头,当是复合型的rule声明时,需要第一个target为当前target时才会被ExecuteDefaultRule执行
if(verifyHead && !verifyMethodHead(this,ruleItem,target,ruleType)){
continue;
}
try {
switch (ruleItem.getRuleType()) {
case RuleItem.INIT:
execInitItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, this.getContext()));
break;
case RuleItem.CHECK:
execCheckItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, this.getContext()));
break;
case RuleItem.DEFAULT:
execDefaultItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, this.getContext()));
break;
case RuleItem.RULE:
execRuleItem(ruleItem.getOrder(), ruleItem.getDotPath(), new RuleItemExecutor(ruleItem, this, this.getContext()));
break;
}
} catch (Exception e) {
log.error("execute Rule Exception",e);
throw e;
} finally {
this.printSlowExecutionLog();
}
}
this.printSlowExecutionLog();
return true;
}
public boolean invokeRuleList(String ruleType,String target,int order){
return invokeRuleList(ruleType,target,order,false);
}
public boolean invokeRuleList(String ruleType,String target,int order,boolean verifyHead){
IContext ctx = MdaEnv.getContext();
try {
ctx.pushEventPath(target);
return executeRuleList(ruleType,target,order,verifyHead);
} catch (Exception e) {
if(e.getCause() instanceof RuleExitException)
throw (RuleExitException) e.getCause();
else if(e.getCause() instanceof RulePromptException){
throw (RulePromptException) e.getCause();
}else if(e.getCause() instanceof RuleExecuteException){
throw (RuleExecuteException) e.getCause();
}
else
throw new RuntimeException(e);
}finally {
ctx.popEventPath();
}
}
@Override
public boolean executeInit(int order) {
return invokeRuleList(RuleItem.INIT,null,order);
}
public boolean executeRule(String target, int order)
{
return invokeRuleList(RuleItem.RULE,target,order);
}
//执行check
public boolean executeCheck( String target, int order)
{
return invokeRuleList(RuleItem.CHECK,target,order);
}
//执行default
public boolean executeDefault( String target, int order) {
return invokeRuleList(RuleItem.DEFAULT,target,order);
}
//执行Post 的default,因为它需要验证复合声明的头
public boolean executePostDefault(String target){
return invokeRuleList(RuleItem.DEFAULT,target,-1,true);
}
public String getModuleName(){
return relatedTransaction().getCanonicalName();
}
@Override
public Map<String, Integer> getDefaultQueue() {
Map<String,Integer> defaultQueue = super.getDefaultQueue();
if(defaultQueue.isEmpty()){
synchronized (defaultQueue){
if(defaultQueue.isEmpty()){
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
//设置默认的DefaultQueue,但要排除ModuleList
if(moduleRuleContext != null){
moduleRuleContext.getDefaultRule().entrySet().forEach(stringListEntry -> {
if(!(stringListEntry.getValue().size() == 1
&& stringListEntry.getValue().get(0).getMethodName().equals("executeDefault"))) {
defaultQueue.put(stringListEntry.getKey(), 0);
}
});
}
}
}
}
return defaultQueue;
}
@Override
public boolean executeDefaultAll(){
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null){
return false;
}
moduleRuleContext.getDefaultRule().entrySet().forEach(stringListEntry -> {
executeRuleList(RuleItem.DEFAULT,stringListEntry.getKey(),-1);
});
return true;
}
@Override
public boolean executeCheckAll() {
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null){
return false;
}
moduleRuleContext.getCheckRule().entrySet().forEach(stringListEntry -> {
executeRuleList(RuleItem.CHECK,stringListEntry.getKey(),-1);
});
return true;
}
}
package com.brilliance.mda.runtime.mda.driver.compile.component;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.IModuleList;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.driver.compile.processor.ModuleAnnotationProcess;
import lombok.AllArgsConstructor;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@AllArgsConstructor
public class DefaultAutoCompileEmitter extends AbstractAutoCompileEmitter{
private Class transClass;
@Override
public Class<?> relatedTransaction() {
return transClass;
}
public IModule getRoot(){
return MdaEnv.getContext().getRoot();
}
@Override
public List<IModuleList> getAllModuleList() {
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null)
return new ArrayList<>();
return moduleRuleContext.getModuleList().stream().map(item->{
return MdaDriver.getModuleList(this.getRoot(),item);
}).collect(Collectors.toList());
}
}
package com.brilliance.mda.runtime.mda.driver.compile.component;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.IModuleList;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.driver.compile.processor.ModuleAnnotationProcess;
import lombok.AllArgsConstructor;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@AllArgsConstructor
public class DefaultAutoCompileScopeEmitter extends AbstractAutoCompileScopeEmitter{
private Class transClass;
@Override
public Class<?> relatedTransaction() {
return transClass;
}
public IModule getRoot(){
return this.getContext();
}
@Override
public List<IModuleList> getAllModuleList() {
String moduleName = getModuleName();
ModuleRuleContext moduleRuleContext = ModuleAnnotationProcess.cache.get(moduleName);
if(moduleRuleContext == null)
return new ArrayList<>();
return moduleRuleContext.getModuleList().stream().map(item->{
return MdaDriver.getModuleList(this.getRoot(),item);
}).collect(Collectors.toList());
}
}
package com.brilliance.mda.runtime.mda.driver.compile.component;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@AllArgsConstructor
public class RuleItemExecutor implements Ruleable<Boolean> {
private static Logger log = LoggerFactory.getLogger(RuleItemExecutor.class);
private RuleItem ruleItem;
private IRuleEmitter ruleEmitter;
private IModule root;
public Boolean exec(){
IModule module = (IModule) MdaDriver.getBaseObject(root,ruleItem.getDotPath());
Object rs = null;
if(module instanceof IModuleList && "executeDefault".equals(ruleItem.getMethodName())){
((IModuleList)module).executeDefault();
return true;
}else if(module instanceof IModuleList && "executeInit".equals(ruleItem.getMethodName())){
((IModuleList)module).executeInit();
return true;
}
else if(ruleItem.getMethod() instanceof Method){
try {
boolean invoke = (boolean) (((Method) ruleItem.getMethod()).invoke(module));
return invoke;
}catch (RulePromptException e) {
return true;
}catch(IllegalAccessException e){
}catch (InvocationTargetException e){
if(e.getCause() instanceof RuntimeException){
throw (RuntimeException)e.getCause();
}
}
return false;
}
else {
rs = MdaUtils.invoke(module, ruleItem.getMethodName());
}
if(rs == null ){
return false;
}
return (Boolean)rs;
}
public RuleItem getRuleItem() {
return ruleItem;
}
public IRuleEmitter getRuleEmitter() {
return ruleEmitter;
}
public IModule getRoot() {
return root;
}
}
package com.brilliance.mda.runtime.mda.driver.compile.component;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.Ruleable;
public abstract class RuleableCompile implements Ruleable<Boolean> {
public RuleableCompile(){
}
@Override
public Boolean exec() {
return false;
}
public abstract Boolean exec(IModule root);
}
package com.brilliance.mda.runtime.mda.driver.compile.processor;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.driver.MdaScanner;
import com.brilliance.mda.runtime.mda.driver.compile.component.AbstractAutoCompileScopeEmitter;
import com.brilliance.mda.runtime.mda.driver.compile.component.ModuleRuleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ModuleListAnnotationProcessor extends TransAnnotationProcessor {
private final Logger log = LoggerFactory.getLogger(this.getClass());
public ModuleListAnnotationProcessor(){
super(false);
}
public void buildModuleListEmitter(Class moduleClass, ModuleRuleContext moduleRuleContext){
try {
//初始化上下文
init(moduleClass);
this.setBeanDefinitionRegistry(MdaEnv.getBean(MdaScanner.class).getBeanDefinitionRegistry());
IModule rootIns = (IModule) moduleClass.newInstance();
this.makeInstance(rootIns,true);
//设置为支持使用emitter了
moduleRuleContext.setUseEmitter(true);
//设置RuleContext
this.setModuleRuleContext(moduleRuleContext);
//注册Emitter
registerEmitterToBeanFactory();
//合并上下文
this.mergeTransRules();
//rule 排序
this.getModuleRuleContext().sortRule();
this.pushToProcessQueue();
}catch (Exception e){
e.printStackTrace();
}
}
public void mergeTransRules(){
//scopeEmitter需要设置上下文
AbstractAutoCompileScopeEmitter abstractAutoCompileScopeEmitter = (AbstractAutoCompileScopeEmitter) MdaEnv.getBean(this.getEmitterKey());
abstractAutoCompileScopeEmitter.acceptContext(this.getInstatnce());
super.mergeTransRules();
abstractAutoCompileScopeEmitter.removeContext();
}
}
package com.brilliance.mda.runtime.mda.driver.compile.processor;
import com.brilliance.mda.runtime.annotation.Transaction;
import com.brilliance.mda.runtime.mda.IContext;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.driver.MdaContext;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.driver.compile.EmitterManager;
import com.brilliance.mda.runtime.mda.driver.compile.component.DefaultAutoCompileEmitter;
import com.brilliance.mda.runtime.mda.driver.compile.component.DefaultAutoCompileScopeEmitter;
import com.brilliance.mda.runtime.mda.driver.compile.component.ModuleRuleContext;
import com.brilliance.mda.runtime.mda.driver.compile.component.RuleItem;
import com.brilliance.mda.runtime.mda.impl.AbstractRuleEmitter;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import java.util.*;
@Data
public class TransAnnotationProcessor extends ModuleAnnotationProcess {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private static List<TransAnnotationProcessor> transAnnotationProcessorsQueue = new LinkedList<>();
private String transName;
private String transNameUpper;
private Class<?> rootClazz;
private BeanDefinitionRegistry beanDefinitionRegistry;
private IModule rootIns;
private boolean isTrans;
public String getEmitterKey(){
return "emitter2."+ this.transName;
}
public TransAnnotationProcessor(){
isTrans = true;
}
public TransAnnotationProcessor(boolean isTrans){
this.isTrans = isTrans;
}
protected void init(Class<?> rootClass){
rootClazz = rootClass;
String transName = rootClass.getSimpleName().toLowerCase();
if(rootClass.isAnnotationPresent(Transaction.class)){
Transaction trnAno = rootClass.getAnnotation(Transaction.class);
if(trnAno.value()!=null && !trnAno.value().isEmpty()){
transName = trnAno.value();
}
}
this.transName = transName;
this.transNameUpper = transName.substring(0,1).toUpperCase()+transName.substring(1);
}
public void buildTransEmitter(Class<?> rootClass, BeanDefinitionRegistry beanDefinitionRegistry) {
try {
//初始化上下文
init(rootClass);
this.beanDefinitionRegistry = beanDefinitionRegistry;
IModule rootIns = (IModule) rootClass.newInstance();
IContext ctx = new MdaContext(rootIns);
this.makeInstance(rootIns,true);
//变量模型
walkModule();
//注册Emitter
registerEmitterToBeanFactory();
//合并Rule Path
mergeTransRules();
this.getModuleRuleContext().sortRule();
pushToProcessQueue();
EmitterManager.loadEmitterIgnoreInfo(rootClass);
}catch (Exception e){
log.error("遍历模型发生异常:{}",e);
}
}
public void registerEmitterToBeanFactory() {
if(isTrans) {
this.getModuleRuleContext().setTrans(true);
registerBean(this.getEmitterKey(),DefaultAutoCompileEmitter.class);
}
else{
this.getModuleRuleContext().setTrans(false);
registerBean(this.getEmitterKey(),DefaultAutoCompileScopeEmitter.class);
}
}
/**
注册bean
**/
private void registerBean( String name, Class<?> beanClass) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
beanDefinitionBuilder.addConstructorArgValue(rootClazz);
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition(name, beanDefinition);
}
/**
* 合并当前所有rule的路径
*/
public void mergeTransRules(){
//利用Emitter开启rule合并
AbstractRuleEmitter abstractRuleEmitter = (AbstractRuleEmitter)MdaEnv.getBean(this.getEmitterKey());
//添加Rule系列函数
Map<String,List<RuleItem>> eventRuleMap = mergeMapRuleItem(abstractRuleEmitter,this.getModuleRuleContext().getEventRule());
Map<String,List<RuleItem>> checkRuleMap = mergeMapRuleItem(abstractRuleEmitter,this.getModuleRuleContext().getCheckRule());
Map<String,List<RuleItem>> defaultRuleMap = mergeMapRuleItem(abstractRuleEmitter,this.getModuleRuleContext().getDefaultRule());
if(isTrans) {
//交易下的rule做下合并和排序
this.getModuleRuleContext().setEventRule(eventRuleMap);
this.getModuleRuleContext().setCheckRule(checkRuleMap);
this.getModuleRuleContext().setDefaultRule(defaultRuleMap);
this.getModuleRuleContext().sortRule();
}else{
//支持ModuleList的Module,为其创建一个副本,因为后续交易编译还要使用。
this.getModuleRuleContext().setUseEmitter(true);
this.getModuleRuleContext().setMergedContext(new ModuleRuleContext(this.getModuleRuleContext().getModuleName(),false));
this.getModuleRuleContext().getMergedContext().setEventRule(eventRuleMap);
this.getModuleRuleContext().getMergedContext().setCheckRule(checkRuleMap);
this.getModuleRuleContext().getMergedContext().setDefaultRule(defaultRuleMap);
this.getModuleRuleContext().getMergedContext().setInitList(this.getModuleRuleContext().getInitList());
this.getModuleRuleContext().getMergedContext().sortRule();
}
}
/**
* 合并rule map,并返回一个副本
*/
private Map<String,List<RuleItem>> mergeMapRuleItem(AbstractRuleEmitter abstractRuleEmitter, Map<String,List<RuleItem>> ruleMap){
Map<String,List<RuleItem>> nRuleMap = new LinkedHashMap<>();
for(Map.Entry<String,List<RuleItem>> entry: ruleMap.entrySet()){
String target = entry.getKey();
List<RuleItem> ruleItemList = entry.getValue();
target = abstractRuleEmitter.getRealPath(target);
List<RuleItem> nRuleItemList = nRuleMap.get(target);
if(nRuleItemList == null){
nRuleItemList = new ArrayList<>();
nRuleMap.put(target,nRuleItemList);
}
nRuleItemList.addAll(ruleItemList);
}
return nRuleMap;
}
public void pushToProcessQueue(){
transAnnotationProcessorsQueue.add(this);
}
public static List<TransAnnotationProcessor> getProcessQueue(){
return transAnnotationProcessorsQueue;
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.util.RuleUtils;
import org.apache.poi.poifs.macros.Module;
import java.util.ArrayList;
import java.util.List;
/**
* @Description
* @Author s_guodong
* @Date 2022/11/15
*/
public abstract class AbstractBaseObject implements IBaseObject {
protected transient List<IRule> defaultRules = null;
protected transient IParent parent;
protected transient long key = -1L;
protected transient String name;
protected transient String url;
protected transient boolean sorted = false;
protected transient boolean disposed = false;
public AbstractBaseObject(IParent parent) {
this.parent = parent;
}
public synchronized void dispose() {
if (this.disposed)
return;
if (this.defaultRules != null)
this.defaultRules.clear();
this.defaultRules = null;
this.parent = null;
this.name = null;
this.url = null;
this.disposed = true;
try {
finalize();
} catch (Throwable throwable) {}
}
public boolean isDisposed() {
return this.disposed;
}
public abstract void clear();
public long getIdAttributeKey() {
return this.key;
}
public void setIdAttributeKey(long key) {
this.key = key;
}
public Object setAttribute(String name, Object attribute) {
if (this instanceof IParent)
return ((IParent)this).setAttribute(this, name, attribute);
return this.parent.setAttribute(this, name, attribute);
}
public Object getAttribute(String name) {
if (this instanceof IParent)
return ((IParent)this).getAttribute(this, name);
if (this.parent == null)
System.out.println(getUrl());
return this.parent.getAttribute(this, name);
}
public IModule getParent() {
return (IModule)this.parent;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public void addDefaultRule(IRule rule) {
if (this.defaultRules == null)
this.defaultRules = new ArrayList<IRule>();
this.defaultRules.add(rule);
}
protected void sort() {
this.sorted = true;
RuleUtils.sort(this.defaultRules);
}
public boolean invokeDefaultRules(IContext ctx) {
if (!this.sorted)
sort();
return RuleUtils.invoke(this.defaultRules, ctx, null);
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public abstract class AbstractDaoSession {
private DataSourceTransactionManager transactionManager;
private ThreadLocal<TransactionStatus> status = new ThreadLocal<TransactionStatus>();
public AbstractDaoSession() {
}
private DataSourceTransactionManager getTransactionManager() {
if (transactionManager == null)
transactionManager = MdaEnv.getBean(DataSourceTransactionManager.class);
return transactionManager;
}
public void dbBegin() {
if(isOpenTrans()) //事务为提交,回滚
this.dbRollback();
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
status.set(getTransactionManager().getTransaction(def));
}
public void dbCommit() {
if(isOpenTrans())
{
getTransactionManager().commit(status.get());
status.remove();
}
}
public void dbRollback() {
if(isOpenTrans())
{
getTransactionManager().rollback(status.get());
status.remove();
}
new RuntimeException("业务处理错误,手动rollback");
}
public boolean isOpenTrans() {
return status.get() != null;
//return false;
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.annotation.Module;
import com.brilliance.mda.runtime.mda.IBaseObject;
import com.brilliance.mda.runtime.mda.IDatafield;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.IModuleRoot;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
@JsonFilter("fieldFilter")
@Module
public abstract class AbstractModule implements IModule, IModuleRoot {
protected Logger logger = LoggerFactory.getLogger(this.getClass().getName());
private String _path;
private String _name;
private IModule _parent;
private boolean _entityflg;
private String serialNum;
private Map<String, Object> attrMaps = new HashMap<>();
public AbstractModule() {
}
public AbstractModule(String name, IModule parent) {
this._name = name;
this._parent = parent;
String prefix = parent.getPath();
if (prefix == null || prefix.length() == 0)
this._path = this._name;
else
this._path = prefix + "." + this._name;
this._entityflg = false;
}
public AbstractModule(String name, IModule parent, boolean isEntity) {
this(name, parent);
this._entityflg = true;
}
public String getFieldPath(String fieldName) {
try {
IBaseObject baseObj = MdaDriver.getBaseObject(this, fieldName);
if (baseObj == null)
return "";
return baseObj.getPath();
// Field field = this.getClass().getDeclaredField(fieldName);
// if(field.getType() == DatafieldImpl.class) //是引用模式的
// {
// return ((DatafieldImpl)field.get(this)).getPath();
// }
} catch (Exception e) {
e.printStackTrace();
}
return "";
// if(null==this._path || this._path.length() ==0 )
// return fieldName;
// return this._path +"."+ fieldName;
}
@JsonIgnore
public String getPath() {
if (this._parent != null && this._parent instanceof ModuleList) {
int idx = ((ModuleList) this._parent).indexOf(this);
String path = this._parent.getPath() + "(" + (idx + 1) + ")";
return path;
}
String _name = this._name;
if (_name == null) {
return separator;
}
IModule _this = this._parent;
StringBuilder sb = new StringBuilder(_name);
while (!(_this.getParent() instanceof ModuleList) && _this.getParent() != null) {
sb.insert(0, _this.getName() + separator);
_this = _this.getParent();
}
if (_this.getParent() == null) {
return this._path == null ? separator : this._path.toUpperCase();
} else {
return _this.getPath() + separator + sb.toString().toUpperCase();
}
}
@JsonIgnore
public String getName() {
return _name;
}
@JsonIgnore
public IModule getParent() {
return _parent;
}
@JsonIgnore
public boolean isEntity() {
return this._entityflg;
}
@Override
public String getSerialNum() {
return serialNum;
}
public void setSerialNum(String serialNum) {
this.serialNum = serialNum;
}
@Override
public void copyValue(IModule src) {
MdaDriver.copyValues(this, src);
}
@Override
public void copyValues(IModule src) {
MdaDriver.copyValues(this, src);
}
public void clear() {
MdaDriver.clearModule(this);
}
/**
* 废弃的方法,不要再使用了
*
* @return
*/
@Deprecated
@Override
@JsonIgnore
public Collection<IDatafield> getDatafields() {
List<IDatafield> list = new ArrayList<>();
Field[] fs = this.getClass().getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field field = fs[i];
if (field.getName().charAt(0) == '_') {
continue;
}
if (field.getType() == DatafieldImpl.class) {
try {
list.add((IDatafield) field.get(this));
} catch (IllegalAccessException e) {
logger.warn("get field exception", e);
}
}
list.add(new DatafieldImpl(this._parent, field));
}
return new ArrayList<>();
}
/**
* 基于反射实现,尽量不用
*
* @return 当前模型下所有的子模型,包括ModuleList
*/
@JsonIgnore
public List<IModule> getModules() {
Class clazz = this.getClass();
ArrayList<IModule> moduleList = new ArrayList<>();
try {
for (Field field : clazz.getDeclaredFields()) {
String name = field.getName(); //获取
String getterName = "get" + MdaDriver.firstUpper(name);
try {
Method m = clazz.getMethod(getterName);
if (IModule.class.isAssignableFrom(m.getReturnType())) {
moduleList.add((IModule) m.invoke(this));
}
} catch (Exception e) {
}
}
} catch (Exception e) {
}
return moduleList;
}
/**
* todo
*
* @param key
* @return
*/
public IBaseObject get(String key) {
return null;
}
@Override
public void assignSerialNum() {
if (StringUtils.isEmpty(this.serialNum)) {
this.setSerialNum(MdaUtils.generateSerialNum());
}
}
@Override
public Map<String, Object> getAttrMaps() {
return attrMaps;
}
public void setAttrMaps(Map<String, Object> attrMaps) {
this.attrMaps = attrMaps;
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.IBaseObject;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import java.util.Stack;
public abstract class AbstractScopeEmitter extends AbstractRuleEmitter{
private ThreadLocal<Stack<IModule>> scopeContext = new ThreadLocal<>();
public void acceptContext(IModule module){
Stack<IModule> stack = scopeContext.get();
if(scopeContext.get() == null){
stack = new Stack<>();
scopeContext.set(stack);
}
stack.push(module);
}
public void removeContext(){
Stack<IModule> stack = scopeContext.get();
if(stack == null){
return;
}
stack.pop();
if(stack.empty()){
scopeContext.remove();
}
}
public IModule getContext(){
Stack<IModule> stack = scopeContext.get();
if(stack == null){
return null;
}
return stack.peek();
}
@Override
public String getRealPath(String path)
{
if(path==null) return "";
String realPath = eqMap.get(path);
if(realPath != null)
return realPath;
//计算path
IBaseObject baseObject = MdaDriver.getBaseObject(getContext(),path);
if(baseObject != null )
realPath = getModuleListFieldAbsolutePath(getContext(),baseObject);
else
{
int lastIndex = path.lastIndexOf('.');
if(lastIndex > 0)
{
//取父级模型,因为按钮在实际中不存在
baseObject = MdaDriver.getBaseObject(getContext(),path.substring(0,lastIndex));
if(baseObject!=null && baseObject instanceof IModule)
{
realPath = ((IModule)baseObject).getFieldPath(path.substring(lastIndex+1));
if(realPath == null || realPath.length() ==0)
{
realPath = baseObject.getPath()+"."+path.substring(lastIndex+1);
}
}
}else{
realPath = path;
eqMap.put(path,realPath);
return realPath;
}
}
if(realPath == null)
return path;
realPath = realPath.toLowerCase().replaceAll("\\\\",".");
if(realPath.charAt(0) == '.')
realPath = realPath.substring(1);
String parentPath = getContext().getPath();
realPath = realPath.substring(parentPath.length());
eqMap.put(path,realPath);
return realPath;
}
public String getModuleListFieldAbsolutePath(IModule itemModule, IBaseObject baseObject){
IModule parent = baseObject.getParent();
StringBuilder sb = new StringBuilder(baseObject.getName());
while(parent != itemModule){
sb.insert(0,parent.getName()+"\\");
parent = parent.getParent();
}
if(parent != null)
sb.insert(0,itemModule.getPath()+"\\");
return sb.toString();
}
}
package com.brilliance.mda.runtime.mda.impl;
public abstract class AbstractTransaction extends AbstractModule {
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.util.RuleUtils;
import java.util.*;
/**
* @Description
* @Author s_guodong
* @Date 2022/11/11
*/
public class AttributeValue<E> extends SimpleValue<E> implements IAttribute, IAttributeValue<E> {
protected transient Map<String, Object> attributes = null;
protected transient List<IRule> checkRules = null;
protected transient List<IEventRule> eventRules = null;
public AttributeValue() {
}
public AttributeValue(E value) {
super(value);
}
public AttributeValue(E value, Class clazz) {
super(value, clazz);
}
public Object setAttribute(String name, Object attribute) {
if (attribute == null)
return (this.attributes == null) ? null : this.attributes.remove(name);
if (this.attributes == null)
this.attributes = new HashMap<String, Object>();
return this.attributes.put(name, attribute);
}
public Object getAttribute(String name) {
if (this.attributes == null)
return null;
return this.attributes.get(name);
}
public Set getAttributeNameSet() {
if (this.attributes == null)
return Collections.EMPTY_SET;
return this.attributes.keySet();
}
public void addCheckRule(IRule rule) {
if (this.checkRules == null)
this.checkRules = new ArrayList<IRule>();
this.checkRules.add(rule);
}
public void addEventRule(IEventRule rule) {
if (this.eventRules == null)
this.eventRules = new ArrayList<IEventRule>();
this.eventRules.add(rule);
}
public boolean invokeEventRules(IContext ctx, EventType type, Object data, int... orders) {
return (this.eventRules == null) ? true : RuleUtils.invoke(this.eventRules, ctx, new Event(this, type, data), orders);
}
public boolean invokeCheckRules(IContext ctx) {
return (this.checkRules == null) ? true : RuleUtils.invoke(this.checkRules, ctx, this);
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.FieldHolder;
import com.brilliance.mda.runtime.mda.IDatafield;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class DatafieldImpl<T> implements IDatafield<T> {
private IModule parent;
private String name;
private Field field;
private Method setter;
private Method getter;
private String path;
public DatafieldImpl(IModule parent, Field field)
{
this.parent = parent;
this.name = field.getName();
this.field = field;
initField();
}
public DatafieldImpl(IModule parent, String fieldName)
{
this.parent = parent;
this.name = fieldName;
try{
this.field = parent.getClass().getDeclaredField(fieldName);
}catch (Exception e)
{
e.printStackTrace();
}
initField();
}
private void initField()
{
field.setAccessible(true);
if(field.getType() == FieldHolder.class)
{
try{
FieldHolder holder = (FieldHolder) field.get(parent);
this.path = holder.getPath();
}catch (Exception e)
{
}
}
else{
String prefix = parent.getPath();
if(prefix == null || prefix.length() ==0)
this.path = this.name;
else
this.path = prefix + "." + this.name;
}
try {
String gettStr = "get"+firstUpper(this.name);
this.getter = parent.getClass().getMethod(gettStr);
}catch (Exception e){}
try {
String settStr = "set" + firstUpper(this.name);
if(this.getter!=null)
this.setter = parent.getClass().getMethod(settStr,this.getter.getReturnType());
else if(this.field != null)
this.setter = parent.getClass().getMethod(settStr,this.field.getType());
}catch (Exception e){}
}
public IModule getParent() {
return parent;
}
public String getName() {
return name;
}
@SuppressWarnings("unchecked")
public T getValue() {
try {
if(this.getter != null)
return (T)this.getter.invoke(parent);
} catch (Exception e)
{
}
return null;
}
public void setValue(T value) {
try {
if(this.setter != null)
setter.invoke(parent,value);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String getPath() {
return this.path;
}
public void clear(){
if(this.setter != null)
{
Class<?>[] clazz = this.setter.getParameterTypes();
if(clazz.length ==1)
{
Object obj = MdaDriver.zero(clazz[0]);
try {
this.setter.invoke(parent,obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private String firstUpper(String str)
{
if(str.length()<=1)
return str.toUpperCase();
return str.substring(0,1).toUpperCase()+str.substring(1);
}
public Class<T> getDataType()
{
return (Class<T>)getter.getReturnType();
}
@Override
public void setAttribute(Object k, Object v) {
}
@Override
public Object getAttribute(Object k) {
return null;
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.IBaseObject;
import com.brilliance.mda.runtime.mda.IDatafield;
import com.brilliance.mda.runtime.mda.IModule;
import com.brilliance.mda.runtime.mda.IModuleList;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@JsonFilter("fieldFilter")
public class ModuleList<T extends IModule> extends ArrayList<T> implements IModuleList<T> {
/**
*
*/
private static final long serialVersionUID = 7746471631508303843L;
private Map<String, Object> attrMaps = new HashMap<>();
private IModule _parent;
private String _name;
private String _path;
private int fullDbSize;
private Class<T> dataClass;
private static Field parentField;
private String moduleType;
static {
try {
parentField = AbstractModule.class.getDeclaredField("_parent");
parentField.setAccessible(true);
} catch (Exception e) {
}
}
public ModuleList() {
}
public ModuleList(String name, IModule parent, Class<T> dataClass) {
this._parent = parent;
this._name = name;
String prefix = parent.getPath();
if (prefix == null || prefix.length() == 0 || prefix.equals(separator))
this._path = separator + this._name;
else
this._path = prefix + separator + this._name;
this.dataClass = dataClass;
this.moduleType = dataClass.getSimpleName().toLowerCase();
}
public ModuleList(String name, IModule parent, int initSize, Class<T> dataClass) {
this(name, parent, dataClass);
initData(initSize);
}
private void initData(int initSize) {
try {
for (int i = 0; i < initSize; i++) {
T module = dataClass.newInstance();
this.addElement(module);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void clear() {
super.clear();
this.fullDbSize = -1;
}
@JsonIgnore
public IModule getParent() {
return _parent;
}
@JsonIgnore
public String getName() {
return _name;
}
@JsonIgnore
@Override
public String getPath() {
return this._path.toUpperCase();
}
//数据库总体数据量
@JsonIgnore
public int getFullDbSize() {
return this.fullDbSize;
}
//获取类型数据
@JsonIgnore
public Class<T> getDataClass() {
return this.dataClass;
}
@JsonIgnore
public int fullSize() {
return this.size();
}
public void removeAll() {
this.clear();
}
/**
* 废弃的方法,不建议使用
*
* @param args IDatafield Argument 两项参数
*/
@Override
public T add(Object... args) {
if (args == null || args.length == 0) return null;
T bean = null;
try {
bean = this.getDataClass().newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
for (Object obj : args) {
if (obj instanceof Argument) {
Argument arg = (Argument) obj;
setFieldValue(arg.getFieldName(), arg.getValue(), bean);
} else if (obj instanceof IDatafield) {
IDatafield df = (IDatafield) obj;
setFieldValue(df.getName(), df.getValue(), bean);
}
}
this.add(bean);
updateParentField(bean);
return bean;
}
private void updateParentField(IModule item) {
try {
parentField.set(item, this);
} catch (Exception e) {
}
}
@Override
public void addElement(T em) {
em.assignSerialNum();
super.add(em);
updateParentField(em);
}
@Override
public void addElement(int idx, T em) {
em.assignSerialNum();
super.add(idx - 1, em);
updateParentField(em);
}
@JsonIgnore
public T getElement(int idx) {
return super.get(idx--);
}
private void setFieldValue(String name, Object value, T bean) {
try {
Field f = this.getDataClass().getDeclaredField(name);
f.setAccessible(true);
f.set(bean, value);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
public void copyValues(IModuleList list) {
if (list.getDataClass() != this.getDataClass())
return;
this.clear();
this.addAll(list);
}
private AbstractScopeEmitter getEmitter() {
String emitterName = AbstractScopeEmitter.EMITTER_PRE + moduleType;
AbstractScopeEmitter emitter = (AbstractScopeEmitter) MdaEnv.getBean(emitterName);
return emitter;
}
@Override
public boolean executeInit() {
AbstractScopeEmitter emitter = getEmitter();
if (emitter == null) {
return true;
}
for (int i = 1; i <= this.size(); i++) {
emitter.acceptContext(this.getElement(i));
try {
emitter.executeInit();
} catch (Exception e) {
e.printStackTrace();
}
}
emitter.removeContext();
return true;
}
@Override
public boolean executeInit(int idx) {
AbstractScopeEmitter emitter = getEmitter();
if (emitter == null) {
return true;
}
emitter.acceptContext(this.getElement(idx));
emitter.executeInit();
emitter.removeContext();
return true;
}
@Override
public void executeDefault(String... paths) {
AbstractScopeEmitter emitter = getEmitter();
if (emitter == null) {
return;
}
for (int i = 1; i <= this.size(); i++) {
emitter.acceptContext(this.getElement(i));
if (paths.length == 0) {
emitter.executeDefaultAll();
} else {
for (String path : paths) {
emitter.executeDefault(path);
}
}
}
emitter.removeContext();
}
@Override
public void executeDefault(int idx, String... paths) {
AbstractScopeEmitter emitter = getEmitter();
if (emitter == null) {
return;
}
emitter.acceptContext(this.getElement(idx));
if (paths.length == 0) {
emitter.executeDefaultAfterInit();
} else {
for (String path : paths) {
emitter.executeDefault(path);
}
}
emitter.removeContext();
}
@Override
public void executeCheckAll() {
AbstractScopeEmitter emitter = getEmitter();
if (emitter == null) {
return;
}
String prefix = this._path;
if (prefix.charAt(0) == '\\') {
prefix = prefix.substring(1);
}
prefix = prefix.replace("\\", ".").toLowerCase();
for (int i = 1; i <= this.size(); i++) {
emitter.acceptContext(this.getElement(i));
MdaEnv.setModuleListCheckItem(prefix + "." + (i - 1));
emitter.executeCheckAll();
}
emitter.removeContext();
}
@Override
public String getFieldPath(String fieldName) {
return null;
}
@Override
public IBaseObject get(String paramString) {
return null;
}
@Override
public Map<String, Object> getAttrMaps() {
return attrMaps;
}
public void setAttrMaps(Map<String, Object> attrMaps) {
this.attrMaps = attrMaps;
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.util.RuleUtils;
import java.util.ArrayList;
import java.util.List;
public class PanelImpl extends AbstractBaseObject implements IPanel {
protected final transient List<IEventRule> eventRules = new ArrayList<IEventRule>();
protected transient Object window;
private String titleI18nKey;
public PanelImpl(IParent parent, String name, String titleI18nKey) {
super(parent);
this.name = name;
this.titleI18nKey = titleI18nKey;
}
public synchronized void dispose() {
this.eventRules.clear();
this.window = null;
super.dispose();
}
@Override
public String getPath() {
return this.name;
}
@Override
public void clear() {
}
@Override
public String getLanguage() {
return null;
}
public IModule getModule() {
return (IModule) this.parent;
}
public String getTitleI18nKey() {
return this.titleI18nKey;
}
public void setWindow(Object window) {
this.window = window;
}
public Object getWindow() {
return this.window;
}
public void addEventRule(IEventRule rule) {
this.eventRules.add(rule);
}
protected void sort() {
super.sort();
RuleUtils.sort2(this.eventRules);
}
public boolean invokeEventRules(IContext ctx, Event event) {
if (!this.sorted)
sort();
return RuleUtils.invoke(this.eventRules, ctx, event, new int[0]);
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.IValue;
/**
* @Description
* @Author s_guodong
* @Date 2022/11/11
*/
public class SimpleValue<E> implements IValue<E> {
E value;
Class clazz;
public SimpleValue() {
this.clazz = Object.class;
}
public SimpleValue(E value, Class clazz) {
this.value = value;
this.clazz = clazz;
}
public SimpleValue(Class clazz) {
this(null, clazz);
}
public SimpleValue(E value) {
this(value, (value == null) ? Object.class : value.getClass());
}
public E setValue(E value) {
this.value = value;
return this.value;
}
public E getValue() {
return this.value;
}
public Class getDataType() {
return this.clazz;
}
public int compareTo(IValue<E> o) {
if (o == null)
return 1;
E nValue = (E)o.getValue();
if (this.value == null || nValue == null)
return (this.value == null) ? -1 : 1;
return this.value.toString().compareTo(nValue.toString());
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.IAttributeValue;
import com.brilliance.mda.runtime.mda.IDatafield;
import com.brilliance.mda.runtime.mda.IValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Description
* @Author s_guodong
* @Date 2022/11/15
*/
public class StreamGrid extends ArrayList<IValue[]> {
static IAttributeValue[] EMPTY = new IAttributeValue[0];
IAttributeValue[] headers;
List<IAttributeValue[]> extHeaders;
int index = -1;
IDatafield datafield;
public IAttributeValue[] getHeaders() {
if (this.headers == null)
return EMPTY;
return this.headers;
}
public void setHeaders(IAttributeValue[] headers) {
this.headers = headers;
}
public List<IAttributeValue[]> getExtHeaders() {
if (this.extHeaders == null)
return Collections.EMPTY_LIST;
return this.extHeaders;
}
public void setExtHeaders(List<IAttributeValue[]> extHeaders) {
this.extHeaders = extHeaders;
}
public int getIndex() {
if (this.index >= size())
setIndex(-1);
return this.index;
}
public void setIndex(int index) {
if (index >= size() || index < 0)
index = -1;
this.index = index;
}
public IDatafield getDatafield() {
return this.datafield;
}
public void setDatafield(IDatafield datafield) {
this.datafield = datafield;
}
public void clear() {
this.datafield = null;
this.index = -1;
super.clear();
}
}
package com.brilliance.mda.runtime.mda.impl;
import com.brilliance.mda.runtime.mda.IStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
* IStream 代理类
*/
public class StreamProxy extends DataGrid implements IStream {
private IStream source;
public StreamProxy() {
}
public StreamProxy(IStream source) {
this.source = source;
}
public void setSource(IStream source) {
this.source = source;
}
@Override
public InputStream getInputStream() {
if (source != null)
return source.getInputStream();
return null;
}
@Override
public OutputStream getOutputStream() {
if (source != null)
return source.getOutputStream();
return null;
}
@Override
public void close() {
if (source != null)
source.close();
}
@Override
public boolean isEmpty() {
if (source != null)
return source.isEmpty();
return false;
}
@Override
public void setType(String type) {
if (source != null)
source.setType(type);
}
@Override
public String getType() {
if (source != null)
return source.getType();
return null;
}
@Override
public void setName(String name) {
if (source != null)
source.setName(name);
}
@Override
public String getName() {
if (source != null)
return source.getName();
return null;
}
@Override
public String setValue(String value) {
if (source != null)
return source.setValue(value);
return value;
}
@Override
public String getValue() {
if (source != null)
return source.getValue();
return null;
}
}
package com.brilliance.mda.runtime.mda.listener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
/**
* 关闭监听
* @author fukai
*
*/
public class EndListener implements ApplicationListener<ContextClosedEvent>{
@Override
public void onApplicationEvent(ContextClosedEvent event) {
}
}
package com.brilliance.mda.runtime.mda.listener;
import com.brilliance.mda.runtime.mda.IDaoSession;
import com.brilliance.mda.runtime.mda.IRuleEmitter;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class StartListener implements ApplicationListener<ContextRefreshedEvent>{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext context = event.getApplicationContext();
//EnvConfig config = context.getBean(EnvConfig.class);
//引入全局pplication context
//String packagePath = config.getTransPackage().replaceAll("\\.", "/");
//扫描所有的交易
//scanModule(context,packagePath);
//扫描提供给MdaContext调用的Dao
scanDao(context);
//扫描事件触发器
//scanEmitter(context);
}
// public void scanModule(ApplicationContext context,String packagePath){
// MdaScanner scanner = context.getBean(MdaScanner.class);
// try {
// Set<Class<?>> clsSet = scanner.doScan(packagePath,Transaction.class);
// //MdaDynamicGenerator.createRuleEmitter(clsSet);
// MdaDriver.createVoSetterAndGetter(clsSet);
// //MdaDynamicGenerator.createVoSetterAndGetter(clsSet);
// } catch (ClassNotFoundException | IOException e) {
// e.printStackTrace();
// }
// }
public void scanDao(ApplicationContext context){
Map<String,Object> beans = context.getBeansWithAnnotation(Mapper.class);
IDaoSession daoProxy = context.getBean(IDaoSession.class);
DaoCyc:
for(Map.Entry<String, Object> entry : beans.entrySet())
{
Object dao = entry.getValue();
Class<?>[] interfaces = dao.getClass().getInterfaces();
if(interfaces == null)
continue;
for(Class<?> inf : interfaces)
{
Type[] types = inf.getGenericInterfaces();
if(types == null)
continue;
for(Type type:types)
{
if(!(type instanceof ParameterizedType))
continue;
Type[] paramTypes = ((ParameterizedType)type).getActualTypeArguments();
if(paramTypes != null)
{
String clazzName = paramTypes[0].getTypeName();
try{
Class<?> clazz = Class.forName(clazzName);
//System.out.print(paramTypes[0].getTypeName()+"->"+inf);
daoProxy.putDao(clazz, dao);
}catch(Exception e)
{}
continue DaoCyc;
}
}
}
}
}
public void scanEmitter(ApplicationContext context)
{
Map<String, IRuleEmitter> emitterMap = context.getBeansOfType(IRuleEmitter.class);
Set<Class<?>> clsSet = new HashSet<>();
for(Map.Entry<String, IRuleEmitter> entry:emitterMap.entrySet())
{
//EmitterFactory.getDefault().putRuleEmmiter(entry.getValue());
Class<?> transactionClass = entry.getValue().relatedTransaction();
clsSet.add(transactionClass);
}
MdaDriver.createVoSetterAndGetter(clsSet);
}
}
package com.brilliance.mda.runtime.mda.util;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.List;
public class ArchiveUtils {
private static final Logger log = LoggerFactory.getLogger(ArchiveUtils.class);
private static void archive(File file, ArchiveOutputStream aos, String entryName)
throws IOException {
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files.length < 1) {
aos.putArchiveEntry(aos.createArchiveEntry(file, entryName));
aos.closeArchiveEntry();
}
for (File _file : files)
archive(_file, aos, entryName + "/" + _file.getName());
} else {
aos.putArchiveEntry(aos.createArchiveEntry(file, entryName));
FileInputStream fis = new FileInputStream(file);
IOUtils.copyLarge(fis, aos);
fis.close();
aos.closeArchiveEntry();
}
}
public static void archive(OutputStream os, String[] fileNames, String baseDirectoryName) {
ZipArchiveOutputStream zos = null;
try {
zos = new ZipArchiveOutputStream(os);
File baseDirectory = baseDirectoryName == null ? null : new File(baseDirectoryName);
for (String fileName : fileNames)
archive(baseDirectory == null ? new File(fileName) : new File(baseDirectory, fileName), zos, fileName);
} catch (Exception e) {
log.error("Archive to zip package error.", e);
}
MdaUtils.closeQuietly(zos);
}
public static void archive(OutputStream os, List<String> fileNames, File baseDirectory) {
ZipArchiveOutputStream zos = null;
try {
zos = new ZipArchiveOutputStream(os);
for (String fileName : fileNames)
archive(baseDirectory == null ? new File(fileName) : new File(baseDirectory, fileName), zos, fileName);
} catch (Exception e) {
log.error("Archive to zip package error.", e);
}
MdaUtils.closeQuietly(zos);
}
public static boolean extract(InputStream is, String entryName, OutputStream os) {
boolean flag = false;
ZipArchiveInputStream zis = null;
try {
zis = new ZipArchiveInputStream(is);
do {
ArchiveEntry entry = zis.getNextEntry();
if (entry == null)
break;
if ((entryName == null) || (!entryName.equals(entry.getName())))
continue;
flag = true;
IOUtils.copyLarge(zis, os, 0L, entry.getSize());
}
while (!flag);
} catch (Exception e) {
log.error("Extract file form zip package error.", e);
}
MdaUtils.closeQuietly(zis);
return flag;
}
}
package com.brilliance.mda.runtime.mda.util;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.support.service.CodetableService;
import com.brilliance.mda.support.td.ModuleInfoManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Codetables {
private static final Logger log = LoggerFactory.getLogger(Codetables.class);
//码表路径
static String codeTableFilePath = "codeTable";
static Map<String, List<CodetableItem>> staticCodeTableCache = new ConcurrentHashMap<>();
public static List<CodetableItem> getCodetable(String codeName) {
return null;
}
public static String getCodetableLabelOfTd(String key, String codetable, String language) {
String label = "";
List<CodetableItem> codeTable = getCodeTable(codetable, language);
if (!CollectionUtils.isEmpty(codeTable)) {
for (CodetableItem codetableItem : codeTable) {
if (key.equalsIgnoreCase(codetableItem.getValue())) {
label = codetableItem.getLabel();
break;
}
}
}
return label;
}
public static String getCodeTableKeyOfTd(String txt, String codetable, String language) {
String key = "";
List<CodetableItem> codeTable = getCodeTable(codetable, language);
if (!CollectionUtils.isEmpty(codeTable)) {
for (CodetableItem codetableItem : codeTable) {
if (txt.equals(codetableItem.getLabel())) {
key = codetableItem.getValue();
}
}
}
return key;
}
public static void setTblText(String key, String table, String language, String value) {
File file = new File(codeTableFilePath, table + "_" + language + ".ctl");
if (file.exists()) {
String codetable = "<?xml version=\"1.0\" encoding = \"UTF-8\" standalone=\"no\"?>\n<codetable>\n";
codetable += "<item> description=\"description\" lable=\"" + value + "\" value=\"" + key + "\"/>\n";
codetable += "</codetable>";
try {
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(codetable);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static IStream getTblKeyList(String codetable, String language) {
IStream keylst = new StreamImpl();
List<CodetableItem> codeTable = getCodeTable(codetable, language);
if (!CollectionUtils.isEmpty(codeTable)) {
for (CodetableItem codetableItem : codeTable) {
keylst.addLine(codetableItem.getValue());
}
}
return keylst;
}
// public static IStream getTblKeyList(String table, String language) {
// return getTblKeyList(table, language);
// }
public static List<CodetableItem> getCodeTable(String codeName, String lang) {
List codetable = new ArrayList<>();
if (codeName.indexOf(":") > 0) {
String arr[] = codeName.split(":");
Map<String, Object> fieldInfo = ModuleInfoManager.getModuleFieldInfo(arr[0].trim().toLowerCase(), arr[1].trim().toLowerCase());
if (fieldInfo == null)
return codetable;
codeName = (String) fieldInfo.get("codetable");
if (MdaUtils.isEmpty(codeName))
return codetable;
} else {
//尝试从组件中加载
CodetableService codetableService = MdaEnv.getBean(CodetableService.class);
List<CodetableItem> dbCodeTable = codetableService.selectList(codeName.toUpperCase(), lang);
if (dbCodeTable != null && !dbCodeTable.isEmpty())
return dbCodeTable;
}
String fileName = codeTableFilePath + "/";
if ("CN".equals(lang)) {
fileName = fileName + codeName.toLowerCase() + "_zh_CN.ctl";
} else {
fileName = fileName + codeName.toLowerCase() + "_en_US.ctl";
}
//Cache判断
List<CodetableItem> tempCodeTableList = staticCodeTableCache.get(fileName);
if (tempCodeTableList != null) {
return tempCodeTableList;
}
//判断结束
log.info("filePath:{}", fileName);
//if(file.exists()){
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
InputStream ins = new ClassPathResource(fileName).getInputStream();
if (ins == null) {
return codetable;
}
Document parse = documentBuilder.parse(ins);
Element documentElement = parse.getDocumentElement();
NodeList item = documentElement.getElementsByTagName("item");
for (int i = 0; i < item.getLength(); i++) {
Element item1 = (Element) item.item(i);
codetable.add(new CodetableItem(item1.getAttribute("label"), item1.getAttribute("value")));
}
} catch (Exception e) {
log.error(e.getMessage());
e.printStackTrace();
}
//缓存放入
staticCodeTableCache.put(fileName, codetable);
return codetable;
}
//private static String ATTR_CODE_VALUES="ATTR_CODE_VALUES";
public static void setCodeValues(String key, IStream stream) {
}
public static void setCodeValues(IDatafield<Object> datafield, IStream values) {
//MdaEnv.getContext().setAttribute(datafield.getParent(),datafield.getName(),ATTR_CODE_VALUES,stream);
setCodeValues(datafield.getParent(), datafield.getName(), values);
}
public static void setCodeValues(IModule parent, String prop, IStream values) {
//拦截做values专项处理
Systems.setValuesToContextSet(parent, prop, values);
MdaEnv.getContext().setAttribute(parent, prop, Constants.ATTR_CODE_VALUES, values);
}
}
package com.brilliance.mda.runtime.mda.util;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@Slf4j
public abstract class Reflects {
public static <T> T fieldGet(Object obj, String name){
try {
Field field = obj.getClass().getDeclaredField(name);
field.setAccessible(true);
Object result = field.get(obj);
return (T)result;
} catch (NoSuchFieldException | IllegalAccessException e) {
log.warn(String.format("get object %s[%s]属性值异常!",obj.toString(),name));
return null;
}
}
public static void fieldSet(Object obj, String name,Object val){
try {
Field field = obj.getClass().getDeclaredField(name);
field.setAccessible(true);
field.set(obj,val);
} catch (NoSuchFieldException | IllegalAccessException e) {
log.warn(String.format("get object %s[%s]属性值异常!",obj.toString(),name));
}
}
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
try {
return clazz.getMethod(methodName, parameterTypes);
} catch (Exception ignore) {
}
return null;
}
}
package com.brilliance.mda.runtime.mda.util;
import com.brilliance.mda.runtime.mda.*;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class RuleUtils {
static Comparator<IRule> c = new Comparator<IRule>() {
public int compare(IRule rule1, IRule rule2) {
return rule1.getOrder() - rule2.getOrder();
}
};
static Comparator<IEventRule> c2 = new Comparator<IEventRule>() {
public int compare(IEventRule rule1, IEventRule rule2) {
if (rule1.getType().equals(rule2.getType()))
return rule1.getOrder() - rule2.getOrder();
return rule1.getType().compareTo(rule2.getType());
}
};
public static final void sort(List<IRule> rules) {
if (rules != null)
Collections.sort(rules, c);
}
public static final InheritableThreadLocal<IContext> ctx = new InheritableThreadLocal<IContext>();
public static final boolean invoke(List<IRule> rules, IContext ctx, IAttributeValue av) {
if (rules == null)
return true;
boolean continued = true;
RuleUtils.ctx.set(ctx);
for (int i = 0; continued && i < rules.size(); i++) {
try {
continued = ((IRule) rules.get(i)).invoke(ctx, av);
} catch (Throwable e) {
if (!(e instanceof ExitEventException))
continued = false;
}
}
return continued;
}
public static final void sort2(List<IEventRule> rules) {
if (rules != null)
Collections.sort(rules, c2);
}
public static final boolean invoke(List<IEventRule> rules, IContext ctx, Event event, int... orders) {
if (rules == null)
return true;
boolean continued = true;
RuleUtils.ctx.set(ctx);
boolean checkMinOrder = (orders != null && orders.length > 0);
boolean checkMaxOrder = (orders != null && orders.length > 1);
int minOrder = checkMinOrder ? orders[0] : 0;
int maxOrder = checkMaxOrder ? orders[1] : 0;
for (IEventRule rule : rules) {
if (rule.getType() == EventType.DEFAULT || rule.getType() == event.getType()) {
if ((checkMinOrder && rule.getOrder() < minOrder) || (checkMaxOrder && rule.getOrder() > maxOrder))
continue;
try {
continued = rule.invoke(ctx, event);
} catch (Throwable e) {
if (!(e instanceof ExitEventException))
continued = false;
}
if (!continued)
break;
}
}
return continued;
}
}
package com.brilliance.mda.runtime.mda.util;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.request.SelectedParams;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.brilliance.mda.runtime.mda.Constants.CR;
public class Streams {
private static final Logger log = LoggerFactory.getLogger(Streams.class);
public static final void copy(InputStream is, OutputStream os)
throws IOException {
try {
IOUtils.copy(is, os);
} finally {
MdaUtils.closeQuietly(is);
MdaUtils.closeQuietly(os);
}
}
public static final void copy(Reader reader, OutputStream os, Charset charset)
throws IOException {
try {
IOUtils.copy(reader, os, charset);
} finally {
MdaUtils.closeQuietly(reader);
MdaUtils.closeQuietly(os);
}
}
//TODO
public static int streamCount(IStream stream) {
if (stream == null) return 0;
return stream.countLines();
}
public static int streamSearch(IStream stream, String line) {
if (stream == null) return 0;
return stream.searchLine(line);
}
public static String streamGetLine(IStream stream, int idx) {
return stream.getLine(idx);
}
public static void streamSet(IStream src, Object dist) {
if (dist instanceof IStream) {
streamSetByIStream(src, (IStream) dist);
} else if (dist instanceof String) {
streamSetByString(src, (String) dist);
}
}
public static void streamSetByIStream(IStream src, IStream dist) {
src.clearLines();
dist.getRows().forEach(src::addLine);
}
public static void streamSetByString(IStream src, String str) {
if (str == null || str.trim().isEmpty()) {
MdaUtils.clear(src);
return;
}
src.clearLines();
String[] lines = str.split("[\\n]|\\r\\n");
Arrays.stream(lines).forEach(line -> src.addLine(line));
}
public static void streamSet(IStream src, String str, int len) {
if (str == null || str.trim().isEmpty()) {
MdaUtils.clear(src);
return;
}
src.clearLines();
String[] lines = str.split("[\\n]|\\r\\n");
Arrays.stream(lines).forEach(line -> {
int begPos = 0;
while (begPos + len < line.length()) {
src.addLine(line.substring(begPos, begPos + len));
begPos += len;
}
if (begPos < line.length()) {
src.addLine(line.substring(begPos));
}
});
}
public static void streamSet(IStream src, String str, double len) {
streamSet(src, str, (int) len);
}
public static void streamInsert(IStream stream, int idx, String line) {
if (stream == null) return;
stream.insertLine(idx, line);
}
public static void streamDelete(IStream stream, int idx) {
stream.deleteLine(idx);
}
public static void streamClear(IStream stream) {
if (stream != null) {
//stream.close();
stream.clearLines();
}
}
public static void getAttributeStream(IStream out, IStream dist, String attr) {
if (dist == null) {
return;
}
IStream tmp = dist.getAttribute(attr);
if (tmp == null || tmp.countLines() == 0) {
out.clearLines();
return;
}
out.setRows(tmp.getRows());
}
public static void setAttributeStream(IStream dist, String attr, IStream value) {
dist.setAttribute(attr, value);
}
public static void setSelectedLine(IStream stm, int idx) {
SelectedParams.setSelectedLine(stm, idx);
}
public static int getSelectedLine(IStream stm) {
return SelectedParams.getSelectedLine(stm);
}
public static void setSelectedRow(IModuleList<? extends IModule> list, int index) {
SelectedParams.setSelectedRow(list, index);
}
public static int getSelectedRow(IModuleList<? extends IModule> list) {
return SelectedParams.getSelectedRow(list);
}
public static int getSelectedRowIndex(IModuleList<? extends IModule> list) {
return getSelectedRow(list);
}
public static String streamGetAdditional(IStream stm, String s1, String s2) {
switch (s1) {
case "ANNOTATION_TEXT":
break;
case "ANNOTATION_CLASS":
break;
case "ANNOTATION_HINT":
break;
case "ANNOTATION_USER":
break;
case "ANNOTATION_TIMESTAMP":
break;
case "ANNOTATION_COUNT":
break;
case "CHARDATA":
if (s2.equals("")) {
return stm.getValue();
}
break;
case "RANGETEXT":
break;
case "SELRANGE":
break;
}
return null;
}
public static void streamSetAdditional(IStream stm, String insert, String insPos, String txt) {
}
public static boolean streamPrint(IStream logstr) {
return true;
}
public static List<String> streamStrSplit(String str) {
List<String> lines = new ArrayList<String>();
if (str == null || str.length() == 0)
return lines;
if (str.indexOf("\r\n") == -1)
lines.add(str);
else {
lines.addAll(Arrays.asList(str.split("\r\n")));
lines.remove(lines.size() - 1);
}
return lines;
}
//前台方法空实现
public static String promptStream(IStream stream, String caption, String values) {
MdaEnv.setGridData(caption, values, stream);
throw new RulePromptException("Propmt out");
}
public static void promptIModule(List<IModule> list) {
Class<? extends IModule> clazz = list.get(0).getClass();
List<String> columnList = new ArrayList<>();
IStream stm1 = new StreamImpl();
String column = "";
int i = 1;
for (Field declaredField : clazz.getDeclaredFields()) {
column = column + (i - 1) + " " + i + " \"" + declaredField.getName().toUpperCase() + "\"410" + CR;
columnList.add(declaredField.getName());
i++;
}
for (int index = 0; index < list.size(); index++) {
IModule iModule1 = list.get(index);
Class<? extends IModule> clazzIModule = iModule1.getClass();
StringBuilder stringBuilder = new StringBuilder();
try {
for (String columnName : columnList) {
String getMethodName = "get" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
Method m = clazzIModule.getMethod(getMethodName);
String vul = (String) m.invoke(iModule1);
stringBuilder.append(vul + "\t");
}
} catch (Exception e) {
}
Streams.streamInsert(stm1, index, stringBuilder.toString());
}
MdaEnv.setGridData(clazz.getSimpleName(), column, stm1);
throw new RulePromptException("Propmt out");
}
public static String promptStream(IStream stgStm, String grdHea, String grdVal, int parseInt, int parseInt1) {
Integer que = SelectedParams.getNomalSelected();
if (que == 0) {
MdaEnv.setGridData(grdHea, grdVal, stgStm);
throw new RulePromptException("Propmt out");
}
return stgStm.getLine(que);
}
/**
* 执行面函面板rule,并将面函模板内容保存至stream
* TODO 根据i的值实现不同类型的模板转换。
*
* @param stream
* @param panel
* @param i
*/
public static void saveTextStream(IStream stream, IPanel panel, int i) {
MdaEnv.getContext().postRule(panel);
IDatafield<String> field = MdaDriver.getDatafield(panel.getPath() + "blk");
if (field != null && Strings.notEmpty(field.getValue())) {
stream.addLine(field.getValue());
}
}
public static void saveTextStream(IStream stream, IPanel panel) {
}
/**
* 将stream中的面函模板赋值给面板panel
*
* @param stm
* @param panel
* @param i
*/
public static void loadTextStream(IStream stm, IPanel panel, int i) {
String blkName = panel.getName() + "blk";
IModule model = panel.getParent();
if (model == null) {
model = MdaEnv.getContext().getRoot();
}
Reflects.fieldSet(model, blkName, stm.getValue());
}
}
package com.brilliance.mda.runtime.request;
import com.brilliance.mda.runtime.mda.IBaseObject;
import com.brilliance.mda.runtime.mda.IDatafield;
import com.brilliance.mda.runtime.mda.IStream;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import java.util.List;
import static com.brilliance.mda.runtime.mda.Constants.tdAttrChecked;
import static com.brilliance.mda.runtime.mda.Constants.tdAttrCheckedIdx;
public class CheckedParams {
public static final String CHK_IDS ="chkIds";
public static final String CHK_DST="chkDst";
public static void checkedParamsInit(BaseVO req) {
List<Integer> chkIds = null;
String chkDst = null;
if(req.getParams().containsKey(CHK_IDS)){
chkIds = (List<Integer>) req.getParams().get(CHK_IDS);
}
if(req.getParams().containsKey(CHK_DST)){
chkDst = (String)req.getParams().get(CHK_DST);
}
if(chkDst == null){
return ;
}
IBaseObject dist = MdaDriver.getBaseObject(null,chkDst);
if(dist == null){
return ;
}
if(dist instanceof IDatafield){
Object val = ((IDatafield)dist).getValue();
if(!(val instanceof IStream)){
return;
}
IStream distStm = (IStream)val;
IStream selStm = new StreamImpl();
IStream selIdsStrem = new StreamImpl();
for (int i = 0; i <chkIds.size(); i++) {
selStm.addLine(distStm.getLine(chkIds.get(i)));
selIdsStrem.addLine(String.valueOf(chkIds.get(i)));
}
distStm.setAttribute(tdAttrChecked,selStm);
distStm.setAttribute(tdAttrCheckedIdx,selIdsStrem);
}
}
}
package com.brilliance.mda.runtime.request;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.impl.StreamImpl;
import com.brilliance.mda.runtime.mda.util.Strings;
import com.brilliance.mda.runtime.mda.util.Systems;
import java.util.List;
import static com.brilliance.mda.runtime.mda.Constants.*;
public class SelectedParams {
public static final String SEL_IDS ="selIds";
public static final String SEL_DST="selDst";
public static final String SEL_BTN_ID="selBtnId";
public static final String ButtonIndex = "ButtonIndex";
public static final String ButtonId = "ButtonId";
public static void selectedParamsInit(BaseVO req){
List<Integer> selIds = null;
String selDst = null;
if(req.getParams().containsKey(SEL_IDS)){
selIds = (List<Integer>) req.getParams().get(SEL_IDS);
}
if(req.getParams().containsKey(SEL_DST)){
selDst = (String)req.getParams().get(SEL_DST);
}
if(selIds == null || selIds.size() == 0){
return ;
}
int tdSel = selIds.get(0);
if(Strings.isEmpty(selDst)){
setNomalSelected(tdSel);
return;
}
IBaseObject dist = MdaDriver.getBaseObject(null,selDst);
if(dist == null){
return ;
}
if(dist instanceof IModuleList){
setSelectedRow((IModuleList)dist,tdSel);
return;
}
if(dist instanceof IDatafield){
Object val = ((IDatafield)dist).getValue();
if(!(val instanceof IStream)){
return;
}
IStream distStm = (IStream)val;
IStream selStm = new StreamImpl();
IStream selIdsStrem = new StreamImpl();
for (int i = 0; i <selIds.size(); i++) {
selStm.addLine(distStm.getLine(selIds.get(i)));
selIdsStrem.addLine(String.valueOf(selIds.get(i)));
}
distStm.setAttribute(tdAttrSelected,selStm);
distStm.setAttribute(tdAttrSelectedIdx,selIdsStrem);
Systems.setAttribute(dist.getParent(),dist.getName(),ButtonIndex,selIds.get(0));
String selBtnId = "";
if(req.getParams().containsKey(SEL_BTN_ID)){
selBtnId = (String) req.getParams().get(SEL_BTN_ID);
Systems.setAttribute(dist.getParent(),dist.getName(),ButtonId,selBtnId);
}
}
}
public static String buildSelKey(Object obj,String ATTR){
return obj.toString()+ATTR;
}
public static void setSelectedLine(IStream stm,int idx){
IStream selected = MdaEnv.getContext().getParam(buildSelKey(stm,tdAttrSelectedIdx));
if(selected == null){
selected = new StreamImpl();
stm.setAttribute(tdAttrSelectedIdx,selected);
}else{
selected.getRows().clear();
}
selected.getRows().add(String.valueOf(idx));
}
public static int getSelectedLine(IStream stream){
IStream selected = stream.getAttribute(tdAttrSelectedIdx);
// IStream selected = MdaEnv.getContext().getParam(buildSelKey(stream,tdAttrSelectedIdx));
if(selected == null || selected.isEmpty()){
return 0;
}
return Integer.valueOf(selected.getRows().get(0));
}
public static void setSelectedRow(IModuleList<? extends IModule> list, int index) {
MdaEnv.getContext().setAttribute(list,"SELECT_INDEX","index",index);
}
public static int getSelectedRow(IModuleList<? extends IModule> list) {
Integer idx = (Integer) MdaEnv.getContext().getAttribute(list,"SELECT_INDEX","index");
return idx == null?0:idx;
}
public static int getSelectedRowIndex(IModuleList<? extends IModule> list) {
return getSelectedRow(list);
}
public static void setNomalSelected(int index){
MdaEnv.getContext().setParam("SELECTED_INDEX_NOMAL",index);
}
public static Integer getNomalSelected(){
Integer idx = MdaEnv.getContext().getParam("SELECTED_INDEX_NOMAL");
if(idx == null){
return 0;
}
return idx;
}
}
package com.brilliance.mda.runtime.response;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.brilliance.mda.runtime.mda.IContext;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseSet<T> {
/**
* 成功代码
*/
public static final String CODE_SUCCESS="AAAAAA";
public static final String MSG_SUCESS="操作成功!";
private String respCode;
private String respMsg;
private Map<String,String> fieldErrors;
private Map<String, List<String>> codeSet;
private Object data;
public ResponseSet(IContext ctx, Object t){
this.respCode = CODE_SUCCESS;
this.respMsg = MSG_SUCESS;
this.data = t;
fieldErrors = cloneFieldErrorsFromContext(ctx);
this.codeSet = getValuesSet(ctx);
ctx.visitValues();
MdaDriver.setValueToVO(ctx, this.data);
}
private Map<String, List<String>> getValuesSet(IContext ctx){
Map<String, List<String>> valuesSet = new LinkedHashMap<>();
ctx.getValuesSet().forEach((key, codeEntity)->{
if(!codeEntity.visited){
valuesSet.put(key,codeEntity.values);
}
});
return valuesSet;
}
private Map<String,String> cloneFieldErrorsFromContext(IContext ctx){
if(ctx == null){
return null;
}
Map<String,String> fieldErrors = ctx.getFieldErrors();
Map<String,String> fieldErrorsClone = new LinkedHashMap<>();
fieldErrorsClone.putAll(fieldErrors);
fieldErrors.clear();
return fieldErrorsClone;
}
public ResponseSet(Object t){
this.respCode = CODE_SUCCESS;
this.respMsg = MSG_SUCESS;
if(MdaEnv.getContext()!=null) {
fieldErrors = cloneFieldErrorsFromContext(MdaEnv.getContext());
this.codeSet = getValuesSet(MdaEnv.getContext());
MdaEnv.getContext().visitValues();
}
this.data = t;
}
public ResponseSet(String errCode,String errMsg){
this.respCode = errCode;
this.respMsg = errMsg;
if(MdaEnv.getContext()!=null) {
fieldErrors = cloneFieldErrorsFromContext(MdaEnv.getContext());
this.codeSet = getValuesSet(MdaEnv.getContext());
MdaEnv.getContext().visitValues();
}
}
// public ResponseSet(String errCode,String errMsg,Map<String,String> fieldErrors){
// this(errCode,errMsg);
// this.fieldErrors = fieldErrors;
// }
public ResponseSet(String errCode,String errMsg,T t){
this(errCode,errMsg);
this.data = t;
if(t!=null) {
MdaDriver.setValueToVO(MdaEnv.getContext(), this.data);
}
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getRespCode() {
return respCode;
}
public void setRespCode(String respCode) {
this.respCode = respCode;
}
public String getRespMsg() {
return respMsg;
}
public void setRespMsg(String respMsg) {
this.respMsg = respMsg;
}
public Map<String, String> getFieldErrors() {
return fieldErrors;
}
public void setFieldErrors(Map<String, String> fieldErrors) {
this.fieldErrors = fieldErrors;
}
public Map<String, List<String>> getCodeSet() {
return codeSet;
}
public void setCodeSet(Map<String, List<String>> codeSet) {
this.codeSet = codeSet;
}
static class BooleanResult{
boolean result;
public BooleanResult(boolean result){
this.result = result;
}
}
static final String FAIL_CODE = "999999";
public static ResponseSet fail(String message) {
ResponseSet responseSet = new ResponseSet(FAIL_CODE,message);
return responseSet;
}
public static ResponseSet simpleSuccess(Object data){
return new ResponseSet(data);
}
}
package com.brilliance.mda.support.cache;
import com.brilliance.mda.runtime.mda.IAuthInfo;
import com.brilliance.mda.runtime.mda.IContext;
import com.brilliance.mda.support.cache.impl.GuavaCache;
import com.brilliance.mda.support.cache.impl.RedisCache;
import com.brilliance.mda.support.cache.serializer.ICacheSerializer;
import com.brilliance.mda.support.cache.serializer.ICacheSerializerEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
@Configuration
public class CacheConfiguration {
private static final Logger logger = LoggerFactory.getLogger(CacheConfiguration.class);
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Value("${envconfig.cache.serializer:kryo}")
private String cacheSerializerType;
@Value("${envconfig.cache.expireAfterAccess:300}")
private long expireAfterAccess;
@Bean("ctxCache")
@ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "guava", matchIfMissing = true)
public ICache<String, IContext> getGuavaCtxCache() {
//2h timeout
logger.info("使用Guava作为Context缓存");
return new GuavaCache<>("CtxCache", expireAfterAccess);
}
@Bean("ctxCache")
@ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "redis")
public ICache<String, IContext> getRedisCtxCache() {
//2h timeout
ICacheSerializer cacheSerializer = getCacheSerializer();
logger.info("使用Redis作为Context缓存,序列化处理器:{}", cacheSerializer.getName());
this.redisTemplate.setKeySerializer(new StringRedisSerializer());
this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return new RedisCache<>("CtxCache", redisTemplate, cacheSerializer, expireAfterAccess);
}
@Bean("ctxCacheSerializer")
public ICacheSerializer getCacheSerializer() {
return ICacheSerializerEnum.getSerializer(cacheSerializerType);
}
@Bean("authCache")
@ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "guava", matchIfMissing = true)
public ICache<String, IAuthInfo> getGuavaAuthCache() {
return new GuavaCache<>("AuthCache", expireAfterAccess);
}
@Bean("authCache")
@ConditionalOnProperty(prefix = "envconfig.cache", name = "type", havingValue = "redis")
public ICache<String, IAuthInfo> getRedisAuthCache() {
ICacheSerializer cacheSerializer = getCacheSerializer();
logger.info("使用Redis作为Auth缓存,序列化处理器:{}", cacheSerializer.getName());
this.redisTemplate.setKeySerializer(new StringRedisSerializer());
this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
return new RedisCache<>("AuthCache", redisTemplate, cacheSerializer, expireAfterAccess);
}
}
package com.brilliance.mda.support.cache.impl;
import com.brilliance.mda.support.cache.ICache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.UUID;
public class GuavaCache<V> implements ICache<String, V> {
private final Logger logger = LoggerFactory.getLogger(GuavaCache.class);
private final LoadingCache<String, V> cache;
private String cacheName;
public GuavaCache(String cacheName, long seconds) {
this.cacheName = cacheName;
cache = CacheBuilder.newBuilder()
.expireAfterAccess(Duration.ofSeconds(seconds))
.build(new CacheLoader<String, V>() {
@Override
public V load(String s) throws Exception {
return null;
}
});
}
@Override
public String store(V v) {
String key = generateKey();
cache.put(key, v);
return key;
}
@Override
public void store(String key, V v) {
cache.put(key, v);
}
@Override
public V get(String k) {
try {
return cache.get(k);
} catch (Exception e) {
logger.warn("Acquire {} cache failed", cacheName);
}
return null;
}
@Override
public void remove(String k) {
cache.invalidate(k);
}
@Override
public String generateKey() {
return UUID.randomUUID().toString();
}
@Override
public void cleanup() {
logger.info("{} clean up start.size:{}",this.cacheName,cache.size());
this.cache.cleanUp();
logger.info("{} clean up over.size:{}",this.cacheName,cache.size());
}
@Override
public boolean contains(String key) {
return this.get(key) != null;
}
}
package com.brilliance.mda.support.cache.impl;
import com.brilliance.mda.runtime.mda.RuleExecuteException;
import com.brilliance.mda.support.cache.ICache;
import com.brilliance.mda.support.cache.serializer.ICacheSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class RedisCache<V> implements ICache<String, V> {
private final Logger logger = LoggerFactory.getLogger(RedisCache.class);
private String cacheName;
private RedisTemplate<String, Object> redisTemplate;
private ICacheSerializer serializer;
private long expireTime;
public RedisCache(String cacheName, RedisTemplate<String, Object> redisTemplate, ICacheSerializer serializer, long expireTime) {
this.cacheName = cacheName;
this.redisTemplate = redisTemplate;
this.serializer = serializer;
this.expireTime = expireTime;
}
@Override
public String store(V v) {
String key = generateKey();
this.store(key, v);
return key;
}
@Override
public void store(String key, V v) {
try {
long time1 = System.currentTimeMillis();
byte[] bytes = serializer.writeToByteArray(v);
if(bytes == null){
logger.debug("{}使用{}序列化 Key:{},Length:{},Timing:{}ms",cacheName,serializer.getName(),key,0,System.currentTimeMillis() - time1);
return;
}
logger.debug("{}使用{}序列化 Key:{},Length:{},Timing:{}ms",cacheName,serializer.getName(),key,bytes.length,System.currentTimeMillis() - time1);
time1 = System.currentTimeMillis();
redisTemplate.opsForValue().set(key, bytes, expireTime, TimeUnit.SECONDS);
logger.debug("{}写入redis Key:{},Length:{},Timing:{}ms",cacheName,key,bytes.length,System.currentTimeMillis() - time1);
} catch (Exception e) {
logger.error(cacheName+"使用"+serializer.getName() + "序列化保存缓存失败", e);
}
}
@Override
@SuppressWarnings("unchecked")
public V get(String s) {
try {
if (null == s) {
logger.error("RedisCache get with null key");
return null;
}
long time1 = System.currentTimeMillis();
byte[] bytes = (byte[]) redisTemplate.opsForValue().get(s);
if (null == bytes){
logger.debug("从redis读取Key:{},Length:{},Timing:{}ms",s,0,System.currentTimeMillis() - time1);
return null;
}
long time2 = System.currentTimeMillis();
logger.debug("从redis读取Key:{},Length:{},Timing:{}ms",s,bytes.length,System.currentTimeMillis() - time1 );
V v = serializer.readFromByteArray(bytes);
logger.debug("{}使用{}反序列化Key:{},Length:{},Timing:{} ms", cacheName,serializer.getName(),s,bytes.length, System.currentTimeMillis() - time2);
return v;
} catch (Exception e) {
logger.error(serializer.getName() + "反序列化失败", e);
if(e instanceof RuleExecuteException){
throw e;
}else{
throw new RuleExecuteException(serializer.getName() + "反序列化失败",e);
}
}
}
@Override
public void remove(String s) {
redisTemplate.delete(s);
}
@Override
public String generateKey() {
return cacheName + "-" + UUID.randomUUID();
}
@Override
public void keeplive(String key) {
if(key == null){
return;
}
redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);
}
@Override
public void cleanup() {
logger.info("RedisCache not clean up .");
}
@Override
public boolean contains(String key) {
return redisTemplate.hasKey(key);
}
}
package com.brilliance.mda.support.cache.serializer;
import com.brilliance.mda.support.cache.serializer.impl.KryoSerializer;
public enum ICacheSerializerEnum {
Kryo("kryo", new KryoSerializer());
private String key;
private ICacheSerializer serializer;
ICacheSerializerEnum(String key, ICacheSerializer serializer) {
this.key = key;
this.serializer = serializer;
}
public static ICacheSerializer getSerializer(String key) {
for (ICacheSerializerEnum e : ICacheSerializerEnum.values()) {
if (e.key.equals(key))
return e.getSerializer();
}
return ICacheSerializerEnum.values()[0].getSerializer();
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public ICacheSerializer getSerializer() {
return serializer;
}
public void setSerializer(ICacheSerializer serializer) {
this.serializer = serializer;
}
}
package com.brilliance.mda.support.cache.serializer.impl;
import com.brilliance.mda.runtime.mda.*;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.brilliance.mda.runtime.mda.impl.AbstractModule;
import com.brilliance.mda.runtime.mda.impl.ModuleList;
import com.brilliance.mda.support.cache.serializer.ICacheSerializer;
import com.esotericsoftware.kryo.kryo5.Kryo;
import com.esotericsoftware.kryo.kryo5.io.Input;
import com.esotericsoftware.kryo.kryo5.io.Output;
import com.esotericsoftware.kryo.kryo5.objenesis.strategy.StdInstantiatorStrategy;
import com.esotericsoftware.kryo.kryo5.util.DefaultInstantiatorStrategy;
import com.esotericsoftware.kryo.kryo5.util.Pool;
import com.google.common.io.Files;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.reflect.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicInteger;
public class KryoSerializer implements ICacheSerializer {
private static final Logger logger = LoggerFactory.getLogger(KryoSerializer.class);
private static final String NAME = "Kryo";
private static final String DEFAULT_ENCODING = StandardCharsets.UTF_8.toString();
private static final int bufferSize = 8192;
private static volatile Pool<Output> outputPool = new Pool<Output>(true, false, 50) {
@Override
protected Output create() {
return new Output(bufferSize, -1);
}
};
private static volatile Pool<Kryo> kryoPool = new Pool<Kryo>(true, false, 50) {
@Override
protected Kryo create() {
Kryo kryo = new Kryo();
kryo.setInstantiatorStrategy(new DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));
kryo.setReferences(true);
kryo.setRegistrationRequired(false);
return kryo;
}
};
@Override
public String getName() {
return NAME;
}
@Override
public <T> byte[] writeToByteArray(T obj) {
Output output = null;
Kryo kryo = null;
try {
output = outputPool.obtain();
kryo = kryoPool.obtain();
kryo.writeClassAndObject(output, obj);
byte[] buff = output.toBytes();
return buff;
} catch (Exception e) {
logger.error("Kryo序列化失败", e);
throw new RuleExecuteException("kryo 序列化异常!", e);
} finally {
if (kryo != null) {
kryoPool.free(kryo);
}
if (output != null) {
outputPool.free(output);
}
}
}
static AtomicInteger count = new AtomicInteger(0);
@Override
@SuppressWarnings("unchecked")
public <T> T readFromByteArray(byte[] bytes) {
Input input = new Input(bytes);
Kryo kryo = null;
try {
kryo = kryoPool.obtain();
long time2 = System.currentTimeMillis();
T t = (T) kryo.readClassAndObject(input);
if (t instanceof IContext) {
IContext context = (IContext) t;
IModule root = context.getRoot();
context.setEmitter(MdaEnv.getBean(IRuleEmitter.EMITTER_PRE + root.getClass().getSimpleName().toLowerCase(), IRuleEmitter.class));
moduleSetting(root);
logger.debug("bytes to module timing:{}ms", System.currentTimeMillis() - time2);
}
return t;
} catch (Exception e) {
logger.error("Kryo反序列化失败", e);
int i = count.incrementAndGet();
try {
File file = new File(MdaEnv.getRootPath(), "kryo_ex_" + i + ".ky");
Files.write(bytes, file);
} catch (Exception ex) {
logger.warn("", ex);
}
throw new RuleExecuteException("kryo反序列化异常!", e);
} finally {
if (kryo != null) {
kryoPool.free(kryo);
}
}
}
private void moduleSetting(IModule module) {
invokeSetArgumentMethod(module);
Field[] fields = module.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
Class<?> clazz = field.getType();
try {
Object o = field.get(module);
if (null == o) continue;
if (AbstractModule.class.isAssignableFrom(clazz)) {
moduleSetting((IModule) o);
} else if (ModuleList.class.isAssignableFrom(clazz)) {
fillModuleList(module, field, (ModuleList<?>) o);
}
} catch (IllegalAccessException ignored) {
}
}
}
private void invokeSetArgumentMethod(IModule module) {
try {
Method method = module.getClass().getMethod("setArgument");
method.invoke(module);
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException ignored) {
}
}
private void fillModuleList(IModule parentModule, Field field, ModuleList<?> moduleList) {
try {
Class<? extends ModuleList> moduleListClass = moduleList.getClass();
Field parentField = moduleListClass.getDeclaredField("_parent");
Field nameField = moduleListClass.getDeclaredField("_name");
Field pathField = moduleListClass.getDeclaredField("_path");
Field dataClassField = moduleListClass.getDeclaredField("dataClass");
Field moduleTypeField = moduleListClass.getDeclaredField("moduleType");
parentField.setAccessible(true);
nameField.setAccessible(true);
pathField.setAccessible(true);
dataClassField.setAccessible(true);
moduleTypeField.setAccessible(true);
parentField.set(moduleList, parentModule);
nameField.set(moduleList, field.getName());
String prefix = parentModule.getPath();
if (prefix == null || prefix.length() == 0 || prefix.equals(IBaseObject.separator)) {
pathField.set(moduleList, IBaseObject.separator + field.getName());
} else {
pathField.set(moduleList, prefix + IBaseObject.separator + field.getName());
}
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType) type;
Type[] actualTypeArguments = t.getActualTypeArguments();
if (null != actualTypeArguments && actualTypeArguments.length > 0) {
Class<?> aClass = (Class<?>) actualTypeArguments[0];
dataClassField.set(moduleList, aClass);
moduleTypeField.set(moduleList, aClass.getSimpleName().toLowerCase());
}
}
for (IModule module : moduleList) {
moduleSetting(module);
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
}
package com.brilliance.mda.support.jaxrs;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationAware implements BeanFactoryPostProcessor, ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//MdaEnv.appContext = applicationContext;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
MdaEnv.beanFactory = configurableListableBeanFactory;
}
}
package com.brilliance.mda.support.service;
import com.brilliance.mda.runtime.mda.CodetableItem;
import java.util.List;
public interface CodetableService {
List<CodetableItem> selectList(String tbl, String lang);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment