387 changed files with 4520 additions and 3830 deletions
@ -0,0 +1,7 @@ |
|||
package io.sc.engine.rule.core.code; |
|||
|
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit; |
|||
|
|||
public interface SourceCodeGenerator { |
|||
public SourceCode generateSourceCode(ExecuteUnit executeUnit) throws Exception; |
|||
} |
@ -0,0 +1,26 @@ |
|||
package io.sc.engine.rule.core.code.generator; |
|||
|
|||
import io.sc.engine.rule.core.code.SourceCode; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit4Lib; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit4Resource; |
|||
|
|||
public class ExecuteUnit4LibGenerator extends ExecuteUnitGenerator { |
|||
private ExecuteUnit4Lib executeUnit; |
|||
|
|||
public ExecuteUnit4LibGenerator(ExecuteUnit4Lib executeUnit) { |
|||
this.executeUnit =executeUnit; |
|||
} |
|||
|
|||
@Override |
|||
public String getClassName() { |
|||
return executeUnit.getLib().getCode() + "_V" + executeUnit.getLib().getVersion(); |
|||
} |
|||
|
|||
@Override |
|||
public String generate() throws Exception { |
|||
StringBuilder sb =new StringBuilder(); |
|||
|
|||
return sb.toString(); |
|||
} |
|||
} |
@ -0,0 +1,59 @@ |
|||
package io.sc.engine.rule.core.code.generator; |
|||
|
|||
import com.jfinal.template.Engine; |
|||
import com.jfinal.template.Template; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit4Resource; |
|||
import io.sc.engine.rule.core.po.resource.ModelResource; |
|||
import io.sc.engine.rule.core.po.resource.Resource; |
|||
import io.sc.engine.rule.core.util.CodeReplacer; |
|||
import io.sc.engine.rule.core.util.ExpressionReplacer; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
public class ExecuteUnit4ResourceGenerator extends ExecuteUnitGenerator { |
|||
private static final String template_location = "/io/sc/engine/rule/core/code/generator/template/resource.tpl"; |
|||
private ExecuteUnit4Resource executeUnit; |
|||
|
|||
public ExecuteUnit4ResourceGenerator(ExecuteUnit4Resource executeUnit) { |
|||
this.executeUnit =executeUnit; |
|||
Resource resource =executeUnit.getResource(); |
|||
if(resource instanceof ModelResource){ |
|||
((ModelResource)resource).getModel().buildFullName(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public String getClassName() { |
|||
return executeUnit.getResource().getCode() + "_V" + executeUnit.getResource().getVersion(); |
|||
} |
|||
|
|||
@Override |
|||
public String generate() throws Exception { |
|||
Engine engine = new Engine(Engine.MAIN_ENGINE_NAME); |
|||
engine.setDevMode(true); |
|||
engine.setToClassPathSourceFactory(); |
|||
engine.setStaticFieldExpression(true); |
|||
engine.setStaticMethodExpression(true); |
|||
|
|||
engine.addSharedStaticMethod(CodeReplacer.class); |
|||
engine.addSharedStaticMethod(ExpressionReplacer.class); |
|||
//engine.addSharedObject("TC",new CodeReplacer());
|
|||
|
|||
Map<String,Object> data =new HashMap<>(); |
|||
data.put("packageName",this.getPackageName()); |
|||
data.put("executeUnit",executeUnit); |
|||
Template template =engine.getTemplate(template_location); |
|||
return template.renderToString(data); |
|||
|
|||
// StringBuilder sb =new StringBuilder();
|
|||
// sb.append(PackageGenerator.generate(getPackageName())).append("\n");
|
|||
// sb.append(CommonImportGenerator.generate()).append("\n");
|
|||
// sb.append(FunctionGenerator.generate(executeUnit.getFunctions())).append("\n");
|
|||
// sb.append(ResourceClassGenerator.generate(executeUnit.getResource())).append("\n");
|
|||
// sb.append(ArgumentClassGenerator.generate(executeUnit.getResource())).append("\n");
|
|||
// sb.append(DictionaryClassGenerator.generate(executeUnit.getDictionaries())).append("\n");
|
|||
// sb.append(LibClassGenerator.generate(executeUnit.getLibs())).append("\n");
|
|||
// return sb.toString();
|
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
package io.sc.engine.rule.core.code.generator; |
|||
|
|||
import io.sc.engine.rule.core.code.SourceCode; |
|||
import io.sc.engine.rule.core.code.generator.impl.CommonImportGenerator; |
|||
import io.sc.engine.rule.core.code.generator.impl.PackageGenerator; |
|||
|
|||
public abstract class ExecuteUnitGenerator { |
|||
public SourceCode generateSourceCode() throws Exception { |
|||
SourceCode sourceCode =new SourceCode(); |
|||
sourceCode.setPackageName(getPackageName()); |
|||
sourceCode.setClassName(getClassName()); |
|||
sourceCode.setSource(generate()); |
|||
return sourceCode; |
|||
} |
|||
|
|||
public String getPackageName() { |
|||
return "io.sc.engine.rule.core.code"; |
|||
} |
|||
|
|||
public abstract String getClassName(); |
|||
public abstract String generate() throws Exception; |
|||
} |
@ -0,0 +1,9 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.resource.Resource; |
|||
|
|||
public class ArgumentClassGenerator { |
|||
public static String generate(Resource resource) { |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import org.springframework.util.StreamUtils; |
|||
|
|||
import java.nio.charset.StandardCharsets; |
|||
|
|||
public class CommonImportGenerator { |
|||
private static final String TEMPLATE_CLASSPATH = "/io/sc/engine/rule/core/code/generator/template/Import.tpl"; |
|||
|
|||
public static String generate() throws Exception{ |
|||
return StreamUtils.copyToString(ResourceClassGenerator.class.getResourceAsStream(TEMPLATE_CLASSPATH), StandardCharsets.UTF_8); |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.dictionary.Dictionary; |
|||
|
|||
import java.util.List; |
|||
|
|||
public class DictionaryClassGenerator { |
|||
public static String generate(List<Dictionary> dictionaries) { |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.function.Function; |
|||
import io.sc.platform.util.StringUtil; |
|||
import org.springframework.util.StreamUtils; |
|||
|
|||
import java.nio.charset.StandardCharsets; |
|||
import java.util.List; |
|||
|
|||
public class FunctionGenerator { |
|||
private static final String TEMPLATE_CLASSPATH = "/io/sc/engine/rule/core/code/generator/template/Function.tpl"; |
|||
|
|||
public static String generate(List<Function> functions) throws Exception{ |
|||
String template =StreamUtils.copyToString(ResourceClassGenerator.class.getResourceAsStream(TEMPLATE_CLASSPATH), StandardCharsets.UTF_8); |
|||
StringBuilder sb =new StringBuilder(""); |
|||
if(functions!=null && !functions.isEmpty()){ |
|||
for(Function function : functions){ |
|||
String[] pattern =new String[]{ |
|||
"/**", |
|||
" * {0}", |
|||
" */", |
|||
}; |
|||
sb.append(StringUtil.format(pattern,function.getDescription())); |
|||
sb.append(function.getBody()).append("\n\n"); |
|||
} |
|||
} |
|||
return StringUtil.format(template,sb.toString()); |
|||
} |
|||
} |
@ -0,0 +1,12 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.dictionary.Dictionary; |
|||
import io.sc.engine.rule.core.po.lib.Lib; |
|||
|
|||
import java.util.List; |
|||
|
|||
public class LibClassGenerator { |
|||
public static String generate(List<Lib> libs) { |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,57 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.model.Model; |
|||
import io.sc.engine.rule.core.util.CodeReplacer; |
|||
import io.sc.platform.util.CollectionUtil; |
|||
import io.sc.platform.util.FileUtil; |
|||
import io.sc.platform.util.StringUtil; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public class ModelGenerator { |
|||
private static final String MODEL_TEMPLATE_CLASSPATH ="classpath:/io/sc/engine/rule/core/code/generator/templates/Model.tpl"; |
|||
private static final String MODEL_EXECUTE_METHOD_TEMPLATE_CLASSPATH ="classpath:/io/sc/engine/rule/core/code/generator/templates/ModelExecuteMethod.tpl"; |
|||
|
|||
public static String generate(Model model) throws Exception{ |
|||
String template = FileUtil.readString(MODEL_TEMPLATE_CLASSPATH); |
|||
StringBuilder sb =new StringBuilder(); |
|||
|
|||
Map<String,Object> variables =new HashMap<>(); |
|||
variables.put("enable",model.getEnable()); |
|||
variables.put("name",model.getName()); |
|||
variables.put("methodName", CodeReplacer.methodName(model.getCode())); |
|||
variables.put("executeMode",model.getExecuteMode().toString()); |
|||
variables.put("executeModelMethods",generateExecuteMethods(model)); |
|||
variables.put("executeParameterMethods",ParameterGenerator.generateExecuteMethods(model)); |
|||
variables.put("modelMethodBodys",generateMethodBodys(model.getChildren())); |
|||
variables.put("parameterMethodBodys",ParameterGenerator.generateMethodBodys(model.getAllParameters())); |
|||
sb.append(StringUtil.format(template,variables)); |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static String generateExecuteMethods(Model model) throws Exception { |
|||
StringBuilder sb =new StringBuilder(""); |
|||
if(CollectionUtil.hasElements(model.getChildren())){ |
|||
String template = FileUtil.readString(MODEL_EXECUTE_METHOD_TEMPLATE_CLASSPATH); |
|||
for(Model subModel : model.getChildren()) { |
|||
Map<String,Object> variables =new HashMap<>(); |
|||
variables.put("methodName", CodeReplacer.methodName(subModel.getCode())); |
|||
variables.put("comments",subModel.getName()); |
|||
sb.append(StringUtil.format(template,variables)); |
|||
} |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static String generateMethodBodys(List<Model> models) throws Exception { |
|||
StringBuilder sb =new StringBuilder(""); |
|||
if(CollectionUtil.hasElements(models)){ |
|||
for(Model model : models) { |
|||
sb.append(generate(model)); |
|||
} |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.platform.util.StringUtil; |
|||
import org.springframework.util.StreamUtils; |
|||
|
|||
import java.nio.charset.StandardCharsets; |
|||
|
|||
public class PackageGenerator { |
|||
private static final String TEMPLATE_CLASSPATH = "/io/sc/engine/rule/core/code/generator/template/Package.tpl"; |
|||
|
|||
public static String generate(String packageName) throws Exception{ |
|||
String template =StreamUtils.copyToString(ResourceClassGenerator.class.getResourceAsStream(TEMPLATE_CLASSPATH), StandardCharsets.UTF_8); |
|||
return StringUtil.format(template,packageName); |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.model.Model; |
|||
import io.sc.engine.rule.core.po.model.Parameter; |
|||
import io.sc.engine.rule.core.po.model.parameter.IntermediateParameter; |
|||
import io.sc.engine.rule.core.po.model.parameter.OutParameter; |
|||
import io.sc.engine.rule.core.util.CodeReplacer; |
|||
import io.sc.platform.util.CollectionUtil; |
|||
import io.sc.platform.util.FileUtil; |
|||
import io.sc.platform.util.StringUtil; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public class ParameterGenerator { |
|||
private static final String PARAMETER_TEMPLATE_CLASSPATH ="classpath:/io/sc/engine/rule/core/code/generator/templates/Parameter.tpl"; |
|||
private static final String PARAMETER_EXECUTE_METHOD_TEMPLATE_CLASSPATH ="classpath:/io/sc/engine/rule/core/code/generator/templates/ParameterExecuteMethod.tpl"; |
|||
|
|||
public static String generate(Parameter parameter) throws Exception{ |
|||
String template = FileUtil.readString(PARAMETER_TEMPLATE_CLASSPATH); |
|||
StringBuilder sb =new StringBuilder(); |
|||
|
|||
Map<String,Object> variables =new HashMap<>(); |
|||
variables.put("name",parameter.getName()); |
|||
variables.put("methodName", CodeReplacer.methodName(parameter.getCode())); |
|||
variables.put("type", parameter.getType().toString()); |
|||
sb.append(StringUtil.format(template,variables)); |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static String generateExecuteMethods(Model model) throws Exception { |
|||
StringBuilder sb =new StringBuilder(""); |
|||
if(CollectionUtil.hasElements(model.getParameters())){ |
|||
String template = FileUtil.readString(PARAMETER_EXECUTE_METHOD_TEMPLATE_CLASSPATH); |
|||
for(Parameter parameter : model.getParameters()) { |
|||
if(parameter instanceof IntermediateParameter || parameter instanceof OutParameter) { |
|||
Map<String, Object> variables = new HashMap<>(); |
|||
variables.put("methodName", CodeReplacer.methodName(parameter.getCode())); |
|||
variables.put("name", parameter.getName()); |
|||
variables.put("type", parameter.getType().toString()); |
|||
sb.append(StringUtil.format(template, variables)); |
|||
} |
|||
} |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static String generateMethodBodys(List<Parameter> parameters) throws Exception { |
|||
StringBuilder sb =new StringBuilder(""); |
|||
if(CollectionUtil.hasElements(parameters)){ |
|||
for(Parameter parameter : parameters) { |
|||
if(parameter instanceof IntermediateParameter || parameter instanceof OutParameter) { |
|||
sb.append(generate(parameter)); |
|||
} |
|||
} |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.model.Parameter; |
|||
import io.sc.platform.util.FileUtil; |
|||
import io.sc.platform.util.StringUtil; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public class ParameterMethodGenerator { |
|||
private static final String TEMPLATE_CLASSPATH ="classpath:/io/sc/engine/rule/core/code/generator/templates/ParameterMethod.tpl"; |
|||
|
|||
public static String generate(Parameter parameter) throws Exception{ |
|||
List<String> templates = FileUtil.readStringAsList(TEMPLATE_CLASSPATH); |
|||
|
|||
Map<String,Object> variables =new HashMap<>(); |
|||
variables.put("code",parameter.getCode()); |
|||
variables.put("name",parameter.getName()); |
|||
|
|||
return StringUtil.format(templates,variables); |
|||
} |
|||
} |
@ -0,0 +1,37 @@ |
|||
package io.sc.engine.rule.core.code.generator.impl; |
|||
|
|||
import io.sc.engine.rule.core.po.model.Model; |
|||
import io.sc.engine.rule.core.po.resource.ModelResource; |
|||
import io.sc.engine.rule.core.po.resource.Resource; |
|||
import io.sc.engine.rule.core.util.CodeReplacer; |
|||
import io.sc.platform.util.FileUtil; |
|||
import io.sc.platform.util.StringUtil; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public class ResourceClassGenerator { |
|||
private static final String TEMPLATE_CLASSPATH ="classpath:/io/sc/engine/rule/core/code/generator/templates/Resource.tpl"; |
|||
|
|||
public static String generate(Resource resource) throws Exception{ |
|||
StringBuilder sb =new StringBuilder(""); |
|||
if(resource!=null){ |
|||
List<String> templates = FileUtil.readStringAsList(TEMPLATE_CLASSPATH); |
|||
|
|||
Map<String,Object> variables =new HashMap<>(); |
|||
variables.put("resourceClassName", CodeReplacer.className(resource.getCode(),resource.getVersion())); |
|||
variables.put("resourceName",resource.getName()); |
|||
variables.put("resourceVersion",resource.getVersion()); |
|||
if(resource instanceof ModelResource) { |
|||
Model model =((ModelResource)resource).getModel(); |
|||
variables.put("topModelName", model.getName()); |
|||
variables.put("topModelMethodName", CodeReplacer.methodName(model.getCode())); |
|||
variables.put("topModelMethod", ModelGenerator.generate(model)); |
|||
} |
|||
|
|||
sb.append(StringUtil.format(templates,variables)); |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
/******************************************************** |
|||
* Functions |
|||
********************************************************/ |
|||
#for(function : executeUnit.functions) |
|||
|
|||
/** |
|||
* #(function.description) |
|||
*/ |
|||
#(function.body) |
|||
#end |
@ -0,0 +1,86 @@ |
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
import com.fasterxml.jackson.core.type.TypeReference; |
|||
import groovy.transform.Canonical; |
|||
import io.sc.engine.rule.client.Executor; |
|||
import io.sc.engine.rule.core.classes.ResourceAbstract; |
|||
import io.sc.engine.rule.core.classes.RuleResult; |
|||
import io.sc.engine.rule.core.classes.SingleRuleResult; |
|||
import io.sc.engine.rule.core.code.impl.support.FieldValidator; |
|||
import io.sc.engine.rule.core.code.impl.support.ParameterResult; |
|||
import io.sc.engine.rule.core.code.impl.support.ResourceResult; |
|||
import io.sc.engine.rule.core.code.impl.support.ValidateResult; |
|||
import io.sc.engine.rule.core.enums.ParameterType; |
|||
import io.sc.engine.rule.core.enums.RuntimeInputParameterType; |
|||
import io.sc.engine.rule.core.function.JpmmlEvaluator; |
|||
import io.sc.engine.rule.core.util.CodeReplacer; |
|||
import io.sc.engine.rule.core.util.ESql; |
|||
import io.sc.platform.util.DateUtil; |
|||
import io.sc.platform.util.ObjectMapperUtil; |
|||
import io.sc.platform.util.StringUtil; |
|||
import io.sc.platform.util.TypeConvertor; |
|||
import java.math.*; |
|||
import java.util.Map; |
|||
import java.util.Random; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.div; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.lg; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.ln; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.log; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.max; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.min; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.randomInt; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.root; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.sum; |
|||
import static io.sc.engine.rule.core.function.ArithmeticFunction.transformSequencing; |
|||
import static io.sc.engine.rule.core.function.DateFunction.now; |
|||
import static io.sc.engine.rule.core.function.DateFunction.yyyyMMdd; |
|||
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd; |
|||
import static io.sc.engine.rule.core.function.NormalDistributionFunction.G; |
|||
import static io.sc.engine.rule.core.function.NormalDistributionFunction.iG; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.infinite; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.isInfinite; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.isNan; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.isNil; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.isZero; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.nan; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.nil; |
|||
import static io.sc.engine.rule.core.function.SpecialValueFunction.zero; |
|||
import static io.sc.engine.rule.core.function.StringFunction.contains; |
|||
import static io.sc.engine.rule.core.function.StringFunction.endsWith; |
|||
import static io.sc.engine.rule.core.function.StringFunction.join; |
|||
import static io.sc.engine.rule.core.function.StringFunction.length; |
|||
import static io.sc.engine.rule.core.function.StringFunction.lowerCase; |
|||
import static io.sc.engine.rule.core.function.StringFunction.startsWith; |
|||
import static io.sc.engine.rule.core.function.StringFunction.trim; |
|||
import static io.sc.engine.rule.core.function.StringFunction.upperCase; |
|||
import static io.sc.engine.rule.core.util.NumberFormater.comma; |
|||
import static io.sc.engine.rule.core.util.NumberFormater.decimal; |
|||
import static io.sc.engine.rule.core.util.NumberFormater.money; |
|||
import static io.sc.engine.rule.core.util.NumberFormater.percent; |
|||
import static java.lang.Math.E; |
|||
import static java.lang.Math.IEEEremainder; |
|||
import static java.lang.Math.PI; |
|||
import static java.lang.Math.abs; |
|||
import static java.lang.Math.acos; |
|||
import static java.lang.Math.asin; |
|||
import static java.lang.Math.atan; |
|||
import static java.lang.Math.atan2; |
|||
import static java.lang.Math.cbrt; |
|||
import static java.lang.Math.ceil; |
|||
import static java.lang.Math.cos; |
|||
import static java.lang.Math.cosh; |
|||
import static java.lang.Math.exp; |
|||
import static java.lang.Math.expm1; |
|||
import static java.lang.Math.floor; |
|||
import static java.lang.Math.pow; |
|||
import static java.lang.Math.random; |
|||
import static java.lang.Math.rint; |
|||
import static java.lang.Math.round; |
|||
import static java.lang.Math.sin; |
|||
import static java.lang.Math.sinh; |
|||
import static java.lang.Math.sqrt; |
|||
import static java.lang.Math.tan; |
|||
import static java.lang.Math.tanh; |
|||
import static java.lang.Math.toDegrees; |
|||
import static java.lang.Math.toRadians; |
@ -0,0 +1,28 @@ |
|||
#define renderModel(model) |
|||
//模型(#(model.fullName)) |
|||
private static void #(methodName(model.code))(Executor executor,Argument argument){ |
|||
if(log.isDebugEnabled()){log.debug("开始调用模型: {}","#(model.fullName)");} |
|||
#if(!model.enable) |
|||
if(log.isDebugEnabled()){log.debug("开始调用模型: enable==false");} |
|||
#end |
|||
#if(model.executeMode.toString()=="DOWN_UP") |
|||
//模型的执行模式为:自下而上,首先执行子模型 |
|||
#for(subModel : model.children) |
|||
#(methodName(subModel.code))(executor,argument);//#(subModel.name) |
|||
#end |
|||
#end |
|||
|
|||
//处理模型的中间值和结果值 |
|||
#for(parameter : model.parameters) |
|||
#if(parameter.type.toString()=="INTERMEDIATE" || parameter.type.toString()=="OUT") |
|||
#(methodName(parameter.code))(executor,argument);//#(parameter.name),#(parameter.type) |
|||
#end |
|||
#end |
|||
} |
|||
|
|||
#for(subModel : model.children) |
|||
#@renderModel(subModel) |
|||
#end |
|||
|
|||
#@renderParameter(model) |
|||
#end |
@ -0,0 +1 @@ |
|||
package #(packageName); |
@ -0,0 +1,37 @@ |
|||
#define renderParameter(model) |
|||
#for(parameter : model.allParameters) |
|||
//参数处理器, #(parameter.name)(#(parameter.type)) |
|||
private static void #(methodName(parameter.code))(Executor executor,Argument argument) { |
|||
if(log.isDebugEnabled()){log.debug(" {}","#(parameter.name)(#(parameter.type))");} |
|||
#for(processor : parameter.processors) |
|||
#if(processor.enable) |
|||
#switch (processor.type.toString()) |
|||
#case ("ARITHMETIC") |
|||
#include("/io/sc/engine/rule/core/code/generator/template/processor/arithmetic.tpl") |
|||
#case ("CONDITION_RANGE") |
|||
#include("/io/sc/engine/rule/core/code/generator/template/processor/conditionRange.ftl") |
|||
#case ("DECISION_TABLE") |
|||
#case ("DECISION_TABLE_2C") |
|||
#case ("DECISION_TREE") |
|||
#case ("EXECUTION_FLOW") |
|||
#case ("GROOVY_SCRIPT") |
|||
#case ("HTTP_REQUEST") |
|||
#case ("MATH_FORMULA") |
|||
#case ("NUMBER_RANGE") |
|||
#include("/io/sc/engine/rule/core/code/generator/template/processor/numberRange.ftl") |
|||
#case ("OBJECT_PROPERTIES") |
|||
#case ("OPTION_VALUE") |
|||
#case ("PMML") |
|||
#case ("RULE") |
|||
#case ("SCORE_CARD") |
|||
#case ("SINGLE_RULE") |
|||
#case ("SQL") |
|||
#case ("TERNARY") |
|||
#case ("WHEN_THEN") |
|||
#end |
|||
#end |
|||
#end |
|||
if(log.isDebugEnabled()){log.debug(" 参数结果值 : {}",argument.#(fieldName(parameter.code)));} |
|||
} |
|||
#end |
|||
#end |
@ -0,0 +1,4 @@ |
|||
//决策表 |
|||
${DecisionTable.generateGroovyCode(parameter,processor)} |
|||
if(log.isDebugEnabled()){log.debug(" 决策表运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
|
@ -0,0 +1,4 @@ |
|||
//简单决策表 |
|||
${DecisionTable2C.generateGroovyCode(parameter,processor)} |
|||
if(log.isDebugEnabled()){log.debug(" 简单决策表运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
|
@ -0,0 +1,4 @@ |
|||
//决策树(此处只是入口,真正的决策树计算逻辑在后面通过一系列方法完成) |
|||
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =Tree_${CodeReplacer.fieldName(parameter.code)}_${DecisionTree.parse(processor.decisionTree).id}(executor,${ExpressionReplacer.ARGUMENT_NAME}); |
|||
if(log.isDebugEnabled()){log.debug(" 决策树运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
|
@ -0,0 +1,13 @@ |
|||
/*-------------------------------------------------------------------------------* |
|||
* 决策树函数 * |
|||
*-------------------------------------------------------------------------------*/ |
|||
<#list (model.getAllParameters())! as parameter><#-- 循环将每个参数处理生成一个方法 --> |
|||
<#if ("INTERMEDIATE"==parameter.type || "OUT"==parameter.type)> |
|||
<#list (parameter.processors)! as processor> |
|||
<#if "DECISION_TREE"==processor.type> |
|||
//${parameter.name}(${parameter.type}) |
|||
${DecisionTree.generateGroovyCode(parameter,processor)} |
|||
</#if> |
|||
</#list> |
|||
</#if> |
|||
</#list> |
@ -0,0 +1,13 @@ |
|||
/*-------------------------------------------------------------------------------* |
|||
* 执行流函数 * |
|||
*-------------------------------------------------------------------------------*/ |
|||
<#list (model.getAllParameters())! as parameter><#-- 循环将每个参数处理生成一个方法 --> |
|||
<#if ("INTERMEDIATE"==parameter.type || "OUT"==parameter.type)> |
|||
<#list (parameter.processors)! as processor> |
|||
<#if "EXECUTION_FLOW"==processor.type> |
|||
//${parameter.name}(${parameter.type}) |
|||
${ExecutionFlow.generateGroovyCode(parameter,processor)} |
|||
</#if> |
|||
</#list> |
|||
</#if> |
|||
</#list> |
@ -0,0 +1,3 @@ |
|||
<#if processor.groovyScript??> |
|||
${ExpressionReplacer.groovy(processor.groovyScript,null)} |
|||
</#if> |
@ -0,0 +1,4 @@ |
|||
//数学公式 |
|||
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${MathFormula.generateGroovyCode(parameter,processor)}; |
|||
if(log.isDebugEnabled()){log.debug(" 数学公式运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
|
@ -0,0 +1,4 @@ |
|||
//对象属性函数 |
|||
${ObjectProperty.generateGroovyCode(parameter,processor)} |
|||
if(log.isDebugEnabled()){log.debug(" 对象属性函数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
|
@ -0,0 +1,34 @@ |
|||
//选项值运算 |
|||
<#assign optionParameter=model.getParameterByOptionParameterCode(processor.optionCode)> |
|||
<#if optionParameter??> |
|||
if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}!=null){ |
|||
<#list model.getParameterOptionsByOptionParameterCode(processor.optionCode) as option> |
|||
<#if option_index==0> |
|||
<#if optionParameter.valueType=='java.lang.String'> |
|||
if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}=="""${option.inputValue}"""){ |
|||
<#else> |
|||
if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}==${option.inputValue}){ |
|||
</#if> |
|||
<#else> |
|||
<#if optionParameter.valueType=='java.lang.String'> |
|||
}else if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}=="""${option.inputValue}"""){ |
|||
<#else> |
|||
}else if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}==${option.inputValue}){ |
|||
</#if> |
|||
</#if> |
|||
<#if parameter.valueType=='java.lang.String'> |
|||
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} ="""${option.value}"""; |
|||
if(log.isDebugEnabled()){log.debug(" 选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
<#else> |
|||
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${option.value}; |
|||
if(log.isDebugEnabled()){log.debug(" 选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
</#if> |
|||
</#list> |
|||
}else{ |
|||
if(log.isDebugEnabled()){log.debug(" !!!未匹配到选项列表,选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
} |
|||
}else{ |
|||
if(log.isDebugEnabled()){log.debug(" !!!未提供选项输入值,选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
} |
|||
</#if> |
|||
|
@ -0,0 +1,3 @@ |
|||
<#if processor.pmml??> |
|||
arg.${CodeReplacer.fieldName(parameter.code)} =JpmmlEvaluator.evaluate('${parameter.id}_${processor.id}','''${processor.pmml}''',arg.toMap()); |
|||
</#if> |
@ -0,0 +1,17 @@ |
|||
//SQL 运算 |
|||
<#if processor.sqlDatasourceName??> |
|||
javax.sql.DataSource ds =io.sc.engine.rule.client.spring.util.EngineSpringApplicationContextUtil.getDataSource('${processor.sqlDatasourceName}'); |
|||
<#else> |
|||
javax.sql.DataSource ds =io.sc.engine.rule.client.spring.util.EngineSpringApplicationContextUtil.getDefaultDataSource(); |
|||
</#if> |
|||
String sql =${ExpressionReplacer.groovy("\n"+processor.sql,"java.lang.String")}; |
|||
<#if processor.sql??> |
|||
ESql.withInstance(ds){ db-> |
|||
db.query(sql) { rs -> |
|||
if (rs.next()) { |
|||
${SqlFieldMapping.generateGroovyCode(parameter,processor)} |
|||
} |
|||
} |
|||
} |
|||
</#if> |
|||
|
@ -0,0 +1,4 @@ |
|||
//三元运算 |
|||
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =(${ExpressionReplacer.groovy(processor.ternaryCondition,null)}) ? (${ExpressionReplacer.groovy(processor.ternaryTrue,parameter.valueType)}) : (${ExpressionReplacer.groovy(processor.ternaryFalse,parameter.valueType)}); |
|||
if(log.isDebugEnabled()){log.debug(" 三元运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});} |
|||
|
@ -0,0 +1,4 @@ |
|||
|
|||
//算数运算 |
|||
argument.#(fieldName(parameter.code)) =#(groovy(processor.arithmetic,parameter.valueType));//#(parameter.type), #(parameter.name) |
|||
if(log.isDebugEnabled()){log.debug(" 算数运算结果 : {}",argument.#(fieldName(parameter.code)));} |
@ -0,0 +1,3 @@ |
|||
//条件分段函数 |
|||
#(io.sc.engine.rule.core.code.impl.support.processor.ConditionRange::generateGroovyCode(parameter,processor)) |
|||
if(log.isDebugEnabled()){log.debug(" 条件分段函数运算结果 : {}",argument.#(fieldName(parameter.code)));} |
@ -0,0 +1,4 @@ |
|||
//数值分段函数 |
|||
#(io.sc.engine.rule.core.code.impl.support.processor.NumberRange::generateGroovyCode(parameter,processor)) |
|||
if(log.isDebugEnabled()){log.debug(" 数值分段函数运算结果 : {}",argument.#(fieldName(parameter.code)));} |
|||
|
@ -0,0 +1,118 @@ |
|||
#include("package.tpl") |
|||
|
|||
#include("import.tpl") |
|||
|
|||
#include("functions.tpl") |
|||
|
|||
#set(resource = executeUnit.resource) |
|||
#set(libs =executeUnit.libs) |
|||
#set(model = resource.model) |
|||
|
|||
/******************************************************** |
|||
* Execute Unit |
|||
********************************************************/ |
|||
/** |
|||
* type: #(executeUnit.type) |
|||
* code: #(resource.code), |
|||
* name: #(resource.name), |
|||
* version: #(resource.version) |
|||
*/ |
|||
class #(className(resource.code,resource.version)) { |
|||
private static final Logger log =LoggerFactory.getLogger(#(className(resource.code,resource.version)).class); |
|||
|
|||
/** |
|||
* 执行方法(Map作为输入参数,该 Map 封装了调用模型的参数) |
|||
* @param map 输入参数封装器 |
|||
* @return 执行结果 |
|||
*/ |
|||
public static ResourceResult execute(Map<String,Object> map) throws Exception{ |
|||
return execute(map["executor"],map["subModelCode"],map["argument"]); |
|||
} |
|||
|
|||
/** |
|||
* 执行方法 |
|||
* @param executor 执行器对象 |
|||
* @param subModelCode 子模型代码 |
|||
* @param data 输入参数 |
|||
* @return 执行结果 |
|||
*/ |
|||
public static ResourceResult execute(Executor executor,String subModelCode,Object data) throws Exception{ |
|||
if(log.isDebugEnabled()){log.debug("开始执行: #(resource.name)");} |
|||
if(data instanceof Map){ |
|||
if(log.isDebugEnabled()){log.debug("显示输入参数(Map)=================================================\n{}",ObjectMapperUtil.json().writeValueAsString(data));} |
|||
}else if(data instanceof String){ |
|||
if(log.isDebugEnabled()){log.debug("显示输入参数(Json字符串)=================================================\n{}",data);} |
|||
} |
|||
|
|||
//初始化指标库 |
|||
#for(lib : libs) |
|||
if(log.isDebugEnabled()){log.debug("初始化指标库 : #(lib.name)_V#(lib.version)");} |
|||
|
|||
#(className(lib.code,lib.version)) #(varName(lib.code,lib.version)) =new #(className)(); |
|||
#(className(lib.code,lib.version)).convertArgument(data); |
|||
#end |
|||
|
|||
//初始化模型参数 |
|||
if(log.isDebugEnabled()){log.debug("从 {} 初始化模型参数","java.lang.String"==data.class?"Json":"Map");} |
|||
Argument argument =Argument.convertArgument(data); |
|||
|
|||
//输入参数合法性检查 |
|||
ValidateResult validateResult =new ValidateResult(); |
|||
|
|||
//输入参数合法性检查(指标库) |
|||
#for(lib : libs) |
|||
if(log.isDebugEnabled()){log.debug("开始检查输入参数数据合法性(指标库: #(lib.name)_V#(lib.version))");} |
|||
#(varName(lib.code,lib.version)).validate(validateResult); |
|||
if(validateResult.hasError()){ |
|||
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");} |
|||
ResourceResult result =new ResourceResult(); |
|||
result.setValidateResult(validateResult); |
|||
return result; |
|||
} |
|||
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");} |
|||
#end |
|||
|
|||
//输入参数合法性检查(模型) |
|||
if(log.isDebugEnabled()){log.debug("开始检查模型输入参数数据合法性");} |
|||
argument.validate(validateResult); |
|||
if(validateResult.hasError()){ |
|||
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");} |
|||
ResourceResult result =new ResourceResult(); |
|||
result.setValidateResult(validateResult); |
|||
return result; |
|||
} |
|||
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");} |
|||
|
|||
//执行指标库 |
|||
#for(lib : executeUnit.getLibs()) |
|||
if(log.isDebugEnabled()){log.debug("开始执行指标库: #(lib.name)_V#(lib.version)");} |
|||
#(varName(lib.code,lib.version)).execute(); |
|||
</#list> |
|||
#end |
|||
|
|||
//合并指标库指标 |
|||
if(log.isDebugEnabled()){log.debug("开始合并指标库指标");} |
|||
Map<String,Object> indicatorLibs =new HashMap<String,Object>(); |
|||
#for(lib : executeUnit.getLibs()) |
|||
indicatorLibs.put("#(varName(lib.code,lib.version))",#(varName(lib.code,lib.version))); |
|||
#end |
|||
argument.mergeParameterValueFromIndicatorLib(indicatorLibs); |
|||
if(log.isDebugEnabled()){log.debug("显示合并后输入参数:\n{}",ObjectMapperUtil.json().writeValueAsString(argument));} |
|||
|
|||
//执行模型 |
|||
if(subModelCode){ |
|||
subModelCode =CodeReplacer.methodName(subModelCode); |
|||
"${subModelCode}"(executor,argument);//调用子模型 |
|||
}else{ |
|||
#(methodName(model.code))(executor,argument);//调用顶级模型(#(model.name)) |
|||
} |
|||
|
|||
//返回结果 |
|||
ResourceResult result =argument.toResult(); |
|||
if(log.isDebugEnabled()){log.debug("模型调用成功,返回结果:\n{}",ObjectMapperUtil.json().writeValueAsString(result));} |
|||
return result; |
|||
} |
|||
|
|||
#include("parameter.tpl") |
|||
#include("model.tpl") |
|||
#@renderModel(model) |
@ -0,0 +1,24 @@ |
|||
package io.sc.engine.rule.core.code.impl; |
|||
|
|||
import io.sc.engine.rule.core.code.SourceCode; |
|||
import io.sc.engine.rule.core.code.SourceCodeGenerator; |
|||
import io.sc.engine.rule.core.code.generator.ExecuteUnit4LibGenerator; |
|||
import io.sc.engine.rule.core.code.generator.ExecuteUnit4ResourceGenerator; |
|||
import io.sc.engine.rule.core.code.generator.ExecuteUnitGenerator; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit4Lib; |
|||
import io.sc.engine.rule.core.code.impl.support.ExecuteUnit4Resource; |
|||
|
|||
public class JavaSourceCodeGenerator implements SourceCodeGenerator { |
|||
@Override |
|||
public SourceCode generateSourceCode(ExecuteUnit executeUnit) throws Exception { |
|||
if(executeUnit instanceof ExecuteUnit4Resource){ |
|||
ExecuteUnitGenerator generator =new ExecuteUnit4ResourceGenerator((ExecuteUnit4Resource)executeUnit); |
|||
return generator.generateSourceCode(); |
|||
}else if(executeUnit instanceof ExecuteUnit4Lib){ |
|||
ExecuteUnitGenerator generator =new ExecuteUnit4LibGenerator((ExecuteUnit4Lib)executeUnit); |
|||
return generator.generateSourceCode(); |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,76 @@ |
|||
package io.sc.engine.rule.core.code.impl.support; |
|||
|
|||
import io.sc.engine.rule.core.enums.ParameterType; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
public class ExecuteResult { |
|||
private ValidateResult validateResult; |
|||
private List<ParameterResult> data =new ArrayList<ParameterResult>(); |
|||
|
|||
/** |
|||
* 添加结果参数 |
|||
* @param code 代码 |
|||
* @param name 名称 |
|||
* @param type 类型 |
|||
* @param valueType 值类型 |
|||
* @param value 值 |
|||
*/ |
|||
public void addParameterResult(String code, String name, ParameterType type, String valueType, String value) { |
|||
data.add(new ParameterResult(code,name,type,valueType,value)); |
|||
} |
|||
|
|||
/** |
|||
* 通过参数代码获取参数值 |
|||
* @param code 参数代码 |
|||
* @return 参数值 |
|||
*/ |
|||
public boolean exists(String code) { |
|||
if(code!=null && !"".equals(code.trim())) { |
|||
if(data!=null && data.size()>0) { |
|||
for(ParameterResult parameterResult : data) { |
|||
if(code.equals(parameterResult.getCode())){ |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* 通过参数代码获取参数值 |
|||
* @param code 参数代码 |
|||
* @return 参数值 |
|||
*/ |
|||
public String getValueByParameterCode(String code) { |
|||
if(code!=null && !"".equals(code.trim())) { |
|||
if(data!=null && data.size()>0) { |
|||
for(ParameterResult parameterResult : data) { |
|||
if(code.equals(parameterResult.getCode())){ |
|||
return parameterResult.getValue(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public ValidateResult getValidateResult() { |
|||
return validateResult; |
|||
} |
|||
public void setValidateResult(ValidateResult validateResult) { |
|||
this.validateResult = validateResult; |
|||
} |
|||
public List<ParameterResult> getData() { |
|||
return data; |
|||
} |
|||
public void setData(List<ParameterResult> data) { |
|||
this.data = data; |
|||
} |
|||
|
|||
public void addParameterResult(ParameterResult result) { |
|||
this.data.add(result); |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
package io.sc.engine.rule.core.code.impl.support; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
import com.fasterxml.jackson.annotation.JsonSubTypes; |
|||
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
|||
import io.sc.engine.rule.core.po.dictionary.Dictionary; |
|||
import io.sc.engine.rule.core.po.function.Function; |
|||
|
|||
import java.util.List; |
|||
|
|||
@JsonIgnoreProperties(ignoreUnknown=true) |
|||
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl=ExecuteUnit4Resource.class) |
|||
@JsonSubTypes({ |
|||
@JsonSubTypes.Type(value=ExecuteUnit4Resource.class), |
|||
@JsonSubTypes.Type(value=ExecuteUnit4Lib.class) |
|||
}) |
|||
public abstract class ExecuteUnit { |
|||
protected List<Dictionary> dictionaries;//元数据
|
|||
protected List<Function> functions; //自定义函数
|
|||
|
|||
public abstract String getType(); |
|||
|
|||
public List<Dictionary> getDictionaries() { |
|||
return dictionaries; |
|||
} |
|||
|
|||
public void setDictionaries(List<Dictionary> dictionaries) { |
|||
this.dictionaries = dictionaries; |
|||
} |
|||
|
|||
public List<Function> getFunctions() { |
|||
return functions; |
|||
} |
|||
|
|||
public void setFunctions(List<Function> functions) { |
|||
this.functions = functions; |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
package io.sc.engine.rule.core.code.impl.support; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonPropertyOrder; |
|||
import io.sc.engine.rule.core.po.lib.Lib; |
|||
|
|||
@JsonPropertyOrder({"type","lib","dictionaries","functions"}) |
|||
public class ExecuteUnit4Lib extends ExecuteUnit { |
|||
protected Lib lib; //指标库
|
|||
|
|||
@Override |
|||
public String getType() { |
|||
return "LIB"; |
|||
} |
|||
|
|||
public Lib getLib() { |
|||
return lib; |
|||
} |
|||
|
|||
public void setLib(Lib lib) { |
|||
this.lib = lib; |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
package io.sc.engine.rule.core.code.impl.support; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonPropertyOrder; |
|||
import io.sc.engine.rule.core.po.lib.Lib; |
|||
import io.sc.engine.rule.core.po.model.Model; |
|||
import io.sc.engine.rule.core.po.resource.Resource; |
|||
import io.sc.engine.rule.core.vo.resource.ModelResource; |
|||
|
|||
import java.util.List; |
|||
|
|||
@JsonPropertyOrder({"type","resource","libs","dictionaries","functions"}) |
|||
public class ExecuteUnit4Resource extends ExecuteUnit{ |
|||
protected Resource resource; //资源
|
|||
protected List<Lib> libs; //指标库
|
|||
|
|||
@Override |
|||
public String getType() { |
|||
return "RESOURCE"; |
|||
} |
|||
|
|||
public Resource getResource() { |
|||
return resource; |
|||
} |
|||
|
|||
public void setResource(Resource resource) { |
|||
this.resource = resource; |
|||
} |
|||
|
|||
public List<Lib> getLibs() { |
|||
return libs; |
|||
} |
|||
|
|||
public void setLibs(List<Lib> libs) { |
|||
this.libs = libs; |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
package io.sc.engine.rule.core.enums; |
|||
|
|||
public enum ReplaceMode { |
|||
NAME_TO_CODE, //名称 -> 代码
|
|||
CODE_TO_NAME; //代码 -> 名称
|
|||
} |
@ -1,22 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import org.springframework.core.convert.ConversionService; |
|||
import io.sc.engine.rule.core.convert.converter.DataTypeConversionService; |
|||
|
|||
/** |
|||
* 数据类型转换器 |
|||
* @author wangshaoping |
|||
* |
|||
*/ |
|||
public class DataTypeConvertor { |
|||
private static ConversionService service =DataTypeConversionService.getSharedInstance(); |
|||
|
|||
public static Object convert(Object value,Class<?> targetClass) throws Exception{ |
|||
if(value!=null){ |
|||
if(!value.getClass().equals(targetClass)){ |
|||
value =service.convert(value, targetClass); |
|||
} |
|||
} |
|||
return value; |
|||
} |
|||
} |
@ -1,235 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import java.text.DateFormat; |
|||
import java.text.DateFormatSymbols; |
|||
import java.text.ParseException; |
|||
import java.text.SimpleDateFormat; |
|||
import java.util.Calendar; |
|||
import java.util.Date; |
|||
import java.util.Locale; |
|||
|
|||
/** |
|||
* 日期工具类 |
|||
* @author wangshaoping |
|||
* |
|||
*/ |
|||
public class DateUtil { |
|||
public static final String GMT ="EEE dd MMM yyyy HH:mm:ss z"; |
|||
public static final String GMT_COMMA ="EEE, dd MMM yyyy HH:mm:ss z"; |
|||
|
|||
public static final String GMT_CHINESE =GMT; |
|||
public static final String GMT_CHINESE_COMMA =GMT_COMMA; |
|||
|
|||
public static final String ISO_8601 ="yyyy-MM-dd'T'HH:mm:ssz"; |
|||
public static final String yyyy_MM_dd_T_HH_mm_ss ="yyyy-MM-dd'T'HH:mm:ss"; |
|||
public static final String yyyy_MM_dd_HH_mm_ss_SSS ="yyyy-MM-dd HH:mm:ss.SSS"; |
|||
public static final String yyyy_MM_dd_HH_mm_ss ="yyyy-MM-dd HH:mm:ss"; |
|||
public static final String yyyy_MM_dd_HH_mm ="yyyy-MM-dd HH:mm"; |
|||
public static final String yyyy_MM_dd_HH ="yyyy-MM-dd HH"; |
|||
public static final String yyyy_MM_dd ="yyyy-MM-dd"; |
|||
|
|||
public static final String yyyyMMdd ="yyyyMMdd"; |
|||
|
|||
public static final String HH_mm_ss ="HH:mm:ss"; |
|||
public static final String HH_mm_ss_SSS ="HH:mm:ss.SSS"; |
|||
|
|||
public static final String FILE_yyyy_MM_dd_HH_mm_ss ="yyyy-MM-dd_HH_mm_ss"; |
|||
public static final String FILE_yyyy_MM_dd ="yyyy-MM-dd"; |
|||
|
|||
public static final String yyyy_MM_dd_HH_mm_ss_fffffffff ="yyyy-MM-dd hh:mm:ss.fffffffff"; |
|||
|
|||
private static final String[] WEEKDAYS = {"", "一", "二", "三", "四", "五", "六", "日"}; |
|||
private static final String[] MONTHS = {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"}; |
|||
private static final String[] AMPM = {"上午", "下午"}; |
|||
private static final String[] SUPPORTED_DATE_FORMAT =new String[]{ |
|||
GMT_CHINESE_COMMA, |
|||
GMT_CHINESE, |
|||
GMT_COMMA, |
|||
GMT, |
|||
ISO_8601, |
|||
yyyy_MM_dd_HH_mm_ss_SSS, |
|||
yyyy_MM_dd_HH_mm_ss, |
|||
yyyy_MM_dd_HH_mm, |
|||
yyyy_MM_dd_HH, |
|||
yyyy_MM_dd, |
|||
yyyyMMdd |
|||
}; |
|||
private static final String SUPPORTED_DATE_FORMAT_EXCEPTION_MESSAGE ="unsupported date format, the valiate format include : \n" |
|||
+ GMT_CHINESE_COMMA + "\n" |
|||
+ GMT_CHINESE + "\n" |
|||
+ GMT_COMMA + "\n" |
|||
+ GMT + "\n" |
|||
+ ISO_8601 + "\n" |
|||
+ yyyy_MM_dd_HH_mm_ss + "\n" |
|||
+ yyyy_MM_dd_HH_mm + "\n" |
|||
+ yyyy_MM_dd_HH + "\n" |
|||
+ yyyy_MM_dd + "\n" |
|||
+ yyyyMMdd + "\n"; |
|||
|
|||
/** |
|||
* 获取日期格式化对象 |
|||
* @param format 日期格式化字符串 |
|||
* @return 日期格式化对象 |
|||
*/ |
|||
public static DateFormat getDateFormat(String format){ |
|||
if(format==null || "".equals(format)){ |
|||
return null; |
|||
} |
|||
if(GMT.equals(format) || GMT_COMMA.equals(format)){ |
|||
return new SimpleDateFormat(format,Locale.US); |
|||
}else if(GMT_CHINESE.equals(format) || GMT_CHINESE_COMMA.equals(format)){ |
|||
DateFormatSymbols sym = new DateFormatSymbols(Locale.CHINA); |
|||
sym.setAmPmStrings(AMPM); |
|||
sym.setShortWeekdays(WEEKDAYS); |
|||
sym.setWeekdays(WEEKDAYS); |
|||
sym.setMonths(MONTHS); |
|||
return new SimpleDateFormat(format); |
|||
}else{ |
|||
return new SimpleDateFormat(format); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 解析日期字符串,格式 yyyy-MM-dd HH:mm:ss |
|||
* @param str 日期字符串 |
|||
* @return 日期 |
|||
*/ |
|||
public static Date parseDate(String str) { |
|||
try { |
|||
return parseDate(str,DateUtil.yyyy_MM_dd_HH_mm_ss); |
|||
} catch (ParseException e) { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 解析日期字符串 |
|||
* @param str 日期字符串 |
|||
* @param format 日期格式字符串 |
|||
* @return 日期 |
|||
* @throws ParseException 违例 |
|||
*/ |
|||
public static Date parseDate(String str, String format) throws ParseException{ |
|||
if(str!=null || !"".equals(str)){ |
|||
DateFormat df =getDateFormat(format); |
|||
if(df!=null){ |
|||
return df.parse(str); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 采用支持的日期格式尝试解析 |
|||
* 只要其中一个能够成功解析则返回解析后的日期,否则抛出违例 |
|||
* @param str 日期字符串 |
|||
* @return 日期 |
|||
* @throws ParseException 违例 |
|||
*/ |
|||
public static Date tryParseDate(String str) throws ParseException{ |
|||
if(str==null || "".equals(str)){ |
|||
return null; |
|||
} |
|||
|
|||
for(String format : SUPPORTED_DATE_FORMAT){ |
|||
try { |
|||
return parseDate(str,format); |
|||
} catch (ParseException e) { |
|||
} |
|||
} |
|||
throw new ParseException(SUPPORTED_DATE_FORMAT_EXCEPTION_MESSAGE,0); |
|||
} |
|||
|
|||
/** |
|||
* 采用支持的日期格式尝试解析 |
|||
* 只要其中一个能够成功解析则返回解析后的日期,否则抛出违例 |
|||
* @param strs 日期字符串数组 |
|||
* @return 日期数组 |
|||
* @throws ParseException 违例 |
|||
*/ |
|||
public static Date[] tryParseDates(String[] strs) throws ParseException{ |
|||
if(strs==null){ |
|||
return null; |
|||
} |
|||
if(strs.length==0){ |
|||
return new Date[0]; |
|||
} |
|||
Date[] result =new Date[strs.length]; |
|||
for(int i=0;i<strs.length;i++){ |
|||
result[i] =tryParseDate(strs[i]); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 格式化日期对象 |
|||
* @param date 日期对象 |
|||
* @param format 日期格式 |
|||
* @return 日期字符串 |
|||
*/ |
|||
public static String formatDate(Date date, String format){ |
|||
if(date!=null){ |
|||
DateFormat df =getDateFormat(format); |
|||
if(df!=null){ |
|||
return df.format(date); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 日期加一天 |
|||
* @param date 日期 |
|||
* @return 加一天后的日期 |
|||
*/ |
|||
public static Date addOneDay(Date date){ |
|||
if(date==null){ |
|||
return null; |
|||
} |
|||
Calendar c =Calendar.getInstance(); |
|||
c.setTime(date); |
|||
c.add(Calendar.DATE, 1); |
|||
return c.getTime(); |
|||
} |
|||
|
|||
/** |
|||
* 日期减一天 |
|||
* @param date 日期 |
|||
* @return 减一天后的日期 |
|||
*/ |
|||
public static Date subOneDay(Date date){ |
|||
if(date==null){ |
|||
return null; |
|||
} |
|||
Calendar c =Calendar.getInstance(); |
|||
c.setTime(date); |
|||
c.add(Calendar.DATE, -1); |
|||
return c.getTime(); |
|||
} |
|||
|
|||
/** |
|||
* 清除日期中的时间部分 |
|||
* @param date 日期 |
|||
* @return 清除日期中的时间部分的日期 |
|||
*/ |
|||
public static Date cleanTime(Date date){ |
|||
if(date==null){ |
|||
return null; |
|||
} |
|||
Calendar c =Calendar.getInstance(); |
|||
c.setTime(date); |
|||
c.set(Calendar.HOUR_OF_DAY, 0); |
|||
c.set(Calendar.MINUTE, 0); |
|||
c.set(Calendar.SECOND, 0); |
|||
return c.getTime(); |
|||
} |
|||
|
|||
/** |
|||
* 将 java.lang.Date 对象转换成 java.sql.Date 对象 |
|||
* @param date java.lang.Date 对象转换成 |
|||
* @return java.sql.Date 对象 |
|||
*/ |
|||
public static java.sql.Date toSqlDate(Date date){ |
|||
return new java.sql.Date(date.getTime()); |
|||
} |
|||
} |
@ -1,523 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import org.springframework.core.io.DefaultResourceLoader; |
|||
import org.springframework.core.io.Resource; |
|||
import org.springframework.util.StreamUtils; |
|||
|
|||
import java.io.*; |
|||
import java.nio.ByteBuffer; |
|||
import java.nio.channels.FileChannel; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.nio.file.Files; |
|||
import java.util.ArrayList; |
|||
import java.util.Collections; |
|||
import java.util.Comparator; |
|||
import java.util.List; |
|||
|
|||
public class FileUtil { |
|||
private FileUtil(){} |
|||
|
|||
/** |
|||
* 判断资源文件是否存在 |
|||
* @param url 资源文件 url |
|||
* @return 资源文件是否存在 |
|||
*/ |
|||
public static boolean exists(String url) { |
|||
ParameterChecker.notTrimEmpty(url); |
|||
Resource rs =new DefaultResourceLoader().getResource(url); |
|||
return rs.exists(); |
|||
} |
|||
|
|||
/** |
|||
* 获取资源文件输入流对象 |
|||
* @param url 资源文件 url |
|||
* @return 资源文件输入流对象 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static InputStream getInputStream(String url) throws IOException { |
|||
ParameterChecker.notTrimEmpty(url); |
|||
Resource rs =new DefaultResourceLoader().getResource(url); |
|||
if(rs.exists()){ |
|||
return rs.getInputStream(); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param url 文件 url |
|||
* @return 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readString(String url) throws IOException { |
|||
ParameterChecker.notTrimEmpty(url); |
|||
return readString(url, StandardCharsets.UTF_8.name()); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param url 文件 url |
|||
* @param encoding 编码 |
|||
* @return 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readString(String url,String encoding) throws IOException { |
|||
ParameterChecker.notTrimEmpty(url); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
return readString(getInputStream(url),encoding); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param inputStream 输入流 |
|||
* @return 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readString(InputStream inputStream) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
return readString(inputStream,StandardCharsets.UTF_8.name()); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param inputStream 输入流 |
|||
* @param encoding 编码 |
|||
* @return 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readString(InputStream inputStream, String encoding) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
String result = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8); |
|||
inputStream.close(); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param url 文件 url |
|||
* @return 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static List<String> readStringAsList(String url) throws IOException{ |
|||
ParameterChecker.notTrimEmpty(url); |
|||
return readStringAsList(getInputStream(url),StandardCharsets.UTF_8.name()); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param url 文件 url |
|||
* @param encoding 编码 |
|||
* @return 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static List<String> readStringAsList(String url,String encoding) throws IOException{ |
|||
ParameterChecker.notTrimEmpty(url); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
return readStringAsList(getInputStream(url),encoding); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param inputStream 输入流 |
|||
* @return 文件内容列表 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static List<String> readStringAsList(InputStream inputStream) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
return readStringAsList(inputStream,StandardCharsets.UTF_8.name()); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容 |
|||
* @param inputStream 输入流 |
|||
* @param encoding 编码 |
|||
* @return 文件内容列表 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static List<String> readStringAsList(InputStream inputStream, String encoding) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
List<String> result =new ArrayList<>(); |
|||
try(BufferedReader br =new BufferedReader(new InputStreamReader(inputStream, encoding));){ |
|||
String dataLine = ""; |
|||
while (null != (dataLine = br.readLine())){ |
|||
result.add(dataLine); |
|||
} |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容(按照 urls 数组顺序访问文件,返回第一个找到的文件内容) |
|||
* @param urls 文件 url 数组 |
|||
* @return 第一个找到的文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readString(String[] urls) throws IOException { |
|||
ParameterChecker.notNull(urls); |
|||
return readString(urls,StandardCharsets.UTF_8.name()); |
|||
} |
|||
|
|||
/** |
|||
* 获取文件内容(按照 urls 数组顺序访问文件,返回第一个找到的文件内容) |
|||
* @param urls 文件 url 数组 |
|||
* @param encoding 编码 |
|||
* @return 第一个找到的文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readString(String[] urls,String encoding) throws IOException { |
|||
ParameterChecker.notNull(urls); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
for(String url : urls) { |
|||
Resource rs =new DefaultResourceLoader().getResource(url); |
|||
if(rs.exists()){ |
|||
return readString(url,encoding); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 读取文件后多少行数的文本 |
|||
* @param file 文件名 |
|||
* @param row 行数 |
|||
* @return 文件后多少行数的文本 |
|||
* @throws Exception 违例 |
|||
*/ |
|||
public static String readStringAsLastRow(String file,int row) throws IOException{ |
|||
ParameterChecker.notTrimEmpty(file); |
|||
return readStringAsLastRow(new File(file),row); |
|||
} |
|||
|
|||
/** |
|||
* 读取文件后多少行数的文本 |
|||
* @param file 文件名 |
|||
* @param count 行数 |
|||
* @return 文件后多少行数的文本 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static String readStringAsLastRow(File file,int count) throws IOException{ |
|||
ParameterChecker.notNull(file); |
|||
try(RandomAccessFile rf =new RandomAccessFile(file, "r")){ |
|||
long len = rf.length(); |
|||
if (len == 0) { |
|||
return null; |
|||
} |
|||
int row = 0; |
|||
while (len > 0 && row < count) { |
|||
rf.seek(--len); |
|||
if (rf.readByte() == '\n') { |
|||
row++; |
|||
} |
|||
} |
|||
StringBuilder sb = new StringBuilder(); |
|||
String str = ""; |
|||
while ((str = rf.readLine()) != null) { |
|||
sb.append(new String(str.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8)).append("\n"); |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 写文件 |
|||
* @param file 文件 |
|||
* @param content 文件内容 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void writeString(String file,String content) throws IOException { |
|||
ParameterChecker.notTrimEmpty(file); |
|||
ParameterChecker.notNull(content); |
|||
writeString(file,content,StandardCharsets.UTF_8.name(),true); |
|||
} |
|||
|
|||
/** |
|||
* 写文件 |
|||
* @param file 文件 |
|||
* @param content 文件内容 |
|||
* @param encoding 文件编码 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void writeString(String file,String content,String encoding) throws IOException { |
|||
ParameterChecker.notTrimEmpty(file); |
|||
ParameterChecker.notNull(content); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
writeString(file,content,encoding,true); |
|||
} |
|||
|
|||
/** |
|||
* 写文件 |
|||
* @param file 文件 |
|||
* @param content 文件内容 |
|||
* @param overwrite 是否覆盖 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void writeString(String file,String content,boolean overwrite) throws IOException { |
|||
ParameterChecker.notTrimEmpty(file); |
|||
ParameterChecker.notNull(content); |
|||
writeString(file,content,StandardCharsets.UTF_8.name(),overwrite); |
|||
} |
|||
|
|||
/** |
|||
* 写文件 |
|||
* @param file 文件 |
|||
* @param content 文件内容 |
|||
* @param encoding 文件编码 |
|||
* @param overwrite 是否覆盖 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void writeString(String file,String content,String encoding,boolean overwrite) throws IOException { |
|||
ParameterChecker.notTrimEmpty(file); |
|||
ParameterChecker.notNull(content); |
|||
ParameterChecker.notTrimEmpty(encoding); |
|||
File targetFile =new File(file); |
|||
boolean needGenerate =true; |
|||
if(!overwrite && targetFile.exists() && targetFile.isFile()){ |
|||
needGenerate =false; |
|||
} |
|||
if(needGenerate){ |
|||
try(OutputStreamWriter writer =new OutputStreamWriter(new FileOutputStream(file),encoding);){ |
|||
writer.write(content); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static void createFixSizeFile(String file, long size) throws IOException { |
|||
ParameterChecker.notTrimEmpty(file); |
|||
createFixSizeFile(new File(file),size); |
|||
} |
|||
|
|||
/** |
|||
* 创建固定大小的文件 |
|||
* @param file 文件 |
|||
* @param size 大小 |
|||
*/ |
|||
public static void createFixSizeFile(File file, long size) throws IOException { |
|||
ParameterChecker.notNull(file); |
|||
try( |
|||
FileOutputStream fos =new FileOutputStream(file); |
|||
FileChannel out =fos.getChannel() |
|||
){ |
|||
int length =1024*1024; |
|||
long index =0; |
|||
while(index<size) { |
|||
if(size-index<length) { |
|||
out.write(ByteBuffer.allocate((int)(size-index))); |
|||
index +=size-index; |
|||
}else{ |
|||
out.write(ByteBuffer.allocate(length)); |
|||
index +=length; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取某个目录下包含扩展名为 includes 的文件 |
|||
* @param dir 路径 |
|||
* @param includes 扩展名数组 |
|||
* @return 所有文件集合 |
|||
*/ |
|||
public static List<File> listAllFile(File dir,String[] includes){ |
|||
ParameterChecker.notNull(dir); |
|||
ParameterChecker.notNull(includes); |
|||
if(!dir.exists()){ |
|||
return Collections.emptyList(); |
|||
} |
|||
File[] files =dir.listFiles(); |
|||
if(files==null || files.length<=0){ |
|||
return Collections.emptyList(); |
|||
} |
|||
List<File> result =new ArrayList<>(); |
|||
for(File file : files){ |
|||
if (file.isDirectory()) { |
|||
result.addAll(listAllFile(file, includes)); |
|||
} else { |
|||
for (String include : includes) { |
|||
if (file.getName().toLowerCase().endsWith("." + include.toLowerCase())) { |
|||
result.add(file); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Collections.sort(result, (o1,o2) -> o1.getName().compareTo(o2.getName())); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 移除目录路径的最后分隔符 |
|||
* @param path 目录路径 |
|||
* @return 无文件分隔符的文件路径 |
|||
*/ |
|||
public static String removePathEndSeparator(String path){ |
|||
ParameterChecker.notTrimEmpty(path); |
|||
char lastChar =path.charAt(path.length()-1); |
|||
while(lastChar=='\\' || lastChar=='/'){ |
|||
path =path.substring(0,path.length()-1); |
|||
lastChar =path.charAt(path.length()-1); |
|||
} |
|||
return path; |
|||
} |
|||
|
|||
/** |
|||
* 创建目录,可同时创建多级目录 |
|||
* @param dir 目录路径能够 |
|||
*/ |
|||
public static void mkdirs(String dir){ |
|||
ParameterChecker.notTrimEmpty(dir); |
|||
File file =new File(dir); |
|||
if(!file.exists()){ |
|||
file.mkdirs(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 递归删除文件夹及其子文件 |
|||
* @param dir 文件夹 |
|||
*/ |
|||
public static void deldirs(String dir) throws IOException { |
|||
ParameterChecker.notTrimEmpty(dir); |
|||
deldirs(new File(dir)); |
|||
} |
|||
|
|||
/** |
|||
* 递归删除文件夹及其子文件 |
|||
* @param dir 文件夹 |
|||
*/ |
|||
public static void deldirs(File dir) throws IOException { |
|||
ParameterChecker.notNull(dir); |
|||
if(dir.exists()) { |
|||
if (dir.isDirectory()) { |
|||
File[] files = dir.listFiles(); |
|||
if (files != null && files.length > 0) { |
|||
for (File file : files) { |
|||
deldirs(file); |
|||
} |
|||
} |
|||
} |
|||
Files.delete(dir.toPath()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 拷贝文件 |
|||
* @param src 源文件 |
|||
* @param target 目标文件 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void copyFile(String src, String target) throws IOException{ |
|||
ParameterChecker.notTrimEmpty(src); |
|||
ParameterChecker.notTrimEmpty(target); |
|||
copyFile(new File(src),new File(target)); |
|||
} |
|||
|
|||
/** |
|||
* 拷贝文件 |
|||
* @param src 源文件对象 |
|||
* @param target 目标文件对象 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void copyFile(File src, File target) throws IOException{ |
|||
ParameterChecker.notNull(src); |
|||
ParameterChecker.notNull(target); |
|||
copyFile(new FileInputStream(src),target); |
|||
} |
|||
|
|||
/** |
|||
* 拷贝文件 |
|||
* @param inputStream 源文件 |
|||
* @param target 目标文件 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void copyFile(InputStream inputStream,String target) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
ParameterChecker.notTrimEmpty(target); |
|||
copyFile(inputStream,new File(target)); |
|||
} |
|||
|
|||
/** |
|||
* 拷贝文件 |
|||
* @param inputStream 源输入流 |
|||
* @param target 目标文件对象 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void copyFile(InputStream inputStream,File target) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
ParameterChecker.notNull(target); |
|||
if(!target.getParentFile().exists()){ |
|||
target.getParentFile().mkdirs(); |
|||
} |
|||
copyFile(inputStream,new FileOutputStream(target)); |
|||
} |
|||
|
|||
/** |
|||
* 拷贝文件 |
|||
* @param inputStream 源输入流 |
|||
* @param outputStream 目标输出流 |
|||
* @throws IOException 违例 |
|||
*/ |
|||
public static void copyFile(InputStream inputStream,OutputStream outputStream) throws IOException{ |
|||
ParameterChecker.notNull(inputStream); |
|||
ParameterChecker.notNull(outputStream); |
|||
byte[] buf = new byte[40960]; |
|||
int read =-1; |
|||
while ((read = inputStream.read(buf)) != -1) { |
|||
outputStream.write(buf, 0, read); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取文件名排序比较器,比较规则: |
|||
* 1. 文件排在目录前面 |
|||
* 2. 按名称排序 |
|||
* @return 文件名排序比较器 |
|||
*/ |
|||
public static Comparator<File> getFileNameComparator() { |
|||
return (File o1, File o2) -> { |
|||
if (o1.isDirectory() && o2.isFile()) |
|||
return 1; |
|||
if (o1.isFile() && o2.isDirectory()) |
|||
return -1; |
|||
return o1.getName().compareTo(o2.getName()); |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件名称 |
|||
* @param filePath 文件全路径 |
|||
* @return 文件名称 |
|||
*/ |
|||
public static String getFileName(String filePath) { |
|||
if(filePath!=null && !"".equals(filePath.trim())) { |
|||
String _filePath =filePath.replace('\\', '/'); |
|||
return new File(_filePath).getName(); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件扩展名 |
|||
* @param name 文件名称 |
|||
* @return 扩展名 |
|||
*/ |
|||
public static String getFileExtName(String name) { |
|||
if(name!=null && !"".equals(name.trim()) && name.lastIndexOf('.')>-1) { |
|||
return name.substring(name.lastIndexOf('.')); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件基本名 |
|||
* @param name 文件名称 |
|||
* @return 文件基本名 |
|||
*/ |
|||
public static String getFileBaseName(String name) { |
|||
if(name!=null && !"".equals(name.trim()) && name.indexOf('.')>-1) { |
|||
return name.substring(0,name.indexOf('.')); |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -1,27 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import java.text.SimpleDateFormat; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; |
|||
import com.fasterxml.jackson.annotation.PropertyAccessor; |
|||
import com.fasterxml.jackson.core.JsonParser.Feature; |
|||
import com.fasterxml.jackson.databind.DeserializationFeature; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.fasterxml.jackson.databind.SerializationFeature; |
|||
|
|||
public class JacksonObjectMapper { |
|||
@SuppressWarnings("deprecation") |
|||
public static ObjectMapper getDefaultObjectMapper(){ |
|||
ObjectMapper result =new ObjectMapper(); |
|||
result.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); |
|||
result.enable(SerializationFeature.INDENT_OUTPUT); |
|||
result.configure(Feature.ALLOW_COMMENTS, true); |
|||
result.configure(Feature.ALLOW_SINGLE_QUOTES, true); |
|||
result.configure(Feature.ALLOW_TRAILING_COMMA, true); |
|||
result.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); |
|||
result.configure(Feature.IGNORE_UNDEFINED, true); |
|||
result.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false); |
|||
result.setVisibility(PropertyAccessor.ALL,Visibility.NONE).setVisibility(PropertyAccessor.FIELD, Visibility.ANY);; |
|||
return result; |
|||
} |
|||
} |
@ -1,51 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import java.io.ByteArrayInputStream; |
|||
import java.io.ByteArrayOutputStream; |
|||
import java.io.IOException; |
|||
import java.io.ObjectInputStream; |
|||
import java.io.ObjectOutputStream; |
|||
|
|||
/** |
|||
* 对象辅助类 |
|||
* @author wangshaoping |
|||
* |
|||
*/ |
|||
public class ObjectUtil { |
|||
/** |
|||
* 深度克隆 |
|||
* @param obj 被克隆的对象 |
|||
* @return 克隆的对象 |
|||
* @throws ClassNotFoundException 违例 |
|||
* @throws IOException 违例 |
|||
* |
|||
* @param <T> 泛型类型 |
|||
*/ |
|||
@SuppressWarnings("unchecked") |
|||
public static <T> T clone(T obj) throws ClassNotFoundException,IOException{ |
|||
T cloneObj = null; |
|||
ObjectOutputStream oos = null; |
|||
ObjectInputStream ois = null; |
|||
try { |
|||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|||
oos = new ObjectOutputStream(baos); |
|||
oos.writeObject(obj); |
|||
|
|||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); |
|||
ois = new ObjectInputStream(bais); |
|||
cloneObj = (T) ois.readObject(); |
|||
} catch (ClassNotFoundException e) { |
|||
throw e; |
|||
} catch (IOException e) { |
|||
throw e; |
|||
} finally { |
|||
if (oos != null) { |
|||
try {oos.close();} catch (Exception e) {} |
|||
} |
|||
if (ois != null) { |
|||
try {ois.close();} catch (Exception e) {} |
|||
} |
|||
} |
|||
return cloneObj; |
|||
} |
|||
} |
@ -1,55 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import net.sourceforge.pinyin4j.PinyinHelper; |
|||
|
|||
/** |
|||
* 汉语拼音辅助类 |
|||
* @author wangshaoping |
|||
* |
|||
*/ |
|||
public class PinyinUtil { |
|||
/** |
|||
* 采用汉语拼音比较两个字符串 |
|||
* @param o1 字符串1 |
|||
* @param o2 字符串2 |
|||
* @return 汉语拼音比较结果 |
|||
*/ |
|||
public static int compareHanyu(String o1, String o2) { |
|||
for (int i = 0; i < o1.length() && i < o2.length(); i++) { |
|||
int codePoint1 = o1.charAt(i); |
|||
int codePoint2 = o2.charAt(i); |
|||
|
|||
if (Character.isSupplementaryCodePoint(codePoint1) |
|||
|| Character.isSupplementaryCodePoint(codePoint2)) { |
|||
i++; |
|||
} |
|||
|
|||
if (codePoint1 != codePoint2) { |
|||
if (Character.isSupplementaryCodePoint(codePoint1) |
|||
|| Character.isSupplementaryCodePoint(codePoint2)) { |
|||
return codePoint1 - codePoint2; |
|||
} |
|||
|
|||
String pinyin1 = hanyuPinyin((char) codePoint1); |
|||
String pinyin2 = hanyuPinyin((char) codePoint2); |
|||
|
|||
if (pinyin1 != null && pinyin2 != null) { |
|||
if (!pinyin1.equals(pinyin2)) { |
|||
return pinyin1.compareTo(pinyin2); |
|||
} |
|||
} else { |
|||
return codePoint1 - codePoint2; |
|||
} |
|||
} |
|||
} |
|||
return o1.length() - o2.length(); |
|||
} |
|||
|
|||
private static String hanyuPinyin(char c) { |
|||
String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c); |
|||
if (pinyins == null) { |
|||
return null; |
|||
} |
|||
return pinyins[0]; |
|||
} |
|||
} |
@ -1,91 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
/** |
|||
* 字符串辅助类 |
|||
* @author wangshaoping |
|||
* |
|||
*/ |
|||
public class Strings { |
|||
public static String toUpperFristChar(String string) { |
|||
if(string!=null && string.length()>0) { |
|||
char[] charArray = string.toCharArray(); |
|||
if(charArray[0]>=97 && charArray[0]<=122) { |
|||
charArray[0] -= 32; |
|||
} |
|||
return String.valueOf(charArray); |
|||
} |
|||
return string; |
|||
} |
|||
|
|||
public static String toLowerFristChar(String string) { |
|||
if(string!=null && string.length()>0) { |
|||
char[] charArray = string.toCharArray(); |
|||
if(charArray[0]>=65 && charArray[0]<=90) { |
|||
charArray[0] += 32; |
|||
} |
|||
return String.valueOf(charArray); |
|||
} |
|||
return string; |
|||
} |
|||
|
|||
public static String repeat(String string, int count) { |
|||
if(string==null) { |
|||
return null; |
|||
} |
|||
if(string.length()==0 || count==0) { |
|||
return ""; |
|||
} |
|||
|
|||
final int len = string.length(); |
|||
final long longSize = (long) len * (long) count; |
|||
final int size = (int) longSize; |
|||
if (size != longSize) { |
|||
throw new ArrayIndexOutOfBoundsException("Required array size too large: " + longSize); |
|||
} |
|||
|
|||
final char[] array = new char[size]; |
|||
string.getChars(0, len, array, 0); |
|||
int n; |
|||
for (n = len; n < size - n; n <<= 1) { |
|||
System.arraycopy(array, 0, array, n, n); |
|||
} |
|||
System.arraycopy(array, 0, array, n, size - n); |
|||
return new String(array); |
|||
} |
|||
|
|||
public static String replaceCR_LF(String str) { |
|||
if(str!=null && !str.isEmpty()) { |
|||
str =str.replace("\n", ""); |
|||
str =str.replace("\r", ""); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
/** |
|||
* 左对齐字符串(右边补空格) |
|||
* @param str 字符串 |
|||
* @param length 对齐后的长度 |
|||
* @return 对齐后的字符串 |
|||
*/ |
|||
public static String leftAlign(String str,int length){ |
|||
if(str==null){ |
|||
return null; |
|||
} |
|||
String format ="%-" + length +"s"; |
|||
return String.format(format,str); |
|||
} |
|||
|
|||
/** |
|||
* 右对齐字符串(左边补空格) |
|||
* @param str 字符串 |
|||
* @param length 对齐后的长度 |
|||
* @return 对齐后的字符串 |
|||
*/ |
|||
public static String rightAlign(String str,int length){ |
|||
if(str==null){ |
|||
return null; |
|||
} |
|||
String format ="%" + length +"s"; |
|||
return String.format(format,str); |
|||
} |
|||
} |
@ -1,76 +0,0 @@ |
|||
package io.sc.engine.rule.core.util; |
|||
|
|||
import java.util.Date; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
|
|||
/** |
|||
* 时间跟踪器 |
|||
* 用于跟踪代码执行耗时 |
|||
* @author wangshaoping |
|||
* |
|||
*/ |
|||
public class TimeTracer { |
|||
private static final Logger log =LoggerFactory.getLogger(TimeTracer.class); |
|||
private static Map<String,TimeTracer> tracers =new HashMap<String,TimeTracer>(); |
|||
|
|||
private String name; |
|||
private long last =new Date().getTime(); |
|||
|
|||
/** |
|||
* 获取时间跟踪器, |
|||
* @param name 时间跟踪器名称 |
|||
* @return 时间跟踪器 |
|||
*/ |
|||
public static TimeTracer getInstance(String name){ |
|||
TimeTracer result =tracers.get(name); |
|||
if(result==null){ |
|||
result =new TimeTracer(name); |
|||
tracers.put(name, result); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 获取自上次跟踪依赖过去的时间间隔 |
|||
* @param name 时间跟踪器名称 |
|||
* @return 自上次跟踪依赖过去的时间间隔,单位毫秒数 |
|||
*/ |
|||
public static long getInterval(String name){ |
|||
return getInstance(name).getInterval(); |
|||
} |
|||
|
|||
|
|||
|
|||
public TimeTracer(){} |
|||
|
|||
public TimeTracer(String name){ |
|||
this.name =name; |
|||
} |
|||
|
|||
public long getInterval(){ |
|||
long current =new Date().getTime(); |
|||
long result =current - last; |
|||
last =current; |
|||
return result; |
|||
} |
|||
|
|||
public String message(String message){ |
|||
return name + " - " + message + " : " + getInterval() + " ms"; |
|||
} |
|||
|
|||
public void log(String message){ |
|||
log.info(message(message)); |
|||
} |
|||
|
|||
public String getName() { |
|||
return name; |
|||
} |
|||
|
|||
public void setName(String name) { |
|||
this.name = name; |
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue