edi.rule.util.ZSRule Maven / Gradle / Ivy
package edi.rule.util;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import edi.rule.config.JSRuleMessage;
import edi.rule.config.JSRuleProperties;
import edi.rule.config.JSRuleSecurity;
import edi.rule.extend.interfaces.IJSRuleModel;
import edi.rule.work.cache.JSRuleActionCache;
import edi.rule.work.cache.JSRuleMappingInfo;
import edi.rule.work.constant.*;
import edi.rule.work.enums.JSRuleCrudEnum;
import edi.rule.work.enums.JSRuleCrudPermitEnum;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import edi.rule.config.JSRuleContext;
import edi.rule.core.JSRuleArgsVessel;
import edi.rule.extend.interfaces.IJSRuleActionModel;
import edi.rule.model.JSBody;
import edi.rule.model.JSResult;
import edi.rule.model.JSRuleAction;
import edi.rule.model.JSRuleDefinition;
import edi.rule.work.cache.JSRuleFrameCache;
import edi.rule.work.custom.JSRuleException;
import edi.rule.work.interfaces.IJSRuleCustom;
/**
* @author 摩拉克斯
* @date 2023年2月9日 下午2:24:31
* 系统工具类,该工具类内部的方法大多数只能基于系统启动后根据相关配置进行方法的使用
*/
@Slf4j
public class ZSRule {
static final ObjectMapper om;
static {
om = new ObjectMapper();
}
public static String getPrefixClassFieldText(String className, String fieldName) {
return className + ZSSign.DOT + fieldName;
}
public static String getPrefixTableFieldText(String tableName, String fieldName) {
return tableName + ZSSign.DOT + fieldName;
}
public static String getPrefixFieldAliasText(String className, String aliasName) {
return className.replaceAll("\\"+ZSSign.DOT,JSRuleDBSign.NAMES_SEPARATOR) + JSRuleDBSign.ALIAS_SEPARATOR + aliasName;
}
public static String getResultAliasName(String classFieldName) {
return classFieldName.substring(classFieldName.indexOf(JSRuleDBSign.ALIAS_SEPARATOR)+1);
}
public static String getMappingClassSimpleName(String location,String fullName) {
return fullName.replace(location + ZSSign.DOT, "");
}
/**
*
用于将json字符串转化成相应的对象
* @param json 要转化成对象的json字符串
* @param targetClass 目标对象的类型
* @param parameterClasses 目标对象的一或多个泛型类型
* */
public static T parseObject(String json, Class> targetClass, Class>... parameterClasses) {
return ZSString.parseObject(json, om, targetClass, parameterClasses);
}
/**
* 用于获取已经执行完毕的action的结果,返回类型仅支持String,int,Double,Boolean类型
* @param name action的名称,如果为空则直接返回value默认值
* @param path 从action执行结果中通过该值所描述的路径获取数据,其语法如/nodeA/0/nodeC,0表示数组第几个元素,nodeA,nodeC表示属性名称
* @param value 默认值,当未从name和path中获取到数据时则返回该默认值
* @param vessel 为全局参数,所有的请求参数以及执行结果等都会存放于这个变量中,可在spring bean对象里通过Autowired注入或在model类中通过JSRuleInject注入
* @see JSRuleArgsVessel
* */
public static Object parseResult(String name, String path, Object value, JSRuleArgsVessel vessel) {
if (ZSString.isBlank(name)) {
return value;
}
JSRuleArgsVessel.JSRuleActionArguments actionArgs = vessel.getActionArgs().get(name);
if (actionArgs==null) {
throw new JSRuleException(JSRuleMessage.read("not.found.action.or.action.result.is.null"),name);
}
if (ZSString.isBlank(path)) {
return actionArgs.getResult();
}
JsonNode node = ZSString.getJsonNodes(ZSObject.objectToJson(actionArgs.getResult())).at(path);
if (node.isTextual()) {
return node.asText();
}else if (node.isInt()) {
return node.asInt();
}else if (node.isDouble()){
return node.asDouble();
}else if (node.isLong()){
return node.asLong();
}else if (node.isBoolean()) {
return node.asBoolean();
}else {
if (node.isMissingNode()) {
return value;
}
throw new JSRuleException(name,JSRuleMessage.read("only.the.following.data.types.are.supported") ,"String,int,Double,Long,Boolean",path);
}
}
/**
*
用于构建一个可执行的action对象,并将其绑定到对应的字段属性中
* @param name action的名字
* @param actionModel action内部可执行的model
* @param define action内部预定义的属性
* @see #buildAction(String, IJSRuleActionModel, JSRuleDefinition)
* @see edi.rule.model.JSRuleAction#setPlugin(IJSRuleActionModel)
* */
public static > A buildPlugin(String name,IJSRuleActionModel extends JSRuleAction> actionModel,JSRuleDefinition define) {
A action = buildAction(name,actionModel,define);
action.setPlugin(actionModel);
return action;
}
/**
* 用于构建一个可执行的action对象
* @param name action的名字
* @param actionModel 可执行action的对象模型
* @param define action内部预定义的属性
* @return 一个可执行的action对象
* */
public static > A buildAction(String name,IJSRuleActionModel extends JSRuleAction> actionModel,JSRuleDefinition define) {
if (actionModel==null) {
throw new JSRuleException(name, JSRuleMessage.read("actionModel.is.required"));
}
A action = createModel(IJSRuleCustom.ExtendType.action);
action.setName(name);
action.setDefine(define);
action.setModel(actionModel);
return action;
}
/**
* 用于构建一个Actions数组
* */
public static > ArrayList actionsInstance() {
return new ArrayList<>();
}
/**
* 用于检查一个Action
* @param action 待执行检查的action
* @param bodyParams {@link JSBody#params}
* @param roles 当前用户的角色集合
* */
public static > void initAction(A action, Map bodyParams,Set roles) {
if (action.getModel() == null) {
action.chooseModel();
}
action.init();
action.getModel().check(action,bodyParams,roles);
}
/**
* 用于检查一个Actions数组
* @param actions 待执行检查的Actions数组
* @param bodyParams {@link JSBody#params}
* @param roles 当前用户的角色集合
* */
@SuppressWarnings("unchecked")
public static > void initActions(List extends JSRuleAction> actions, Map bodyParams,Set roles) {
if (ZSVessel.isEmpty(actions)){
throw new JSRuleException(JSRuleMessage.read("actions.can't.be.empty"));
}
Set actionNames = new HashSet<>();
for (A action:(List)actions){
if (!actionNames.add(action.name)){
throw new JSRuleException(JSRuleMessage.read("action.name.duplication"));
}
initAction(action,bodyParams,roles);
}
}
/**
* 检查是否为可用的model类型
* @param f 待检验的字段
* */
public static boolean isModelType(Field f){
return f != null && IJSRuleActionModel.class.isAssignableFrom(f.getType());
}
/**
*
检查是否为可用的model类型
* @param o 待检验的对象
* */
public static boolean isModelType(Object o){
return o != null && IJSRuleActionModel.class.isAssignableFrom(o.getClass());
}
/**
*
检查映射类信息以及对应的角色信息是否具有crud操作权限
* @param actionName action名
* @param className 直接类名,如有重复则需给出类全名
* @param type 此次操作的crud类型
* @param roles 当前用户的角色集合
* */
public static void checkCrudPermit(String actionName, String className, JSRuleCrudEnum type, Set roles) throws JSRuleException{
JSRuleMappingInfo mappingInfo = JSRuleFrameCache.getMappingInfo(className,actionName);
if (mappingInfo.permit.permit.contains(type.code)){
checkRolePermit(actionName,className,mappingInfo,roles);
checkRolePermit(actionName,className,type,roles);
return;
}
throw new JSRuleException(actionName,JSRuleCrudPermitEnum.getPermitFailMsg(className,type.name));
}
/**
* 检查映射类信息对应的角色是否具有映射对象的访问权限,注解限定角色校验
* @param actionName action名
* @param className 直接类名,如有重复则需给出类全名
* @param mappingInfo 映射对象信息
* @param roles 当前用户的角色集合
* */
public static void checkRolePermit(String actionName,String className,JSRuleMappingInfo mappingInfo,Set roles){
if (ZSVessel.isNotEmpty(mappingInfo.roles)){
if (ZSVessel.isNotEmpty(roles)){
for (String role:mappingInfo.roles){
if (roles.contains(role)){
return;
}
}
}
throw new JSRuleException(actionName,JSRuleCrudPermitEnum.getRolesFailMsg(className,mappingInfo.roles));
}
}
/**
* 检查映射类信息对应的角色是否具有映射对象的访问权限
* @param actionName action名
* @param className 直接类名,如有重复则需给出类全名
* @param type 此次操作的crud类型
* @param roles 当前用户的角色集合
* */
public static void checkRolePermit(String actionName, String className, JSRuleCrudEnum type, Set roles) throws JSRuleException{
if (JSRuleFrameCache.isRolesPermitNotEmpty){
if (ZSVessel.isNotEmpty(roles)){
JSRuleCrudPermitEnum permit;
for (String role:roles){
permit = JSRuleFrameCache.getCrudPermits(role,className);
if (permit != null && permit.permit.contains(type.code)){
return;
}
}
}
throw new JSRuleException(actionName,JSRuleCrudPermitEnum.getAuthorityFailMsg(className,roles,type.name));
}
}
/**
* 将model类转化成对应的json字符串,注意model类中尽量避免boolean类型以is开头命名的方法或变量,因为jackson在写入时有可能会抛出异常
* @param model 待转化的model类
* */
public static String modelToJson(M model) {
return ZSObject.objectToJson(model);
}
/**
* 用于验证系统内部所支持的加密密文是否被篡改
* @param text 待验签的文本
* @param signText 需要比对验证的签名文本(进行签名算法后得到的文本)
* */
public static void verify(String text, String signText) {
if (JSRuleSecurity.isSecurityMode() && ZSString.isBlank(signText)){
throw new JSRuleException(JSRuleMessage.read("in.secure.mode.the.signature.text.cannot.be.empty"));
}
if (!JSRuleContext.getSecurity().verify.apply(text,signText)){
throw new JSRuleException(JSRuleMessage.read("signature.check.error"));
}
}
/**
*
用于解密系统内部所支持的加密密文,自动根据配置的{@link JSRuleProperties.Security#type}安全模式进行解密操作
* @param plainText 需要解密操作的密文
* @return 返回解密后的文本
* */
public static String decrypt(String plainText) {
return JSRuleContext.getSecurity().decrypt.apply(plainText);
}
/**
*
用于将一个字符串转化为JSBody对象,在转化之前会根据系统配置判断是否需要安全验证
* @param body 表示JSBody对象的json字符串
* @param signText 需要比对验证的签名文本(进行签名算法后得到的文本)
* @return 返回json字符串转化后的对象
* */
public static JSBody> parseJSBody(String body,String signText) {
verify(body,signText);
return parseObject(decrypt(body),JSBody.class,JSRuleFrameCache.actionType);
}
/**
*
用于获取框架实际运行的result返回值对象的泛型表示
* */
public static R getResultModel() {
return createModel(IJSRuleCustom.ExtendType.result);
}
/**
* 用于创建框架实际运行的自定义扩展的单例对象
* @param modelType 可扩展的自定义模型类型
* @see IJSRuleCustom
* */
public static T createModel(IJSRuleCustom.ExtendType modelType) {
return ZSReflect.createObject(JSRuleFrameCache.getRunTimeCustomModel(modelType));
}
public static JSRuleProperties.Config initConfig(JSRuleActionCache cache, Function process){
if (cache.define != null && cache.define.config != null){
return process.apply(cache.define.config);
}else{
return process.apply(new JSRuleProperties.Config());
}
}
}