功能:在保险、规则、交易、积分和短信模块中实现初始功能和基础组件。

This commit is contained in:
abcv7
2026-03-03 04:04:22 +08:00
parent e050eb3317
commit e156d625bf
1999 changed files with 146080 additions and 63 deletions
@@ -0,0 +1,184 @@
lexer grammar RuleLexer;
COUNT : 'count';
AVG : 'avg';
SUM : 'sum';
MAX : 'max';
MIN : 'min';
AND : 'and'|'&&'|','|'\u5e76\u4e14'|'\u4e14';
OR : 'or'|'||'|'\u6216\u8005'|'\u6216';
Datatype : 'String'
| 'int'
| 'Integer'
| 'double'
| 'Double'
| 'long'
| 'Long'
| 'float'
| 'Float'
| 'BigDecimal'
| 'boolean'
| 'Boolean'
| 'Date'
| 'List'
| 'Set'
| 'Map'
| 'Enum'
| 'Object'
;
GreaterThen : '>'|'\u5927\u4e8e';
GreaterThenOrEquals : '>='|'\u5927\u4e8e\u7b49\u4e8e';
LessThen : '<'|'\u5c0f\u4e8e';
LessThenOrEquals : '<='|'\u5c0f\u4e8e\u7b49\u4e8e';
Equals : '=='|'\u7b49\u4e8e';
NotEquals : '!='|'\u4e0d\u7b49\u4e8e';
EndWith : 'EndWith'|'\u7ed3\u675f\u4e8e';
NotEndWith : 'NotEndWith'|'\u4e0d\u7ed3\u675f\u4e8e' ;
StartWith : 'StartWith'|'\u5f00\u59cb\u4e8e';
NotStartWith : 'NotStartWith'|'\u4e0d\u5f00\u59cb\u4e8e';
In : 'In'|'\u5728\u96c6\u5408\u4e2d';
NotIn : 'NotIn'|'\u4e0d\u5728\u96c6\u5408\u4e2d';
Match : 'Match'|'\u5339\u914d';
NotMatch : 'NotMatch'|'\u4e0d\u5339\u914d';
EqualsIgnoreCase : 'EqualsIgnoreCase'|'\u5ffd\u7565\u5927\u5c0f\u5199\u7b49\u4e8e';
NotEqualsIgnoreCase : 'NotEqualsIgnoreCase'|'\u5ffd\u7565\u5927\u5c0f\u5199\u4e0d\u7b49\u4e8e';
ARITH
:
'+'
| '-'
| '*'
| '/'
| '%'
;
NUMBER
:
'-'? INT '.' INT EXP? // ('-'? INT '.' INT EXP?)1.35, 1.35E-9, 0.3, -4.5
| '-'? INT EXP // 1e10 -3e4
| '-'? INT // -3, 45
;
Boolean : 'true'
| 'false'
;
Identifier
:
StartChar Char*
;
STRING :
'"' STRING_CONTENT '"'
;
fragment
STRING_CONTENT :
( EscapeSequence | ~('"'))*
;
fragment
INT
:
DIGIT+
;
fragment
EXP
:
[Ee] [+\-]? INT
; // \- since - means "range" inside [...]
fragment
EscapeSequence
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UnicodeEscape
| OctalEscape
;
fragment
OctalEscape
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UnicodeEscape
:
'\\' 'u' HEX HEX HEX HEX
;
fragment
Char : StartChar
| '-' | '_' | DIGIT
| '\u00B7'
| '\u0300'..'\u036F'
| '\u203F'..'\u2040'
;
fragment
StartChar
: [a-zA-Z]
| '\u2070'..'\u218F'
| '\u2C00'..'\u2FEF'
| '\u3001'..'\uD7FF'
| '\uF900'..'\uFDCF'
| '\uFDF0'..'\uFFFD'
;
fragment
DIGIT
:
[0-9]
;
fragment
HEX
:
[0-9a-fA-F]
;
WS
:
[ \t\r\n]+ -> channel(HIDDEN)
;
NL
:
'\r'? '\n' ->channel(HIDDEN)
;
COMMENT
: '/*' .*? '*/' ->channel(HIDDEN);
LINE_COMMENT
: '//' ~[\r\n]* '\r'? '\n' ->channel(HIDDEN)
;
@@ -0,0 +1,255 @@
grammar RuleParser;
import RuleLexer;
ruleSet : ruleSetHeader
ruleSetBody
;
ruleSetHeader : resource*
| functionImport*
| resource* functionImport*
| functionImport* resource*
;
ruleSetBody : rules* ;
rules : ruleDef | loopRuleDef ;
functionImport : 'import' packageDef';'?;
packageDef : Identifier
| Identifier('.'Identifier)+
| packageDef'.*';
resource : importVariableLibrary
| importActionLibrary
| importConstantLibrary
| importParameterLibrary
;
importParameterLibrary : 'importParameterLibrary' STRING ';'?;
importVariableLibrary : 'importVariableLibrary' STRING ';'?;
importConstantLibrary : 'importConstantLibrary' STRING ';'?;
importActionLibrary : 'importActionLibrary' STRING ';'?;
functionDef : 'function' Identifier '(' functionParameters? ')' '{' expressionBody '}'';'?;
functionParameters : functionParameter (','functionParameter)* ;
functionParameter : Datatype Identifier ;
ruleDef : ('rule'|'\u89c4\u5219') STRING
attribute*
left
right
other?
('end'|'\u7ed3\u675f') ';'?
;
loopRuleDef : ('loopRule' | '\u5faa\u73af\u89c4\u5219') STRING
attribute*
loopTarget
loopStart?
left
right
other?
loopEnd?
('end'|'\u7ed3\u675f') ';'?
;
loopTarget : ('loopTarget' | '\u5faa\u73af\u5bf9\u8c61') complexValue ;
loopStart : ('loopStart' | '\u5f00\u59cb\u524d\u52a8\u4f5c') action* ;
loopEnd : ('loopEnd' | '\u7ed3\u675f\u540e\u52a8\u4f5c') action*;
attribute :loopAttribute
| salienceAttribute
| effectiveDateAttribute
| expiresDateAttribute
| enabledAttribute
| debugAttribute
| activationGroupAttribute
| agendaGroupAttribute
| autoFocusAttribute
| ruleflowGroupAttribute
;
loopAttribute : ('loop' | '\u5141\u8bb8\u5faa\u73af\u89e6\u53d1') '=' Boolean ','?;
salienceAttribute : ('salience' | '\u4f18\u5148\u7ea7') '=' NUMBER ','?;
effectiveDateAttribute : ('effective-date' | '\u751f\u6548\u65f6\u95f4' | '\u751f\u6548\u65e5\u671f') '=' STRING ','?;
expiresDateAttribute : ('expires-date' | '\u5931\u6548\u65f6\u95f4' | '\u5931\u6548\u65e5\u671f') '=' STRING ','?;
enabledAttribute : ('enabled' | '\u6fc0\u6d3b' | '\u542f\u7528') '=' Boolean ','?;
debugAttribute : ('debug' | '\u8c03\u8bd5' | '\u5141\u8bb8\u8c03\u8bd5') '=' Boolean ','?;
activationGroupAttribute : ('activation-group' | '\u6fc0\u6d3b\u7ec4') '=' STRING ','? ;
agendaGroupAttribute : ('agenda-group' | '\u8bae\u7a0b\u7ec4') '=' STRING ','? ;
autoFocusAttribute : ('auto-focus' | '\u81ea\u52a8\u83b7\u53d6\u7126\u70b9') '=' Boolean ','?;
ruleflowGroupAttribute : ('ruleflow-group' | '\u89c4\u5219\u6d41\u7ec4') '=' STRING ','?;
left :
('if'|'\u5982\u679c')
condition?
;
condition : leftParen condition rightParen #parenConditions
| condition (join condition)+ #multiConditions
| conditionLeft op (complexValue|nullValue) #singleCondition
| namedConditionSet #singleNamedConditionSet
;
namedConditionSet : (refName colon)? refObject leftParen namedCondition rightParen;
namedCondition : leftParen namedCondition rightParen #parenNamedConditions
| namedCondition (join namedCondition)+ #multiNamedConditions
| property op (complexValue|nullValue) #singleNamedConditions
;
decisionTableCellCondition : op (complexValue|nullValue) #singleCellCondition
| decisionTableCellCondition (join decisionTableCellCondition)+ #multiCellConditions
| leftParen decisionTableCellCondition rightParen #parenCellConditions
;
refName : Identifier ;
refObject : variableCategory | parameterName ;
nullValue : 'null';
conditionLeft : (variable|parameter|functionInvoke|methodInvoke|expEval|expAll|expExists|expCollect|commonFunction) (ARITH value)* ;
expEval : 'eval'leftParen expressionBody rightParen;
expAll : 'all'leftParen
(variable|parameter)
',' exprCondition
(',' (NUMBER|percent))?
rightParen;
expExists : 'exist'leftParen
(variable|parameter)
',' exprCondition
(',' (NUMBER|percent))?
rightParen;
expCollect : 'collect'leftParen
(variable|parameter)
(',' exprCondition)?
rightParen
'.'
( COUNT | property'.'(SUM|AVG|MAX|MIN))
;
commonFunction : Identifier leftParen complexValue(','property)? rightParen ;
exprCondition : property op (complexValue|nullValue)
| exprCondition (join exprCondition)+
;
expressionBody : .*? ;
percent : NUMBER'%';
leftParen : '(';
rightParen : ')';
colon : ':';
join :
AND
| OR
;
right : ('then'|'\u90a3\u4e48')
action*
;
other : ('else'|'\u5426\u5219')
action*
;
actions : action*;
action : assignAction ';'?
| outAction ';'?
| methodInvoke ';'?
| functionInvoke ';'?
| commonFunction ';'?
;
assignAction : (variable|namedVariable|parameter) '=' complexValue;
outAction : 'out''(' complexValue ')';
methodInvoke : beanMethod'('actionParameters?')';
functionInvoke : '@'Identifier'(' actionParameters? ')';
actionParameters : complexValue (',' complexValue)* ;
beanMethod : Identifier'.'Identifier ;
complexValue : value
| variable
| namedVariable
| constant
| variableCategory
| parameter
| methodInvoke
| functionInvoke
| commonFunction
| leftParen complexValue rightParen
| complexValue (ARITH complexValue)+
;
parameter : parameterName'.'Identifier;
parameterName : 'parameter'|'\u53c2\u6570' ;
constant : constantCategory'.'property;
variable : variableCategory'.'property;
namedVariable : namedVariableCategory'.'property;
property : Identifier('.'Identifier)*;
variableCategory : Identifier;
namedVariableCategory : '!'Identifier;
constantCategory : '$'Identifier;
value :
STRING
| NUMBER
| Boolean
;
op
:
GreaterThen
| GreaterThenOrEquals
| LessThen
| LessThenOrEquals
| Equals
| NotEquals
| EndWith
| NotEndWith
| StartWith
| NotStartWith
| In
| NotIn
| Match
| NotMatch
| EqualsIgnoreCase
| NotEqualsIgnoreCase
;
@@ -0,0 +1,173 @@
<?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>
<artifactId>sfbx-framework</artifactId>
<groupId>com.itheima.sfbx</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>framework-rule-base</artifactId>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.5</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.3</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.11</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.45</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.xsd</include>
<include>**/*.schemas</include>
<include>**/*.handlers</include>
<include>**/*.properties</include>
<include>**/*.png</include>
<include>**/*.jpg</include>
<include>**/*.gif</include>
<include>**/*.css</include>
<include>**/*.map</include>
<include>**/*.js</include>
<include>**/*.swf</include>
<include>**/*.swz</include>
<include>**/*.html</include>
<include>**/*.jsp</include>
<include>**/*.txt</include>
<include>**/*.eot</include>
<include>**/*.svg</include>
<include>**/*.ttf</include>
<include>**/*.woff</include>
<include>**/*.woff2</include>
<include>**/*.md</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.xsd</include>
<include>**/*.schemas</include>
<include>**/*.handlers</include>
<include>**/*.properties</include>
<include>**/*.png</include>
<include>**/*.jpg</include>
<include>**/*.gif</include>
<include>**/*.css</include>
<include>**/*.map</include>
<include>**/*.js</include>
<include>**/*.html</include>
<include>**/*.jsp</include>
<include>**/*.txt</include>
<include>**/*.eot</include>
<include>**/*.svg</include>
<include>**/*.ttf</include>
<include>**/*.woff</include>
<include>**/*.woff2</include>
<include>**/*.md</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
</project>
@@ -0,0 +1,184 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
import com.itheima.sfbx.framework.rule.model.Label;
import com.itheima.sfbx.framework.rule.model.library.Datatype;
import com.itheima.sfbx.framework.rule.model.library.variable.Act;
import com.itheima.sfbx.framework.rule.model.library.variable.Variable;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
/**
* @author Jacky.gao
* @since 2016年6月2日
*/
public class ClassUtils {
public static void classToXml(Class<?> cls,File file){
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
OutputStream out=null;
try{
out=new FileOutputStream(file);
List<Variable> variables=classToVariables(cls);
StringBuffer sb=new StringBuffer();
sb.append("<variables clazz=\""+cls.getName()+"\">");
for(Variable var:variables){
sb.append("<variable ");
sb.append("name=\""+var.getName()+"\" ");
if(var.getLabel()!=null){
sb.append("label=\""+var.getLabel()+"\" ");
}
if(var.getDefaultValue()!=null){
sb.append("defaultValue=\""+var.getDefaultValue()+"\" ");
}
if(var.getType()!=null){
sb.append("type=\""+var.getType()+"\" ");
}
if(var.getAct()!=null){
sb.append("act=\""+var.getAct()+"\" ");
}
sb.append(">");
sb.append("</variable>");
}
sb.append("</variables>");
Document doc=DocumentHelper.parseText(sb.toString());
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer=new XMLWriter(out,format);
writer.write(doc);
writer.close();
out.close();
}catch(Exception ex){
throw new RuntimeException(ex);
}finally{
IOUtils.closeQuietly(out);
}
}
public static List<Variable> classToVariables(Class<?> cls){
try {
List<Variable> result = paserClass("",cls, new ArrayList<Class<?>>());
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static List<Variable> paserClass(String path,Class<?> cls, Collection<Class<?>> parsed) throws Exception{
List<Variable> variables=new ArrayList<Variable>();
BeanInfo beanInfo=Introspector.getBeanInfo(cls,Object.class);
PropertyDescriptor[] pds= beanInfo.getPropertyDescriptors();
if(pds!=null && !parsed.contains(cls)){
parsed.add(cls);
for(PropertyDescriptor pd:pds){
Variable variable=new Variable();
Class<?> type=pd.getPropertyType();
Datatype dataType=getDateType(type);
String propertyName=pd.getName();
String label=getPropertyAnnotationLabel(cls, propertyName);
String name=path+pd.getName();
variable.setName(name);
variable.setLabel(label==null?name:label);
variable.setType(dataType);
variable.setAct(Act.InOut);
if(Datatype.Object.equals(dataType)){
variables.addAll(paserClass(path+pd.getName()+".",type, parsed));
}else{
variables.add(variable);
}
}
}
return variables;
}
private static String getPropertyAnnotationLabel(Class<?> cls,String fieldName) throws Exception{
Field field = null;
while(field==null){
try{
field=cls.getDeclaredField(fieldName);
}catch(NoSuchFieldException ex){
if(cls==Object.class){
throw ex;
}
cls=cls.getSuperclass();
}
}
Label pd=field.getAnnotation(Label.class);
if(pd!=null){
return pd.value();
}
return null;
}
private static Datatype getDateType(Class<?> type){
if(String.class.isAssignableFrom(type)){
return Datatype.String;
}else if(Boolean.class.isAssignableFrom(type)
||boolean.class.isAssignableFrom(type)){
return Datatype.Boolean;
}else if(Integer.class.isAssignableFrom(type)
||int.class.isAssignableFrom(type)){
return Datatype.Integer;
}else if(Float.class.isAssignableFrom(type)
||float.class.isAssignableFrom(type)){
return Datatype.Float;
}else if(Long.class.isAssignableFrom(type)
||long.class.isAssignableFrom(type)){
return Datatype.Long;
}else if(BigDecimal.class.isAssignableFrom(type)){
return Datatype.BigDecimal;
}else if(Double.class.isAssignableFrom(type)
||double.class.isAssignableFrom(type)){
return Datatype.Double;
}else if(Date.class.isAssignableFrom(type)){
return Datatype.Date;
}else if(Date.class.isAssignableFrom(type)){
return Datatype.Date;
}else if(List.class.isAssignableFrom(type)){
return Datatype.List;
}else if(Map.class.isAssignableFrom(type)){
return Datatype.Map;
}else if(Set.class.isAssignableFrom(type)){
return Datatype.Set;
}else if(Enum.class.isAssignableFrom(type)){
return Datatype.Enum;
}else if(Character.class.isAssignableFrom(type) || char.class.isAssignableFrom(type)){
return Datatype.Char;
}else{
return Datatype.Object;
}
}
}
@@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
import org.apache.commons.lang.StringUtils;
/**
* @author Jacky.gao
* @since 2015年2月16日
*/
public class Configure {
private static String dateFormat;
private static String tempStorePath;
public void setDateFormat(String dateFormat) {
if(StringUtils.isEmpty(dateFormat) || dateFormat.equals("${urule.dateFormat}")){
Configure.dateFormat = "yyyy-MM-dd HH:mm:ss";
}else{
Configure.dateFormat = dateFormat;
}
}
public void setTempStorePath(String tempStorePath) {
if(!tempStorePath.equals("${urule.tempStorePath}")){
Configure.tempStorePath = tempStorePath;
}
}
public static String getTempStorePath() {
return tempStorePath;
}
public static String getDateFormat() {
return dateFormat;
}
}
@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
import com.itheima.sfbx.framework.rule.model.flow.FlowDefinition;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackage;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import com.itheima.sfbx.framework.rule.runtime.cache.CacheUtils;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2016年2月27日
*/
public class KnowledgePackageReceiverServlet extends HttpServlet {
private static final long serialVersionUID = -4342175088856372588L;
public static final String URL="/knowledgepackagereceiver";
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String packageId=req.getParameter("packageId");
if(StringUtils.isEmpty(packageId)){
return;
}
packageId=URLDecoder.decode(packageId, "utf-8");
if(packageId.startsWith("/")){
packageId=packageId.substring(1,packageId.length());
}
String content=req.getParameter("content");
if(StringUtils.isEmpty(content)){
return;
}
content=URLDecoder.decode(content, "utf-8");
ObjectMapper mapper=new ObjectMapper();
mapper.getDeserializationConfig().withDateFormat(new SimpleDateFormat(Configure.getDateFormat()));
KnowledgePackageWrapper wrapper=mapper.readValue(content, KnowledgePackageWrapper.class);
wrapper.buildDeserialize();
KnowledgePackage knowledgePackage=wrapper.getKnowledgePackage();
Map<String, FlowDefinition> flowMap=knowledgePackage.getFlowMap();
if(flowMap!=null && flowMap.size()>0){
for(FlowDefinition fd:flowMap.values()){
fd.buildConnectionToNode();
}
}
CacheUtils.getKnowledgeCache().putKnowledge(packageId, knowledgePackage);
SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("["+sd.format(new Date())+"] "+"Successfully receive the server side to pushed package:"+packageId);
resp.setContentType("text/plain");
PrintWriter pw=resp.getWriter();
pw.write("ok");
pw.flush();
pw.close();
}
}
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
/**
* @author Jacky.gao
* @since 2014年11月29日
*/
public class RuleException extends RuntimeException {
private static final long serialVersionUID = -8624533394127244753L;
public RuleException(){
}
public RuleException(String msg){
super(msg);
}
public RuleException(Exception ex){
super(ex);
ex.printStackTrace();
}
}
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
/**
* @author Jacky.gao
* @since 2017年8月28日
*/
public class Splash {
public void print(){
StringBuilder sb=new StringBuilder();
sb.append("\n");
sb.append(". 四方保险规则引擎启动\n");
sb.append(".....................................................................................................");
sb.append("\n");
System.out.println(sb.toString());
}
public static void main(String[] args) {
Splash s=new Splash();
s.print();
}
}
@@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
/**
* @author Jacky.gao
* @since 2016年5月25日
*/
public class URulePropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
public URulePropertyPlaceholderConfigurer() {
setIgnoreUnresolvablePlaceholders(true);
setOrder(100);
}
}
@@ -0,0 +1,221 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule;
import com.itheima.sfbx.framework.rule.debug.DebugWriter;
import com.itheima.sfbx.framework.rule.model.function.FunctionDescriptor;
import com.itheima.sfbx.framework.rule.model.library.Datatype;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
/**
* @author Jacky.gao
* @since 2015年1月8日
*/
public class Utils implements ApplicationContextAware{
private static boolean debug;
private static boolean debugToFile;
private static ApplicationContext applicationContext;
private static Collection<DebugWriter> debugWriters;
private static Map<String,FunctionDescriptor> functionDescriptorMap=new HashMap<String,FunctionDescriptor>();
private static Map<String,FunctionDescriptor> functionDescriptorLabelMap=new HashMap<String,FunctionDescriptor>();
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static String decodeURL(String str){
if(StringUtils.isBlank(str)){
return str;
}
try {
return URLDecoder.decode(URLDecoder.decode(str,"utf-8"),"utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuleException(e);
}
}
public static String encodeURL(String str){
if(StringUtils.isBlank(str)){
return str;
}
try {
return URLEncoder.encode(str,"utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuleException(e);
}
}
public static String toUTF8(String text){
try{
if (text == null) {
return null;
}
byte[] fileBytes=text.getBytes("iso8859-1");
boolean isiso=text.equals(new String(fileBytes, "iso8859-1"));
if(isiso){
text=new String(fileBytes,"utf-8");
}
isiso=text.equals(new String(text.getBytes("iso8859-1"), "iso8859-1"));
if(isiso){
text=new String(fileBytes,"utf-8");
}
return text;
}catch(Exception ex){
throw new RuleException(ex);
}
}
public static Object getObjectProperty(Object object,String property){
try {
return PropertyUtils.getProperty(object, property);
} catch (Exception e) {
throw new RuleException(e);
}
}
public static void setObjectProperty(Object object,String property,Object value){
try {
BeanUtils.setProperty(object, property, value);
} catch (Exception e) {
throw new RuleException(e);
}
}
public static Datatype getDatatype(Object obj){
Datatype datatype=null;
if(obj==null){
datatype=Datatype.Object;
}else{
if(obj instanceof Integer){
datatype=Datatype.Integer;
}else if(obj instanceof Long){
datatype=Datatype.Long;
}else if(obj instanceof Double){
datatype=Datatype.Double;
}else if(obj instanceof Float){
datatype=Datatype.Float;
}else if(obj instanceof BigDecimal){
datatype=Datatype.BigDecimal;
}else if(obj instanceof Boolean){
datatype=Datatype.Boolean;
}else if(obj instanceof Date){
datatype=Datatype.Date;
}else if(obj instanceof List){
datatype=Datatype.List;
}else if(obj instanceof Set){
datatype=Datatype.Set;
}else if(obj instanceof Enum){
datatype=Datatype.Enum;
}else if(obj instanceof Map){
datatype=Datatype.Map;
}else if(obj instanceof String){
datatype=Datatype.String;
}else if(obj instanceof Character){
datatype=Datatype.Char;
}else{
datatype=Datatype.Object;
}
}
return datatype;
}
public static BigDecimal toBigDecimal(Object val) {
try{
if (val instanceof BigDecimal) {
return (BigDecimal) val;
} else if (val == null) {
throw new IllegalArgumentException("Null can not to BigDecimal.");
} else if (val instanceof String) {
String str = (String) val;
if ("".equals(str.trim())) {
return BigDecimal.valueOf(0);
}
str=str.trim();
return new BigDecimal(str);
} else if (val instanceof Number) {
return new BigDecimal(val.toString());
} else if (val instanceof Character) {
int i = ((Character) val).charValue();
return new BigDecimal(i);
}
}catch(Exception ex){
throw new NumberFormatException("Can not convert "+val+" to number.");
}
throw new IllegalArgumentException(val.getClass().getName()+" can not to BigDecimal.");
}
public static FunctionDescriptor findFunctionDescriptor(String functionName){
if(!functionDescriptorMap.containsKey(functionName)){
throw new RuleException("Function["+functionName+"] not exist.");
}
return functionDescriptorMap.get(functionName);
}
public static Map<String, FunctionDescriptor> getFunctionDescriptorLabelMap() {
return functionDescriptorLabelMap;
}
public static Map<String, FunctionDescriptor> getFunctionDescriptorMap() {
return functionDescriptorMap;
}
public void setDebug(boolean debug) {
Utils.debug = debug;
}
public void setDebugToFile(boolean debugToFile) {
Utils.debugToFile = debugToFile;
}
public static boolean isDebugToFile() {
return debugToFile;
}
public static boolean isDebug() {
return debug;
}
public static Collection<DebugWriter> getDebugWriters() {
return debugWriters;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
functionDescriptorMap.clear();
functionDescriptorLabelMap.clear();
Collection<FunctionDescriptor> functionDescriptors=applicationContext.getBeansOfType(FunctionDescriptor.class).values();
for(FunctionDescriptor fun:functionDescriptors){
if(fun.isDisabled()){
continue;
}
if(functionDescriptorMap.containsKey(fun.getName())){
throw new RuntimeException("Duplicate function ["+fun.getName()+"]");
}
functionDescriptorMap.put(fun.getName(), fun);
functionDescriptorLabelMap.put(fun.getLabel(), fun);
}
debugWriters=applicationContext.getBeansOfType(DebugWriter.class).values();
Utils.applicationContext=applicationContext;
new Splash().print();
}
}
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
/**
* @author Jacky.gao
* @since 2015年4月8日
*/
public abstract class AbstractAction implements Action {
private int priority;
protected boolean debug;
@Override
public int compareTo(Action o) {
return o.getPriority()-priority;
}
@Override
public int getPriority() {
return priority;
}
@Override
public void setDebug(boolean debug) {
this.debug=debug;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public interface Action extends Comparable<Action>{
ActionValue execute(Context context, Object matchedObject, List<Object> allMatchedObjects, Map<String,Object> variableMap);
ActionType getActionType();
int getPriority();
void setDebug(boolean debug);
}
@@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Jacky.gao
* @since 2015年3月27日
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionId {
public String value();
}
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
/**
* @author Jacky.gao
* @since 2014年12月29日
*/
public enum ActionType {
ConsolePrint,ExecuteMethod,VariableAssign,ExecuteCommonFunction,Scoring;
}
@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
/**
* @author Jacky.gao
* @since 2015年1月6日
*/
public interface ActionValue {
String getActionId();
Object getValue();
}
@@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
/**
* @author Jacky.gao
* @since 2015年3月27日
*/
public class ActionValueImpl implements ActionValue {
private String actionId;
private Object value;
public ActionValueImpl(String actionId,Object value) {
this.actionId=actionId;
this.value=value;
}
@Override
public String getActionId() {
return actionId;
}
@Override
public Object getValue() {
return value;
}
}
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年3月18日
*/
public class BsfVariableCollector implements ApplicationContextAware{
public static final String BEAN_ID="urule.bsfVariableCollector";
private Collection<BsfVariableProvider> providers;
private ApplicationContext applicationContext;
public Map<String,Object> getVariableMap(Context context){
Map<String,Object> variableMap=new HashMap<String,Object>();
variableMap.put("workingMemory", context.getWorkingMemory());
variableMap.put("applicationContext", applicationContext);
for(BsfVariableProvider provider:providers){
Map<String,Object> map=provider.provide();
if(map==null){
continue;
}
variableMap.putAll(map);
}
return variableMap;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
providers=applicationContext.getBeansOfType(BsfVariableProvider.class).values();
this.applicationContext=applicationContext;
}
}
@@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年3月18日
*/
public interface BsfVariableProvider {
Map<String,Object> provide();
}
@@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.Utils;
import com.itheima.sfbx.framework.rule.debug.MsgType;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import com.itheima.sfbx.framework.rule.runtime.rete.ValueCompute;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class ConsolePrintAction extends AbstractAction {
private Value value;
private ActionType actionType=ActionType.ConsolePrint;
public ActionValue execute(Context context,Object matchedObject,List<Object> allMatchedObjects,Map<String,Object> variableMap) {
if(!Utils.isDebug()){
return null;
}
ValueCompute valueCompute=(ValueCompute)context.getApplicationContext().getBean(ValueCompute.BEAN_ID);
Object content=valueCompute.complexValueCompute(value, matchedObject, context,allMatchedObjects,variableMap);
if(content instanceof BigDecimal){
BigDecimal b=(BigDecimal)content;
context.debugMsg("☢☢☢控制台输出:"+b.toPlainString(), MsgType.ConsoleOutput, true);
}else if(content instanceof Double){
Double d=(Double)content;
context.debugMsg("☢☢☢控制台输出:"+d.toString(), MsgType.ConsoleOutput, true);
}else{
String msg=(content==null ? "null" : content.toString());
context.debugMsg("☢☢☢控制台输出:"+msg, MsgType.ConsoleOutput, true);
}
return null;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
public ActionType getActionType() {
return actionType;
}
}
@@ -0,0 +1,100 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.Utils;
import com.itheima.sfbx.framework.rule.debug.MsgType;
import com.itheima.sfbx.framework.rule.model.function.FunctionDescriptor;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.rule.lhs.CommonFunctionParameter;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年7月31日
*/
public class ExecuteCommonFunctionAction extends AbstractAction{
private String name;
private String label;
private CommonFunctionParameter parameter;
@Override
public ActionValue execute(Context context, Object matchedObject, List<Object> allMatchedObjects, Map<String,Object> variableMap) {
FunctionDescriptor function=null;
if(Utils.getFunctionDescriptorMap().containsKey(name)){
function=Utils.findFunctionDescriptor(name);
}else if(Utils.getFunctionDescriptorLabelMap().containsKey(label)){
function=Utils.getFunctionDescriptorLabelMap().get(label);
}
if(function==null){
throw new RuleException("Function["+name+"] not exist.");
}
String info=(label==null)?name:label;
Value value=null;
Object object=null;
if(parameter!=null){
value=parameter.getObjectParameter();
object=context.getValueCompute().complexValueCompute(value, matchedObject, context, allMatchedObjects,variableMap);
}
String property=null;
if(function.getArgument()!=null && function.getArgument().isNeedProperty()){
property=parameter.getProperty();
}
Object result=function.doFunction(object, property,context.getWorkingMemory());
if(debug && Utils.isDebug()){
info=info+(object==null ? "" : object);
String msg="***执行函数:"+info;
context.debugMsg(msg, MsgType.ExecuteFunction, debug);
}
if(result!=null){
return new ActionValueImpl(name,result);
}else{
return null;
}
}
@Override
public ActionType getActionType() {
return ActionType.ExecuteCommonFunction;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public CommonFunctionParameter getParameter() {
return parameter;
}
public void setParameter(CommonFunctionParameter parameter) {
this.parameter = parameter;
}
}
@@ -0,0 +1,311 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.Utils;
import com.itheima.sfbx.framework.rule.debug.MsgType;
import com.itheima.sfbx.framework.rule.model.library.Datatype;
import com.itheima.sfbx.framework.rule.model.rule.Parameter;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import com.itheima.sfbx.framework.rule.runtime.rete.ValueCompute;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class ExecuteMethodAction extends AbstractAction {
private String beanId;
private String beanLabel;
private String methodLabel;
private String methodName;
private List<Parameter> parameters;
private ActionType actionType=ActionType.ExecuteMethod;
public ActionValue execute(Context context,Object matchedObject,List<Object> allMatchedObjects,Map<String,Object> variableMap) {
String info=(beanLabel==null ? beanId : beanLabel)+(methodLabel==null ? methodName : methodLabel);
info="$$$执行动作:"+info;
try{
Object obj=context.getApplicationContext().getBean(beanId);
Method method=null;
if(parameters!=null && parameters.size()>0){
ParametersWrap wrap=buildParameterClasses(context,matchedObject,allMatchedObjects,variableMap);
Method[] methods=obj.getClass().getMethods();
Datatype[] targetDatatypes=wrap.getDatatypes();
boolean match=false;
for(Method m:methods){
method=m;
String name=m.getName();
if(!name.equals(methodName)){
continue;
}
Class<?> parameterClasses[]=m.getParameterTypes();
if(parameterClasses.length!=parameters.size()){
continue;
}
for(int i=0;i<parameterClasses.length;i++){
Class<?> clazz=parameterClasses[i];
Datatype datatype=targetDatatypes[i];
match = classMatch(clazz, datatype);
if(!match){
break;
}
}
if(match){
break;
}
}
if(!match){
throw new RuleException("Bean ["+beanId+"."+methodName+"] with "+parameters.size()+" parameters not exist");
}
String valueKey=methodName;
ActionId actionId=method.getAnnotation(ActionId.class);
if(actionId!=null){
valueKey=actionId.value();
}
Object value=method.invoke(obj, wrap.getValues());
if(debug && Utils.isDebug()){
String msg=info+"("+wrap.valuesToString()+")";
context.debugMsg(msg, MsgType.ExecuteBeanMethod, debug);
}
if(value!=null){
return new ActionValueImpl(valueKey,value);
}else{
return null;
}
}else{
method=obj.getClass().getMethod(methodName, new Class[]{});
String valueKey=methodName;
ActionId actionId=method.getAnnotation(ActionId.class);
if(actionId!=null){
valueKey=actionId.value();
}
Object value=method.invoke(obj);
if(debug && Utils.isDebug()){
String msg=info+"()";
context.debugMsg(msg, MsgType.ExecuteBeanMethod, debug);
}
if(value!=null){
return new ActionValueImpl(valueKey,value);
}else{
return null;
}
}
}catch(Exception ex){
throw new RuleException(ex);
}
}
private boolean classMatch(Class<?> clazz, Datatype datatype) {
boolean match=false;
switch(datatype){
case String:
if(clazz.equals(String.class)){
match=true;
}else{
match=false;
}
break;
case BigDecimal:
if(clazz.equals(BigDecimal.class)){
match=true;
}else{
match=false;
}
break;
case Boolean:
if(clazz.equals(Boolean.class) || clazz.equals(boolean.class)){
match=true;
}else{
match=false;
}
break;
case Date:
if(clazz.equals(Date.class)){
match=true;
}else{
match=false;
}
break;
case Double:
if(clazz.equals(Double.class) || clazz.equals(double.class)){
match=true;
}else{
match=false;
}
break;
case Enum:
if(Enum.class.isAssignableFrom(clazz)){
match=true;
}else{
match=false;
}
break;
case Float:
if(clazz.equals(Float.class) || clazz.equals(float.class)){
match=true;
}else{
match=false;
}
break;
case Integer:
if(clazz.equals(Integer.class) || clazz.equals(int.class)){
match=true;
}else{
match=false;
}
break;
case Char:
if(clazz.equals(Character.class) || clazz.equals(char.class)){
match=true;
}else{
match=false;
}
break;
case List:
if(List.class.isAssignableFrom(clazz)){
match=true;
}else{
match=false;
}
break;
case Long:
if(clazz.equals(Long.class) || clazz.equals(long.class)){
match=true;
}else{
match=false;
}
break;
case Map:
if(Map.class.isAssignableFrom(clazz)){
match=true;
}else{
match=false;
}
break;
case Set:
if(Set.class.isAssignableFrom(clazz)){
match=true;
}else{
match=false;
}
break;
case Object:
match=true;
break;
}
return match;
}
private ParametersWrap buildParameterClasses(Context context,Object matchedObject,List<Object> allMatchedObjects,Map<String,Object> variableMap){
List<Datatype> list=new ArrayList<Datatype>();
List<Object> values=new ArrayList<Object>();
ValueCompute valueCompute=context.getValueCompute();
for(Parameter param:parameters){
Datatype type=param.getType();
list.add(type);
Object value=valueCompute.complexValueCompute(param.getValue(), matchedObject, context,allMatchedObjects,variableMap);
values.add(type.convert(value));
}
Datatype[] datatypes=new Datatype[list.size()];
list.toArray(datatypes);
Object[] objs=new Object[values.size()];
values.toArray(objs);
ParametersWrap wrap=new ParametersWrap();
wrap.setDatatypes(datatypes);
wrap.setValues(objs);
return wrap;
}
public String getMethodLabel() {
return methodLabel;
}
public void setMethodLabel(String methodLabel) {
this.methodLabel = methodLabel;
}
public String getBeanId() {
return beanId;
}
public void setBeanId(String beanId) {
this.beanId = beanId;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getBeanLabel() {
return beanLabel;
}
public void setBeanLabel(String beanLabel) {
this.beanLabel = beanLabel;
}
public List<Parameter> getParameters() {
return parameters;
}
public void setParameters(List<Parameter> parameters) {
this.parameters = parameters;
}
public void addParameter(Parameter parameter) {
if(parameters==null){
parameters=new ArrayList<Parameter>();
}
parameters.add(parameter);
}
public ActionType getActionType() {
return actionType;
}
}
class ParametersWrap{
private Datatype[] datatypes;
private Object[] values;
public Datatype[] getDatatypes() {
return datatypes;
}
public void setDatatypes(Datatype[] datatypes) {
this.datatypes = datatypes;
}
public Object[] getValues() {
return values;
}
public void setValues(Object[] values) {
this.values = values;
}
public String valuesToString(){
if(values==null){
return "";
}
StringBuffer sb=new StringBuffer();
for(Object obj:values){
if(sb.length()>0){
sb.append(",");
}
if(obj==null){
sb.append("null");
}else{
sb.append(obj);
}
}
return sb.toString();
}
}
@@ -0,0 +1,72 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.scorecard.runtime.ScoreRuntimeValue;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import com.itheima.sfbx.framework.rule.runtime.rete.ValueCompute;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2016年9月26日
*/
public class ScoringAction extends AbstractAction {
private Value value;
private int rowNumber;
private String name;
private String weight;
private ActionType actionType=ActionType.Scoring;
public ScoringAction(int rowNumber,String name,String weight) {
this.rowNumber=rowNumber;
this.name=name;
this.weight=weight;
}
@Override
public ActionValue execute(Context context, Object matchedObject,List<Object> allMatchedObjects, Map<String, Object> variableMap) {
ValueCompute valueCompute=(ValueCompute)context.getApplicationContext().getBean(ValueCompute.BEAN_ID);
Object content=valueCompute.complexValueCompute(value, matchedObject, context,allMatchedObjects,variableMap);
ScoreRuntimeValue scoreRuntimeValue=new ScoreRuntimeValue(this.rowNumber,this.name,this.weight,content);
return new ActionValueImpl(scoreRuntimeValue.getName(),scoreRuntimeValue);
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
public String getName() {
return name;
}
public String getWeight() {
return weight;
}
@Override
public ActionType getActionType() {
return actionType;
}
public int getRowNumber() {
return rowNumber;
}
}
@@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class SimpleAction extends AbstractAction {
public SimpleAction(Object value) {
}
public ActionValue execute(Context context,Object matchedObject,List<Object> allMatchedObjects,Map<String,Object> variableMap) {
return null;
}
public ActionType getActionType() {
return ActionType.ConsolePrint;
}
}
@@ -0,0 +1,152 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.action;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.Utils;
import com.itheima.sfbx.framework.rule.debug.MsgType;
import com.itheima.sfbx.framework.rule.model.library.Datatype;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.rule.lhs.LeftType;
import com.itheima.sfbx.framework.rule.runtime.rete.Context;
import com.itheima.sfbx.framework.rule.runtime.rete.ValueCompute;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class VariableAssignAction extends AbstractAction {
private String referenceName;//for script rule
private String variableName;
private String variableLabel;
private String variableCategory;
private Datatype datatype;
private Value value;
private LeftType type;
private ActionType actionType=ActionType.VariableAssign;
@SuppressWarnings({ "unchecked", "rawtypes" })
public ActionValue execute(Context context,Object matchedObject,List<Object> allMatchedObjects,Map<String,Object> variableMap) {
Object targetFact=null;
String propertyName=null;
ValueCompute valueCompute=context.getValueCompute();
Object obj=valueCompute.complexValueCompute(value, matchedObject, context,allMatchedObjects,variableMap);
String label=null;
if(type!=null && type.equals(LeftType.NamedReference)){
String refName=referenceName;
targetFact=variableMap.get(refName);
if(targetFact==null){
refName=refName.substring(1,refName.length());
targetFact=variableMap.get(refName);
}
if(targetFact==null){
throw new RuleException("Reference ["+referenceName+"] not define.");
}
propertyName=variableName;
label=referenceName+"."+(variableLabel==null ? variableName : variableLabel);
}else{
String className=context.getVariableCategoryClass(variableCategory);
if(className.equals(Map.class.getName())){
targetFact=context.getWorkingMemory().getParameters();
}else{
targetFact=valueCompute.findObject(className, matchedObject, context);
}
if(targetFact==null){
throw new RuleException("Class["+className+"] not found in workingmemory.");
}
if(datatype.equals(Datatype.Enum) && obj!=null && StringUtils.isNotBlank(obj.toString())){
PropertyDescriptor pd=BeanUtils.getPropertyDescriptor(targetFact.getClass(), variableName);
Class<Enum> targetClass=(Class<Enum>)pd.getPropertyType();
obj=Enum.valueOf(targetClass, obj.toString());
}else if(obj!=null){
obj=datatype.convert(obj);
}
propertyName=variableName;
label=variableCategory+"."+(variableLabel==null ? variableName : variableLabel);
}
Utils.setObjectProperty(targetFact, propertyName, obj);
if(debug && Utils.isDebug()){
String msg="###变量赋值:"+label+"="+obj;
context.debugMsg(msg, MsgType.VarAssign, debug);
}
return null;
}
public LeftType getType() {
return type;
}
public void setType(LeftType type) {
this.type = type;
}
public String getReferenceName() {
return referenceName;
}
public void setReferenceName(String referenceName) {
this.referenceName = referenceName;
}
public String getVariableName() {
return variableName;
}
public void setVariableName(String variableName) {
this.variableName = variableName;
}
public String getVariableLabel() {
return variableLabel;
}
public void setVariableLabel(String variableLabel) {
this.variableLabel = variableLabel;
}
public String getVariableCategory() {
return variableCategory;
}
public void setVariableCategory(String variableCategory) {
this.variableCategory = variableCategory;
}
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
public Datatype getDatatype() {
return datatype;
}
public void setDatatype(Datatype datatype) {
this.datatype = datatype;
}
public ActionType getActionType() {
return actionType;
}
}
@@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceBuilder;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceProvider;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Collection;
/**
* @author Jacky.gao
* @since 2015年2月16日
*/
@SuppressWarnings("rawtypes")
public abstract class AbstractBuilder implements ApplicationContextAware{
protected Collection<ResourceProvider> providers;
protected ApplicationContext applicationContext;
protected Collection<ResourceBuilder> resourceBuilders;
public ResourceBase newResourceBase(){
return new ResourceBase(providers);
}
protected Element parseResource(String content){
try {
Document document = DocumentHelper.parseText(content);
Element root=document.getRootElement();
return root;
} catch (DocumentException e) {
throw new RuleException(e);
}
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
resourceBuilders=applicationContext.getBeansOfType(ResourceBuilder.class).values();
providers=applicationContext.getBeansOfType(ResourceProvider.class).values();
this.applicationContext=applicationContext;
applicationContext.getBeansWithAnnotation(SuppressWarnings.class);
}
}
@@ -0,0 +1,136 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.model.decisiontree.*;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.Rhs;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.RuleSet;
import com.itheima.sfbx.framework.rule.model.rule.lhs.And;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Criteria;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Lhs;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年2月26日
*/
public class DecisionTreeRulesBuilder {
public RuleSet buildRules(DecisionTree tree) throws IOException{
RuleSet rs=new RuleSet();
List<Library> libs=tree.getLibraries();
if(libs!=null){
for(Library lib:libs){
rs.addLibrary(lib);
}
}
List<VariableTreeNode> nodes=new ArrayList<VariableTreeNode>();
nodes.add(tree.getVariableTreeNode());
List<ActionTreeNode> list=new ArrayList<ActionTreeNode>();
fetchActionTreeNodes(nodes, list);
List<Rule> rules=new ArrayList<Rule>();
for(ActionTreeNode actionNode:list){
Rule rule=new Rule();
rule.setDebug(tree.getDebug());
rule.setEnabled(tree.getEnabled());
rule.setEffectiveDate(tree.getEffectiveDate());
rule.setExpiresDate(tree.getExpiresDate());
rule.setSalience(tree.getSalience());
rules.add(rule);
rule.setName("tree-rule");
Rhs rhs=new Rhs();
rhs.setActions(actionNode.getActions());
rule.setRhs(rhs);
Lhs lhs=new Lhs();
rule.setLhs(lhs);
And and=new And();
lhs.setCriterion(and);
ConditionTreeNode treeNode=(ConditionTreeNode)actionNode.getParentNode();
buildCriterion(and,treeNode);
}
rs.setRules(rules);
return rs;
}
private void buildCriterion(And and,ConditionTreeNode node){
if(node==null)return;
List<ConditionTreeNode> nodes=new ArrayList<ConditionTreeNode>();
nodes.add(node);
VariableTreeNode varNode=null;
TreeNode parentNode=node.getParentNode();
while(parentNode!=null){
if(parentNode instanceof VariableTreeNode){
varNode=(VariableTreeNode)parentNode;
buildCriterion(and,(ConditionTreeNode)parentNode.getParentNode());
break;
}else if(parentNode instanceof ConditionTreeNode){
ConditionTreeNode parentConditionTreeNode=(ConditionTreeNode)parentNode;
nodes.add(parentConditionTreeNode);
parentNode=parentConditionTreeNode.getParentNode();
}
}
if(varNode==null){
throw new RuleException("Decision tree is invalid.");
}
for(ConditionTreeNode cn:nodes){
and.addCriterion(buildCriteria(cn,varNode));
}
}
private Criteria buildCriteria(ConditionTreeNode cn,VariableTreeNode varNode){
Criteria c=new Criteria();
c.setLeft(varNode.getLeft());
c.setOp(cn.getOp());
c.setValue(cn.getValue());
return c;
}
public void fetchActionTreeNodes(List<? extends TreeNode> nodes,List<ActionTreeNode> list){
for(TreeNode node:nodes){
if(node instanceof ActionTreeNode){
list.add((ActionTreeNode)node);
}else if(node instanceof VariableTreeNode){
VariableTreeNode vn=(VariableTreeNode)node;
List<ConditionTreeNode> conditionNodes=vn.getConditionTreeNodes();
if(conditionNodes!=null){
fetchActionTreeNodes(conditionNodes, list);
}
}else if(node instanceof ConditionTreeNode){
ConditionTreeNode cn=(ConditionTreeNode)node;
List<ActionTreeNode> actionNodes=cn.getActionTreeNodes();
if(actionNodes!=null){
fetchActionTreeNodes(actionNodes, list);
}
List<ConditionTreeNode> conditionNodes=cn.getConditionTreeNodes();
if(conditionNodes!=null){
fetchActionTreeNodes(conditionNodes, list);
}
List<VariableTreeNode> varNodes=cn.getVariableTreeNodes();
if(varNodes!=null){
fetchActionTreeNodes(varNodes, list);
}
}
}
}
}
@@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.model.flow.FlowDefinition;
import com.itheima.sfbx.framework.rule.model.library.ResourceLibrary;
import com.itheima.sfbx.framework.rule.model.library.variable.Variable;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableCategory;
import com.itheima.sfbx.framework.rule.model.rete.Rete;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackage;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageImpl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class KnowledgeBase {
private ResourceLibrary resourceLibrary;
private Map<String,FlowDefinition> flowMap;
private Rete rete;
private KnowledgePackageImpl knowledgePackage;
private List<Rule> noLhsRules;
public KnowledgeBase(Rete rete) {
this(rete, null, null);
}
protected KnowledgeBase(Rete rete,Map<String,FlowDefinition> flowMap,List<Rule> noLhsRules) {
this.rete=rete;
this.resourceLibrary=rete.getResourceLibrary();
this.flowMap=flowMap;
this.noLhsRules=noLhsRules;
}
public KnowledgePackage getKnowledgePackage(){
if(knowledgePackage!=null){
return knowledgePackage;
}
knowledgePackage=new KnowledgePackageImpl();
knowledgePackage.setRete(rete);
knowledgePackage.setNoLhsRules(noLhsRules);
knowledgePackage.setFlowMap(flowMap);
knowledgePackage.buildWithElseRules();
Map<String,String> variableCategoryMap=new HashMap<String,String>();
knowledgePackage.setVariableCategoryMap(variableCategoryMap);
List<VariableCategory> variableCategories=resourceLibrary.getVariableCategories();
Map<String,String> parameters=new HashMap<String,String>();
knowledgePackage.setParameters(parameters);
for(VariableCategory category:variableCategories){
String name=category.getName();
variableCategoryMap.put(name, category.getClazz());
if(name.equals(VariableCategory.PARAM_CATEGORY)){
List<Variable> variables=category.getVariables();
if(variables==null || variables.size()==0){
continue;
}
for(Variable var:variables){
parameters.put(var.getName(), var.getType().name());
}
}
}
return knowledgePackage;
}
public List<Rule> getNoLhsRules() {
return noLhsRules;
}
public Rete getRete() {
return rete;
}
public ResourceLibrary getResourceLibrary() {
return resourceLibrary;
}
public Map<String, FlowDefinition> getFlowMap() {
return flowMap;
}
}
@@ -0,0 +1,216 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.builder.resource.Resource;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceBuilder;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceType;
import com.itheima.sfbx.framework.rule.builder.table.DecisionTableRulesBuilder;
import com.itheima.sfbx.framework.rule.builder.table.ScriptDecisionTableRulesBuilder;
import com.itheima.sfbx.framework.rule.dsl.DSLRuleSetBuilder;
import com.itheima.sfbx.framework.rule.model.decisiontree.DecisionTree;
import com.itheima.sfbx.framework.rule.model.flow.FlowDefinition;
import com.itheima.sfbx.framework.rule.model.library.ResourceLibrary;
import com.itheima.sfbx.framework.rule.model.rete.Rete;
import com.itheima.sfbx.framework.rule.model.rete.builder.ReteBuilder;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.RuleSet;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Lhs;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopRule;
import com.itheima.sfbx.framework.rule.model.scorecard.runtime.ScoreRule;
import com.itheima.sfbx.framework.rule.model.table.DecisionTable;
import com.itheima.sfbx.framework.rule.model.table.ScriptDecisionTable;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import com.itheima.sfbx.framework.rule.runtime.service.KnowledgePackageService;
import org.dom4j.Element;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class KnowledgeBuilder extends AbstractBuilder{
private ResourceLibraryBuilder resourceLibraryBuilder;
private ReteBuilder reteBuilder;
private RulesRebuilder rulesRebuilder;
private DecisionTreeRulesBuilder decisionTreeRulesBuilder;
private DecisionTableRulesBuilder decisionTableRulesBuilder;
private ScriptDecisionTableRulesBuilder scriptDecisionTableRulesBuilder;
private DSLRuleSetBuilder dslRuleSetBuilder;
public static final String BEAN_ID="urule.knowledgeBuilder";
public KnowledgeBase buildKnowledgeBase(ResourceBase resourceBase) throws IOException{
KnowledgePackageService knowledgePackageService=(KnowledgePackageService)applicationContext.getBean(KnowledgePackageService.BEAN_ID);
List<Rule> rules=new ArrayList<Rule>();
Map<String,Library> libMap=new HashMap<String,Library>();
Map<String,FlowDefinition> flowMap=new HashMap<String,FlowDefinition>();
for(Resource resource:resourceBase.getResources()){
if(dslRuleSetBuilder.support(resource)){
RuleSet ruleSet=dslRuleSetBuilder.build(resource.getContent());
addToLibraryMap(libMap,ruleSet.getLibraries());
if(ruleSet.getRules()!=null){
rules.addAll(ruleSet.getRules());
}
continue;
}
Element root=parseResource(resource.getContent());
for(ResourceBuilder<?> builder:resourceBuilders){
if(!builder.support(root)){
continue;
}
Object object=builder.build(root);
ResourceType type=builder.getType();
if(type.equals(ResourceType.RuleSet)){
RuleSet ruleSet=(RuleSet)object;
addToLibraryMap(libMap,ruleSet.getLibraries());
if(ruleSet.getRules()!=null){
List<Rule> ruleList=ruleSet.getRules();
rulesRebuilder.convertNamedJunctions(ruleList);
for(Rule rule:ruleList){
if(rule.getEnabled()!=null && rule.getEnabled()==false){
continue;
}
rules.add(rule);
}
}
}else if(type.equals(ResourceType.DecisionTree)){
DecisionTree tree=(DecisionTree)object;
addToLibraryMap(libMap,tree.getLibraries());
RuleSet ruleSet=decisionTreeRulesBuilder.buildRules(tree);
addToLibraryMap(libMap,ruleSet.getLibraries());
if(ruleSet.getRules()!=null){
rules.addAll(ruleSet.getRules());
}
}else if(type.equals(ResourceType.DecisionTable)){
DecisionTable table=(DecisionTable)object;
addToLibraryMap(libMap,table.getLibraries());
List<Rule> tableRules=decisionTableRulesBuilder.buildRules(table);
rules.addAll(tableRules);
}else if(type.equals(ResourceType.ScriptDecisionTable)){
ScriptDecisionTable table=(ScriptDecisionTable)object;
RuleSet ruleSet=scriptDecisionTableRulesBuilder.buildRules(table);
addToLibraryMap(libMap,ruleSet.getLibraries());
if(ruleSet.getRules()!=null){
rules.addAll(ruleSet.getRules());
}
}else if(type.equals(ResourceType.Flow)){
FlowDefinition fd=(FlowDefinition)object;
fd.initNodeKnowledgePackage(this, knowledgePackageService, dslRuleSetBuilder);
addToLibraryMap(libMap,fd.getLibraries());
flowMap.put(fd.getId(), fd);
}else if(type.equals(ResourceType.Scorecard)){
ScoreRule rule=(ScoreRule)object;
rules.add(rule);
addToLibraryMap(libMap,rule.getLibraries());
}
break;
}
}
ResourceLibrary resourceLibrary=resourceLibraryBuilder.buildResourceLibrary(libMap.values());
buildLoopRules(rules, resourceLibrary);
Rete rete=reteBuilder.buildRete(rules, resourceLibrary);
return new KnowledgeBase(rete,flowMap,retriveNoLhsRules(rules));
}
private void buildLoopRules(List<Rule> rules,ResourceLibrary resourceLibrary){
for(Rule rule:rules){
if(!(rule instanceof LoopRule)){
continue;
}
LoopRule loopRule=(LoopRule)rule;
List<Rule> ruleList=buildRules(loopRule);
Rete rete=reteBuilder.buildRete(ruleList, resourceLibrary);
KnowledgeBase base=new KnowledgeBase(rete);
KnowledgePackageWrapper knowledgeWrapper=new KnowledgePackageWrapper(base.getKnowledgePackage());
loopRule.setKnowledgePackageWrapper(knowledgeWrapper);
}
}
private List<Rule> buildRules(LoopRule loopRule){
Rule rule=new Rule();
rule.setDebug(loopRule.getDebug());
rule.setName("loop-rule");
rule.setLhs(loopRule.getLhs());
rule.setRhs(loopRule.getRhs());
rule.setOther(loopRule.getOther());
List<Rule> rules=new ArrayList<Rule>();
rules.add(rule);
return rules;
}
public KnowledgeBase buildKnowledgeBase(RuleSet ruleSet){
List<Rule> rules=new ArrayList<Rule>();
Map<String,Library> libMap=new HashMap<String,Library>();
addToLibraryMap(libMap,ruleSet.getLibraries());
if(ruleSet.getRules()!=null){
rules.addAll(ruleSet.getRules());
}
ResourceLibrary resourceLibrary=resourceLibraryBuilder.buildResourceLibrary(libMap.values());
Rete rete=reteBuilder.buildRete(rules, resourceLibrary);
return new KnowledgeBase(rete,null,retriveNoLhsRules(rules));
}
private List<Rule> retriveNoLhsRules(List<Rule> rules) {
List<Rule> noLhsRules=new ArrayList<Rule>();
for(Rule rule:rules){
Lhs lhs=rule.getLhs();
if((rule instanceof LoopRule) || (lhs==null || lhs.getCriterion()==null)){
noLhsRules.add(rule);
}
}
return noLhsRules;
}
private void addToLibraryMap(Map<String,Library> map,List<Library> libraries){
if(libraries==null){
return;
}
for(Library lib:libraries){
String path=lib.getPath();
if(map.containsKey(path)){
continue;
}
map.put(path, lib);
}
}
public void setRulesRebuilder(RulesRebuilder rulesRebuilder) {
this.rulesRebuilder = rulesRebuilder;
}
public void setReteBuilder(ReteBuilder reteBuilder) {
this.reteBuilder = reteBuilder;
}
public void setDecisionTableRulesBuilder(DecisionTableRulesBuilder decisionTableRulesBuilder) {
this.decisionTableRulesBuilder = decisionTableRulesBuilder;
}
public void setScriptDecisionTableRulesBuilder(ScriptDecisionTableRulesBuilder scriptDecisionTableRulesBuilder) {
this.scriptDecisionTableRulesBuilder = scriptDecisionTableRulesBuilder;
}
public void setDslRuleSetBuilder(DSLRuleSetBuilder dslRuleSetBuilder) {
this.dslRuleSetBuilder = dslRuleSetBuilder;
}
public void setResourceLibraryBuilder(ResourceLibraryBuilder resourceLibraryBuilder) {
this.resourceLibraryBuilder = resourceLibraryBuilder;
}
public void setDecisionTreeRulesBuilder(DecisionTreeRulesBuilder decisionTreeRulesBuilder) {
this.decisionTreeRulesBuilder = decisionTreeRulesBuilder;
}
}
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.builder.resource.Resource;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceProvider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class ResourceBase {
private Collection<ResourceProvider> providers;
private List<Resource> resources=new ArrayList<Resource>();
protected ResourceBase(Collection<ResourceProvider> providers) {
this.providers=providers;
}
public ResourceBase addResource(String path,String version){
boolean support=false;
for(ResourceProvider provider:providers){
if(provider.support(path)){
support=true;
resources.add(provider.provide(path,version));
break;
}
}
if(!support){
throw new RuleException("Unsupport rule file source : "+path);
}
return this;
}
public List<Resource> getResources() {
return resources;
}
}
@@ -0,0 +1,110 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.builder.resource.Resource;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceBuilder;
import com.itheima.sfbx.framework.rule.builder.resource.ResourceType;
import com.itheima.sfbx.framework.rule.model.library.ResourceLibrary;
import com.itheima.sfbx.framework.rule.model.library.action.ActionLibrary;
import com.itheima.sfbx.framework.rule.model.library.action.SpringBean;
import com.itheima.sfbx.framework.rule.model.library.constant.ConstantLibrary;
import com.itheima.sfbx.framework.rule.model.library.variable.Variable;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableCategory;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableLibrary;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.runtime.BuiltInActionLibraryBuilder;
import org.dom4j.Element;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年2月16日
*/
public class ResourceLibraryBuilder extends AbstractBuilder{
private BuiltInActionLibraryBuilder builtInActionLibraryBuilder;
@SuppressWarnings("unchecked")
public ResourceLibrary buildResourceLibrary(Collection<Library> libraries){
if(libraries==null){
libraries=Collections.EMPTY_LIST;
}
List<ConstantLibrary> constantLibraryLibs=new ArrayList<ConstantLibrary>();
List<ActionLibrary> actionLibraryLibs=new ArrayList<ActionLibrary>();
List<VariableLibrary> variableCategoryLibs=new ArrayList<VariableLibrary>();
List<VariableCategory> parameterVariableCategories=new ArrayList<VariableCategory>();
ResourceBase resourceBase=newResourceBase();
for(Library lib:libraries){
resourceBase.addResource(lib.getPath(),lib.getVersion());
}
for(Resource resource:resourceBase.getResources()){
String content=resource.getContent();
Element root=parseResource(content);
for(ResourceBuilder<?> builder:resourceBuilders){
if(!builder.support(root)){
continue;
}
Object object=builder.build(root);
ResourceType type=builder.getType();
if(type.equals(ResourceType.ActionLibrary)){
ActionLibrary al=(ActionLibrary)object;
actionLibraryLibs.add(al);
}else if(type.equals(ResourceType.VariableLibrary)){
VariableLibrary vl=(VariableLibrary)object;
variableCategoryLibs.add(vl);
}else if(type.equals(ResourceType.ConstantLibrary)){
ConstantLibrary cl=(ConstantLibrary)object;
constantLibraryLibs.add(cl);
}else if(type.equals(ResourceType.ParameterLibrary)){
VariableCategory category=(VariableCategory)object;
parameterVariableCategories.add(category);
}
break;
}
}
if(parameterVariableCategories.size()>0){
VariableCategory category=parameterVariableCategories.get(0);
for(VariableCategory vc:parameterVariableCategories){
if(vc.equals(category)){
continue;
}
if(vc.getVariables()==null){
continue;
}
for(Variable v:vc.getVariables()){
category.addVariable(v);
}
}
VariableLibrary parameterLib=new VariableLibrary();
parameterLib.addVariableCategory(category);
variableCategoryLibs.add(parameterLib);
}
List<SpringBean> builtInActions=builtInActionLibraryBuilder.getBuiltInActions();
if(builtInActions.size()>0){
ActionLibrary al=new ActionLibrary();
al.setSpringBeans(builtInActions);
actionLibraryLibs.add(al);
}
return new ResourceLibrary(variableCategoryLibs,actionLibraryLibs,constantLibraryLibs);
}
public void setBuiltInActionLibraryBuilder(
BuiltInActionLibraryBuilder builtInActionLibraryBuilder) {
this.builtInActionLibraryBuilder = builtInActionLibraryBuilder;
}
}
@@ -0,0 +1,711 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.Action;
import com.itheima.sfbx.framework.rule.action.ConsolePrintAction;
import com.itheima.sfbx.framework.rule.action.ExecuteMethodAction;
import com.itheima.sfbx.framework.rule.action.VariableAssignAction;
import com.itheima.sfbx.framework.rule.model.flow.Connection;
import com.itheima.sfbx.framework.rule.model.flow.DecisionItem;
import com.itheima.sfbx.framework.rule.model.library.Datatype;
import com.itheima.sfbx.framework.rule.model.library.ResourceLibrary;
import com.itheima.sfbx.framework.rule.model.library.action.ActionLibrary;
import com.itheima.sfbx.framework.rule.model.library.action.Method;
import com.itheima.sfbx.framework.rule.model.library.action.SpringBean;
import com.itheima.sfbx.framework.rule.model.library.constant.ConstantCategory;
import com.itheima.sfbx.framework.rule.model.library.variable.Variable;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableCategory;
import com.itheima.sfbx.framework.rule.model.rule.*;
import com.itheima.sfbx.framework.rule.model.rule.lhs.*;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopEnd;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopRule;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopStart;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopTarget;
import org.apache.commons.lang.StringUtils;
import java.util.*;
/**
* @author Jacky.gao
* @since 2015年8月19日
*/
public class RulesRebuilder {
private ResourceLibraryBuilder resourceLibraryBuilder;
public void rebuildRules(List<Library> libraries, List<Rule> rules) {
if(libraries==null){
return;
}
if(rules==null){
return;
}
ResourceLibrary resLibraries=resourceLibraryBuilder.buildResourceLibrary(libraries);
for(Rule rule:rules){
Map<String,String> namedMap=new HashMap<String,String>();
if(rule.getLhs()!=null){
Criterion criterion=rule.getLhs().getCriterion();
rebuildCriterion(criterion, resLibraries,namedMap,false);
}
Rhs rhs=rule.getRhs();
List<Action> actions=rhs.getActions();
if(actions!=null){
for(Action action:actions){
rebuildAction(action,resLibraries,namedMap,false);
}
}
Other other=rule.getOther();
if(other!=null){
List<Action> otherActions=other.getActions();
if(otherActions!=null){
for(Action action:otherActions){
rebuildAction(action,resLibraries,namedMap,false);
}
}
}
if(rule instanceof LoopRule){
LoopRule loopRule=(LoopRule)rule;
LoopTarget target=loopRule.getLoopTarget();
if(target!=null){
Value value=target.getValue();
rebuildValue(value, resLibraries,namedMap,false);
}
LoopStart start=loopRule.getLoopStart();
if(start!=null && start.getActions()!=null){
for(Action action:start.getActions()){
rebuildAction(action,resLibraries,namedMap,false);
}
}
LoopEnd end=loopRule.getLoopEnd();
if(end!=null && end.getActions()!=null){
for(Action action:end.getActions()){
rebuildAction(action,resLibraries,namedMap,false);
}
}
}
}
}
public void rebuildRulesForDSL(List<Library> libraries, List<Rule> rules) {
if(libraries==null){
return;
}
if(rules==null){
return;
}
ResourceLibrary resLibraries=resourceLibraryBuilder.buildResourceLibrary(libraries);
for(Rule rule:rules){
Map<String,String> namedMap=new HashMap<String,String>();
if(rule.getLhs()!=null){
Criterion criterion=rule.getLhs().getCriterion();
rebuildCriterion(criterion, resLibraries,namedMap,true);
}
Rhs rhs=rule.getRhs();
List<Action> actions=rhs.getActions();
if(actions!=null){
for(Action action:actions){
rebuildAction(action,resLibraries,namedMap,true);
}
}
Other other=rule.getOther();
if(other!=null){
List<Action> otherActions=other.getActions();
if(otherActions!=null){
for(Action action:otherActions){
rebuildAction(action,resLibraries,namedMap,true);
}
}
}
if(rule instanceof LoopRule){
LoopRule loopRule=(LoopRule)rule;
LoopTarget target=loopRule.getLoopTarget();
if(target!=null){
Value value=target.getValue();
rebuildValue(value, resLibraries,namedMap,true);
}
LoopStart start=loopRule.getLoopStart();
if(start!=null && start.getActions()!=null){
for(Action action:start.getActions()){
rebuildAction(action,resLibraries,namedMap,true);
}
}
LoopEnd end=loopRule.getLoopEnd();
if(end!=null && end.getActions()!=null){
for(Action action:end.getActions()){
rebuildAction(action,resLibraries,namedMap,true);
}
}
}
}
}
public void convertNamedJunctions(List<Rule> rules){
for(Rule rule:rules){
if(rule.getLhs()==null){
continue;
}
Criterion criterion=rule.getLhs().getCriterion();
Criterion newCriterion=buildCriterion(criterion);
rule.getLhs().setCriterion(newCriterion);
}
}
private Criterion buildCriterion(Criterion criterion) {
if(!(criterion instanceof NamedJunction) && !(criterion instanceof Junction)){
return criterion;
}
if(criterion instanceof NamedJunction){
NamedJunction jun=(NamedJunction)criterion;
NamedCriteria criteria=buildNamedJunction(jun);
return criteria;
}else if(criterion instanceof Junction){
buildJunction((Junction)criterion);
}
return criterion;
}
private void buildJunction(Junction jun) {
List<Criterion> criterions=jun.getCriterions();
List<Criterion> newCriterions=new ArrayList<Criterion>();
for(Criterion c:criterions){
NamedCriteria namedCriteria=buildNamedJunction(c);
if(namedCriteria!=null){
newCriterions.add(namedCriteria);
}else if(c instanceof Junction){
buildJunction((Junction)c);
}
newCriterions.add(c);
}
jun.setCriterions(newCriterions);
}
private NamedCriteria buildNamedJunction(Criterion criterion) {
if(!(criterion instanceof NamedJunction)){
return null;
}
NamedJunction jun=(NamedJunction)criterion;
NamedCriteria criteria=new NamedCriteria();
criteria.setReferenceName(jun.getReferenceName());
criteria.setParent(jun.getParent());
criteria.setVariableCategory(jun.getVariableCategory());
JunctionType junctionType=jun.getJunctionType();
List<NamedItem> items=jun.getItems();
List<CriteriaUnit> nextUnits=null;
for(NamedItem item:items){
CriteriaUnit unit=new CriteriaUnit();
unit.setJunctionType(junctionType);
Criteria c=new Criteria();
unit.setCriteria(c);
c.setOp(item.getOp());
Left left=new Left();
left.setType(LeftType.NamedReference);
VariableLeftPart leftPart=new VariableLeftPart();
leftPart.setDatatype(item.getDatatype());
leftPart.setVariableCategory(jun.getVariableCategory());
leftPart.setVariableLabel(item.getVariableLabel());
leftPart.setVariableName(item.getVariableName());
left.setLeftPart(leftPart);
c.setLeft(left);
c.setValue(item.getValue());
if(nextUnits==null){
criteria.setUnit(unit);
nextUnits=new ArrayList<CriteriaUnit>();
unit.setNextUnits(nextUnits);
}else{
nextUnits.add(unit);
}
}
return criteria;
}
public void rebuildAction(Action action,ResourceLibrary resLibraries,Map<String,String> namedMap,boolean forDSL){
if(action==null){
return;
}
if(action instanceof VariableAssignAction){
List<VariableCategory> variableCategories=resLibraries.getVariableCategories();
if(variableCategories==null){
return;
}
VariableAssignAction varAction=(VariableAssignAction)action;
LeftType type=varAction.getType();
if(type==null || !type.equals(LeftType.NamedReference)){
String variableCategory=varAction.getVariableCategory();
String variableLabel=varAction.getVariableLabel();
if(variableLabel.equals(Connection.RETURN_VALUE_KEY)){
varAction.setVariableName(variableLabel);
varAction.setDatatype(Datatype.Boolean);
}else if(variableLabel.equals(DecisionItem.RETURN_VALUE_KEY)){
varAction.setVariableName(variableLabel);
varAction.setDatatype(Datatype.String);
}else{
String variableName=varAction.getVariableName();
if(forDSL){
Variable var=getVariableByLabel(variableCategories, variableCategory, variableLabel,namedMap);
varAction.setVariableName(var.getName());
varAction.setDatatype(var.getType());
}else{
if(StringUtils.isNotBlank(variableName)){
Variable var=getVariableByName(variableCategories, variableCategory, variableName,namedMap);
varAction.setVariableLabel(var.getLabel());
varAction.setDatatype(var.getType());
}else{
Variable var=getVariableByLabel(variableCategories, variableCategory, variableLabel,namedMap);
varAction.setVariableName(var.getName());
varAction.setDatatype(var.getType());
}
}
}
}
if(type!=null && type.equals(LeftType.NamedReference)){
String refName=varAction.getReferenceName();
String variableCategory=namedMap.get(refName);
if(variableCategory==null){
refName=refName.substring(1,refName.length());
variableCategory=namedMap.get(refName);
}
if(variableCategory==null){
throw new RuleException("Reference ["+refName+"] not define.");
}
if(forDSL){
Variable var=getVariableByLabel(variableCategories, variableCategory, varAction.getVariableLabel(),namedMap);
varAction.setVariableName(var.getName());
varAction.setVariableCategory(variableCategory);
varAction.setDatatype(var.getType());
}else{
String variableName=varAction.getVariableName();
if(StringUtils.isNotBlank(variableName)){
Variable var=getVariableByLabel(variableCategories, variableCategory, variableName,namedMap);
varAction.setVariableLabel(var.getLabel());
varAction.setVariableCategory(variableCategory);
varAction.setDatatype(var.getType());
}else{
Variable var=getVariableByLabel(variableCategories, variableCategory, varAction.getVariableLabel(),namedMap);
varAction.setVariableName(var.getName());
varAction.setVariableCategory(variableCategory);
varAction.setDatatype(var.getType());
}
}
}
Value value=((VariableAssignAction) action).getValue();
rebuildValue(value,resLibraries,namedMap,forDSL);
}else if(action instanceof ConsolePrintAction){
ConsolePrintAction consoleAction=(ConsolePrintAction)action;
Value value=consoleAction.getValue();
rebuildValue(value, resLibraries,namedMap,forDSL);
}else if(action instanceof ExecuteMethodAction){
List<ActionLibrary> actionLibraries=resLibraries.getActionLibraries();
if(actionLibraries==null){
return;
}
ExecuteMethodAction methodAction=(ExecuteMethodAction)action;
String beanLabel=methodAction.getBeanLabel();
String methodLabel=methodAction.getMethodLabel();
SpringBean targetBean=null;
for(ActionLibrary al:actionLibraries){
List<SpringBean> beans=al.getSpringBeans();
if(beans==null){
continue;
}
for(SpringBean bean:beans){
if(beanLabel.equals(bean.getName())){
targetBean=bean;
break;
}
}
if(targetBean!=null)break;
}
Method targetMethod=null;
if(targetBean!=null){
methodAction.setBeanId(targetBean.getId());
List<Method> methods=targetBean.getMethods();
if(methods==null){
throw new RuleException("Bean ["+beanLabel+"] not define methods.");
}
for(Method method:methods){
if(method.getName().equals(methodLabel)){
targetMethod=method;
break;
}
}
if(targetMethod==null){
throw new RuleException("Bean ["+beanLabel+"] method["+methodLabel+"] not define.");
}
methodAction.setMethodName(targetMethod.getMethodName());
}
List<Parameter> parameters=methodAction.getParameters();
rebuildParameters(resLibraries, parameters,targetMethod.getParameters(),namedMap,forDSL);
}
}
private void rebuildCommonFunctionParameter(CommonFunctionParameter parameter,ResourceLibrary resLibraries,Map<String,String> namedMap,boolean forDSL){
String property=parameter.getProperty();
if(StringUtils.isEmpty(property)){
return;
}
Value value=parameter.getObjectParameter();
rebuildValue(value, resLibraries,namedMap,forDSL);
String category=null;
if(value instanceof VariableValue){
VariableValue vv=(VariableValue)value;
category=vv.getVariableCategory();
}else if(value instanceof VariableCategoryValue){
VariableCategoryValue vc=(VariableCategoryValue)value;
category=vc.getVariableCategory();
}else{
throw new RuleException("Function parameter is invalid.");
}
List<VariableCategory> variableCategories=resLibraries.getVariableCategories();
for(VariableCategory vc:variableCategories){
if(!category.equals(vc.getName())){
continue;
}
for(Variable v:vc.getVariables()){
if(v.getName().equals(property) || v.getLabel().equals(property)){
parameter.setProperty(v.getName());
parameter.setPropertyLabel(v.getLabel());
break;
}
}
}
}
private void rebuildParameters(ResourceLibrary resLibraries,List<Parameter> parameters,List<com.itheima.sfbx.framework.rule.model.library.action.Parameter> targetParameters,Map<String,String> namedMap,boolean forDSL) {
if(parameters!=null && targetParameters!=null){
for(int i=0;i<parameters.size();i++){
if(i>targetParameters.size()-1){
break;
}
Parameter parameter=parameters.get(i);
com.itheima.sfbx.framework.rule.model.library.action.Parameter p=targetParameters.get(i);
parameter.setType(p.getType());
Value value=parameter.getValue();
rebuildValue(value, resLibraries,namedMap,forDSL);
}
}
}
public void rebuildCriterion(Criterion criterion,ResourceLibrary resLibraries,Map<String,String> namedMap,boolean forDSL){
if(criterion==null){
return;
}
if(criterion instanceof Criteria){
Criteria criteria=(Criteria)criterion;
rebuildCriteria(resLibraries,criteria,namedMap,forDSL);
}else if(criterion instanceof Junction){
Junction junction=(Junction)criterion;
Collection<Criterion> criterionList=junction.getCriterions();
if(criterionList!=null){
for(Criterion c:criterionList){
rebuildCriterion(c, resLibraries,namedMap,forDSL);
}
}
}else if(criterion instanceof NamedCriteria){
NamedCriteria namedCriteria=(NamedCriteria)criterion;
namedMap.put(namedCriteria.getReferenceName(), namedCriteria.getVariableCategory());
CriteriaUnit unit=namedCriteria.getUnit();
buildCriteriaUnit(unit,resLibraries,namedMap,forDSL);
}else if(criterion instanceof NamedJunction){
NamedJunction jun=(NamedJunction)criterion;
namedMap.put(jun.getReferenceName(), jun.getVariableCategory());
}
}
private void buildCriteriaUnit(CriteriaUnit unit,ResourceLibrary resLibraries,Map<String,String> namedMap,boolean forDSL){
Criteria criteria=unit.getCriteria();
if(criteria!=null){
rebuildCriteria(resLibraries,criteria,namedMap,forDSL);
}
List<CriteriaUnit> units=unit.getNextUnits();
if(units!=null){
for(CriteriaUnit nextUnit:units){
buildCriteriaUnit(nextUnit, resLibraries,namedMap,forDSL);
}
}
}
private void rebuildCriteria(ResourceLibrary resLibraries,Criteria criteria,Map<String,String> namedMap,boolean forDSL) {
List<VariableCategory> variableCategories=resLibraries.getVariableCategories();
Left left=criteria.getLeft();
LeftPart leftPart=left.getLeftPart();
if(leftPart instanceof VariableLeftPart){
VariableLeftPart part=(VariableLeftPart)leftPart;
String variableLabel=part.getVariableLabel();
String variableName=part.getVariableName();
if(StringUtils.isNotBlank(variableLabel)){
String variableCategory=part.getVariableCategory();
if(forDSL){
Variable var=getVariableByLabel(variableCategories, variableCategory, variableLabel,namedMap);
part.setVariableName(var.getName());
part.setDatatype(var.getType());
}else{
Variable var=getVariableByName(variableCategories, variableCategory, variableName,namedMap);
part.setVariableLabel(var.getLabel());
part.setDatatype(var.getType());
}
}
}else if(leftPart instanceof AbstractLeftPart){
AbstractLeftPart part=(AbstractLeftPart)leftPart;
String variableCategory=part.getVariableCategory();
String variableLabel=part.getVariableLabel();
String variableName=part.getVariableName();
if(forDSL){
Variable var=getVariableByLabel(variableCategories, variableCategory, variableLabel,namedMap);
part.setVariableName(var.getName());
}else{
Variable var=getVariableByName(variableCategories, variableCategory, variableName,namedMap);
part.setVariableLabel(var.getLabel());
}
}else if(leftPart instanceof CommonFunctionLeftPart){
CommonFunctionLeftPart p=(CommonFunctionLeftPart)leftPart;
CommonFunctionParameter parameter=p.getParameter();
rebuildCommonFunctionParameter(parameter,resLibraries,namedMap,forDSL);
}else if(leftPart instanceof MethodLeftPart){
MethodLeftPart part=(MethodLeftPart)leftPart;
String beanLabel=part.getBeanLabel();
String methodLabel=part.getMethodLabel();
List<ActionLibrary> actionLibraries=resLibraries.getActionLibraries();
SpringBean targetBean=null;
for(ActionLibrary al:actionLibraries){
List<SpringBean> beans=al.getSpringBeans();
for(SpringBean bean:beans){
if(beanLabel.equals(bean.getName())){
part.setBeanId(bean.getId());
targetBean=bean;
break;
}
}
if(targetBean!=null){
break;
}
}
if(targetBean==null){
throw new RuleException("Bean["+beanLabel+"] not exist.");
}
Method targetMethod=null;
for(Method method:targetBean.getMethods()){
if(methodLabel.equals(method.getName())){
targetMethod=method;
part.setMethodName(method.getMethodName());
break;
}
}
if(targetMethod==null){
throw new RuleException("Bean["+beanLabel+"] method["+targetMethod+"] not exist.");
}
List<Parameter> parameters=part.getParameters();
rebuildParameters(resLibraries, parameters,targetMethod.getParameters(),namedMap,forDSL);
}else if(leftPart instanceof FunctionLeftPart){
FunctionLeftPart part=(FunctionLeftPart)leftPart;
List<Parameter> parameters=part.getParameters();
if(parameters!=null && parameters.size()>0){
for(Parameter param:parameters){
Value pv=param.getValue();
if(pv==null){
continue;
}
rebuildValue(pv,resLibraries,namedMap,forDSL);
}
}
}
Value value=criteria.getValue();
rebuildValue(value, resLibraries,namedMap,forDSL);
}
public void rebuildValue(Value value,ResourceLibrary resLibraries,Map<String,String> namedMap,boolean forDSL){
if(value==null){
return;
}
if(value instanceof ParenValue){
ParenValue pv=(ParenValue)value;
Value v=pv.getValue();
rebuildValue(v,resLibraries,namedMap,forDSL);
}else if(value instanceof ConstantValue){
ConstantValue cv=(ConstantValue)value;
String category=cv.getConstantCategory();
if(forDSL){
String label=cv.getConstantLabel();
com.itheima.sfbx.framework.rule.model.library.constant.Constant constant=getConstantByLabel(resLibraries.getConstantCategories(), category, label);
cv.setConstantName(constant.getName());
}else{
String name=cv.getConstantName();
com.itheima.sfbx.framework.rule.model.library.constant.Constant constant=getConstantByName(resLibraries.getConstantCategories(), category, name);
cv.setConstantLabel(constant.getLabel());
}
}else if(value instanceof VariableValue){
VariableValue variableValue=(VariableValue)value;
if(forDSL){
if(StringUtils.isNotBlank(variableValue.getVariableLabel())){
Variable var=getVariableByLabel(resLibraries.getVariableCategories(), variableValue.getVariableCategory(), variableValue.getVariableLabel(),namedMap);
variableValue.setVariableName(var.getName());
variableValue.setDatatype(var.getType());
}
}else{
if(StringUtils.isNotBlank(variableValue.getVariableName())){
Variable var=getVariableByName(resLibraries.getVariableCategories(), variableValue.getVariableCategory(), variableValue.getVariableName(),namedMap);
variableValue.setVariableLabel(var.getLabel());
variableValue.setDatatype(var.getType());
}
}
}else if(value instanceof ParameterValue){
ParameterValue parameterValue=(ParameterValue)value;
if(forDSL){
String variableLabel=parameterValue.getVariableLabel();
Variable var=getVariableByLabel(resLibraries.getVariableCategories(), VariableCategory.PARAM_CATEGORY, variableLabel,namedMap);
parameterValue.setVariableName(var.getName());
}else{
String variableName=parameterValue.getVariableName();
Variable var=getVariableByName(resLibraries.getVariableCategories(), VariableCategory.PARAM_CATEGORY, variableName,namedMap);
parameterValue.setVariableLabel(var.getLabel());
}
}else if(value instanceof NamedReferenceValue){
NamedReferenceValue refValue=(NamedReferenceValue)value;
String propertyLabel=refValue.getPropertyLabel();
String propertyName=refValue.getPropertyName();
String refName=refValue.getReferenceName();
String variableCategory=namedMap.get(refName);
if(variableCategory==null){
refName=refName.substring(1,refName.length());
variableCategory=namedMap.get(refName);
}
if(variableCategory==null){
throw new RuleException("Reference ["+refName+"] not define.");
}
if(forDSL){
Variable var=getVariableByLabel(resLibraries.getVariableCategories(), variableCategory, propertyLabel,namedMap);
refValue.setPropertyName(var.getName());
refValue.setDatatype(var.getType());
}else{
Variable var=getVariableByName(resLibraries.getVariableCategories(), variableCategory, propertyName,namedMap);
refValue.setPropertyLabel(var.getLabel());
refValue.setDatatype(var.getType());
}
}else if(value instanceof CommonFunctionValue){
CommonFunctionValue cfv=(CommonFunctionValue)value;
CommonFunctionParameter parameter=cfv.getParameter();
rebuildCommonFunctionParameter(parameter,resLibraries,namedMap,forDSL);
}else if(value instanceof MethodValue){
MethodValue methodValue=(MethodValue)value;
String beanLabel=methodValue.getBeanLabel();
String methodLabel=methodValue.getMethodLabel();
List<ActionLibrary> actionLibraries=resLibraries.getActionLibraries();
SpringBean targetBean=null;
for(ActionLibrary al:actionLibraries){
List<SpringBean> beans=al.getSpringBeans();
for(SpringBean bean:beans){
if(beanLabel.equals(bean.getName())){
methodValue.setBeanId(bean.getId());
targetBean=bean;
break;
}
}
if(targetBean!=null)break;
}
if(targetBean==null){
throw new RuleException("Bean["+beanLabel+"] not exist.");
}
Method targetMethod=null;
for(Method method:targetBean.getMethods()){
if(methodLabel.equals(method.getName())){
targetMethod=method;
methodValue.setMethodName(method.getMethodName());
break;
}
}
if(targetMethod==null){
throw new RuleException("Bean["+beanLabel+"] method["+targetMethod+"] not exist.");
}
List<Parameter> parameters=methodValue.getParameters();
rebuildParameters(resLibraries, parameters,targetMethod.getParameters(),namedMap,forDSL);
}
ComplexArithmetic complexArithmetic=value.getArithmetic();
if(complexArithmetic==null){
return;
}
Value subValue=complexArithmetic.getValue();
rebuildValue(subValue, resLibraries,namedMap,forDSL);
}
private com.itheima.sfbx.framework.rule.model.library.constant.Constant getConstantByName(List<ConstantCategory> constantCategories,String category,String name){
for(ConstantCategory c:constantCategories){
if(!c.getLabel().equals(category)){
continue;
}
for(com.itheima.sfbx.framework.rule.model.library.constant.Constant constant:c.getConstants()){
if(constant.getName().equals(name)){
return constant;
}
}
}
throw new RuleException("Constant ["+category+"."+name+"] was not found.");
}
private com.itheima.sfbx.framework.rule.model.library.constant.Constant getConstantByLabel(List<ConstantCategory> constantCategories,String category,String label){
for(ConstantCategory c:constantCategories){
if(!c.getLabel().equals(category)){
continue;
}
for(com.itheima.sfbx.framework.rule.model.library.constant.Constant constant:c.getConstants()){
if(constant.getLabel().equals(label)){
return constant;
}
}
}
throw new RuleException("Constant ["+category+"."+label+"] was not found.");
}
public Variable getVariableByName(List<VariableCategory> variableCategories,String category,String name,Map<String,String> namedMap){
if(namedMap!=null){
if(namedMap.containsKey(category)){
category=namedMap.get(category);
}
}
for(VariableCategory c:variableCategories){
if(!c.getName().equals(category)){
continue;
}
for(Variable var:c.getVariables()){
if(var.getName().equals(name)){
return var;
}
}
}
throw new RuleException("Variable ["+category+"."+name+"] was not found.");
}
public Variable getVariableByLabel(List<VariableCategory> variableCategories,String category,String label,Map<String,String> namedMap){
if(namedMap!=null){
if(namedMap.containsKey(category)){
category=namedMap.get(category);
}
}
for(VariableCategory c:variableCategories){
if(!c.getName().equals(category)){
continue;
}
for(Variable var:c.getVariables()){
if(var.getLabel().equals(label)){
return var;
}
}
}
throw new RuleException("Variable ["+category+"."+label+"] was not found.");
}
public void setResourceLibraryBuilder(ResourceLibraryBuilder resourceLibraryBuilder) {
this.resourceLibraryBuilder = resourceLibraryBuilder;
}
public ResourceLibraryBuilder getResourceLibraryBuilder() {
return resourceLibraryBuilder;
}
}
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.library.action.ActionLibrary;
import com.itheima.sfbx.framework.rule.parse.deserializer.ActionLibraryDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2014年11月22日
*/
public class ActionLibraryResourceBuilder implements ResourceBuilder<ActionLibrary> {
private ActionLibraryDeserializer actionLibraryDeserializer;
public ActionLibrary build(Element root) {
return actionLibraryDeserializer.deserialize(root);
}
public void setActionLibraryDeserializer(ActionLibraryDeserializer actionLibraryDeserializer) {
this.actionLibraryDeserializer = actionLibraryDeserializer;
}
public boolean support(Element root) {
return actionLibraryDeserializer.support(root);
}
public ResourceType getType() {
return ResourceType.ActionLibrary;
}
}
@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.library.constant.ConstantLibrary;
import com.itheima.sfbx.framework.rule.parse.deserializer.ConstantLibraryDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2015年1月15日
*/
public class ConstantLibraryResourceBuilder implements ResourceBuilder<ConstantLibrary> {
private ConstantLibraryDeserializer constantLibraryDeserializer;
public ConstantLibrary build(Element root) {
return constantLibraryDeserializer.deserialize(root);
}
public boolean support(Element root) {
return constantLibraryDeserializer.support(root);
}
public ResourceType getType() {
return ResourceType.ConstantLibrary;
};
public void setConstantLibraryDeserializer(
ConstantLibraryDeserializer constantLibraryDeserializer) {
this.constantLibraryDeserializer = constantLibraryDeserializer;
}
}
@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.table.DecisionTable;
import com.itheima.sfbx.framework.rule.parse.deserializer.DecisionTableDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2015年2月9日
*/
public class DecisionTableResourceBuilder implements ResourceBuilder<DecisionTable> {
private DecisionTableDeserializer decisionTableDeserializer;
public DecisionTable build(Element root) {
return decisionTableDeserializer.deserialize(root);
}
public ResourceType getType() {
return ResourceType.DecisionTable;
}
public boolean support(Element root) {
return decisionTableDeserializer.support(root);
}
public void setDecisionTableDeserializer(
DecisionTableDeserializer decisionTableDeserializer) {
this.decisionTableDeserializer = decisionTableDeserializer;
}
}
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.decisiontree.DecisionTree;
import com.itheima.sfbx.framework.rule.parse.deserializer.DecisionTreeDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2016年2月29日
*/
public class DecisionTreeResourceBuilder implements ResourceBuilder<DecisionTree> {
private DecisionTreeDeserializer decisionTreeDeserializer;
@Override
public DecisionTree build(Element root) {
return decisionTreeDeserializer.deserialize(root);
}
@Override
public ResourceType getType() {
return ResourceType.DecisionTree;
}
@Override
public boolean support(Element root) {
return decisionTreeDeserializer.support(root);
}
public void setDecisionTreeDeserializer(
DecisionTreeDeserializer decisionTreeDeserializer) {
this.decisionTreeDeserializer = decisionTreeDeserializer;
}
}
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.RuleException;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class FileResourceProvider implements ResourceProvider,ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public Resource provide(String path,String version) {
try {
InputStream inputStream=applicationContext.getResource(path).getInputStream();
String content=IOUtils.toString(inputStream,"utf-8");
IOUtils.closeQuietly(inputStream);
return new Resource(content,path);
} catch (IOException e) {
throw new RuleException(e);
}
}
public boolean support(String path) {
return path.startsWith("classpath:") || path.startsWith("file:") || path.startsWith("WEB-INF/");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
}
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.flow.FlowDefinition;
import com.itheima.sfbx.framework.rule.parse.deserializer.FlowDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class FlowResourceBuilder implements ResourceBuilder<FlowDefinition> {
private FlowDeserializer flowDeserializer;
public FlowDefinition build(Element root) {
return flowDeserializer.deserialize(root);
}
public ResourceType getType() {
return ResourceType.Flow;
}
public boolean support(Element root) {
return flowDeserializer.support(root);
}
public void setFlowDeserializer(FlowDeserializer flowDeserializer) {
this.flowDeserializer = flowDeserializer;
}
}
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.library.variable.CategoryType;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableCategory;
import com.itheima.sfbx.framework.rule.parse.deserializer.ParameterLibraryDeserializer;
import org.dom4j.Element;
import java.util.HashMap;
/**
* @author Jacky.gao
* @since 2015年3月11日
*/
public class ParameterLibraryResourceBuilder implements ResourceBuilder<VariableCategory> {
private ParameterLibraryDeserializer parameterLibraryDeserializer;
@Override
public VariableCategory build(Element root) {
VariableCategory category=new VariableCategory();
category.setName(VariableCategory.PARAM_CATEGORY);
category.setClazz(HashMap.class.getName());
category.setType(CategoryType.Clazz);
category.setVariables(parameterLibraryDeserializer.deserialize(root));
return category;
}
@Override
public ResourceType getType() {
return ResourceType.ParameterLibrary;
}
@Override
public boolean support(Element root) {
return parameterLibraryDeserializer.support(root);
}
public void setParameterLibraryDeserializer(
ParameterLibraryDeserializer parameterLibraryDeserializer) {
this.parameterLibraryDeserializer = parameterLibraryDeserializer;
}
}
@@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class Resource {
private String path;
private String content;
public Resource(String content,String path) {
this.content = content;
this.path=path;
}
public String getPath() {
return path;
}
public String getContent() {
return content;
}
}
@@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public interface ResourceBuilder<T>{
T build(Element root);
boolean support(Element root);
ResourceType getType();
}
@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public interface ResourceProvider {
Resource provide(String path,String version);
boolean support(String path);
}
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public enum ResourceType {
RuleSet,DecisionTable,ScriptDecisionTable,CrossDecisionTable,Flow,VariableLibrary,ActionLibrary,ConstantLibrary,ParameterLibrary,DecisionTree,Scorecard;
}
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class RuleResource extends Resource {
public RuleResource(String content,String path) {
super(content,path);
}
}
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.rule.RuleSet;
import com.itheima.sfbx.framework.rule.parse.deserializer.RuleSetDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class RuleSetResourceBuilder implements ResourceBuilder<RuleSet> {
private RuleSetDeserializer ruleSetDeserializer;
public RuleSet build(Element root) {
return ruleSetDeserializer.deserialize(root);
}
public boolean support(Element root) {
return ruleSetDeserializer.support(root);
}
public ResourceType getType() {
return ResourceType.RuleSet;
}
public void setRuleSetDeserializer(RuleSetDeserializer ruleSetDeserializer) {
this.ruleSetDeserializer = ruleSetDeserializer;
}
}
@@ -0,0 +1,186 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.Action;
import com.itheima.sfbx.framework.rule.action.ScoringAction;
import com.itheima.sfbx.framework.rule.builder.KnowledgeBase;
import com.itheima.sfbx.framework.rule.builder.ResourceLibraryBuilder;
import com.itheima.sfbx.framework.rule.builder.RulesRebuilder;
import com.itheima.sfbx.framework.rule.model.library.ResourceLibrary;
import com.itheima.sfbx.framework.rule.model.rete.Rete;
import com.itheima.sfbx.framework.rule.model.rete.builder.ReteBuilder;
import com.itheima.sfbx.framework.rule.model.rule.Rhs;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.lhs.*;
import com.itheima.sfbx.framework.rule.model.scorecard.*;
import com.itheima.sfbx.framework.rule.model.scorecard.runtime.ScoreRule;
import com.itheima.sfbx.framework.rule.model.scorecard.runtime.ScoreRuntimeValue;
import com.itheima.sfbx.framework.rule.model.table.Condition;
import com.itheima.sfbx.framework.rule.parse.deserializer.ScorecardDeserializer;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import org.dom4j.Element;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年9月26日
*/
public class ScorecardResourceBuilder implements ResourceBuilder<ScoreRule> {
private ReteBuilder reteBuilder;
private ResourceLibraryBuilder resourceLibraryBuilder;
private ScorecardDeserializer scorecardDeserializer;
private RulesRebuilder rulesRebuilder;
@Override
public ScoreRule build(Element root) {
ScorecardDefinition scorecard = scorecardDeserializer.deserialize(root);
ScoreRule scoreRule=new ScoreRule();
scoreRule.setName(scorecard.getName());
scoreRule.setEffectiveDate(scorecard.getEffectiveDate());
scoreRule.setExpiresDate(scorecard.getExpiresDate());
scoreRule.setEnabled(scorecard.getEnabled());
scoreRule.setSalience(scorecard.getSalience());
scoreRule.setDebug(scorecard.getDebug());
scoreRule.setScoringBean(scorecard.getScoringBean());
scoreRule.setScoringType(scorecard.getScoringType());
scoreRule.setAssignTargetType(scorecard.getAssignTargetType());
scoreRule.setDatatype(scorecard.getDatatype());
scoreRule.setVariableCategory(scorecard.getVariableCategory());
scoreRule.setVariableName(scorecard.getVariableName());
scoreRule.setVariableLabel(scorecard.getVariableLabel());
scoreRule.setLibraries(scorecard.getLibraries());
List<AttributeRow> rows=scorecard.getRows();
List<CardCell> cells=scorecard.getCells();
List<CustomCol> customCols=scorecard.getCustomCols();
String attributeVariableCategory=scorecard.getAttributeColVariableCategory();
List<Rule> rules=new ArrayList<Rule>();
for(AttributeRow row:rows){
List<ConditionRow> conditionRows=row.getConditionRows();
int attributeRowNumber=row.getRowNumber();
Rule rule = buildRule(cells, customCols,attributeVariableCategory, attributeRowNumber,attributeRowNumber);
rules.add(rule);
rule.setDebug(scorecard.getDebug());
for(ConditionRow conditionRow:conditionRows){
int conditionRowNumber=conditionRow.getRowNumber();
Rule r = buildRule(cells,customCols,attributeVariableCategory,attributeRowNumber,conditionRowNumber);
r.setDebug(scorecard.getDebug());
rules.add(r);
}
}
rulesRebuilder.rebuildRules(scorecard.getLibraries(), rules);
ResourceLibrary resourceLibrary=resourceLibraryBuilder.buildResourceLibrary(scorecard.getLibraries());
Rete rete=reteBuilder.buildRete(rules, resourceLibrary);
KnowledgeBase base=new KnowledgeBase(rete);
KnowledgePackageWrapper knowledgePackageWrapper=new KnowledgePackageWrapper(base.getKnowledgePackage());
scoreRule.setKnowledgePackageWrapper(knowledgePackageWrapper);
return scoreRule;
}
private Rule buildRule(List<CardCell> cells, List<CustomCol> customCols,String attributeVariableCategory, int attributeRowNumber,int rowNumber) {
Rule scoreRule=buildScoreRule(cells, attributeVariableCategory,attributeRowNumber,rowNumber);
scoreRule.getRhs().getActions().addAll(buildCustomColActions(cells, customCols, attributeRowNumber));
return scoreRule;
}
private List<Action> buildCustomColActions(List<CardCell> cells,List<CustomCol> customCols,int rowNumber){
List<Action> actions=new ArrayList<Action>();
for(CustomCol col:customCols){
ScoringAction action=new ScoringAction(rowNumber,col.getName(),null);
CardCell cardCell=fetchCell(cells, rowNumber, col.getColNumber());
action.setValue(cardCell.getValue());
actions.add(action);
}
return actions;
}
private Rule buildScoreRule(List<CardCell> cells,String attributeVariableCategory,int attributeRowNumber,int rowNumber) {
CardCell attributeCell=fetchCell(cells, attributeRowNumber, 1);
CardCell conditionCell=fetchCell(cells, rowNumber, 2);
CardCell scoreCell=fetchCell(cells, rowNumber, 3);
Rule rule = buildRule(attributeVariableCategory,attributeCell,conditionCell,scoreCell);
rule.setName("sc"+rowNumber);
return rule;
}
private Rule buildRule(String variableCategory,CardCell attributeCell,CardCell conditionCell,CardCell scoreCell){
Rule rule=new Rule();
Lhs lhs=new Lhs();
rule.setLhs(lhs);
Junction jun=conditionCell.getJoint().getJunction();
lhs.setCriterion(jun);
for(Condition condition:conditionCell.getJoint().getConditions()){
Criteria criteria=new Criteria();
criteria.setOp(condition.getOp());
Left left=new Left();
VariableLeftPart leftPart=new VariableLeftPart();
leftPart.setVariableCategory(variableCategory);
leftPart.setDatatype(attributeCell.getDatatype());
leftPart.setVariableName(attributeCell.getVariableName());
leftPart.setVariableLabel(attributeCell.getVariableLabel());
left.setLeftPart(leftPart);
criteria.setLeft(left);
left.setType(LeftType.variable);
criteria.setValue(condition.getValue());
jun.addCriterion(criteria);
}
Rhs rhs=new Rhs();
rule.setRhs(rhs);
ScoringAction action=new ScoringAction(attributeCell.getRow(),ScoreRuntimeValue.SCORE_VALUE,attributeCell.getWeight());
action.setValue(scoreCell.getValue());
rhs.addAction(action);
return rule;
}
private CardCell fetchCell(List<CardCell> cells,int row,int col){
for(CardCell cell:cells){
if(cell.getRow()==row && cell.getCol()==col){
return cell;
}
}
throw new RuleException("CardCell ["+row+","+col+"] not exist.");
}
@Override
public ResourceType getType() {
return ResourceType.Scorecard;
}
@Override
public boolean support(Element root) {
return scorecardDeserializer.support(root);
}
public void setScorecardDeserializer(ScorecardDeserializer scorecardDeserializer) {
this.scorecardDeserializer = scorecardDeserializer;
}
public void setResourceLibraryBuilder(ResourceLibraryBuilder resourceLibraryBuilder) {
this.resourceLibraryBuilder = resourceLibraryBuilder;
}
public void setReteBuilder(ReteBuilder reteBuilder) {
this.reteBuilder = reteBuilder;
}
public void setRulesRebuilder(RulesRebuilder rulesRebuilder) {
this.rulesRebuilder = rulesRebuilder;
}
}
@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.table.ScriptDecisionTable;
import com.itheima.sfbx.framework.rule.parse.deserializer.ScriptDecisionTableDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2015年2月9日
*/
public class ScriptDecisionTableResourceBuilder implements ResourceBuilder<ScriptDecisionTable> {
private ScriptDecisionTableDeserializer scriptDecisionTableDeserializer;
public ScriptDecisionTable build(Element root) {
return scriptDecisionTableDeserializer.deserialize(root);
}
public ResourceType getType() {
return ResourceType.ScriptDecisionTable;
}
public boolean support(Element root) {
return scriptDecisionTableDeserializer.support(root);
}
public void setScriptDecisionTableDeserializer(
ScriptDecisionTableDeserializer scriptDecisionTableDeserializer) {
this.scriptDecisionTableDeserializer = scriptDecisionTableDeserializer;
}
}
@@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class VariableLibraryResource extends Resource {
public VariableLibraryResource(String content,String path) {
super(content,path);
}
}
@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.resource;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableLibrary;
import com.itheima.sfbx.framework.rule.parse.deserializer.VariableLibraryDeserializer;
import org.dom4j.Element;
/**
* @author Jacky.gao
* @since 2014年12月22日
*/
public class VariableLibraryResourceBuilder implements ResourceBuilder<VariableLibrary> {
private VariableLibraryDeserializer variableLibraryDeserializer;
public VariableLibrary build(Element root) {
VariableLibrary lib=new VariableLibrary();
lib.setVariableCategories(variableLibraryDeserializer.deserialize(root));
return lib;
}
public boolean support(Element root) {
return variableLibraryDeserializer.support(root);
}
public ResourceType getType() {
return ResourceType.VariableLibrary;
}
public void setVariableLibraryDeserializer(VariableLibraryDeserializer variableLibraryDeserializer) {
this.variableLibraryDeserializer = variableLibraryDeserializer;
}
}
@@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.table;
import com.itheima.sfbx.framework.rule.model.rule.lhs.*;
import com.itheima.sfbx.framework.rule.model.table.*;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年1月20日
*/
public class CellContentBuilder {
public Criterion buildCriterion(Cell cell,Column col){
Joint joint=cell.getJoint();
if(joint==null){
return null;
}
List<Condition> conditions=joint.getConditions();
List<Joint> joints=joint.getJoints();
if((conditions==null || conditions.size()==0) && (joints==null || joints.size()==0)){
return null;
}
Junction topJunction=null;
if(conditions.size()==1){
return newCriteria(col, conditions.get(0));
}else{
if(joint.getType().equals(JointType.and)){
topJunction=new And();
}else{
topJunction=new Or();
}
buildConditionsCriterion(conditions, topJunction, col);
buildJointsCriterion(joints, col, topJunction);
return topJunction;
}
}
private void buildJointsCriterion(List<Joint> joints,Column col,Junction parentJunction){
if(joints==null || joints.size()==0){
return;
}
for(Joint joint:joints){
Junction junction=joint.getJunction();
List<Condition> conditions=joint.getConditions();
buildConditionsCriterion(conditions,junction,col);
List<Joint> children=joint.getJoints();
buildJointsCriterion(children,col,junction);
parentJunction.addCriterion(junction);
}
}
private void buildConditionsCriterion(List<Condition> conditions,Junction junction,Column col){
if(conditions==null || conditions.size()==0){
return;
}
for(Condition condition:conditions){
Criteria criteria = newCriteria(col, condition);
junction.addCriterion(criteria);
}
}
private Criteria newCriteria(Column col, Condition condition) {
Criteria criteria=new Criteria();
Left left=new Left();
VariableLeftPart part=new VariableLeftPart();
part.setVariableCategory(col.getVariableCategory());
part.setVariableName(col.getVariableName());
part.setVariableLabel(col.getVariableLabel());
part.setDatatype(col.getDatatype());
left.setLeftPart(part);
left.setType(LeftType.variable);
criteria.setLeft(left);
criteria.setOp(condition.getOp());
criteria.setValue(condition.getValue());
return criteria;
}
}
@@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.table;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.dsl.CellScriptRuleParserBaseVisitor;
import com.itheima.sfbx.framework.rule.dsl.RuleParserLexer;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser;
import com.itheima.sfbx.framework.rule.dsl.ScriptDecisionTableErrorListener;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
/**
* @author Jacky.gao
* @since 2015年5月6日
*/
public class CellScriptDSLBuilder {
public String buildCriteriaScript(String script,String propertyName){
ANTLRInputStream antlrInputStream=new ANTLRInputStream(script);
RuleParserLexer lexer=new RuleParserLexer(antlrInputStream);
CommonTokenStream tokenStream=new CommonTokenStream(lexer);
RuleParserParser parser=new RuleParserParser(tokenStream);
ScriptDecisionTableErrorListener errorListener=new ScriptDecisionTableErrorListener();
parser.addErrorListener(errorListener);
CellScriptRuleParserBaseVisitor visitor=new CellScriptRuleParserBaseVisitor(propertyName);
String resultScript=visitor.visit(parser.decisionTableCellCondition());
String error=errorListener.getErrorMessage();
if(error!=null){
throw new RuleException("Script Parse error:"+error);
}
return resultScript;
}
}
@@ -0,0 +1,124 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.table;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.AbstractAction;
import com.itheima.sfbx.framework.rule.action.Action;
import com.itheima.sfbx.framework.rule.action.ConsolePrintAction;
import com.itheima.sfbx.framework.rule.action.VariableAssignAction;
import com.itheima.sfbx.framework.rule.model.rule.Rhs;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.rule.lhs.And;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Criterion;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Lhs;
import com.itheima.sfbx.framework.rule.model.table.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年1月20日
*/
public class DecisionTableRulesBuilder {
private CellContentBuilder cellContentBuilder;
public List<Rule> buildRules(DecisionTable table){
List<Rule> rules=new ArrayList<Rule>();
List<Row> rows=table.getRows();
List<Column> columns=table.getColumns();
for(Row row:rows){
Rule rule=new Rule();
rule.setDebug(table.getDebug());
rule.setSalience(table.getSalience());
rule.setExpiresDate(table.getExpiresDate());
rule.setEffectiveDate(table.getEffectiveDate());
rule.setEnabled(table.getEnabled());
rule.setName("r"+row.getNum());
Lhs lhs=new Lhs();
And and=new And();
lhs.setCriterion(and);
rule.setLhs(lhs);
Rhs rhs=new Rhs();
rule.setRhs(rhs);
rules.add(rule);
Value value=null;
for(Column col:columns){
Cell cell=getCell(table,row.getNum(),col.getNum());
ColumnType type=col.getType();
switch(type){
case Criteria:
Criterion criterion=cellContentBuilder.buildCriterion(cell,col);
if(criterion!=null){
and.addCriterion(criterion);
}
break;
case ConsolePrint:
value=cell.getValue();
if(value!=null){
ConsolePrintAction consolePrintAction=new ConsolePrintAction();
consolePrintAction.setPriority(1000-col.getNum());
consolePrintAction.setValue(value);
rhs.addAction(consolePrintAction);
}
break;
case Assignment:
value=cell.getValue();
if(value!=null){
VariableAssignAction variableAssignAction=new VariableAssignAction();
variableAssignAction.setPriority(1000-col.getNum());
variableAssignAction.setValue(value);
variableAssignAction.setDatatype(col.getDatatype());
variableAssignAction.setVariableName(col.getVariableName());
variableAssignAction.setVariableLabel(col.getVariableLabel());
variableAssignAction.setVariableCategory(col.getVariableCategory());
rhs.addAction(variableAssignAction);
}
break;
case ExecuteMethod:
Action action=cell.getAction();
if(action!=null){
AbstractAction aa=(AbstractAction)action;
aa.setPriority(1000-col.getNum());
rhs.addAction(aa);
}
break;
}
}
}
return rules;
}
private Cell getCell(DecisionTable table,int row,int column){
Map<String,Cell> cellMap=table.getCellMap();
Cell cell=null;
for(int i=row;i>-1;i--){
String key=table.buildCellKey(i,column);
if(cellMap.containsKey(key)){
cell=cellMap.get(key);
break;
}
}
if(cell==null){
throw new RuleException("Decision table cell["+row+","+column+"] not exist.");
}
return cell;
}
public void setCellContentBuilder(CellContentBuilder cellContentBuilder) {
this.cellContentBuilder = cellContentBuilder;
}
}
@@ -0,0 +1,139 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.builder.table;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.dsl.DSLRuleSetBuilder;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.LibraryType;
import com.itheima.sfbx.framework.rule.model.rule.RuleSet;
import com.itheima.sfbx.framework.rule.model.table.*;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年1月20日
*/
public class ScriptDecisionTableRulesBuilder {
private CellScriptDSLBuilder cellScriptDSLBuilder;
private DSLRuleSetBuilder dslRuleSetBuilder;
public RuleSet buildRules(ScriptDecisionTable table) throws IOException{
List<Row> rows=table.getRows();
List<Column> columns=table.getColumns();
List<Library> libraries=table.getLibraries();
StringBuffer sb = buildLibraryScript(libraries);
for(Row row:rows){
sb.append("rule \"r"+row.getNum()+"\"");
sb.append("\r\n");
sb.append("if");
sb.append("\r\n");
StringBuffer criteriasSb=new StringBuffer();
StringBuffer actionsSb=new StringBuffer();
for(Column col:columns){
ScriptCell cell=getCell(table,row.getNum(),col.getNum());
String script=cell.getScript();
if(StringUtils.isBlank(script)){
continue;
}
ColumnType type=col.getType();
switch(type){
case Criteria:
String propertyName=col.getVariableCategory()+"."+col.getVariableLabel();
String newScript=cellScriptDSLBuilder.buildCriteriaScript(script, propertyName);
if(StringUtils.isBlank(newScript)){
continue;
}
newScript=newScript.trim();
if(criteriasSb.length()>1){
criteriasSb.append(" and ");
}
if(!newScript.startsWith("(")){
newScript="("+newScript+")";
}
criteriasSb.append(newScript);
break;
case ConsolePrint:
actionsSb.append("out("+script+");\r\n");
break;
case Assignment:
propertyName=col.getVariableCategory()+"."+col.getVariableLabel();
actionsSb.append(propertyName+" = "+script+";\r\n");
break;
case ExecuteMethod:
actionsSb.append(script+";\r\n");
break;
}
}
sb.append(criteriasSb);
sb.append("\r\n");
sb.append("then");
sb.append("\r\n");
sb.append(actionsSb);
sb.append("\r\n");
sb.append("end;");
sb.append("\r\n");
}
RuleSet ruleSet=dslRuleSetBuilder.build(sb.toString());
return ruleSet;
}
private StringBuffer buildLibraryScript(List<Library> libraries) {
StringBuffer sb=new StringBuffer();
for(Library lib:libraries){
LibraryType type=lib.getType();
switch(type){
case Action:
sb.append("importActionLibrary \""+lib.getPath()+"\";\r\n");
break;
case Constant:
sb.append("importConstantLibrary \""+lib.getPath()+"\";\r\n");
break;
case Parameter:
sb.append("importParameterLibrary \""+lib.getPath()+"\";\r\n");
break;
case Variable:
sb.append("importVariableLibrary \""+lib.getPath()+"\";\r\n");
break;
}
}
return sb;
}
private ScriptCell getCell(ScriptDecisionTable table,int row,int column){
Map<String,ScriptCell> cellMap=table.getCellMap();
ScriptCell cell=null;
for(int i=row;i>-1;i--){
String key=table.buildCellKey(i,column);
if(cellMap.containsKey(key)){
cell=cellMap.get(key);
break;
}
}
if(cell==null){
throw new RuleException("Decision table cell["+row+","+column+"] not exist.");
}
return cell;
}
public void setCellScriptDSLBuilder(CellScriptDSLBuilder cellScriptDSLBuilder) {
this.cellScriptDSLBuilder = cellScriptDSLBuilder;
}
public void setDslRuleSetBuilder(DSLRuleSetBuilder dslRuleSetBuilder) {
this.dslRuleSetBuilder = dslRuleSetBuilder;
}
}
@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.debug;
import java.io.IOException;
import java.util.List;
/**
* @author Jacky.gao
* @since 2017年11月27日
*/
public interface DebugWriter {
void write(List<MessageItem> items) throws IOException;
}
@@ -0,0 +1,39 @@
package com.itheima.sfbx.framework.rule.debug;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
/**
* @author Jacky.gao
* @since 2017年11月27日
*/
public class DefaultHtmlFileDebugWriter implements DebugWriter{
private String path;
@Override
public void write(List<MessageItem> items) throws IOException{
if(StringUtils.isBlank(path)){
return;
}
StringBuilder msg=new StringBuilder();
for(MessageItem item:items){
msg.append(item.toHtml());
}
String fullPath=path+"/urule-debug.html";
StringBuilder sb=new StringBuilder();
sb.append("<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>URule调试日志信息</title><body style='font-size:12px'>");
sb.append(msg.toString());
sb.append("</body></html>");
FileOutputStream out=new FileOutputStream(new File(fullPath));
IOUtils.write(sb.toString(), out);
out.flush();
out.close();
}
public void setPath(String path) {
this.path = path;
}
}
@@ -0,0 +1,65 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.debug;
/**
* @author Jacky.gao
* @since 2017年11月27日
*/
public class MessageItem {
private String msg;
private MsgType type;
public MessageItem(String msg,MsgType type) {
this.msg=msg;
this.type=type;
}
public String toHtml(){
String color="#000";
switch(type){
case Condition:
color="#6495ED";
break;
case ConsoleOutput:
color="#000";
break;
case ExecuteBeanMethod:
color="#8A2BE2";
break;
case ExecuteFunction:
color="#008B8B";
break;
case RuleFlow:
color="#9932CC";
break;
case VarAssign:
color="#FF7F50";
break;
case ScoreCard:
color="#40E0D0";
break;
case RuleMatch:
color="#666600";
break;
}
return "<div style=\"color:"+color+";margin:2px\">"+msg+"</div>";
}
public String getMsg() {
return msg;
}
public MsgType getType() {
return type;
}
}
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.debug;
/**
* @author Jacky.gao
* @since 2017年11月27日
*/
public enum MsgType {
Condition,VarAssign,ExecuteBeanMethod,ExecuteFunction,ConsoleOutput,RuleFlow,ScoreCard,RuleMatch
}
@@ -0,0 +1,414 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import com.itheima.sfbx.framework.rule.Configure;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.Action;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.*;
import com.itheima.sfbx.framework.rule.dsl.builder.BuildUtils;
import com.itheima.sfbx.framework.rule.dsl.builder.ContextBuilder;
import com.itheima.sfbx.framework.rule.dsl.builder.NamedConditionBuilder;
import com.itheima.sfbx.framework.rule.model.rule.*;
import com.itheima.sfbx.framework.rule.model.rule.lhs.*;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopEnd;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopRule;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopStart;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopTarget;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.ParseTree;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Jacky.gao
* @since 2015年2月14日
*/
public class BuildRulesVisitor extends RuleParserBaseVisitor<Object> {
private Map<ParseTree,Junction> map=new HashMap<ParseTree,Junction>();
private Collection<ContextBuilder> builders;
private NamedConditionBuilder namedConditionBuilder=new NamedConditionBuilder();
private CommonTokenStream tokenStream;
public BuildRulesVisitor(Collection<ContextBuilder> builders,CommonTokenStream tokenStream) {
this.builders=builders;
this.tokenStream=tokenStream;
}
@Override
public RuleSet visitRuleSet(RuleSetContext ctx) {
RuleSet ruleSet=new RuleSet();
RuleSetHeaderContext ruleSetHeaderContext=ctx.ruleSetHeader();
List<ResourceContext> resourcesContext=ruleSetHeaderContext.resource();
if(resourcesContext!=null){
for(ResourceContext context:resourcesContext){
ruleSet.addLibrary(visitResource(context));
}
}
StringBuffer sb=null;
List<FunctionImportContext> functionImportContextList=ruleSetHeaderContext.functionImport();
if(functionImportContextList!=null){
sb=new StringBuffer();
for(FunctionImportContext importContext:functionImportContextList){
sb.append("import ");
sb.append(importContext.packageDef().getText());
sb.append(";");
}
}
RuleSetBodyContext ruleSetBodyContext=ctx.ruleSetBody();
List<RulesContext> rulesContextList=ruleSetBodyContext.rules();
if(rulesContextList!=null){
List<Rule> rules=new ArrayList<Rule>();
ruleSet.setRules(rules);
for(RulesContext ruleContext:rulesContextList){
RuleDefContext ruleDefContext=ruleContext.ruleDef();
if(ruleDefContext!=null){
Rule rule=visitRuleDef(ruleDefContext);
rules.add(rule);
}
LoopRuleDefContext loopRuleDefContext=ruleContext.loopRuleDef();
if(loopRuleDefContext!=null){
LoopRule rule=visitLoopRuleDef(loopRuleDefContext);
rules.add(rule);
}
}
}
return ruleSet;
}
@SuppressWarnings("unused")
private String buildFunctionBody(ExpressionBodyContext expressionBodyContext){
StringBuffer sb=new StringBuffer();
for(ParseTree node:expressionBodyContext.children){
Interval interval=node.getSourceInterval();
int index=interval.a;
List<Token> leftTokens=tokenStream.getHiddenTokensToLeft(index);
if(leftTokens!=null){
Token token=leftTokens.get(0);
String text=token.getText();
sb.append(text);
}
sb.append(node.getText());
List<Token> rightTokens=tokenStream.getHiddenTokensToRight(index);
if(rightTokens!=null){
Token token=rightTokens.get(0);
String text=token.getText();
sb.append(text);
}
}
return sb.toString();
}
@Override
public Library visitResource(ResourceContext ctx) {
return (Library)doBuilder(ctx);
}
@Override
public LoopRule visitLoopRuleDef(LoopRuleDefContext ctx) {
SimpleDateFormat sd=new SimpleDateFormat(Configure.getDateFormat());
LoopRule rule=new LoopRule();
String name=ctx.STRING().getText();
name=name.substring(1,name.length()-1);
rule.setName(name);
LoopTargetContext target=ctx.loopTarget();
ComplexValueContext valueContext=target.complexValue();
LoopTarget loopTarget=new LoopTarget();
loopTarget.setValue(BuildUtils.buildValue(valueContext));
rule.setLoopTarget(loopTarget);
LoopStartContext startContext=ctx.loopStart();
if(startContext!=null){
List<ActionContext> actionContextList=startContext.action();
if(actionContextList!=null){
LoopStart loopStart=new LoopStart();
loopStart.setActions(buildActions(actionContextList));
rule.setLoopStart(loopStart);
}
}
LoopEndContext endContext=ctx.loopEnd();
if(endContext!=null){
List<ActionContext> actionContextList=endContext.action();
if(actionContextList!=null){
LoopEnd loopEnd=new LoopEnd();
loopEnd.setActions(buildActions(actionContextList));
rule.setLoopEnd(loopEnd);
}
}
List<AttributeContext> attributesContext=ctx.attribute();
if(attributesContext!=null){
for(AttributeContext context:attributesContext){
if(context.salienceAttribute()!=null){
rule.setSalience(Integer.valueOf(context.salienceAttribute().NUMBER().getText()));
}else if(context.loopAttribute()!=null){
rule.setLoop(Boolean.valueOf(context.loopAttribute().Boolean().getText()));
}else if(context.effectiveDateAttribute()!=null){
try {
String dateValue=context.effectiveDateAttribute().STRING().getText();
dateValue=dateValue.substring(1,dateValue.length()-1);
rule.setEffectiveDate(sd.parse(dateValue));
} catch (ParseException e) {
throw new RuleException(e);
}
}else if(context.expiresDateAttribute()!=null){
try {
String dateValue=context.expiresDateAttribute().STRING().getText();
dateValue=dateValue.substring(1,dateValue.length()-1);
rule.setExpiresDate(sd.parse(dateValue));
} catch (ParseException e) {
throw new RuleException(e);
}
}else if(context.enabledAttribute()!=null){
rule.setEnabled(Boolean.valueOf(context.enabledAttribute().Boolean().getText()));
}else if(context.debugAttribute()!=null){
rule.setDebug(Boolean.valueOf(context.debugAttribute().Boolean().getText()));
}else if(context.activationGroupAttribute()!=null){
String value=context.activationGroupAttribute().STRING().getText();
value=value.substring(1,value.length()-1);
rule.setActivationGroup(value);
}else if(context.agendaGroupAttribute()!=null){
String value=context.agendaGroupAttribute().STRING().getText();
value=value.substring(1,value.length()-1);
rule.setAgendaGroup(value);
}else if(context.autoFocusAttribute()!=null){
rule.setAutoFocus(Boolean.valueOf(context.autoFocusAttribute().Boolean().getText()));
}else if(context.ruleflowGroupAttribute()!=null){
String value=context.ruleflowGroupAttribute().STRING().getText();
value=value.substring(1,value.length()-1);
rule.setRuleflowGroup(value);
}
}
}
LeftContext leftContext=ctx.left();
ParseTree parseTree=leftContext.getChild(1);
Lhs lhs=new Lhs();
rule.setLhs(lhs);
Criterion criterion = buildCriterion(parseTree);
lhs.setCriterion(criterion);
Rhs rhs=new Rhs();
rhs.setActions(visitRight(ctx.right()));
rule.setRhs(rhs);
Other other=new Other();
other.setActions(visitOther(ctx.other()));
rule.setOther(other);
return rule;
}
@Override
public Rule visitRuleDef(RuleDefContext ctx) {
SimpleDateFormat sd=new SimpleDateFormat(Configure.getDateFormat());
Rule rule=new Rule();
String name=ctx.STRING().getText();
name=name.substring(1,name.length()-1);
rule.setName(name);
List<AttributeContext> attributesContext=ctx.attribute();
if(attributesContext!=null){
for(AttributeContext context:attributesContext){
if(context.salienceAttribute()!=null){
rule.setSalience(Integer.valueOf(context.salienceAttribute().NUMBER().getText()));
}else if(context.loopAttribute()!=null){
rule.setLoop(Boolean.valueOf(context.loopAttribute().Boolean().getText()));
}else if(context.effectiveDateAttribute()!=null){
try {
String dateValue=context.effectiveDateAttribute().STRING().getText();
dateValue=dateValue.substring(1,dateValue.length()-1);
rule.setEffectiveDate(sd.parse(dateValue));
} catch (ParseException e) {
throw new RuleException(e);
}
}else if(context.expiresDateAttribute()!=null){
try {
String dateValue=context.expiresDateAttribute().STRING().getText();
dateValue=dateValue.substring(1,dateValue.length()-1);
rule.setExpiresDate(sd.parse(dateValue));
} catch (ParseException e) {
throw new RuleException(e);
}
}else if(context.enabledAttribute()!=null){
rule.setEnabled(Boolean.valueOf(context.enabledAttribute().Boolean().getText()));
}else if(context.debugAttribute()!=null){
rule.setDebug(Boolean.valueOf(context.debugAttribute().Boolean().getText()));
}else if(context.activationGroupAttribute()!=null){
String value=context.activationGroupAttribute().STRING().getText();
value=value.substring(1,value.length()-1);
rule.setActivationGroup(value);
}else if(context.agendaGroupAttribute()!=null){
String value=context.agendaGroupAttribute().STRING().getText();
value=value.substring(1,value.length()-1);
rule.setAgendaGroup(value);
}else if(context.autoFocusAttribute()!=null){
rule.setAutoFocus(Boolean.valueOf(context.autoFocusAttribute().Boolean().getText()));
}else if(context.ruleflowGroupAttribute()!=null){
String value=context.ruleflowGroupAttribute().STRING().getText();
value=value.substring(1,value.length()-1);
rule.setRuleflowGroup(value);
}
}
}
LeftContext leftContext=ctx.left();
ParseTree parseTree=leftContext.getChild(1);
Lhs lhs=new Lhs();
rule.setLhs(lhs);
Criterion criterion = buildCriterion(parseTree);
lhs.setCriterion(criterion);
Rhs rhs=new Rhs();
rhs.setActions(visitRight(ctx.right()));
rule.setRhs(rhs);
Other other=new Other();
other.setActions(visitOther(ctx.other()));
rule.setOther(other);
return rule;
}
@Override
public Criteria visitSingleCondition(SingleConditionContext ctx) {
return (Criteria)doBuilder(ctx);
}
@Override
public Criterion visitParenConditions(ParenConditionsContext ctx) {
ParseTree parseTree=ctx.getChild(1);
return buildCriterion(parseTree);
}
@Override
public Criterion visitSingleNamedConditionSet(SingleNamedConditionSetContext ctx) {
NamedCriteria criteria=new NamedCriteria();
NamedConditionSetContext conditionSet=ctx.namedConditionSet();
if(conditionSet.refName()!=null){
criteria.setReferenceName(conditionSet.refName().getText());
}
criteria.setVariableCategory(conditionSet.refObject().getText());
NamedConditionContext namedConditionContext=conditionSet.namedCondition();
CriteriaUnit unit=namedConditionBuilder.buildNamedCriteria(namedConditionContext, criteria.getVariableCategory());
criteria.setUnit(unit);
return criteria;
}
@Override
public Criterion visitMultiConditions(MultiConditionsContext ctx) {
Junction topJunction=null;
Criterion criterion=null;
Junction junction=map.get(ctx);
int childCount=ctx.getChildCount();
for(int i=0;i<childCount;i++){
ParseTree parseTree=ctx.getChild(i);
if(parseTree instanceof JoinContext){
JoinContext joinContext=(JoinContext)parseTree;
if(joinContext.AND()!=null){
if(junction==null){
junction=new And();
topJunction=junction;
junction.addCriterion(criterion);
}else if(!(junction instanceof And)){
And newAnd=new And();
junction.addCriterion(newAnd);
junction=newAnd;
}
}else{
if(junction==null){
junction=new Or();
topJunction=junction;
junction.addCriterion(criterion);
}else if(!(junction instanceof Or)){
Or newOr=new Or();
junction.addCriterion(newOr);
junction=newOr;
}
}
}else{
boolean isMulti=false;
if(parseTree instanceof MultiConditionsContext){
isMulti=true;
}
if(junction!=null && isMulti){
map.put(parseTree, junction);
}
criterion=buildCriterion(parseTree);
if(junction!=null && !isMulti){
junction.addCriterion(criterion);
}
}
}
if(topJunction!=null){
return topJunction;
}
return criterion;
}
@Override
public List<Action> visitRight(RightContext ctx) {
if(ctx==null ||ctx.action()==null){
return null;
}
List<ActionContext> actionContexts=ctx.action();
return buildActions(actionContexts);
}
private List<Action> buildActions(List<ActionContext> actionContexts) {
List<Action> actions=new ArrayList<Action>();
for(ActionContext actionContext:actionContexts){
Action action=(Action)doBuilder(actionContext);
actions.add(action);
}
return actions;
}
@Override
public List<Action> visitOther(OtherContext ctx) {
if(ctx==null ||ctx.action()==null){
return null;
}
List<Action> actions=new ArrayList<Action>();
for(ActionContext actionContext:ctx.action()){
Action action=(Action)doBuilder(actionContext);
actions.add(action);
}
return actions;
}
private Criterion buildCriterion(ParseTree parseTree) {
Criterion criterion=null;
if(parseTree instanceof ParenConditionsContext){
criterion=visitParenConditions((ParenConditionsContext)parseTree);
}else if(parseTree instanceof SingleConditionContext){
criterion=visitSingleCondition((SingleConditionContext)parseTree);
}else if(parseTree instanceof MultiConditionsContext){
criterion=visitMultiConditions((MultiConditionsContext)parseTree);
}else if(parseTree instanceof SingleNamedConditionSetContext){
criterion=visitSingleNamedConditionSet((SingleNamedConditionSetContext)parseTree);
}
return criterion;
}
private Object doBuilder(ParserRuleContext context){
for(ContextBuilder builder:builders){
if(builder.support(context)){
return builder.build(context);
}
}
return null;
}
}
@@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.DecisionTableCellConditionContext;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.MultiCellConditionsContext;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.ParenCellConditionsContext;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.SingleCellConditionContext;
import org.antlr.v4.runtime.tree.ParseTree;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年5月6日
*/
public class CellScriptRuleParserBaseVisitor extends RuleParserBaseVisitor<String> {
private String propertyName;
public CellScriptRuleParserBaseVisitor(String propertyName) {
this.propertyName=propertyName;
}
@Override
public String visitSingleCellCondition(SingleCellConditionContext ctx) {
StringBuffer sb=new StringBuffer();
sb.append(propertyName);
sb.append(" ");
String op=ctx.op().getText();
sb.append(op);
sb.append(" ");
if(ctx.complexValue()!=null){
sb.append(ctx.complexValue().getText());
}else{
sb.append(ctx.nullValue().getText());
}
sb.append(" ");
return sb.toString();
}
@Override
public String visitMultiCellConditions(MultiCellConditionsContext ctx) {
StringBuffer sb=new StringBuffer();
List<ParseTree> children=ctx.children;
for(ParseTree child:children){
sb.append(" ");
buildChildren(sb, child);
}
return sb.toString();
}
@Override
public String visitParenCellConditions(ParenCellConditionsContext ctx) {
StringBuffer sb=new StringBuffer();
sb.append(" ");
sb.append(ctx.leftParen().getText());
DecisionTableCellConditionContext context=ctx.decisionTableCellCondition();
buildChildren(sb,context);
sb.append(ctx.rightParen().getText());
return sb.toString();
}
private void buildChildren(StringBuffer sb, ParseTree child) {
if(child instanceof SingleCellConditionContext){
SingleCellConditionContext singleCellConditionContext=(SingleCellConditionContext)child;
sb.append(visitSingleCellCondition(singleCellConditionContext));
}else if(child instanceof ParenCellConditionsContext){
ParenCellConditionsContext parenCellConditionsContext=(ParenCellConditionsContext)child;
sb.append(visitParenCellConditions(parenCellConditionsContext));
}else if(child instanceof MultiCellConditionsContext){
MultiCellConditionsContext multiCellConditionsContext=(MultiCellConditionsContext)child;
sb.append(visitMultiCellConditions(multiCellConditionsContext));
}else{
sb.append(child.getText());
}
}
}
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
/**
* @author Jacky.gao
* @since 2015年2月16日
*/
public interface Constant {
public static final String UL_SUFFIX=".ul";
public static final String XML_SUFFIX=".xml";
}
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.builder.RulesRebuilder;
import com.itheima.sfbx.framework.rule.builder.resource.Resource;
import com.itheima.sfbx.framework.rule.dsl.builder.ContextBuilder;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.RuleSet;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年2月16日
*/
public class DSLRuleSetBuilder implements ApplicationContextAware{
public static final String BEAN_ID="urule.dslRuleSetBuilder";
private Collection<ContextBuilder> contextBuilders;
private RulesRebuilder rulesRebuilder;
public RuleSet build(String script) throws IOException{
ANTLRInputStream antlrInputStream=new ANTLRInputStream(script);
RuleParserLexer lexer=new RuleParserLexer(antlrInputStream);
CommonTokenStream tokenStream=new CommonTokenStream(lexer);
RuleParserParser parser=new RuleParserParser(tokenStream);
ScriptDecisionTableErrorListener errorListener=new ScriptDecisionTableErrorListener();
parser.addErrorListener(errorListener);
BuildRulesVisitor visitor=new BuildRulesVisitor(contextBuilders,tokenStream);
RuleSet ruleSet=visitor.visitRuleSet(parser.ruleSet());
rebuildRuleSet(ruleSet);
String error=errorListener.getErrorMessage();
if(error!=null){
throw new RuleException("Script parse error:"+error);
}
return ruleSet;
}
private void rebuildRuleSet(RuleSet ruleSet){
List<Library> libraries=ruleSet.getLibraries();
List<Rule> rules=ruleSet.getRules();
rulesRebuilder.rebuildRulesForDSL(libraries, rules);
}
public void setRulesRebuilder(RulesRebuilder rulesRebuilder) {
this.rulesRebuilder = rulesRebuilder;
}
public boolean support(Resource resource){
String path=resource.getPath();
return path.toLowerCase().endsWith(Constant.UL_SUFFIX);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
contextBuilders=applicationContext.getBeansOfType(ContextBuilder.class).values();
}
}
@@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.OpContext;
import com.itheima.sfbx.framework.rule.model.rule.Op;
/**
* @author Jacky.gao
* @since 2015年5月6日
*/
public class DSLUtils {
public static Op parseOp(OpContext ctx){
if(ctx.GreaterThen()!=null){
return Op.GreaterThen;
}else if(ctx.GreaterThenOrEquals()!=null){
return Op.GreaterThenEquals;
}else if(ctx.LessThen()!=null){
return Op.LessThen;
}else if(ctx.LessThenOrEquals()!=null){
return Op.LessThenEquals;
}else if(ctx.Equals()!=null){
return Op.Equals;
}else if(ctx.NotEquals()!=null){
return Op.NotEquals;
}else if(ctx.EndWith()!=null){
return Op.EndWith;
}else if(ctx.NotEndWith()!=null){
return Op.NotEndWith;
}else if(ctx.StartWith()!=null){
return Op.StartWith;
}else if(ctx.NotStartWith()!=null){
return Op.NotStartWith;
}else if(ctx.In()!=null){
return Op.In;
}else if(ctx.NotIn()!=null){
return Op.NotIn;
}else if(ctx.Match()!=null){
return Op.Match;
}else if(ctx.NotMatch()!=null){
return Op.NotMatch;
}else if(ctx.EqualsIgnoreCase()!=null){
return Op.EqualsIgnoreCase;
}else if(ctx.NotEqualsIgnoreCase()!=null) {
return Op.NotEqualsIgnoreCase;
}
// }else if(ctx.Contain()!=null){
// return Op.Contain;
// }else if(ctx.NotContain()!=null){
// return Op.NotContain;
// }
throw new RuleException("Operator ["+ctx+"] is invalid.");
}
}
@@ -0,0 +1,333 @@
// Generated from RuleLexer.g4 by ANTLR 4.5.3
package com.itheima.sfbx.framework.rule.dsl;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class RuleLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
COUNT=1, AVG=2, SUM=3, MAX=4, MIN=5, AND=6, OR=7, Datatype=8, GreaterThen=9,
GreaterThenOrEquals=10, LessThen=11, LessThenOrEquals=12, Equals=13, NotEquals=14,
EndWith=15, NotEndWith=16, StartWith=17, NotStartWith=18, In=19, NotIn=20,
Match=21, NotMatch=22, Contain=23, NotContain=24, EqualsIgnoreCase=25,
NotEqualsIgnoreCase=26, ARITH=27, NUMBER=28, Boolean=29, Identifier=30,
STRING=31, WS=32, NL=33, COMMENT=34, LINE_COMMENT=35;
public static String[] modeNames = {
"DEFAULT_MODE"
};
public static final String[] ruleNames = {
"COUNT", "AVG", "SUM", "MAX", "MIN", "AND", "OR", "Datatype", "GreaterThen",
"GreaterThenOrEquals", "LessThen", "LessThenOrEquals", "Equals", "NotEquals",
"EndWith", "NotEndWith", "StartWith", "NotStartWith", "In", "NotIn", "Match",
"NotMatch", "Contain", "NotContain", "EqualsIgnoreCase", "NotEqualsIgnoreCase",
"ARITH", "NUMBER", "Boolean", "Identifier", "STRING", "STRING_CONTENT",
"INT", "EXP", "EscapeSequence", "OctalEscape", "UnicodeEscape", "Char",
"StartChar", "DIGIT", "HEX", "WS", "NL", "COMMENT", "LINE_COMMENT"
};
private static final String[] _LITERAL_NAMES = {
null, "'count'", "'avg'", "'sum'", "'max'", "'min'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, "COUNT", "AVG", "SUM", "MAX", "MIN", "AND", "OR", "Datatype", "GreaterThen",
"GreaterThenOrEquals", "LessThen", "LessThenOrEquals", "Equals", "NotEquals",
"EndWith", "NotEndWith", "StartWith", "NotStartWith", "In", "NotIn", "Match",
"NotMatch", "Contain", "NotContain", "EqualsIgnoreCase", "NotEqualsIgnoreCase",
"ARITH", "NUMBER", "Boolean", "Identifier", "STRING", "WS", "NL", "COMMENT",
"LINE_COMMENT"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public RuleLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "RuleLexer.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2%\u0254\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
",\t,\4-\t-\4.\t.\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3"+
"\4\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7"+
"\5\7}\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\5\b\u0086\n\b\3\t\3\t\3\t\3\t\3"+
"\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t"+
"\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"+
"\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t"+
"\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3"+
"\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t"+
"\3\t\3\t\5\t\u00e6\n\t\3\n\3\n\3\n\5\n\u00eb\n\n\3\13\3\13\3\13\3\13\3"+
"\13\3\13\5\13\u00f3\n\13\3\f\3\f\3\f\5\f\u00f8\n\f\3\r\3\r\3\r\3\r\3\r"+
"\3\r\5\r\u0100\n\r\3\16\3\16\3\16\3\16\5\16\u0106\n\16\3\17\3\17\3\17"+
"\3\17\3\17\5\17\u010d\n\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+
"\3\20\5\20\u0119\n\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+
"\3\21\3\21\3\21\3\21\5\21\u0129\n\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22"+
"\3\22\3\22\3\22\3\22\3\22\5\22\u0137\n\22\3\23\3\23\3\23\3\23\3\23\3\23"+
"\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u0149\n\23\3\24"+
"\3\24\3\24\3\24\3\24\3\24\5\24\u0151\n\24\3\25\3\25\3\25\3\25\3\25\3\25"+
"\3\25\3\25\3\25\3\25\5\25\u015d\n\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26"+
"\5\26\u0166\n\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+
"\5\27\u0173\n\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u017e"+
"\n\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+
"\5\31\u018d\n\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32"+
"\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\5\32\u01a6"+
"\n\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+
"\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+
"\5\33\u01c3\n\33\3\34\3\34\3\35\5\35\u01c8\n\35\3\35\3\35\3\35\3\35\5"+
"\35\u01ce\n\35\3\35\5\35\u01d1\n\35\3\35\3\35\3\35\3\35\5\35\u01d7\n\35"+
"\3\35\5\35\u01da\n\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\5\36"+
"\u01e5\n\36\3\37\3\37\7\37\u01e9\n\37\f\37\16\37\u01ec\13\37\3 \3 \3 "+
"\3 \3!\3!\7!\u01f4\n!\f!\16!\u01f7\13!\3\"\6\"\u01fa\n\"\r\"\16\"\u01fb"+
"\3#\3#\5#\u0200\n#\3#\3#\3$\3$\3$\3$\5$\u0208\n$\3%\3%\3%\3%\3%\3%\3%"+
"\3%\3%\5%\u0213\n%\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\5\'\u0220\n\'"+
"\3(\5(\u0223\n(\3)\3)\3*\3*\3+\6+\u022a\n+\r+\16+\u022b\3+\3+\3,\5,\u0231"+
"\n,\3,\3,\3,\3,\3-\3-\3-\3-\7-\u023b\n-\f-\16-\u023e\13-\3-\3-\3-\3-\3"+
"-\3.\3.\3.\3.\7.\u0249\n.\f.\16.\u024c\13.\3.\5.\u024f\n.\3.\3.\3.\3."+
"\3\u023c\2/\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"+
"\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"+
"\359\36;\37= ?!A\2C\2E\2G\2I\2K\2M\2O\2Q\2S\2U\"W#Y$[%\3\2\16\6\2\'\'"+
",-//\61\61\3\2$$\4\2GGgg\4\2--//\n\2$$))^^ddhhppttvv\4\2//aa\5\2\u00b9"+
"\u00b9\u0302\u0371\u2041\u2042\t\2C\\c|\u2072\u2191\u2c02\u2ff1\u3003"+
"\ud801\uf902\ufdd1\ufdf2\uffff\3\2\62;\5\2\62;CHch\5\2\13\f\17\17\"\""+
"\4\2\f\f\17\17\u028b\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2"+
"\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3"+
"\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2"+
"\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2"+
"\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2"+
"\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2"+
"\2Y\3\2\2\2\2[\3\2\2\2\3]\3\2\2\2\5c\3\2\2\2\7g\3\2\2\2\tk\3\2\2\2\13"+
"o\3\2\2\2\r|\3\2\2\2\17\u0085\3\2\2\2\21\u00e5\3\2\2\2\23\u00ea\3\2\2"+
"\2\25\u00f2\3\2\2\2\27\u00f7\3\2\2\2\31\u00ff\3\2\2\2\33\u0105\3\2\2\2"+
"\35\u010c\3\2\2\2\37\u0118\3\2\2\2!\u0128\3\2\2\2#\u0136\3\2\2\2%\u0148"+
"\3\2\2\2\'\u0150\3\2\2\2)\u015c\3\2\2\2+\u0165\3\2\2\2-\u0172\3\2\2\2"+
"/\u017d\3\2\2\2\61\u018c\3\2\2\2\63\u01a5\3\2\2\2\65\u01c2\3\2\2\2\67"+
"\u01c4\3\2\2\29\u01d9\3\2\2\2;\u01e4\3\2\2\2=\u01e6\3\2\2\2?\u01ed\3\2"+
"\2\2A\u01f5\3\2\2\2C\u01f9\3\2\2\2E\u01fd\3\2\2\2G\u0207\3\2\2\2I\u0212"+
"\3\2\2\2K\u0214\3\2\2\2M\u021f\3\2\2\2O\u0222\3\2\2\2Q\u0224\3\2\2\2S"+
"\u0226\3\2\2\2U\u0229\3\2\2\2W\u0230\3\2\2\2Y\u0236\3\2\2\2[\u0244\3\2"+
"\2\2]^\7e\2\2^_\7q\2\2_`\7w\2\2`a\7p\2\2ab\7v\2\2b\4\3\2\2\2cd\7c\2\2"+
"de\7x\2\2ef\7i\2\2f\6\3\2\2\2gh\7u\2\2hi\7w\2\2ij\7o\2\2j\b\3\2\2\2kl"+
"\7o\2\2lm\7c\2\2mn\7z\2\2n\n\3\2\2\2op\7o\2\2pq\7k\2\2qr\7p\2\2r\f\3\2"+
"\2\2st\7c\2\2tu\7p\2\2u}\7f\2\2vw\7(\2\2w}\7(\2\2x}\7.\2\2yz\7\u5e78\2"+
"\2z}\7\u4e16\2\2{}\7\u4e16\2\2|s\3\2\2\2|v\3\2\2\2|x\3\2\2\2|y\3\2\2\2"+
"|{\3\2\2\2}\16\3\2\2\2~\177\7q\2\2\177\u0086\7t\2\2\u0080\u0081\7~\2\2"+
"\u0081\u0086\7~\2\2\u0082\u0083\7\u6218\2\2\u0083\u0086\7\u8007\2\2\u0084"+
"\u0086\7\u6218\2\2\u0085~\3\2\2\2\u0085\u0080\3\2\2\2\u0085\u0082\3\2"+
"\2\2\u0085\u0084\3\2\2\2\u0086\20\3\2\2\2\u0087\u0088\7U\2\2\u0088\u0089"+
"\7v\2\2\u0089\u008a\7t\2\2\u008a\u008b\7k\2\2\u008b\u008c\7p\2\2\u008c"+
"\u00e6\7i\2\2\u008d\u008e\7k\2\2\u008e\u008f\7p\2\2\u008f\u00e6\7v\2\2"+
"\u0090\u0091\7K\2\2\u0091\u0092\7p\2\2\u0092\u0093\7v\2\2\u0093\u0094"+
"\7g\2\2\u0094\u0095\7i\2\2\u0095\u0096\7g\2\2\u0096\u00e6\7t\2\2\u0097"+
"\u0098\7f\2\2\u0098\u0099\7q\2\2\u0099\u009a\7w\2\2\u009a\u009b\7d\2\2"+
"\u009b\u009c\7n\2\2\u009c\u00e6\7g\2\2\u009d\u009e\7F\2\2\u009e\u009f"+
"\7q\2\2\u009f\u00a0\7w\2\2\u00a0\u00a1\7d\2\2\u00a1\u00a2\7n\2\2\u00a2"+
"\u00e6\7g\2\2\u00a3\u00a4\7n\2\2\u00a4\u00a5\7q\2\2\u00a5\u00a6\7p\2\2"+
"\u00a6\u00e6\7i\2\2\u00a7\u00a8\7N\2\2\u00a8\u00a9\7q\2\2\u00a9\u00aa"+
"\7p\2\2\u00aa\u00e6\7i\2\2\u00ab\u00ac\7h\2\2\u00ac\u00ad\7n\2\2\u00ad"+
"\u00ae\7q\2\2\u00ae\u00af\7c\2\2\u00af\u00e6\7v\2\2\u00b0\u00b1\7H\2\2"+
"\u00b1\u00b2\7n\2\2\u00b2\u00b3\7q\2\2\u00b3\u00b4\7c\2\2\u00b4\u00e6"+
"\7v\2\2\u00b5\u00b6\7D\2\2\u00b6\u00b7\7k\2\2\u00b7\u00b8\7i\2\2\u00b8"+
"\u00b9\7F\2\2\u00b9\u00ba\7g\2\2\u00ba\u00bb\7e\2\2\u00bb\u00bc\7k\2\2"+
"\u00bc\u00bd\7o\2\2\u00bd\u00be\7c\2\2\u00be\u00e6\7n\2\2\u00bf\u00c0"+
"\7d\2\2\u00c0\u00c1\7q\2\2\u00c1\u00c2\7q\2\2\u00c2\u00c3\7n\2\2\u00c3"+
"\u00c4\7g\2\2\u00c4\u00c5\7c\2\2\u00c5\u00e6\7p\2\2\u00c6\u00c7\7D\2\2"+
"\u00c7\u00c8\7q\2\2\u00c8\u00c9\7q\2\2\u00c9\u00ca\7n\2\2\u00ca\u00cb"+
"\7g\2\2\u00cb\u00cc\7c\2\2\u00cc\u00e6\7p\2\2\u00cd\u00ce\7F\2\2\u00ce"+
"\u00cf\7c\2\2\u00cf\u00d0\7v\2\2\u00d0\u00e6\7g\2\2\u00d1\u00d2\7N\2\2"+
"\u00d2\u00d3\7k\2\2\u00d3\u00d4\7u\2\2\u00d4\u00e6\7v\2\2\u00d5\u00d6"+
"\7U\2\2\u00d6\u00d7\7g\2\2\u00d7\u00e6\7v\2\2\u00d8\u00d9\7O\2\2\u00d9"+
"\u00da\7c\2\2\u00da\u00e6\7r\2\2\u00db\u00dc\7G\2\2\u00dc\u00dd\7p\2\2"+
"\u00dd\u00de\7w\2\2\u00de\u00e6\7o\2\2\u00df\u00e0\7Q\2\2\u00e0\u00e1"+
"\7d\2\2\u00e1\u00e2\7l\2\2\u00e2\u00e3\7g\2\2\u00e3\u00e4\7e\2\2\u00e4"+
"\u00e6\7v\2\2\u00e5\u0087\3\2\2\2\u00e5\u008d\3\2\2\2\u00e5\u0090\3\2"+
"\2\2\u00e5\u0097\3\2\2\2\u00e5\u009d\3\2\2\2\u00e5\u00a3\3\2\2\2\u00e5"+
"\u00a7\3\2\2\2\u00e5\u00ab\3\2\2\2\u00e5\u00b0\3\2\2\2\u00e5\u00b5\3\2"+
"\2\2\u00e5\u00bf\3\2\2\2\u00e5\u00c6\3\2\2\2\u00e5\u00cd\3\2\2\2\u00e5"+
"\u00d1\3\2\2\2\u00e5\u00d5\3\2\2\2\u00e5\u00d8\3\2\2\2\u00e5\u00db\3\2"+
"\2\2\u00e5\u00df\3\2\2\2\u00e6\22\3\2\2\2\u00e7\u00eb\7@\2\2\u00e8\u00e9"+
"\7\u5929\2\2\u00e9\u00eb\7\u4e90\2\2\u00ea\u00e7\3\2\2\2\u00ea\u00e8\3"+
"\2\2\2\u00eb\24\3\2\2\2\u00ec\u00ed\7@\2\2\u00ed\u00f3\7?\2\2\u00ee\u00ef"+
"\7\u5929\2\2\u00ef\u00f0\7\u4e90\2\2\u00f0\u00f1\7\u7b4b\2\2\u00f1\u00f3"+
"\7\u4e90\2\2\u00f2\u00ec\3\2\2\2\u00f2\u00ee\3\2\2\2\u00f3\26\3\2\2\2"+
"\u00f4\u00f8\7>\2\2\u00f5\u00f6\7\u5c11\2\2\u00f6\u00f8\7\u4e90\2\2\u00f7"+
"\u00f4\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f8\30\3\2\2\2\u00f9\u00fa\7>\2\2"+
"\u00fa\u0100\7?\2\2\u00fb\u00fc\7\u5c11\2\2\u00fc\u00fd\7\u4e90\2\2\u00fd"+
"\u00fe\7\u7b4b\2\2\u00fe\u0100\7\u4e90\2\2\u00ff\u00f9\3\2\2\2\u00ff\u00fb"+
"\3\2\2\2\u0100\32\3\2\2\2\u0101\u0102\7?\2\2\u0102\u0106\7?\2\2\u0103"+
"\u0104\7\u7b4b\2\2\u0104\u0106\7\u4e90\2\2\u0105\u0101\3\2\2\2\u0105\u0103"+
"\3\2\2\2\u0106\34\3\2\2\2\u0107\u0108\7#\2\2\u0108\u010d\7?\2\2\u0109"+
"\u010a\7\u4e0f\2\2\u010a\u010b\7\u7b4b\2\2\u010b\u010d\7\u4e90\2\2\u010c"+
"\u0107\3\2\2\2\u010c\u0109\3\2\2\2\u010d\36\3\2\2\2\u010e\u010f\7G\2\2"+
"\u010f\u0110\7p\2\2\u0110\u0111\7f\2\2\u0111\u0112\7Y\2\2\u0112\u0113"+
"\7k\2\2\u0113\u0114\7v\2\2\u0114\u0119\7j\2\2\u0115\u0116\7\u7ed5\2\2"+
"\u0116\u0117\7\u6761\2\2\u0117\u0119\7\u4e90\2\2\u0118\u010e\3\2\2\2\u0118"+
"\u0115\3\2\2\2\u0119 \3\2\2\2\u011a\u011b\7P\2\2\u011b\u011c\7q\2\2\u011c"+
"\u011d\7v\2\2\u011d\u011e\7G\2\2\u011e\u011f\7p\2\2\u011f\u0120\7f\2\2"+
"\u0120\u0121\7Y\2\2\u0121\u0122\7k\2\2\u0122\u0123\7v\2\2\u0123\u0129"+
"\7j\2\2\u0124\u0125\7\u4e0f\2\2\u0125\u0126\7\u7ed5\2\2\u0126\u0127\7"+
"\u6761\2\2\u0127\u0129\7\u4e90\2\2\u0128\u011a\3\2\2\2\u0128\u0124\3\2"+
"\2\2\u0129\"\3\2\2\2\u012a\u012b\7U\2\2\u012b\u012c\7v\2\2\u012c\u012d"+
"\7c\2\2\u012d\u012e\7t\2\2\u012e\u012f\7v\2\2\u012f\u0130\7Y\2\2\u0130"+
"\u0131\7k\2\2\u0131\u0132\7v\2\2\u0132\u0137\7j\2\2\u0133\u0134\7\u5f02"+
"\2\2\u0134\u0135\7\u59cd\2\2\u0135\u0137\7\u4e90\2\2\u0136\u012a\3\2\2"+
"\2\u0136\u0133\3\2\2\2\u0137$\3\2\2\2\u0138\u0139\7P\2\2\u0139\u013a\7"+
"q\2\2\u013a\u013b\7v\2\2\u013b\u013c\7U\2\2\u013c\u013d\7v\2\2\u013d\u013e"+
"\7c\2\2\u013e\u013f\7t\2\2\u013f\u0140\7v\2\2\u0140\u0141\7Y\2\2\u0141"+
"\u0142\7k\2\2\u0142\u0143\7v\2\2\u0143\u0149\7j\2\2\u0144\u0145\7\u4e0f"+
"\2\2\u0145\u0146\7\u5f02\2\2\u0146\u0147\7\u59cd\2\2\u0147\u0149\7\u4e90"+
"\2\2\u0148\u0138\3\2\2\2\u0148\u0144\3\2\2\2\u0149&\3\2\2\2\u014a\u014b"+
"\7K\2\2\u014b\u0151\7p\2\2\u014c\u014d\7\u572a\2\2\u014d\u014e\7\u96c8"+
"\2\2\u014e\u014f\7\u540a\2\2\u014f\u0151\7\u4e2f\2\2\u0150\u014a\3\2\2"+
"\2\u0150\u014c\3\2\2\2\u0151(\3\2\2\2\u0152\u0153\7P\2\2\u0153\u0154\7"+
"q\2\2\u0154\u0155\7v\2\2\u0155\u0156\7K\2\2\u0156\u015d\7p\2\2\u0157\u0158"+
"\7\u4e0f\2\2\u0158\u0159\7\u572a\2\2\u0159\u015a\7\u96c8\2\2\u015a\u015b"+
"\7\u540a\2\2\u015b\u015d\7\u4e2f\2\2\u015c\u0152\3\2\2\2\u015c\u0157\3"+
"\2\2\2\u015d*\3\2\2\2\u015e\u015f\7O\2\2\u015f\u0160\7c\2\2\u0160\u0161"+
"\7v\2\2\u0161\u0162\7e\2\2\u0162\u0166\7j\2\2\u0163\u0164\7\u533b\2\2"+
"\u0164\u0166\7\u914f\2\2\u0165\u015e\3\2\2\2\u0165\u0163\3\2\2\2\u0166"+
",\3\2\2\2\u0167\u0168\7P\2\2\u0168\u0169\7q\2\2\u0169\u016a\7v\2\2\u016a"+
"\u016b\7O\2\2\u016b\u016c\7c\2\2\u016c\u016d\7v\2\2\u016d\u016e\7e\2\2"+
"\u016e\u0173\7j\2\2\u016f\u0170\7\u4e0f\2\2\u0170\u0171\7\u533b\2\2\u0171"+
"\u0173\7\u914f\2\2\u0172\u0167\3\2\2\2\u0172\u016f\3\2\2\2\u0173.\3\2"+
"\2\2\u0174\u0175\7E\2\2\u0175\u0176\7q\2\2\u0176\u0177\7p\2\2\u0177\u0178"+
"\7v\2\2\u0178\u0179\7c\2\2\u0179\u017a\7k\2\2\u017a\u017e\7p\2\2\u017b"+
"\u017c\7\u5307\2\2\u017c\u017e\7\u542d\2\2\u017d\u0174\3\2\2\2\u017d\u017b"+
"\3\2\2\2\u017e\60\3\2\2\2\u017f\u0180\7P\2\2\u0180\u0181\7q\2\2\u0181"+
"\u0182\7v\2\2\u0182\u0183\7E\2\2\u0183\u0184\7q\2\2\u0184\u0185\7p\2\2"+
"\u0185\u0186\7v\2\2\u0186\u0187\7c\2\2\u0187\u0188\7k\2\2\u0188\u018d"+
"\7p\2\2\u0189\u018a\7\u4e0f\2\2\u018a\u018b\7\u5307\2\2\u018b\u018d\7"+
"\u542d\2\2\u018c\u017f\3\2\2\2\u018c\u0189\3\2\2\2\u018d\62\3\2\2\2\u018e"+
"\u018f\7G\2\2\u018f\u0190\7s\2\2\u0190\u0191\7w\2\2\u0191\u0192\7c\2\2"+
"\u0192\u0193\7n\2\2\u0193\u0194\7u\2\2\u0194\u0195\7K\2\2\u0195\u0196"+
"\7i\2\2\u0196\u0197\7p\2\2\u0197\u0198\7q\2\2\u0198\u0199\7t\2\2\u0199"+
"\u019a\7g\2\2\u019a\u019b\7E\2\2\u019b\u019c\7c\2\2\u019c\u019d\7u\2\2"+
"\u019d\u01a6\7g\2\2\u019e\u019f\7\u5fff\2\2\u019f\u01a0\7\u7567\2\2\u01a0"+
"\u01a1\7\u5929\2\2\u01a1\u01a2\7\u5c11\2\2\u01a2\u01a3\7\u519b\2\2\u01a3"+
"\u01a4\7\u7b4b\2\2\u01a4\u01a6\7\u4e90\2\2\u01a5\u018e\3\2\2\2\u01a5\u019e"+
"\3\2\2\2\u01a6\64\3\2\2\2\u01a7\u01a8\7P\2\2\u01a8\u01a9\7q\2\2\u01a9"+
"\u01aa\7v\2\2\u01aa\u01ab\7G\2\2\u01ab\u01ac\7s\2\2\u01ac\u01ad\7w\2\2"+
"\u01ad\u01ae\7c\2\2\u01ae\u01af\7n\2\2\u01af\u01b0\7u\2\2\u01b0\u01b1"+
"\7K\2\2\u01b1\u01b2\7i\2\2\u01b2\u01b3\7p\2\2\u01b3\u01b4\7q\2\2\u01b4"+
"\u01b5\7t\2\2\u01b5\u01b6\7g\2\2\u01b6\u01b7\7E\2\2\u01b7\u01b8\7c\2\2"+
"\u01b8\u01b9\7u\2\2\u01b9\u01c3\7g\2\2\u01ba\u01bb\7\u5fff\2\2\u01bb\u01bc"+
"\7\u7567\2\2\u01bc\u01bd\7\u5929\2\2\u01bd\u01be\7\u5c11\2\2\u01be\u01bf"+
"\7\u519b\2\2\u01bf\u01c0\7\u4e0f\2\2\u01c0\u01c1\7\u7b4b\2\2\u01c1\u01c3"+
"\7\u4e90\2\2\u01c2\u01a7\3\2\2\2\u01c2\u01ba\3\2\2\2\u01c3\66\3\2\2\2"+
"\u01c4\u01c5\t\2\2\2\u01c58\3\2\2\2\u01c6\u01c8\7/\2\2\u01c7\u01c6\3\2"+
"\2\2\u01c7\u01c8\3\2\2\2\u01c8\u01c9\3\2\2\2\u01c9\u01ca\5C\"\2\u01ca"+
"\u01cb\7\60\2\2\u01cb\u01cd\5C\"\2\u01cc\u01ce\5E#\2\u01cd\u01cc\3\2\2"+
"\2\u01cd\u01ce\3\2\2\2\u01ce\u01da\3\2\2\2\u01cf\u01d1\7/\2\2\u01d0\u01cf"+
"\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1\u01d2\3\2\2\2\u01d2\u01d3\5C\"\2\u01d3"+
"\u01d4\5E#\2\u01d4\u01da\3\2\2\2\u01d5\u01d7\7/\2\2\u01d6\u01d5\3\2\2"+
"\2\u01d6\u01d7\3\2\2\2\u01d7\u01d8\3\2\2\2\u01d8\u01da\5C\"\2\u01d9\u01c7"+
"\3\2\2\2\u01d9\u01d0\3\2\2\2\u01d9\u01d6\3\2\2\2\u01da:\3\2\2\2\u01db"+
"\u01dc\7v\2\2\u01dc\u01dd\7t\2\2\u01dd\u01de\7w\2\2\u01de\u01e5\7g\2\2"+
"\u01df\u01e0\7h\2\2\u01e0\u01e1\7c\2\2\u01e1\u01e2\7n\2\2\u01e2\u01e3"+
"\7u\2\2\u01e3\u01e5\7g\2\2\u01e4\u01db\3\2\2\2\u01e4\u01df\3\2\2\2\u01e5"+
"<\3\2\2\2\u01e6\u01ea\5O(\2\u01e7\u01e9\5M\'\2\u01e8\u01e7\3\2\2\2\u01e9"+
"\u01ec\3\2\2\2\u01ea\u01e8\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb>\3\2\2\2"+
"\u01ec\u01ea\3\2\2\2\u01ed\u01ee\7$\2\2\u01ee\u01ef\5A!\2\u01ef\u01f0"+
"\7$\2\2\u01f0@\3\2\2\2\u01f1\u01f4\5G$\2\u01f2\u01f4\n\3\2\2\u01f3\u01f1"+
"\3\2\2\2\u01f3\u01f2\3\2\2\2\u01f4\u01f7\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f5"+
"\u01f6\3\2\2\2\u01f6B\3\2\2\2\u01f7\u01f5\3\2\2\2\u01f8\u01fa\5Q)\2\u01f9"+
"\u01f8\3\2\2\2\u01fa\u01fb\3\2\2\2\u01fb\u01f9\3\2\2\2\u01fb\u01fc\3\2"+
"\2\2\u01fcD\3\2\2\2\u01fd\u01ff\t\4\2\2\u01fe\u0200\t\5\2\2\u01ff\u01fe"+
"\3\2\2\2\u01ff\u0200\3\2\2\2\u0200\u0201\3\2\2\2\u0201\u0202\5C\"\2\u0202"+
"F\3\2\2\2\u0203\u0204\7^\2\2\u0204\u0208\t\6\2\2\u0205\u0208\5K&\2\u0206"+
"\u0208\5I%\2\u0207\u0203\3\2\2\2\u0207\u0205\3\2\2\2\u0207\u0206\3\2\2"+
"\2\u0208H\3\2\2\2\u0209\u020a\7^\2\2\u020a\u020b\4\62\65\2\u020b\u020c"+
"\4\629\2\u020c\u0213\4\629\2\u020d\u020e\7^\2\2\u020e\u020f\4\629\2\u020f"+
"\u0213\4\629\2\u0210\u0211\7^\2\2\u0211\u0213\4\629\2\u0212\u0209\3\2"+
"\2\2\u0212\u020d\3\2\2\2\u0212\u0210\3\2\2\2\u0213J\3\2\2\2\u0214\u0215"+
"\7^\2\2\u0215\u0216\7w\2\2\u0216\u0217\5S*\2\u0217\u0218\5S*\2\u0218\u0219"+
"\5S*\2\u0219\u021a\5S*\2\u021aL\3\2\2\2\u021b\u0220\5O(\2\u021c\u0220"+
"\t\7\2\2\u021d\u0220\5Q)\2\u021e\u0220\t\b\2\2\u021f\u021b\3\2\2\2\u021f"+
"\u021c\3\2\2\2\u021f\u021d\3\2\2\2\u021f\u021e\3\2\2\2\u0220N\3\2\2\2"+
"\u0221\u0223\t\t\2\2\u0222\u0221\3\2\2\2\u0223P\3\2\2\2\u0224\u0225\t"+
"\n\2\2\u0225R\3\2\2\2\u0226\u0227\t\13\2\2\u0227T\3\2\2\2\u0228\u022a"+
"\t\f\2\2\u0229\u0228\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u0229\3\2\2\2\u022b"+
"\u022c\3\2\2\2\u022c\u022d\3\2\2\2\u022d\u022e\b+\2\2\u022eV\3\2\2\2\u022f"+
"\u0231\7\17\2\2\u0230\u022f\3\2\2\2\u0230\u0231\3\2\2\2\u0231\u0232\3"+
"\2\2\2\u0232\u0233\7\f\2\2\u0233\u0234\3\2\2\2\u0234\u0235\b,\2\2\u0235"+
"X\3\2\2\2\u0236\u0237\7\61\2\2\u0237\u0238\7,\2\2\u0238\u023c\3\2\2\2"+
"\u0239\u023b\13\2\2\2\u023a\u0239\3\2\2\2\u023b\u023e\3\2\2\2\u023c\u023d"+
"\3\2\2\2\u023c\u023a\3\2\2\2\u023d\u023f\3\2\2\2\u023e\u023c\3\2\2\2\u023f"+
"\u0240\7,\2\2\u0240\u0241\7\61\2\2\u0241\u0242\3\2\2\2\u0242\u0243\b-"+
"\2\2\u0243Z\3\2\2\2\u0244\u0245\7\61\2\2\u0245\u0246\7\61\2\2\u0246\u024a"+
"\3\2\2\2\u0247\u0249\n\r\2\2\u0248\u0247\3\2\2\2\u0249\u024c\3\2\2\2\u024a"+
"\u0248\3\2\2\2\u024a\u024b\3\2\2\2\u024b\u024e\3\2\2\2\u024c\u024a\3\2"+
"\2\2\u024d\u024f\7\17\2\2\u024e\u024d\3\2\2\2\u024e\u024f\3\2\2\2\u024f"+
"\u0250\3\2\2\2\u0250\u0251\7\f\2\2\u0251\u0252\3\2\2\2\u0252\u0253\b."+
"\2\2\u0253\\\3\2\2\2,\2|\u0085\u00e5\u00ea\u00f2\u00f7\u00ff\u0105\u010c"+
"\u0118\u0128\u0136\u0148\u0150\u015c\u0165\u0172\u017d\u018c\u01a5\u01c2"+
"\u01c7\u01cd\u01d0\u01d6\u01d9\u01e4\u01ea\u01f3\u01f5\u01fb\u01ff\u0207"+
"\u0212\u021f\u0222\u022b\u0230\u023c\u024a\u024e\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}
@@ -0,0 +1,40 @@
COUNT=1
AVG=2
SUM=3
MAX=4
MIN=5
AND=6
OR=7
Datatype=8
GreaterThen=9
GreaterThenOrEquals=10
LessThen=11
LessThenOrEquals=12
Equals=13
NotEquals=14
EndWith=15
NotEndWith=16
StartWith=17
NotStartWith=18
In=19
NotIn=20
Match=21
NotMatch=22
Contain=23
NotContain=24
EqualsIgnoreCase=25
NotEqualsIgnoreCase=26
ARITH=27
NUMBER=28
Boolean=29
Identifier=30
STRING=31
WS=32
NL=33
COMMENT=34
LINE_COMMENT=35
'count'=1
'avg'=2
'sum'=3
'max'=4
'min'=5
@@ -0,0 +1,180 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
T__10=11
T__11=12
T__12=13
T__13=14
T__14=15
T__15=16
T__16=17
T__17=18
T__18=19
T__19=20
T__20=21
T__21=22
T__22=23
T__23=24
T__24=25
T__25=26
T__26=27
T__27=28
T__28=29
T__29=30
T__30=31
T__31=32
T__32=33
T__33=34
T__34=35
T__35=36
T__36=37
T__37=38
T__38=39
T__39=40
T__40=41
T__41=42
T__42=43
T__43=44
T__44=45
T__45=46
T__46=47
T__47=48
T__48=49
T__49=50
T__50=51
T__51=52
T__52=53
T__53=54
T__54=55
T__55=56
T__56=57
T__57=58
T__58=59
T__59=60
T__60=61
T__61=62
T__62=63
T__63=64
T__64=65
T__65=66
T__66=67
T__67=68
T__68=69
T__69=70
COUNT=71
AVG=72
SUM=73
MAX=74
MIN=75
AND=76
OR=77
Datatype=78
GreaterThen=79
GreaterThenOrEquals=80
LessThen=81
LessThenOrEquals=82
Equals=83
NotEquals=84
EndWith=85
NotEndWith=86
StartWith=87
NotStartWith=88
In=89
NotIn=90
Match=91
NotMatch=92
Contain=93
NotContain=94
EqualsIgnoreCase=95
NotEqualsIgnoreCase=96
ARITH=97
NUMBER=98
Boolean=99
Identifier=100
STRING=101
WS=102
NL=103
COMMENT=104
LINE_COMMENT=105
'import'=1
';'=2
'.'=3
'.*'=4
'importParameterLibrary'=5
'importVariableLibrary'=6
'importConstantLibrary'=7
'importActionLibrary'=8
'function'=9
'('=10
')'=11
'{'=12
'}'=13
','=14
'rule'=15
'\u89c4\u5219'=16
'end'=17
'\u7ed3\u675f'=18
'loopRule'=19
'\u5faa\u73af\u89c4\u5219'=20
'loopTarget'=21
'\u5faa\u73af\u5bf9\u8c61'=22
'loopStart'=23
'\u5f00\u59cb\u524d\u52a8\u4f5c'=24
'loopEnd'=25
'\u7ed3\u675f\u540e\u52a8\u4f5c'=26
'loop'=27
'\u5141\u8bb8\u5faa\u73af\u89e6\u53d1'=28
'='=29
'salience'=30
'\u4f18\u5148\u7ea7'=31
'effective-date'=32
'\u751f\u6548\u65f6\u95f4'=33
'\u751f\u6548\u65e5\u671f'=34
'expires-date'=35
'\u5931\u6548\u65f6\u95f4'=36
'\u5931\u6548\u65e5\u671f'=37
'enabled'=38
'\u6fc0\u6d3b'=39
'\u542f\u7528'=40
'debug'=41
'\u8c03\u8bd5'=42
'\u5141\u8bb8\u8c03\u8bd5'=43
'activation-group'=44
'\u6fc0\u6d3b\u7ec4'=45
'agenda-group'=46
'\u8bae\u7a0b\u7ec4'=47
'auto-focus'=48
'\u81ea\u52a8\u83b7\u53d6\u7126\u70b9'=49
'ruleflow-group'=50
'\u89c4\u5219\u6d41\u7ec4'=51
'if'=52
'\u5982\u679c'=53
'null'=54
'eval'=55
'all'=56
'exist'=57
'collect'=58
'%'=59
':'=60
'then'=61
'\u90a3\u4e48'=62
'else'=63
'\u5426\u5219'=64
'out'=65
'@'=66
'parameter'=67
'\u53c2\u6570'=68
'!'=69
'$'=70
'count'=71
'avg'=72
'sum'=73
'max'=74
'min'=75
@@ -0,0 +1,574 @@
// Generated from RuleParser.g4 by ANTLR 4.5.3
package com.itheima.sfbx.framework.rule.dsl;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
* This class provides an empty implementation of {@link RuleParserVisitor},
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public class RuleParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements RuleParserVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRuleSet(RuleParserParser.RuleSetContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRuleSetHeader(RuleParserParser.RuleSetHeaderContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRuleSetBody(RuleParserParser.RuleSetBodyContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRules(RuleParserParser.RulesContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionImport(RuleParserParser.FunctionImportContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitPackageDef(RuleParserParser.PackageDefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitResource(RuleParserParser.ResourceContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitImportParameterLibrary(RuleParserParser.ImportParameterLibraryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitImportVariableLibrary(RuleParserParser.ImportVariableLibraryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitImportConstantLibrary(RuleParserParser.ImportConstantLibraryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitImportActionLibrary(RuleParserParser.ImportActionLibraryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionDef(RuleParserParser.FunctionDefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionParameters(RuleParserParser.FunctionParametersContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionParameter(RuleParserParser.FunctionParameterContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRuleDef(RuleParserParser.RuleDefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLoopRuleDef(RuleParserParser.LoopRuleDefContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLoopTarget(RuleParserParser.LoopTargetContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLoopStart(RuleParserParser.LoopStartContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLoopEnd(RuleParserParser.LoopEndContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAttribute(RuleParserParser.AttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLoopAttribute(RuleParserParser.LoopAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSalienceAttribute(RuleParserParser.SalienceAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitEffectiveDateAttribute(RuleParserParser.EffectiveDateAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpiresDateAttribute(RuleParserParser.ExpiresDateAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitEnabledAttribute(RuleParserParser.EnabledAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDebugAttribute(RuleParserParser.DebugAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitActivationGroupAttribute(RuleParserParser.ActivationGroupAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAgendaGroupAttribute(RuleParserParser.AgendaGroupAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAutoFocusAttribute(RuleParserParser.AutoFocusAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRuleflowGroupAttribute(RuleParserParser.RuleflowGroupAttributeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLeft(RuleParserParser.LeftContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParenConditions(RuleParserParser.ParenConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMultiConditions(RuleParserParser.MultiConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSingleCondition(RuleParserParser.SingleConditionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSingleNamedConditionSet(RuleParserParser.SingleNamedConditionSetContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNamedConditionSet(RuleParserParser.NamedConditionSetContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParenNamedConditions(RuleParserParser.ParenNamedConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMultiNamedConditions(RuleParserParser.MultiNamedConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSingleNamedConditions(RuleParserParser.SingleNamedConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSingleCellCondition(RuleParserParser.SingleCellConditionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMultiCellConditions(RuleParserParser.MultiCellConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParenCellConditions(RuleParserParser.ParenCellConditionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRefName(RuleParserParser.RefNameContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRefObject(RuleParserParser.RefObjectContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNullValue(RuleParserParser.NullValueContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConditionLeft(RuleParserParser.ConditionLeftContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpEval(RuleParserParser.ExpEvalContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpAll(RuleParserParser.ExpAllContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpExists(RuleParserParser.ExpExistsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpCollect(RuleParserParser.ExpCollectContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitCommonFunction(RuleParserParser.CommonFunctionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprCondition(RuleParserParser.ExprConditionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExpressionBody(RuleParserParser.ExpressionBodyContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitPercent(RuleParserParser.PercentContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLeftParen(RuleParserParser.LeftParenContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRightParen(RuleParserParser.RightParenContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitColon(RuleParserParser.ColonContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitJoin(RuleParserParser.JoinContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitRight(RuleParserParser.RightContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitOther(RuleParserParser.OtherContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitActions(RuleParserParser.ActionsContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAction(RuleParserParser.ActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAssignAction(RuleParserParser.AssignActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitOutAction(RuleParserParser.OutActionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMethodInvoke(RuleParserParser.MethodInvokeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFunctionInvoke(RuleParserParser.FunctionInvokeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitActionParameters(RuleParserParser.ActionParametersContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitBeanMethod(RuleParserParser.BeanMethodContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitComplexValue(RuleParserParser.ComplexValueContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParameter(RuleParserParser.ParameterContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParameterName(RuleParserParser.ParameterNameContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConstant(RuleParserParser.ConstantContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitVariable(RuleParserParser.VariableContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNamedVariable(RuleParserParser.NamedVariableContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitProperty(RuleParserParser.PropertyContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitVariableCategory(RuleParserParser.VariableCategoryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNamedVariableCategory(RuleParserParser.NamedVariableCategoryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConstantCategory(RuleParserParser.ConstantCategoryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitValue(RuleParserParser.ValueContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitOp(RuleParserParser.OpContext ctx) { return visitChildren(ctx); }
}
@@ -0,0 +1,568 @@
// Generated from RuleParser.g4 by ANTLR 4.5.3
package com.itheima.sfbx.framework.rule.dsl;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class RuleParserLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.5.3", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31,
T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38,
T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45,
T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52,
T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59,
T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66,
T__66=67, T__67=68, T__68=69, T__69=70, COUNT=71, AVG=72, SUM=73, MAX=74,
MIN=75, AND=76, OR=77, Datatype=78, GreaterThen=79, GreaterThenOrEquals=80,
LessThen=81, LessThenOrEquals=82, Equals=83, NotEquals=84, EndWith=85,
NotEndWith=86, StartWith=87, NotStartWith=88, In=89, NotIn=90, Match=91,
NotMatch=92, Contain=93, NotContain=94, EqualsIgnoreCase=95, NotEqualsIgnoreCase=96,
ARITH=97, NUMBER=98, Boolean=99, Identifier=100, STRING=101, WS=102, NL=103,
COMMENT=104, LINE_COMMENT=105;
public static String[] modeNames = {
"DEFAULT_MODE"
};
public static final String[] ruleNames = {
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24",
"T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32",
"T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40",
"T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48",
"T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56",
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "T__67", "T__68", "T__69", "COUNT", "AVG", "SUM", "MAX",
"MIN", "AND", "OR", "Datatype", "GreaterThen", "GreaterThenOrEquals",
"LessThen", "LessThenOrEquals", "Equals", "NotEquals", "EndWith", "NotEndWith",
"StartWith", "NotStartWith", "In", "NotIn", "Match", "NotMatch", "Contain",
"NotContain", "EqualsIgnoreCase", "NotEqualsIgnoreCase", "ARITH", "NUMBER",
"Boolean", "Identifier", "STRING", "STRING_CONTENT", "INT", "EXP", "EscapeSequence",
"OctalEscape", "UnicodeEscape", "Char", "StartChar", "DIGIT", "HEX", "WS",
"NL", "COMMENT", "LINE_COMMENT"
};
private static final String[] _LITERAL_NAMES = {
null, "'import'", "';'", "'.'", "'.*'", "'importParameterLibrary'", "'importVariableLibrary'",
"'importConstantLibrary'", "'importActionLibrary'", "'function'", "'('",
"')'", "'{'", "'}'", "','", "'rule'", "'\\u89c4\\u5219'", "'end'", "'\\u7ed3\\u675f'",
"'loopRule'", "'\\u5faa\\u73af\\u89c4\\u5219'", "'loopTarget'", "'\\u5faa\\u73af\\u5bf9\\u8c61'",
"'loopStart'", "'\\u5f00\\u59cb\\u524d\\u52a8\\u4f5c'", "'loopEnd'", "'\\u7ed3\\u675f\\u540e\\u52a8\\u4f5c'",
"'loop'", "'\\u5141\\u8bb8\\u5faa\\u73af\\u89e6\\u53d1'", "'='", "'salience'",
"'\\u4f18\\u5148\\u7ea7'", "'effective-date'", "'\\u751f\\u6548\\u65f6\\u95f4'",
"'\\u751f\\u6548\\u65e5\\u671f'", "'expires-date'", "'\\u5931\\u6548\\u65f6\\u95f4'",
"'\\u5931\\u6548\\u65e5\\u671f'", "'enabled'", "'\\u6fc0\\u6d3b'", "'\\u542f\\u7528'",
"'debug'", "'\\u8c03\\u8bd5'", "'\\u5141\\u8bb8\\u8c03\\u8bd5'", "'activation-group'",
"'\\u6fc0\\u6d3b\\u7ec4'", "'agenda-group'", "'\\u8bae\\u7a0b\\u7ec4'",
"'auto-focus'", "'\\u81ea\\u52a8\\u83b7\\u53d6\\u7126\\u70b9'", "'ruleflow-group'",
"'\\u89c4\\u5219\\u6d41\\u7ec4'", "'if'", "'\\u5982\\u679c'", "'null'",
"'eval'", "'all'", "'exist'", "'collect'", "'%'", "':'", "'then'", "'\\u90a3\\u4e48'",
"'else'", "'\\u5426\\u5219'", "'out'", "'@'", "'parameter'", "'\\u53c2\\u6570'",
"'!'", "'$'", "'count'", "'avg'", "'sum'", "'max'", "'min'"
};
private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, "COUNT",
"AVG", "SUM", "MAX", "MIN", "AND", "OR", "Datatype", "GreaterThen", "GreaterThenOrEquals",
"LessThen", "LessThenOrEquals", "Equals", "NotEquals", "EndWith", "NotEndWith",
"StartWith", "NotStartWith", "In", "NotIn", "Match", "NotMatch", "Contain",
"NotContain", "EqualsIgnoreCase", "NotEqualsIgnoreCase", "ARITH", "NUMBER",
"Boolean", "Identifier", "STRING", "WS", "NL", "COMMENT", "LINE_COMMENT"
};
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public RuleParserLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "RuleParser.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2k\u04a3\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\3\2\3\2\3\2\3"+
"\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+
"\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3"+
"\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7"+
"\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3"+
"\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t"+
"\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3"+
"\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3"+
"\20\3\20\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3"+
"\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3"+
"\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3"+
"\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3"+
"\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3"+
"\33\3\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3"+
"\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3"+
"!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3#\3#\3#"+
"\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&"+
"\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3)\3)\3)\3*\3*\3*\3*\3"+
"*\3*\3+\3+\3+\3,\3,\3,\3,\3,\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3-\3"+
"-\3-\3-\3-\3.\3.\3.\3.\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3\60\3\60"+
"\3\60\3\60\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\61\3\62"+
"\3\62\3\62\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\63"+
"\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\65\3\65"+
"\3\65\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39\39"+
"\39\3:\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;\3;\3;\3;\3<\3<\3=\3=\3>\3>\3>\3>"+
"\3>\3?\3?\3?\3@\3@\3@\3@\3@\3A\3A\3A\3B\3B\3B\3B\3C\3C\3D\3D\3D\3D\3D"+
"\3D\3D\3D\3D\3D\3E\3E\3E\3F\3F\3G\3G\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3J"+
"\3J\3J\3J\3K\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3M\3M\3M\5M\u02cc"+
"\nM\3N\3N\3N\3N\3N\3N\3N\5N\u02d5\nN\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O"+
"\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O"+
"\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O"+
"\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O"+
"\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\5O\u0335\nO\3P\3P\3P\5P\u033a"+
"\nP\3Q\3Q\3Q\3Q\3Q\3Q\5Q\u0342\nQ\3R\3R\3R\5R\u0347\nR\3S\3S\3S\3S\3S"+
"\3S\5S\u034f\nS\3T\3T\3T\3T\5T\u0355\nT\3U\3U\3U\3U\3U\5U\u035c\nU\3V"+
"\3V\3V\3V\3V\3V\3V\3V\3V\3V\5V\u0368\nV\3W\3W\3W\3W\3W\3W\3W\3W\3W\3W"+
"\3W\3W\3W\3W\5W\u0378\nW\3X\3X\3X\3X\3X\3X\3X\3X\3X\3X\3X\3X\5X\u0386"+
"\nX\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\5Y\u0398\nY\3Z\3Z"+
"\3Z\3Z\3Z\3Z\5Z\u03a0\nZ\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\5[\u03ac\n[\3\\"+
"\3\\\3\\\3\\\3\\\3\\\3\\\5\\\u03b5\n\\\3]\3]\3]\3]\3]\3]\3]\3]\3]\3]\3"+
"]\5]\u03c2\n]\3^\3^\3^\3^\3^\3^\3^\3^\3^\5^\u03cd\n^\3_\3_\3_\3_\3_\3"+
"_\3_\3_\3_\3_\3_\3_\3_\5_\u03dc\n_\3`\3`\3`\3`\3`\3`\3`\3`\3`\3`\3`\3"+
"`\3`\3`\3`\3`\3`\3`\3`\3`\3`\3`\3`\5`\u03f5\n`\3a\3a\3a\3a\3a\3a\3a\3"+
"a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\3a\5a\u0412\n"+
"a\3b\3b\3c\5c\u0417\nc\3c\3c\3c\3c\5c\u041d\nc\3c\5c\u0420\nc\3c\3c\3"+
"c\3c\5c\u0426\nc\3c\5c\u0429\nc\3d\3d\3d\3d\3d\3d\3d\3d\3d\5d\u0434\n"+
"d\3e\3e\7e\u0438\ne\fe\16e\u043b\13e\3f\3f\3f\3f\3g\3g\7g\u0443\ng\fg"+
"\16g\u0446\13g\3h\6h\u0449\nh\rh\16h\u044a\3i\3i\5i\u044f\ni\3i\3i\3j"+
"\3j\3j\3j\5j\u0457\nj\3k\3k\3k\3k\3k\3k\3k\3k\3k\5k\u0462\nk\3l\3l\3l"+
"\3l\3l\3l\3l\3m\3m\3m\3m\5m\u046f\nm\3n\5n\u0472\nn\3o\3o\3p\3p\3q\6q"+
"\u0479\nq\rq\16q\u047a\3q\3q\3r\5r\u0480\nr\3r\3r\3r\3r\3s\3s\3s\3s\7"+
"s\u048a\ns\fs\16s\u048d\13s\3s\3s\3s\3s\3s\3t\3t\3t\3t\7t\u0498\nt\ft"+
"\16t\u049b\13t\3t\5t\u049e\nt\3t\3t\3t\3t\3\u048b\2u\3\3\5\4\7\5\t\6\13"+
"\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'"+
"\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'"+
"M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177"+
"A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093"+
"K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7"+
"U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb"+
"_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cd\2\u00cf"+
"\2\u00d1\2\u00d3\2\u00d5\2\u00d7\2\u00d9\2\u00db\2\u00dd\2\u00df\2\u00e1"+
"h\u00e3i\u00e5j\u00e7k\3\2\16\6\2\'\',-//\61\61\3\2$$\4\2GGgg\4\2--//"+
"\n\2$$))^^ddhhppttvv\4\2//aa\5\2\u00b9\u00b9\u0302\u0371\u2041\u2042\t"+
"\2C\\c|\u2072\u2191\u2c02\u2ff1\u3003\ud801\uf902\ufdd1\ufdf2\uffff\3"+
"\2\62;\5\2\62;CHch\5\2\13\f\17\17\"\"\4\2\f\f\17\17\u04da\2\3\3\2\2\2"+
"\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2"+
"\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2"+
"\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2"+
"\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2"+
"\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2"+
"\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2"+
"\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W"+
"\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2"+
"\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2"+
"\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}"+
"\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2"+
"\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f"+
"\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2"+
"\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1"+
"\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2"+
"\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3"+
"\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2"+
"\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5"+
"\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00e1\3\2\2"+
"\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\3\u00e9\3\2\2\2\5\u00f0"+
"\3\2\2\2\7\u00f2\3\2\2\2\t\u00f4\3\2\2\2\13\u00f7\3\2\2\2\r\u010e\3\2"+
"\2\2\17\u0124\3\2\2\2\21\u013a\3\2\2\2\23\u014e\3\2\2\2\25\u0157\3\2\2"+
"\2\27\u0159\3\2\2\2\31\u015b\3\2\2\2\33\u015d\3\2\2\2\35\u015f\3\2\2\2"+
"\37\u0161\3\2\2\2!\u0166\3\2\2\2#\u0169\3\2\2\2%\u016d\3\2\2\2\'\u0170"+
"\3\2\2\2)\u0179\3\2\2\2+\u017e\3\2\2\2-\u0189\3\2\2\2/\u018e\3\2\2\2\61"+
"\u0198\3\2\2\2\63\u019e\3\2\2\2\65\u01a6\3\2\2\2\67\u01ac\3\2\2\29\u01b1"+
"\3\2\2\2;\u01b8\3\2\2\2=\u01ba\3\2\2\2?\u01c3\3\2\2\2A\u01c7\3\2\2\2C"+
"\u01d6\3\2\2\2E\u01db\3\2\2\2G\u01e0\3\2\2\2I\u01ed\3\2\2\2K\u01f2\3\2"+
"\2\2M\u01f7\3\2\2\2O\u01ff\3\2\2\2Q\u0202\3\2\2\2S\u0205\3\2\2\2U\u020b"+
"\3\2\2\2W\u020e\3\2\2\2Y\u0213\3\2\2\2[\u0224\3\2\2\2]\u0228\3\2\2\2_"+
"\u0235\3\2\2\2a\u0239\3\2\2\2c\u0244\3\2\2\2e\u024b\3\2\2\2g\u025a\3\2"+
"\2\2i\u025f\3\2\2\2k\u0262\3\2\2\2m\u0265\3\2\2\2o\u026a\3\2\2\2q\u026f"+
"\3\2\2\2s\u0273\3\2\2\2u\u0279\3\2\2\2w\u0281\3\2\2\2y\u0283\3\2\2\2{"+
"\u0285\3\2\2\2}\u028a\3\2\2\2\177\u028d\3\2\2\2\u0081\u0292\3\2\2\2\u0083"+
"\u0295\3\2\2\2\u0085\u0299\3\2\2\2\u0087\u029b\3\2\2\2\u0089\u02a5\3\2"+
"\2\2\u008b\u02a8\3\2\2\2\u008d\u02aa\3\2\2\2\u008f\u02ac\3\2\2\2\u0091"+
"\u02b2\3\2\2\2\u0093\u02b6\3\2\2\2\u0095\u02ba\3\2\2\2\u0097\u02be\3\2"+
"\2\2\u0099\u02cb\3\2\2\2\u009b\u02d4\3\2\2\2\u009d\u0334\3\2\2\2\u009f"+
"\u0339\3\2\2\2\u00a1\u0341\3\2\2\2\u00a3\u0346\3\2\2\2\u00a5\u034e\3\2"+
"\2\2\u00a7\u0354\3\2\2\2\u00a9\u035b\3\2\2\2\u00ab\u0367\3\2\2\2\u00ad"+
"\u0377\3\2\2\2\u00af\u0385\3\2\2\2\u00b1\u0397\3\2\2\2\u00b3\u039f\3\2"+
"\2\2\u00b5\u03ab\3\2\2\2\u00b7\u03b4\3\2\2\2\u00b9\u03c1\3\2\2\2\u00bb"+
"\u03cc\3\2\2\2\u00bd\u03db\3\2\2\2\u00bf\u03f4\3\2\2\2\u00c1\u0411\3\2"+
"\2\2\u00c3\u0413\3\2\2\2\u00c5\u0428\3\2\2\2\u00c7\u0433\3\2\2\2\u00c9"+
"\u0435\3\2\2\2\u00cb\u043c\3\2\2\2\u00cd\u0444\3\2\2\2\u00cf\u0448\3\2"+
"\2\2\u00d1\u044c\3\2\2\2\u00d3\u0456\3\2\2\2\u00d5\u0461\3\2\2\2\u00d7"+
"\u0463\3\2\2\2\u00d9\u046e\3\2\2\2\u00db\u0471\3\2\2\2\u00dd\u0473\3\2"+
"\2\2\u00df\u0475\3\2\2\2\u00e1\u0478\3\2\2\2\u00e3\u047f\3\2\2\2\u00e5"+
"\u0485\3\2\2\2\u00e7\u0493\3\2\2\2\u00e9\u00ea\7k\2\2\u00ea\u00eb\7o\2"+
"\2\u00eb\u00ec\7r\2\2\u00ec\u00ed\7q\2\2\u00ed\u00ee\7t\2\2\u00ee\u00ef"+
"\7v\2\2\u00ef\4\3\2\2\2\u00f0\u00f1\7=\2\2\u00f1\6\3\2\2\2\u00f2\u00f3"+
"\7\60\2\2\u00f3\b\3\2\2\2\u00f4\u00f5\7\60\2\2\u00f5\u00f6\7,\2\2\u00f6"+
"\n\3\2\2\2\u00f7\u00f8\7k\2\2\u00f8\u00f9\7o\2\2\u00f9\u00fa\7r\2\2\u00fa"+
"\u00fb\7q\2\2\u00fb\u00fc\7t\2\2\u00fc\u00fd\7v\2\2\u00fd\u00fe\7R\2\2"+
"\u00fe\u00ff\7c\2\2\u00ff\u0100\7t\2\2\u0100\u0101\7c\2\2\u0101\u0102"+
"\7o\2\2\u0102\u0103\7g\2\2\u0103\u0104\7v\2\2\u0104\u0105\7g\2\2\u0105"+
"\u0106\7t\2\2\u0106\u0107\7N\2\2\u0107\u0108\7k\2\2\u0108\u0109\7d\2\2"+
"\u0109\u010a\7t\2\2\u010a\u010b\7c\2\2\u010b\u010c\7t\2\2\u010c\u010d"+
"\7{\2\2\u010d\f\3\2\2\2\u010e\u010f\7k\2\2\u010f\u0110\7o\2\2\u0110\u0111"+
"\7r\2\2\u0111\u0112\7q\2\2\u0112\u0113\7t\2\2\u0113\u0114\7v\2\2\u0114"+
"\u0115\7X\2\2\u0115\u0116\7c\2\2\u0116\u0117\7t\2\2\u0117\u0118\7k\2\2"+
"\u0118\u0119\7c\2\2\u0119\u011a\7d\2\2\u011a\u011b\7n\2\2\u011b\u011c"+
"\7g\2\2\u011c\u011d\7N\2\2\u011d\u011e\7k\2\2\u011e\u011f\7d\2\2\u011f"+
"\u0120\7t\2\2\u0120\u0121\7c\2\2\u0121\u0122\7t\2\2\u0122\u0123\7{\2\2"+
"\u0123\16\3\2\2\2\u0124\u0125\7k\2\2\u0125\u0126\7o\2\2\u0126\u0127\7"+
"r\2\2\u0127\u0128\7q\2\2\u0128\u0129\7t\2\2\u0129\u012a\7v\2\2\u012a\u012b"+
"\7E\2\2\u012b\u012c\7q\2\2\u012c\u012d\7p\2\2\u012d\u012e\7u\2\2\u012e"+
"\u012f\7v\2\2\u012f\u0130\7c\2\2\u0130\u0131\7p\2\2\u0131\u0132\7v\2\2"+
"\u0132\u0133\7N\2\2\u0133\u0134\7k\2\2\u0134\u0135\7d\2\2\u0135\u0136"+
"\7t\2\2\u0136\u0137\7c\2\2\u0137\u0138\7t\2\2\u0138\u0139\7{\2\2\u0139"+
"\20\3\2\2\2\u013a\u013b\7k\2\2\u013b\u013c\7o\2\2\u013c\u013d\7r\2\2\u013d"+
"\u013e\7q\2\2\u013e\u013f\7t\2\2\u013f\u0140\7v\2\2\u0140\u0141\7C\2\2"+
"\u0141\u0142\7e\2\2\u0142\u0143\7v\2\2\u0143\u0144\7k\2\2\u0144\u0145"+
"\7q\2\2\u0145\u0146\7p\2\2\u0146\u0147\7N\2\2\u0147\u0148\7k\2\2\u0148"+
"\u0149\7d\2\2\u0149\u014a\7t\2\2\u014a\u014b\7c\2\2\u014b\u014c\7t\2\2"+
"\u014c\u014d\7{\2\2\u014d\22\3\2\2\2\u014e\u014f\7h\2\2\u014f\u0150\7"+
"w\2\2\u0150\u0151\7p\2\2\u0151\u0152\7e\2\2\u0152\u0153\7v\2\2\u0153\u0154"+
"\7k\2\2\u0154\u0155\7q\2\2\u0155\u0156\7p\2\2\u0156\24\3\2\2\2\u0157\u0158"+
"\7*\2\2\u0158\26\3\2\2\2\u0159\u015a\7+\2\2\u015a\30\3\2\2\2\u015b\u015c"+
"\7}\2\2\u015c\32\3\2\2\2\u015d\u015e\7\177\2\2\u015e\34\3\2\2\2\u015f"+
"\u0160\7.\2\2\u0160\36\3\2\2\2\u0161\u0162\7t\2\2\u0162\u0163\7w\2\2\u0163"+
"\u0164\7n\2\2\u0164\u0165\7g\2\2\u0165 \3\2\2\2\u0166\u0167\7\u89c6\2"+
"\2\u0167\u0168\7\u521b\2\2\u0168\"\3\2\2\2\u0169\u016a\7g\2\2\u016a\u016b"+
"\7p\2\2\u016b\u016c\7f\2\2\u016c$\3\2\2\2\u016d\u016e\7\u7ed5\2\2\u016e"+
"\u016f\7\u6761\2\2\u016f&\3\2\2\2\u0170\u0171\7n\2\2\u0171\u0172\7q\2"+
"\2\u0172\u0173\7q\2\2\u0173\u0174\7r\2\2\u0174\u0175\7T\2\2\u0175\u0176"+
"\7w\2\2\u0176\u0177\7n\2\2\u0177\u0178\7g\2\2\u0178(\3\2\2\2\u0179\u017a"+
"\7\u5fac\2\2\u017a\u017b\7\u73b1\2\2\u017b\u017c\7\u89c6\2\2\u017c\u017d"+
"\7\u521b\2\2\u017d*\3\2\2\2\u017e\u017f\7n\2\2\u017f\u0180\7q\2\2\u0180"+
"\u0181\7q\2\2\u0181\u0182\7r\2\2\u0182\u0183\7V\2\2\u0183\u0184\7c\2\2"+
"\u0184\u0185\7t\2\2\u0185\u0186\7i\2\2\u0186\u0187\7g\2\2\u0187\u0188"+
"\7v\2\2\u0188,\3\2\2\2\u0189\u018a\7\u5fac\2\2\u018a\u018b\7\u73b1\2\2"+
"\u018b\u018c\7\u5bfb\2\2\u018c\u018d\7\u8c63\2\2\u018d.\3\2\2\2\u018e"+
"\u018f\7n\2\2\u018f\u0190\7q\2\2\u0190\u0191\7q\2\2\u0191\u0192\7r\2\2"+
"\u0192\u0193\7U\2\2\u0193\u0194\7v\2\2\u0194\u0195\7c\2\2\u0195\u0196"+
"\7t\2\2\u0196\u0197\7v\2\2\u0197\60\3\2\2\2\u0198\u0199\7\u5f02\2\2\u0199"+
"\u019a\7\u59cd\2\2\u019a\u019b\7\u524f\2\2\u019b\u019c\7\u52aa\2\2\u019c"+
"\u019d\7\u4f5e\2\2\u019d\62\3\2\2\2\u019e\u019f\7n\2\2\u019f\u01a0\7q"+
"\2\2\u01a0\u01a1\7q\2\2\u01a1\u01a2\7r\2\2\u01a2\u01a3\7G\2\2\u01a3\u01a4"+
"\7p\2\2\u01a4\u01a5\7f\2\2\u01a5\64\3\2\2\2\u01a6\u01a7\7\u7ed5\2\2\u01a7"+
"\u01a8\7\u6761\2\2\u01a8\u01a9\7\u5410\2\2\u01a9\u01aa\7\u52aa\2\2\u01aa"+
"\u01ab\7\u4f5e\2\2\u01ab\66\3\2\2\2\u01ac\u01ad\7n\2\2\u01ad\u01ae\7q"+
"\2\2\u01ae\u01af\7q\2\2\u01af\u01b0\7r\2\2\u01b08\3\2\2\2\u01b1\u01b2"+
"\7\u5143\2\2\u01b2\u01b3\7\u8bba\2\2\u01b3\u01b4\7\u5fac\2\2\u01b4\u01b5"+
"\7\u73b1\2\2\u01b5\u01b6\7\u89e8\2\2\u01b6\u01b7\7\u53d3\2\2\u01b7:\3"+
"\2\2\2\u01b8\u01b9\7?\2\2\u01b9<\3\2\2\2\u01ba\u01bb\7u\2\2\u01bb\u01bc"+
"\7c\2\2\u01bc\u01bd\7n\2\2\u01bd\u01be\7k\2\2\u01be\u01bf\7g\2\2\u01bf"+
"\u01c0\7p\2\2\u01c0\u01c1\7e\2\2\u01c1\u01c2\7g\2\2\u01c2>\3\2\2\2\u01c3"+
"\u01c4\7\u4f1a\2\2\u01c4\u01c5\7\u514a\2\2\u01c5\u01c6\7\u7ea9\2\2\u01c6"+
"@\3\2\2\2\u01c7\u01c8\7g\2\2\u01c8\u01c9\7h\2\2\u01c9\u01ca\7h\2\2\u01ca"+
"\u01cb\7g\2\2\u01cb\u01cc\7e\2\2\u01cc\u01cd\7v\2\2\u01cd\u01ce\7k\2\2"+
"\u01ce\u01cf\7x\2\2\u01cf\u01d0\7g\2\2\u01d0\u01d1\7/\2\2\u01d1\u01d2"+
"\7f\2\2\u01d2\u01d3\7c\2\2\u01d3\u01d4\7v\2\2\u01d4\u01d5\7g\2\2\u01d5"+
"B\3\2\2\2\u01d6\u01d7\7\u7521\2\2\u01d7\u01d8\7\u654a\2\2\u01d8\u01d9"+
"\7\u65f8\2\2\u01d9\u01da\7\u95f6\2\2\u01daD\3\2\2\2\u01db\u01dc\7\u7521"+
"\2\2\u01dc\u01dd\7\u654a\2\2\u01dd\u01de\7\u65e7\2\2\u01de\u01df\7\u6721"+
"\2\2\u01dfF\3\2\2\2\u01e0\u01e1\7g\2\2\u01e1\u01e2\7z\2\2\u01e2\u01e3"+
"\7r\2\2\u01e3\u01e4\7k\2\2\u01e4\u01e5\7t\2\2\u01e5\u01e6\7g\2\2\u01e6"+
"\u01e7\7u\2\2\u01e7\u01e8\7/\2\2\u01e8\u01e9\7f\2\2\u01e9\u01ea\7c\2\2"+
"\u01ea\u01eb\7v\2\2\u01eb\u01ec\7g\2\2\u01ecH\3\2\2\2\u01ed\u01ee\7\u5933"+
"\2\2\u01ee\u01ef\7\u654a\2\2\u01ef\u01f0\7\u65f8\2\2\u01f0\u01f1\7\u95f6"+
"\2\2\u01f1J\3\2\2\2\u01f2\u01f3\7\u5933\2\2\u01f3\u01f4\7\u654a\2\2\u01f4"+
"\u01f5\7\u65e7\2\2\u01f5\u01f6\7\u6721\2\2\u01f6L\3\2\2\2\u01f7\u01f8"+
"\7g\2\2\u01f8\u01f9\7p\2\2\u01f9\u01fa\7c\2\2\u01fa\u01fb\7d\2\2\u01fb"+
"\u01fc\7n\2\2\u01fc\u01fd\7g\2\2\u01fd\u01fe\7f\2\2\u01feN\3\2\2\2\u01ff"+
"\u0200\7\u6fc2\2\2\u0200\u0201\7\u6d3d\2\2\u0201P\3\2\2\2\u0202\u0203"+
"\7\u5431\2\2\u0203\u0204\7\u752a\2\2\u0204R\3\2\2\2\u0205\u0206\7f\2\2"+
"\u0206\u0207\7g\2\2\u0207\u0208\7d\2\2\u0208\u0209\7w\2\2\u0209\u020a"+
"\7i\2\2\u020aT\3\2\2\2\u020b\u020c\7\u8c05\2\2\u020c\u020d\7\u8bd7\2\2"+
"\u020dV\3\2\2\2\u020e\u020f\7\u5143\2\2\u020f\u0210\7\u8bba\2\2\u0210"+
"\u0211\7\u8c05\2\2\u0211\u0212\7\u8bd7\2\2\u0212X\3\2\2\2\u0213\u0214"+
"\7c\2\2\u0214\u0215\7e\2\2\u0215\u0216\7v\2\2\u0216\u0217\7k\2\2\u0217"+
"\u0218\7x\2\2\u0218\u0219\7c\2\2\u0219\u021a\7v\2\2\u021a\u021b\7k\2\2"+
"\u021b\u021c\7q\2\2\u021c\u021d\7p\2\2\u021d\u021e\7/\2\2\u021e\u021f"+
"\7i\2\2\u021f\u0220\7t\2\2\u0220\u0221\7q\2\2\u0221\u0222\7w\2\2\u0222"+
"\u0223\7r\2\2\u0223Z\3\2\2\2\u0224\u0225\7\u6fc2\2\2\u0225\u0226\7\u6d3d"+
"\2\2\u0226\u0227\7\u7ec6\2\2\u0227\\\3\2\2\2\u0228\u0229\7c\2\2\u0229"+
"\u022a\7i\2\2\u022a\u022b\7g\2\2\u022b\u022c\7p\2\2\u022c\u022d\7f\2\2"+
"\u022d\u022e\7c\2\2\u022e\u022f\7/\2\2\u022f\u0230\7i\2\2\u0230\u0231"+
"\7t\2\2\u0231\u0232\7q\2\2\u0232\u0233\7w\2\2\u0233\u0234\7r\2\2\u0234"+
"^\3\2\2\2\u0235\u0236\7\u8bb0\2\2\u0236\u0237\7\u7a0d\2\2\u0237\u0238"+
"\7\u7ec6\2\2\u0238`\3\2\2\2\u0239\u023a\7c\2\2\u023a\u023b\7w\2\2\u023b"+
"\u023c\7v\2\2\u023c\u023d\7q\2\2\u023d\u023e\7/\2\2\u023e\u023f\7h\2\2"+
"\u023f\u0240\7q\2\2\u0240\u0241\7e\2\2\u0241\u0242\7w\2\2\u0242\u0243"+
"\7u\2\2\u0243b\3\2\2\2\u0244\u0245\7\u81ec\2\2\u0245\u0246\7\u52aa\2\2"+
"\u0246\u0247\7\u83b9\2\2\u0247\u0248\7\u53d8\2\2\u0248\u0249\7\u7128\2"+
"\2\u0249\u024a\7\u70bb\2\2\u024ad\3\2\2\2\u024b\u024c\7t\2\2\u024c\u024d"+
"\7w\2\2\u024d\u024e\7n\2\2\u024e\u024f\7g\2\2\u024f\u0250\7h\2\2\u0250"+
"\u0251\7n\2\2\u0251\u0252\7q\2\2\u0252\u0253\7y\2\2\u0253\u0254\7/\2\2"+
"\u0254\u0255\7i\2\2\u0255\u0256\7t\2\2\u0256\u0257\7q\2\2\u0257\u0258"+
"\7w\2\2\u0258\u0259\7r\2\2\u0259f\3\2\2\2\u025a\u025b\7\u89c6\2\2\u025b"+
"\u025c\7\u521b\2\2\u025c\u025d\7\u6d43\2\2\u025d\u025e\7\u7ec6\2\2\u025e"+
"h\3\2\2\2\u025f\u0260\7k\2\2\u0260\u0261\7h\2\2\u0261j\3\2\2\2\u0262\u0263"+
"\7\u5984\2\2\u0263\u0264\7\u679e\2\2\u0264l\3\2\2\2\u0265\u0266\7p\2\2"+
"\u0266\u0267\7w\2\2\u0267\u0268\7n\2\2\u0268\u0269\7n\2\2\u0269n\3\2\2"+
"\2\u026a\u026b\7g\2\2\u026b\u026c\7x\2\2\u026c\u026d\7c\2\2\u026d\u026e"+
"\7n\2\2\u026ep\3\2\2\2\u026f\u0270\7c\2\2\u0270\u0271\7n\2\2\u0271\u0272"+
"\7n\2\2\u0272r\3\2\2\2\u0273\u0274\7g\2\2\u0274\u0275\7z\2\2\u0275\u0276"+
"\7k\2\2\u0276\u0277\7u\2\2\u0277\u0278\7v\2\2\u0278t\3\2\2\2\u0279\u027a"+
"\7e\2\2\u027a\u027b\7q\2\2\u027b\u027c\7n\2\2\u027c\u027d\7n\2\2\u027d"+
"\u027e\7g\2\2\u027e\u027f\7e\2\2\u027f\u0280\7v\2\2\u0280v\3\2\2\2\u0281"+
"\u0282\7\'\2\2\u0282x\3\2\2\2\u0283\u0284\7<\2\2\u0284z\3\2\2\2\u0285"+
"\u0286\7v\2\2\u0286\u0287\7j\2\2\u0287\u0288\7g\2\2\u0288\u0289\7p\2\2"+
"\u0289|\3\2\2\2\u028a\u028b\7\u90a5\2\2\u028b\u028c\7\u4e4a\2\2\u028c"+
"~\3\2\2\2\u028d\u028e\7g\2\2\u028e\u028f\7n\2\2\u028f\u0290\7u\2\2\u0290"+
"\u0291\7g\2\2\u0291\u0080\3\2\2\2\u0292\u0293\7\u5428\2\2\u0293\u0294"+
"\7\u521b\2\2\u0294\u0082\3\2\2\2\u0295\u0296\7q\2\2\u0296\u0297\7w\2\2"+
"\u0297\u0298\7v\2\2\u0298\u0084\3\2\2\2\u0299\u029a\7B\2\2\u029a\u0086"+
"\3\2\2\2\u029b\u029c\7r\2\2\u029c\u029d\7c\2\2\u029d\u029e\7t\2\2\u029e"+
"\u029f\7c\2\2\u029f\u02a0\7o\2\2\u02a0\u02a1\7g\2\2\u02a1\u02a2\7v\2\2"+
"\u02a2\u02a3\7g\2\2\u02a3\u02a4\7t\2\2\u02a4\u0088\3\2\2\2\u02a5\u02a6"+
"\7\u53c4\2\2\u02a6\u02a7\7\u6572\2\2\u02a7\u008a\3\2\2\2\u02a8\u02a9\7"+
"#\2\2\u02a9\u008c\3\2\2\2\u02aa\u02ab\7&\2\2\u02ab\u008e\3\2\2\2\u02ac"+
"\u02ad\7e\2\2\u02ad\u02ae\7q\2\2\u02ae\u02af\7w\2\2\u02af\u02b0\7p\2\2"+
"\u02b0\u02b1\7v\2\2\u02b1\u0090\3\2\2\2\u02b2\u02b3\7c\2\2\u02b3\u02b4"+
"\7x\2\2\u02b4\u02b5\7i\2\2\u02b5\u0092\3\2\2\2\u02b6\u02b7\7u\2\2\u02b7"+
"\u02b8\7w\2\2\u02b8\u02b9\7o\2\2\u02b9\u0094\3\2\2\2\u02ba\u02bb\7o\2"+
"\2\u02bb\u02bc\7c\2\2\u02bc\u02bd\7z\2\2\u02bd\u0096\3\2\2\2\u02be\u02bf"+
"\7o\2\2\u02bf\u02c0\7k\2\2\u02c0\u02c1\7p\2\2\u02c1\u0098\3\2\2\2\u02c2"+
"\u02c3\7c\2\2\u02c3\u02c4\7p\2\2\u02c4\u02cc\7f\2\2\u02c5\u02c6\7(\2\2"+
"\u02c6\u02cc\7(\2\2\u02c7\u02cc\7.\2\2\u02c8\u02c9\7\u5e78\2\2\u02c9\u02cc"+
"\7\u4e16\2\2\u02ca\u02cc\7\u4e16\2\2\u02cb\u02c2\3\2\2\2\u02cb\u02c5\3"+
"\2\2\2\u02cb\u02c7\3\2\2\2\u02cb\u02c8\3\2\2\2\u02cb\u02ca\3\2\2\2\u02cc"+
"\u009a\3\2\2\2\u02cd\u02ce\7q\2\2\u02ce\u02d5\7t\2\2\u02cf\u02d0\7~\2"+
"\2\u02d0\u02d5\7~\2\2\u02d1\u02d2\7\u6218\2\2\u02d2\u02d5\7\u8007\2\2"+
"\u02d3\u02d5\7\u6218\2\2\u02d4\u02cd\3\2\2\2\u02d4\u02cf\3\2\2\2\u02d4"+
"\u02d1\3\2\2\2\u02d4\u02d3\3\2\2\2\u02d5\u009c\3\2\2\2\u02d6\u02d7\7U"+
"\2\2\u02d7\u02d8\7v\2\2\u02d8\u02d9\7t\2\2\u02d9\u02da\7k\2\2\u02da\u02db"+
"\7p\2\2\u02db\u0335\7i\2\2\u02dc\u02dd\7k\2\2\u02dd\u02de\7p\2\2\u02de"+
"\u0335\7v\2\2\u02df\u02e0\7K\2\2\u02e0\u02e1\7p\2\2\u02e1\u02e2\7v\2\2"+
"\u02e2\u02e3\7g\2\2\u02e3\u02e4\7i\2\2\u02e4\u02e5\7g\2\2\u02e5\u0335"+
"\7t\2\2\u02e6\u02e7\7f\2\2\u02e7\u02e8\7q\2\2\u02e8\u02e9\7w\2\2\u02e9"+
"\u02ea\7d\2\2\u02ea\u02eb\7n\2\2\u02eb\u0335\7g\2\2\u02ec\u02ed\7F\2\2"+
"\u02ed\u02ee\7q\2\2\u02ee\u02ef\7w\2\2\u02ef\u02f0\7d\2\2\u02f0\u02f1"+
"\7n\2\2\u02f1\u0335\7g\2\2\u02f2\u02f3\7n\2\2\u02f3\u02f4\7q\2\2\u02f4"+
"\u02f5\7p\2\2\u02f5\u0335\7i\2\2\u02f6\u02f7\7N\2\2\u02f7\u02f8\7q\2\2"+
"\u02f8\u02f9\7p\2\2\u02f9\u0335\7i\2\2\u02fa\u02fb\7h\2\2\u02fb\u02fc"+
"\7n\2\2\u02fc\u02fd\7q\2\2\u02fd\u02fe\7c\2\2\u02fe\u0335\7v\2\2\u02ff"+
"\u0300\7H\2\2\u0300\u0301\7n\2\2\u0301\u0302\7q\2\2\u0302\u0303\7c\2\2"+
"\u0303\u0335\7v\2\2\u0304\u0305\7D\2\2\u0305\u0306\7k\2\2\u0306\u0307"+
"\7i\2\2\u0307\u0308\7F\2\2\u0308\u0309\7g\2\2\u0309\u030a\7e\2\2\u030a"+
"\u030b\7k\2\2\u030b\u030c\7o\2\2\u030c\u030d\7c\2\2\u030d\u0335\7n\2\2"+
"\u030e\u030f\7d\2\2\u030f\u0310\7q\2\2\u0310\u0311\7q\2\2\u0311\u0312"+
"\7n\2\2\u0312\u0313\7g\2\2\u0313\u0314\7c\2\2\u0314\u0335\7p\2\2\u0315"+
"\u0316\7D\2\2\u0316\u0317\7q\2\2\u0317\u0318\7q\2\2\u0318\u0319\7n\2\2"+
"\u0319\u031a\7g\2\2\u031a\u031b\7c\2\2\u031b\u0335\7p\2\2\u031c\u031d"+
"\7F\2\2\u031d\u031e\7c\2\2\u031e\u031f\7v\2\2\u031f\u0335\7g\2\2\u0320"+
"\u0321\7N\2\2\u0321\u0322\7k\2\2\u0322\u0323\7u\2\2\u0323\u0335\7v\2\2"+
"\u0324\u0325\7U\2\2\u0325\u0326\7g\2\2\u0326\u0335\7v\2\2\u0327\u0328"+
"\7O\2\2\u0328\u0329\7c\2\2\u0329\u0335\7r\2\2\u032a\u032b\7G\2\2\u032b"+
"\u032c\7p\2\2\u032c\u032d\7w\2\2\u032d\u0335\7o\2\2\u032e\u032f\7Q\2\2"+
"\u032f\u0330\7d\2\2\u0330\u0331\7l\2\2\u0331\u0332\7g\2\2\u0332\u0333"+
"\7e\2\2\u0333\u0335\7v\2\2\u0334\u02d6\3\2\2\2\u0334\u02dc\3\2\2\2\u0334"+
"\u02df\3\2\2\2\u0334\u02e6\3\2\2\2\u0334\u02ec\3\2\2\2\u0334\u02f2\3\2"+
"\2\2\u0334\u02f6\3\2\2\2\u0334\u02fa\3\2\2\2\u0334\u02ff\3\2\2\2\u0334"+
"\u0304\3\2\2\2\u0334\u030e\3\2\2\2\u0334\u0315\3\2\2\2\u0334\u031c\3\2"+
"\2\2\u0334\u0320\3\2\2\2\u0334\u0324\3\2\2\2\u0334\u0327\3\2\2\2\u0334"+
"\u032a\3\2\2\2\u0334\u032e\3\2\2\2\u0335\u009e\3\2\2\2\u0336\u033a\7@"+
"\2\2\u0337\u0338\7\u5929\2\2\u0338\u033a\7\u4e90\2\2\u0339\u0336\3\2\2"+
"\2\u0339\u0337\3\2\2\2\u033a\u00a0\3\2\2\2\u033b\u033c\7@\2\2\u033c\u0342"+
"\7?\2\2\u033d\u033e\7\u5929\2\2\u033e\u033f\7\u4e90\2\2\u033f\u0340\7"+
"\u7b4b\2\2\u0340\u0342\7\u4e90\2\2\u0341\u033b\3\2\2\2\u0341\u033d\3\2"+
"\2\2\u0342\u00a2\3\2\2\2\u0343\u0347\7>\2\2\u0344\u0345\7\u5c11\2\2\u0345"+
"\u0347\7\u4e90\2\2\u0346\u0343\3\2\2\2\u0346\u0344\3\2\2\2\u0347\u00a4"+
"\3\2\2\2\u0348\u0349\7>\2\2\u0349\u034f\7?\2\2\u034a\u034b\7\u5c11\2\2"+
"\u034b\u034c\7\u4e90\2\2\u034c\u034d\7\u7b4b\2\2\u034d\u034f\7\u4e90\2"+
"\2\u034e\u0348\3\2\2\2\u034e\u034a\3\2\2\2\u034f\u00a6\3\2\2\2\u0350\u0351"+
"\7?\2\2\u0351\u0355\7?\2\2\u0352\u0353\7\u7b4b\2\2\u0353\u0355\7\u4e90"+
"\2\2\u0354\u0350\3\2\2\2\u0354\u0352\3\2\2\2\u0355\u00a8\3\2\2\2\u0356"+
"\u0357\7#\2\2\u0357\u035c\7?\2\2\u0358\u0359\7\u4e0f\2\2\u0359\u035a\7"+
"\u7b4b\2\2\u035a\u035c\7\u4e90\2\2\u035b\u0356\3\2\2\2\u035b\u0358\3\2"+
"\2\2\u035c\u00aa\3\2\2\2\u035d\u035e\7G\2\2\u035e\u035f\7p\2\2\u035f\u0360"+
"\7f\2\2\u0360\u0361\7Y\2\2\u0361\u0362\7k\2\2\u0362\u0363\7v\2\2\u0363"+
"\u0368\7j\2\2\u0364\u0365\7\u7ed5\2\2\u0365\u0366\7\u6761\2\2\u0366\u0368"+
"\7\u4e90\2\2\u0367\u035d\3\2\2\2\u0367\u0364\3\2\2\2\u0368\u00ac\3\2\2"+
"\2\u0369\u036a\7P\2\2\u036a\u036b\7q\2\2\u036b\u036c\7v\2\2\u036c\u036d"+
"\7G\2\2\u036d\u036e\7p\2\2\u036e\u036f\7f\2\2\u036f\u0370\7Y\2\2\u0370"+
"\u0371\7k\2\2\u0371\u0372\7v\2\2\u0372\u0378\7j\2\2\u0373\u0374\7\u4e0f"+
"\2\2\u0374\u0375\7\u7ed5\2\2\u0375\u0376\7\u6761\2\2\u0376\u0378\7\u4e90"+
"\2\2\u0377\u0369\3\2\2\2\u0377\u0373\3\2\2\2\u0378\u00ae\3\2\2\2\u0379"+
"\u037a\7U\2\2\u037a\u037b\7v\2\2\u037b\u037c\7c\2\2\u037c\u037d\7t\2\2"+
"\u037d\u037e\7v\2\2\u037e\u037f\7Y\2\2\u037f\u0380\7k\2\2\u0380\u0381"+
"\7v\2\2\u0381\u0386\7j\2\2\u0382\u0383\7\u5f02\2\2\u0383\u0384\7\u59cd"+
"\2\2\u0384\u0386\7\u4e90\2\2\u0385\u0379\3\2\2\2\u0385\u0382\3\2\2\2\u0386"+
"\u00b0\3\2\2\2\u0387\u0388\7P\2\2\u0388\u0389\7q\2\2\u0389\u038a\7v\2"+
"\2\u038a\u038b\7U\2\2\u038b\u038c\7v\2\2\u038c\u038d\7c\2\2\u038d\u038e"+
"\7t\2\2\u038e\u038f\7v\2\2\u038f\u0390\7Y\2\2\u0390\u0391\7k\2\2\u0391"+
"\u0392\7v\2\2\u0392\u0398\7j\2\2\u0393\u0394\7\u4e0f\2\2\u0394\u0395\7"+
"\u5f02\2\2\u0395\u0396\7\u59cd\2\2\u0396\u0398\7\u4e90\2\2\u0397\u0387"+
"\3\2\2\2\u0397\u0393\3\2\2\2\u0398\u00b2\3\2\2\2\u0399\u039a\7K\2\2\u039a"+
"\u03a0\7p\2\2\u039b\u039c\7\u572a\2\2\u039c\u039d\7\u96c8\2\2\u039d\u039e"+
"\7\u540a\2\2\u039e\u03a0\7\u4e2f\2\2\u039f\u0399\3\2\2\2\u039f\u039b\3"+
"\2\2\2\u03a0\u00b4\3\2\2\2\u03a1\u03a2\7P\2\2\u03a2\u03a3\7q\2\2\u03a3"+
"\u03a4\7v\2\2\u03a4\u03a5\7K\2\2\u03a5\u03ac\7p\2\2\u03a6\u03a7\7\u4e0f"+
"\2\2\u03a7\u03a8\7\u572a\2\2\u03a8\u03a9\7\u96c8\2\2\u03a9\u03aa\7\u540a"+
"\2\2\u03aa\u03ac\7\u4e2f\2\2\u03ab\u03a1\3\2\2\2\u03ab\u03a6\3\2\2\2\u03ac"+
"\u00b6\3\2\2\2\u03ad\u03ae\7O\2\2\u03ae\u03af\7c\2\2\u03af\u03b0\7v\2"+
"\2\u03b0\u03b1\7e\2\2\u03b1\u03b5\7j\2\2\u03b2\u03b3\7\u533b\2\2\u03b3"+
"\u03b5\7\u914f\2\2\u03b4\u03ad\3\2\2\2\u03b4\u03b2\3\2\2\2\u03b5\u00b8"+
"\3\2\2\2\u03b6\u03b7\7P\2\2\u03b7\u03b8\7q\2\2\u03b8\u03b9\7v\2\2\u03b9"+
"\u03ba\7O\2\2\u03ba\u03bb\7c\2\2\u03bb\u03bc\7v\2\2\u03bc\u03bd\7e\2\2"+
"\u03bd\u03c2\7j\2\2\u03be\u03bf\7\u4e0f\2\2\u03bf\u03c0\7\u533b\2\2\u03c0"+
"\u03c2\7\u914f\2\2\u03c1\u03b6\3\2\2\2\u03c1\u03be\3\2\2\2\u03c2\u00ba"+
"\3\2\2\2\u03c3\u03c4\7E\2\2\u03c4\u03c5\7q\2\2\u03c5\u03c6\7p\2\2\u03c6"+
"\u03c7\7v\2\2\u03c7\u03c8\7c\2\2\u03c8\u03c9\7k\2\2\u03c9\u03cd\7p\2\2"+
"\u03ca\u03cb\7\u5307\2\2\u03cb\u03cd\7\u542d\2\2\u03cc\u03c3\3\2\2\2\u03cc"+
"\u03ca\3\2\2\2\u03cd\u00bc\3\2\2\2\u03ce\u03cf\7P\2\2\u03cf\u03d0\7q\2"+
"\2\u03d0\u03d1\7v\2\2\u03d1\u03d2\7E\2\2\u03d2\u03d3\7q\2\2\u03d3\u03d4"+
"\7p\2\2\u03d4\u03d5\7v\2\2\u03d5\u03d6\7c\2\2\u03d6\u03d7\7k\2\2\u03d7"+
"\u03dc\7p\2\2\u03d8\u03d9\7\u4e0f\2\2\u03d9\u03da\7\u5307\2\2\u03da\u03dc"+
"\7\u542d\2\2\u03db\u03ce\3\2\2\2\u03db\u03d8\3\2\2\2\u03dc\u00be\3\2\2"+
"\2\u03dd\u03de\7G\2\2\u03de\u03df\7s\2\2\u03df\u03e0\7w\2\2\u03e0\u03e1"+
"\7c\2\2\u03e1\u03e2\7n\2\2\u03e2\u03e3\7u\2\2\u03e3\u03e4\7K\2\2\u03e4"+
"\u03e5\7i\2\2\u03e5\u03e6\7p\2\2\u03e6\u03e7\7q\2\2\u03e7\u03e8\7t\2\2"+
"\u03e8\u03e9\7g\2\2\u03e9\u03ea\7E\2\2\u03ea\u03eb\7c\2\2\u03eb\u03ec"+
"\7u\2\2\u03ec\u03f5\7g\2\2\u03ed\u03ee\7\u5fff\2\2\u03ee\u03ef\7\u7567"+
"\2\2\u03ef\u03f0\7\u5929\2\2\u03f0\u03f1\7\u5c11\2\2\u03f1\u03f2\7\u519b"+
"\2\2\u03f2\u03f3\7\u7b4b\2\2\u03f3\u03f5\7\u4e90\2\2\u03f4\u03dd\3\2\2"+
"\2\u03f4\u03ed\3\2\2\2\u03f5\u00c0\3\2\2\2\u03f6\u03f7\7P\2\2\u03f7\u03f8"+
"\7q\2\2\u03f8\u03f9\7v\2\2\u03f9\u03fa\7G\2\2\u03fa\u03fb\7s\2\2\u03fb"+
"\u03fc\7w\2\2\u03fc\u03fd\7c\2\2\u03fd\u03fe\7n\2\2\u03fe\u03ff\7u\2\2"+
"\u03ff\u0400\7K\2\2\u0400\u0401\7i\2\2\u0401\u0402\7p\2\2\u0402\u0403"+
"\7q\2\2\u0403\u0404\7t\2\2\u0404\u0405\7g\2\2\u0405\u0406\7E\2\2\u0406"+
"\u0407\7c\2\2\u0407\u0408\7u\2\2\u0408\u0412\7g\2\2\u0409\u040a\7\u5fff"+
"\2\2\u040a\u040b\7\u7567\2\2\u040b\u040c\7\u5929\2\2\u040c\u040d\7\u5c11"+
"\2\2\u040d\u040e\7\u519b\2\2\u040e\u040f\7\u4e0f\2\2\u040f\u0410\7\u7b4b"+
"\2\2\u0410\u0412\7\u4e90\2\2\u0411\u03f6\3\2\2\2\u0411\u0409\3\2\2\2\u0412"+
"\u00c2\3\2\2\2\u0413\u0414\t\2\2\2\u0414\u00c4\3\2\2\2\u0415\u0417\7/"+
"\2\2\u0416\u0415\3\2\2\2\u0416\u0417\3\2\2\2\u0417\u0418\3\2\2\2\u0418"+
"\u0419\5\u00cfh\2\u0419\u041a\7\60\2\2\u041a\u041c\5\u00cfh\2\u041b\u041d"+
"\5\u00d1i\2\u041c\u041b\3\2\2\2\u041c\u041d\3\2\2\2\u041d\u0429\3\2\2"+
"\2\u041e\u0420\7/\2\2\u041f\u041e\3\2\2\2\u041f\u0420\3\2\2\2\u0420\u0421"+
"\3\2\2\2\u0421\u0422\5\u00cfh\2\u0422\u0423\5\u00d1i\2\u0423\u0429\3\2"+
"\2\2\u0424\u0426\7/\2\2\u0425\u0424\3\2\2\2\u0425\u0426\3\2\2\2\u0426"+
"\u0427\3\2\2\2\u0427\u0429\5\u00cfh\2\u0428\u0416\3\2\2\2\u0428\u041f"+
"\3\2\2\2\u0428\u0425\3\2\2\2\u0429\u00c6\3\2\2\2\u042a\u042b\7v\2\2\u042b"+
"\u042c\7t\2\2\u042c\u042d\7w\2\2\u042d\u0434\7g\2\2\u042e\u042f\7h\2\2"+
"\u042f\u0430\7c\2\2\u0430\u0431\7n\2\2\u0431\u0432\7u\2\2\u0432\u0434"+
"\7g\2\2\u0433\u042a\3\2\2\2\u0433\u042e\3\2\2\2\u0434\u00c8\3\2\2\2\u0435"+
"\u0439\5\u00dbn\2\u0436\u0438\5\u00d9m\2\u0437\u0436\3\2\2\2\u0438\u043b"+
"\3\2\2\2\u0439\u0437\3\2\2\2\u0439\u043a\3\2\2\2\u043a\u00ca\3\2\2\2\u043b"+
"\u0439\3\2\2\2\u043c\u043d\7$\2\2\u043d\u043e\5\u00cdg\2\u043e\u043f\7"+
"$\2\2\u043f\u00cc\3\2\2\2\u0440\u0443\5\u00d3j\2\u0441\u0443\n\3\2\2\u0442"+
"\u0440\3\2\2\2\u0442\u0441\3\2\2\2\u0443\u0446\3\2\2\2\u0444\u0442\3\2"+
"\2\2\u0444\u0445\3\2\2\2\u0445\u00ce\3\2\2\2\u0446\u0444\3\2\2\2\u0447"+
"\u0449\5\u00ddo\2\u0448\u0447\3\2\2\2\u0449\u044a\3\2\2\2\u044a\u0448"+
"\3\2\2\2\u044a\u044b\3\2\2\2\u044b\u00d0\3\2\2\2\u044c\u044e\t\4\2\2\u044d"+
"\u044f\t\5\2\2\u044e\u044d\3\2\2\2\u044e\u044f\3\2\2\2\u044f\u0450\3\2"+
"\2\2\u0450\u0451\5\u00cfh\2\u0451\u00d2\3\2\2\2\u0452\u0453\7^\2\2\u0453"+
"\u0457\t\6\2\2\u0454\u0457\5\u00d7l\2\u0455\u0457\5\u00d5k\2\u0456\u0452"+
"\3\2\2\2\u0456\u0454\3\2\2\2\u0456\u0455\3\2\2\2\u0457\u00d4\3\2\2\2\u0458"+
"\u0459\7^\2\2\u0459\u045a\4\62\65\2\u045a\u045b\4\629\2\u045b\u0462\4"+
"\629\2\u045c\u045d\7^\2\2\u045d\u045e\4\629\2\u045e\u0462\4\629\2\u045f"+
"\u0460\7^\2\2\u0460\u0462\4\629\2\u0461\u0458\3\2\2\2\u0461\u045c\3\2"+
"\2\2\u0461\u045f\3\2\2\2\u0462\u00d6\3\2\2\2\u0463\u0464\7^\2\2\u0464"+
"\u0465\7w\2\2\u0465\u0466\5\u00dfp\2\u0466\u0467\5\u00dfp\2\u0467\u0468"+
"\5\u00dfp\2\u0468\u0469\5\u00dfp\2\u0469\u00d8\3\2\2\2\u046a\u046f\5\u00db"+
"n\2\u046b\u046f\t\7\2\2\u046c\u046f\5\u00ddo\2\u046d\u046f\t\b\2\2\u046e"+
"\u046a\3\2\2\2\u046e\u046b\3\2\2\2\u046e\u046c\3\2\2\2\u046e\u046d\3\2"+
"\2\2\u046f\u00da\3\2\2\2\u0470\u0472\t\t\2\2\u0471\u0470\3\2\2\2\u0472"+
"\u00dc\3\2\2\2\u0473\u0474\t\n\2\2\u0474\u00de\3\2\2\2\u0475\u0476\t\13"+
"\2\2\u0476\u00e0\3\2\2\2\u0477\u0479\t\f\2\2\u0478\u0477\3\2\2\2\u0479"+
"\u047a\3\2\2\2\u047a\u0478\3\2\2\2\u047a\u047b\3\2\2\2\u047b\u047c\3\2"+
"\2\2\u047c\u047d\bq\2\2\u047d\u00e2\3\2\2\2\u047e\u0480\7\17\2\2\u047f"+
"\u047e\3\2\2\2\u047f\u0480\3\2\2\2\u0480\u0481\3\2\2\2\u0481\u0482\7\f"+
"\2\2\u0482\u0483\3\2\2\2\u0483\u0484\br\2\2\u0484\u00e4\3\2\2\2\u0485"+
"\u0486\7\61\2\2\u0486\u0487\7,\2\2\u0487\u048b\3\2\2\2\u0488\u048a\13"+
"\2\2\2\u0489\u0488\3\2\2\2\u048a\u048d\3\2\2\2\u048b\u048c\3\2\2\2\u048b"+
"\u0489\3\2\2\2\u048c\u048e\3\2\2\2\u048d\u048b\3\2\2\2\u048e\u048f\7,"+
"\2\2\u048f\u0490\7\61\2\2\u0490\u0491\3\2\2\2\u0491\u0492\bs\2\2\u0492"+
"\u00e6\3\2\2\2\u0493\u0494\7\61\2\2\u0494\u0495\7\61\2\2\u0495\u0499\3"+
"\2\2\2\u0496\u0498\n\r\2\2\u0497\u0496\3\2\2\2\u0498\u049b\3\2\2\2\u0499"+
"\u0497\3\2\2\2\u0499\u049a\3\2\2\2\u049a\u049d\3\2\2\2\u049b\u0499\3\2"+
"\2\2\u049c\u049e\7\17\2\2\u049d\u049c\3\2\2\2\u049d\u049e\3\2\2\2\u049e"+
"\u049f\3\2\2\2\u049f\u04a0\7\f\2\2\u04a0\u04a1\3\2\2\2\u04a1\u04a2\bt"+
"\2\2\u04a2\u00e8\3\2\2\2,\2\u02cb\u02d4\u0334\u0339\u0341\u0346\u034e"+
"\u0354\u035b\u0367\u0377\u0385\u0397\u039f\u03ab\u03b4\u03c1\u03cc\u03db"+
"\u03f4\u0411\u0416\u041c\u041f\u0425\u0428\u0433\u0439\u0442\u0444\u044a"+
"\u044e\u0456\u0461\u046e\u0471\u047a\u047f\u048b\u0499\u049d\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}
@@ -0,0 +1,180 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
T__10=11
T__11=12
T__12=13
T__13=14
T__14=15
T__15=16
T__16=17
T__17=18
T__18=19
T__19=20
T__20=21
T__21=22
T__22=23
T__23=24
T__24=25
T__25=26
T__26=27
T__27=28
T__28=29
T__29=30
T__30=31
T__31=32
T__32=33
T__33=34
T__34=35
T__35=36
T__36=37
T__37=38
T__38=39
T__39=40
T__40=41
T__41=42
T__42=43
T__43=44
T__44=45
T__45=46
T__46=47
T__47=48
T__48=49
T__49=50
T__50=51
T__51=52
T__52=53
T__53=54
T__54=55
T__55=56
T__56=57
T__57=58
T__58=59
T__59=60
T__60=61
T__61=62
T__62=63
T__63=64
T__64=65
T__65=66
T__66=67
T__67=68
T__68=69
T__69=70
COUNT=71
AVG=72
SUM=73
MAX=74
MIN=75
AND=76
OR=77
Datatype=78
GreaterThen=79
GreaterThenOrEquals=80
LessThen=81
LessThenOrEquals=82
Equals=83
NotEquals=84
EndWith=85
NotEndWith=86
StartWith=87
NotStartWith=88
In=89
NotIn=90
Match=91
NotMatch=92
Contain=93
NotContain=94
EqualsIgnoreCase=95
NotEqualsIgnoreCase=96
ARITH=97
NUMBER=98
Boolean=99
Identifier=100
STRING=101
WS=102
NL=103
COMMENT=104
LINE_COMMENT=105
'import'=1
';'=2
'.'=3
'.*'=4
'importParameterLibrary'=5
'importVariableLibrary'=6
'importConstantLibrary'=7
'importActionLibrary'=8
'function'=9
'('=10
')'=11
'{'=12
'}'=13
','=14
'rule'=15
'\u89c4\u5219'=16
'end'=17
'\u7ed3\u675f'=18
'loopRule'=19
'\u5faa\u73af\u89c4\u5219'=20
'loopTarget'=21
'\u5faa\u73af\u5bf9\u8c61'=22
'loopStart'=23
'\u5f00\u59cb\u524d\u52a8\u4f5c'=24
'loopEnd'=25
'\u7ed3\u675f\u540e\u52a8\u4f5c'=26
'loop'=27
'\u5141\u8bb8\u5faa\u73af\u89e6\u53d1'=28
'='=29
'salience'=30
'\u4f18\u5148\u7ea7'=31
'effective-date'=32
'\u751f\u6548\u65f6\u95f4'=33
'\u751f\u6548\u65e5\u671f'=34
'expires-date'=35
'\u5931\u6548\u65f6\u95f4'=36
'\u5931\u6548\u65e5\u671f'=37
'enabled'=38
'\u6fc0\u6d3b'=39
'\u542f\u7528'=40
'debug'=41
'\u8c03\u8bd5'=42
'\u5141\u8bb8\u8c03\u8bd5'=43
'activation-group'=44
'\u6fc0\u6d3b\u7ec4'=45
'agenda-group'=46
'\u8bae\u7a0b\u7ec4'=47
'auto-focus'=48
'\u81ea\u52a8\u83b7\u53d6\u7126\u70b9'=49
'ruleflow-group'=50
'\u89c4\u5219\u6d41\u7ec4'=51
'if'=52
'\u5982\u679c'=53
'null'=54
'eval'=55
'all'=56
'exist'=57
'collect'=58
'%'=59
':'=60
'then'=61
'\u90a3\u4e48'=62
'else'=63
'\u5426\u5219'=64
'out'=65
'@'=66
'parameter'=67
'\u53c2\u6570'=68
'!'=69
'$'=70
'count'=71
'avg'=72
'sum'=73
'max'=74
'min'=75
@@ -0,0 +1,503 @@
// Generated from RuleParser.g4 by ANTLR 4.5.3
package com.itheima.sfbx.framework.rule.dsl;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link RuleParserParser}.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public interface RuleParserVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link RuleParserParser#ruleSet}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRuleSet(RuleParserParser.RuleSetContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#ruleSetHeader}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRuleSetHeader(RuleParserParser.RuleSetHeaderContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#ruleSetBody}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRuleSetBody(RuleParserParser.RuleSetBodyContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#rules}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRules(RuleParserParser.RulesContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#functionImport}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunctionImport(RuleParserParser.FunctionImportContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#packageDef}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitPackageDef(RuleParserParser.PackageDefContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#resource}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitResource(RuleParserParser.ResourceContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#importParameterLibrary}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitImportParameterLibrary(RuleParserParser.ImportParameterLibraryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#importVariableLibrary}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitImportVariableLibrary(RuleParserParser.ImportVariableLibraryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#importConstantLibrary}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitImportConstantLibrary(RuleParserParser.ImportConstantLibraryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#importActionLibrary}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitImportActionLibrary(RuleParserParser.ImportActionLibraryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#functionDef}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunctionDef(RuleParserParser.FunctionDefContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#functionParameters}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunctionParameters(RuleParserParser.FunctionParametersContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#functionParameter}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunctionParameter(RuleParserParser.FunctionParameterContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#ruleDef}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRuleDef(RuleParserParser.RuleDefContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#loopRuleDef}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLoopRuleDef(RuleParserParser.LoopRuleDefContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#loopTarget}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLoopTarget(RuleParserParser.LoopTargetContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#loopStart}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLoopStart(RuleParserParser.LoopStartContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#loopEnd}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLoopEnd(RuleParserParser.LoopEndContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#attribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAttribute(RuleParserParser.AttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#loopAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLoopAttribute(RuleParserParser.LoopAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#salienceAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSalienceAttribute(RuleParserParser.SalienceAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#effectiveDateAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitEffectiveDateAttribute(RuleParserParser.EffectiveDateAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#expiresDateAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpiresDateAttribute(RuleParserParser.ExpiresDateAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#enabledAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitEnabledAttribute(RuleParserParser.EnabledAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#debugAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDebugAttribute(RuleParserParser.DebugAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#activationGroupAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitActivationGroupAttribute(RuleParserParser.ActivationGroupAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#agendaGroupAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAgendaGroupAttribute(RuleParserParser.AgendaGroupAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#autoFocusAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAutoFocusAttribute(RuleParserParser.AutoFocusAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#ruleflowGroupAttribute}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRuleflowGroupAttribute(RuleParserParser.RuleflowGroupAttributeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#left}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLeft(RuleParserParser.LeftContext ctx);
/**
* Visit a parse tree produced by the {@code parenConditions}
* labeled alternative in {@link RuleParserParser#condition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParenConditions(RuleParserParser.ParenConditionsContext ctx);
/**
* Visit a parse tree produced by the {@code multiConditions}
* labeled alternative in {@link RuleParserParser#condition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMultiConditions(RuleParserParser.MultiConditionsContext ctx);
/**
* Visit a parse tree produced by the {@code singleCondition}
* labeled alternative in {@link RuleParserParser#condition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSingleCondition(RuleParserParser.SingleConditionContext ctx);
/**
* Visit a parse tree produced by the {@code singleNamedConditionSet}
* labeled alternative in {@link RuleParserParser#condition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSingleNamedConditionSet(RuleParserParser.SingleNamedConditionSetContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#namedConditionSet}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNamedConditionSet(RuleParserParser.NamedConditionSetContext ctx);
/**
* Visit a parse tree produced by the {@code parenNamedConditions}
* labeled alternative in {@link RuleParserParser#namedCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParenNamedConditions(RuleParserParser.ParenNamedConditionsContext ctx);
/**
* Visit a parse tree produced by the {@code multiNamedConditions}
* labeled alternative in {@link RuleParserParser#namedCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMultiNamedConditions(RuleParserParser.MultiNamedConditionsContext ctx);
/**
* Visit a parse tree produced by the {@code singleNamedConditions}
* labeled alternative in {@link RuleParserParser#namedCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSingleNamedConditions(RuleParserParser.SingleNamedConditionsContext ctx);
/**
* Visit a parse tree produced by the {@code singleCellCondition}
* labeled alternative in {@link RuleParserParser#decisionTableCellCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSingleCellCondition(RuleParserParser.SingleCellConditionContext ctx);
/**
* Visit a parse tree produced by the {@code multiCellConditions}
* labeled alternative in {@link RuleParserParser#decisionTableCellCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMultiCellConditions(RuleParserParser.MultiCellConditionsContext ctx);
/**
* Visit a parse tree produced by the {@code parenCellConditions}
* labeled alternative in {@link RuleParserParser#decisionTableCellCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParenCellConditions(RuleParserParser.ParenCellConditionsContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#refName}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRefName(RuleParserParser.RefNameContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#refObject}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRefObject(RuleParserParser.RefObjectContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#nullValue}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNullValue(RuleParserParser.NullValueContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#conditionLeft}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConditionLeft(RuleParserParser.ConditionLeftContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#expEval}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpEval(RuleParserParser.ExpEvalContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#expAll}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpAll(RuleParserParser.ExpAllContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#expExists}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpExists(RuleParserParser.ExpExistsContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#expCollect}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpCollect(RuleParserParser.ExpCollectContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#commonFunction}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitCommonFunction(RuleParserParser.CommonFunctionContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#exprCondition}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprCondition(RuleParserParser.ExprConditionContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#expressionBody}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExpressionBody(RuleParserParser.ExpressionBodyContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#percent}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitPercent(RuleParserParser.PercentContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#leftParen}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLeftParen(RuleParserParser.LeftParenContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#rightParen}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRightParen(RuleParserParser.RightParenContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#colon}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitColon(RuleParserParser.ColonContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#join}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitJoin(RuleParserParser.JoinContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#right}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitRight(RuleParserParser.RightContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#other}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitOther(RuleParserParser.OtherContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#actions}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitActions(RuleParserParser.ActionsContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#action}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAction(RuleParserParser.ActionContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#assignAction}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAssignAction(RuleParserParser.AssignActionContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#outAction}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitOutAction(RuleParserParser.OutActionContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#methodInvoke}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitMethodInvoke(RuleParserParser.MethodInvokeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#functionInvoke}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFunctionInvoke(RuleParserParser.FunctionInvokeContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#actionParameters}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitActionParameters(RuleParserParser.ActionParametersContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#beanMethod}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitBeanMethod(RuleParserParser.BeanMethodContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#complexValue}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitComplexValue(RuleParserParser.ComplexValueContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#parameter}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParameter(RuleParserParser.ParameterContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#parameterName}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParameterName(RuleParserParser.ParameterNameContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#constant}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConstant(RuleParserParser.ConstantContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#variable}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitVariable(RuleParserParser.VariableContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#namedVariable}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNamedVariable(RuleParserParser.NamedVariableContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#property}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitProperty(RuleParserParser.PropertyContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#variableCategory}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitVariableCategory(RuleParserParser.VariableCategoryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#namedVariableCategory}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNamedVariableCategory(RuleParserParser.NamedVariableCategoryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#constantCategory}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConstantCategory(RuleParserParser.ConstantCategoryContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#value}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitValue(RuleParserParser.ValueContext ctx);
/**
* Visit a parse tree produced by {@link RuleParserParser#op}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitOp(RuleParserParser.OpContext ctx);
}
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
/**
* @author Jacky.gao
* @since 2015年5月11日
*/
public class ScriptDecisionTableErrorListener extends BaseErrorListener {
private StringBuffer sb;
@Override
public void syntaxError(Recognizer<?, ?> recognizer,Object offendingSymbol,
int line, int charPositionInLine,
String msg, RecognitionException e) {
if(sb==null){
sb=new StringBuffer();
}
sb.append("["+offendingSymbol+"] is invalid:"+msg);
sb.append("\r\n");
}
public String getErrorMessage(){
if(sb==null){
return null;
}
return sb.toString();
}
}
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
/**
* @author Jacky.gao
* @since 2015年2月27日
*/
public class SyntaxErrorListener extends BaseErrorListener {
private SyntaxErrorReportor reportor;
public SyntaxErrorListener(SyntaxErrorReportor reportor) {
this.reportor=reportor;
}
@Override
public void syntaxError(Recognizer<?, ?> recognizer,
Object offendingSymbol, int line, int charPositionInLine,
String msg, RecognitionException e) {
this.reportor.addError(line, charPositionInLine, offendingSymbol, msg);
//super.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
}
}
@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年2月27日
*/
public class SyntaxErrorReportor {
private List<String> errorList=new ArrayList<String>();
public void addError(int line,int charPositionInLine,Object offendingSymbol,String msg){
errorList.add(line+"行,"+charPositionInLine+"列,"+offendingSymbol+"字符处,存在语法错误:"+msg);
}
public String getSyntaxErrorMessage(){
StringBuffer sb=new StringBuffer();
for(String msg:errorList){
sb.append(msg);
sb.append("\n");
}
return sb.toString();
}
}
@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
/**
* @author Jacky.gao
* @since 2015年2月15日
*/
public abstract class AbstractContextBuilder implements ContextBuilder {
}
@@ -0,0 +1,133 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.*;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.*;
import com.itheima.sfbx.framework.rule.model.function.FunctionDescriptor;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableCategory;
import com.itheima.sfbx.framework.rule.model.rule.Parameter;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.rule.lhs.CommonFunctionParameter;
import com.itheima.sfbx.framework.rule.model.rule.lhs.LeftType;
import org.antlr.v4.runtime.ParserRuleContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Collection;
/**
* @author Jacky.gao
* @since 2015年2月15日
*/
public class ActionContextBuilder extends AbstractContextBuilder implements ApplicationContextAware{
private Collection<FunctionDescriptor> functionDescriptors;
@Override
public Action build(ParserRuleContext context) {
ActionContext ctx=(ActionContext)context;
if(ctx.outAction()!=null){
return buildConsolePrintAction(ctx.outAction());
}else if(ctx.assignAction()!=null){
return buildVariableAssignAction(ctx.assignAction());
}else if(ctx.methodInvoke()!=null){
return buildExecuteMethodAction(ctx.methodInvoke());
}else if(ctx.commonFunction()!=null){
return buildExecuteCommonFunctionAction(ctx.commonFunction());
}
return null;
}
private ExecuteCommonFunctionAction buildExecuteCommonFunctionAction(CommonFunctionContext context){
ExecuteCommonFunctionAction action=new ExecuteCommonFunctionAction();
String nameorlabel=context.Identifier().getText();
for(FunctionDescriptor fun:functionDescriptors){
if(nameorlabel.equals(fun.getName())){
action.setName(fun.getName());
action.setLabel(fun.getLabel());
break;
}else if(nameorlabel.equals(fun.getLabel())){
action.setName(fun.getName());
action.setLabel(fun.getLabel());
break;
}
}
if(action.getName()==null){
throw new RuleException("Function["+nameorlabel+"] not exist.");
}
ComplexValueContext value=context.complexValue();
CommonFunctionParameter param=new CommonFunctionParameter();
param.setObjectParameter(BuildUtils.buildValue(value));
PropertyContext propertyContext=context.property();
if(propertyContext!=null){
param.setProperty(propertyContext.getText());
}
action.setParameter(param);
return action;
}
private ExecuteMethodAction buildExecuteMethodAction(MethodInvokeContext context){
ExecuteMethodAction action=new ExecuteMethodAction();
BeanMethodContext methodContext=context.beanMethod();
action.setBeanLabel(methodContext.getChild(0).getText());
action.setMethodLabel(methodContext.getChild(2).getText());
ActionParametersContext parametersContext=context.actionParameters();
if(parametersContext!=null){
for(ComplexValueContext ctx:parametersContext.complexValue()){
Parameter parameter=new Parameter();
parameter.setValue(BuildUtils.buildValue(ctx));
action.addParameter(parameter);
}
}
return action;
}
private VariableAssignAction buildVariableAssignAction(AssignActionContext context){
VariableAssignAction action=new VariableAssignAction();
ParameterContext parameterContext=context.parameter();
NamedVariableContext namedVariableContext=context.namedVariable();
if(namedVariableContext!=null){
action.setReferenceName(namedVariableContext.namedVariableCategory().getText());
action.setVariableLabel(namedVariableContext.property().getText());
action.setType(LeftType.NamedReference);
}else if(parameterContext==null){
action.setVariableCategory(context.variable().variableCategory().getText());
action.setVariableLabel(context.variable().property().getText());
}else{
action.setVariableCategory(VariableCategory.PARAM_CATEGORY);
action.setVariableLabel(parameterContext.Identifier().getText());
}
action.setValue(BuildUtils.buildValue(context.complexValue()));
return action;
}
private ConsolePrintAction buildConsolePrintAction(OutActionContext context){
ConsolePrintAction action=new ConsolePrintAction();
Value value=BuildUtils.buildValue(context.complexValue());
action.setValue(value);
return action;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
functionDescriptors=applicationContext.getBeansOfType(FunctionDescriptor.class).values();
}
@Override
public boolean support(ParserRuleContext context) {
return context instanceof ActionContext;
}
}
@@ -0,0 +1,158 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.Utils;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.*;
import com.itheima.sfbx.framework.rule.model.function.FunctionDescriptor;
import com.itheima.sfbx.framework.rule.model.rule.*;
import com.itheima.sfbx.framework.rule.model.rule.lhs.CommonFunctionParameter;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年6月1日
*/
public class BuildUtils {
public static AbstractValue buildValue(ComplexValueContext context){
AbstractValue value=null;
if(context.leftParen()!=null){
ParenValue pv=new ParenValue();
List<ComplexValueContext> values=context.complexValue();
Value v=buildValue(values.get(0));
pv.setValue(v);
value=pv;
}else if(context.value()!=null){
value=buildSimpleValue(context.value());
}else if(context.variable()!=null){
value=buildVariableValue(context.variable());
}else if(context.constant()!=null){
value=buildConstantValue(context.constant());
}else if(context.variableCategory()!=null){
VariableCategoryContext vcc=context.variableCategory();
String name=vcc.Identifier().getText();
value=new VariableCategoryValue(name);
}else if(context.parameter()!=null){
ParameterContext parameterContext=context.parameter();
ParameterValue parameterValue=new ParameterValue();
parameterValue.setVariableLabel(parameterContext.Identifier().getText());
value=parameterValue;
}else if(context.namedVariable()!=null){
NamedVariableContext namedVariableContext=context.namedVariable();
String refName=namedVariableContext.namedVariableCategory().getText();
String property=namedVariableContext.property().getText();
NamedReferenceValue refValue=new NamedReferenceValue();
refValue.setReferenceName(refName);
refValue.setPropertyLabel(property);
value=refValue;
}else if(context.methodInvoke()!=null){
MethodInvokeContext actionContext=(MethodInvokeContext)context.methodInvoke();
MethodValue mv=new MethodValue();
BeanMethodContext beanMethodContext=actionContext.beanMethod();
String beanLabel=beanMethodContext.Identifier(0).getText();
String methodLabel=beanMethodContext.Identifier(1).getText();
mv.setBeanLabel(beanLabel);
mv.setMethodLabel(methodLabel);
ActionParametersContext actionParametersContext=actionContext.actionParameters();
if(actionParametersContext!=null && actionParametersContext.complexValue()!=null){
List<ComplexValueContext> values=actionParametersContext.complexValue();
List<Parameter> parameters=new ArrayList<Parameter>();
for(ComplexValueContext cvx:values){
Parameter parameter=new Parameter();
parameter.setValue(buildValue(cvx));
parameters.add(parameter);
}
mv.setParameters(parameters);
}
value=mv;
}else if(context.commonFunction()!=null){
CommonFunctionContext commonFunctionContext=context.commonFunction();
Collection<FunctionDescriptor> functionDescriptors=Utils.getApplicationContext().getBeansOfType(FunctionDescriptor.class).values();
CommonFunctionValue functionValue=new CommonFunctionValue();
String nameorlabel=commonFunctionContext.Identifier().getText();
for(FunctionDescriptor fun:functionDescriptors){
if(nameorlabel.equals(fun.getName())){
functionValue.setName(fun.getName());
functionValue.setLabel(fun.getLabel());
break;
}else if(nameorlabel.equals(fun.getLabel())){
functionValue.setName(fun.getName());;
functionValue.setLabel(fun.getLabel());
break;
}
}
if(functionValue.getName()==null){
throw new RuleException("Function["+nameorlabel+"] not exist.");
}
ComplexValueContext complexValue=commonFunctionContext.complexValue();
CommonFunctionParameter param=new CommonFunctionParameter();
param.setObjectParameter(buildValue(complexValue));
PropertyContext propertyContext=commonFunctionContext.property();
if(propertyContext!=null){
param.setProperty(propertyContext.getText());
}
functionValue.setParameter(param);
value=functionValue;
}else if(context.complexValue()!=null){
List<ComplexValueContext> values=context.complexValue();
value=buildValue(values.get(0));
}
List<TerminalNode> arithList=context.ARITH();
if(arithList!=null && arithList.size()>0){
TerminalNode arithNode=arithList.get(0);
ComplexArithmetic arith=new ComplexArithmetic();
arith.setType(ArithmeticType.parse(arithNode.getText()));
ParseTree nextContext=context.getChild(2);
arith.setValue(buildValue((ComplexValueContext)nextContext));
value.setArithmetic(arith);
}
return value;
}
private static ConstantValue buildConstantValue(ConstantContext context){
ConstantValue value=new ConstantValue();
value.setConstantCategory(context.constantCategory().Identifier().getText());
value.setConstantLabel(context.property().getText());
return value;
}
private static VariableValue buildVariableValue(VariableContext context){
VariableValue value=new VariableValue();
value.setVariableCategory(context.variableCategory().getText());
value.setVariableLabel(context.property().getText());
return value;
}
private static SimpleValue buildSimpleValue(ValueContext context){
SimpleValue value=new SimpleValue();
if(context.STRING()!=null){
value.setContent(getSTRINGContent(context.STRING()));
}else if(context.Boolean()!=null){
value.setContent(context.Boolean().getText());
}else if(context.NUMBER()!=null){
value.setContent(context.NUMBER().getText());
}
return value;
}
public static String getSTRINGContent(TerminalNode node){
String text=node.getText();
return text.substring(1,text.length()-1);
}
}
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
import org.antlr.v4.runtime.ParserRuleContext;
/**
* @author Jacky.gao
* @since 2015年2月15日
*/
public interface ContextBuilder {
Object build(ParserRuleContext context);
boolean support(ParserRuleContext context);
}
@@ -0,0 +1,308 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.dsl.DSLUtils;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.*;
import com.itheima.sfbx.framework.rule.model.function.FunctionDescriptor;
import com.itheima.sfbx.framework.rule.model.library.variable.VariableCategory;
import com.itheima.sfbx.framework.rule.model.rule.Op;
import com.itheima.sfbx.framework.rule.model.rule.Parameter;
import com.itheima.sfbx.framework.rule.model.rule.lhs.*;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年2月15日
*/
public class CriteriaContextBuilder extends AbstractContextBuilder implements ApplicationContextAware{
private Collection<FunctionDescriptor> functionDescriptors;
@Override
public Criteria build(ParserRuleContext context) {
SingleConditionContext ctx=(SingleConditionContext)context;
ConditionLeftContext conditionLeftContext=ctx.conditionLeft();
VariableContext variableContext=conditionLeftContext.variable();
ParameterContext parameterContext=conditionLeftContext.parameter();
FunctionInvokeContext functionInvokeContext=conditionLeftContext.functionInvoke();
CommonFunctionContext commonFunctionContext=conditionLeftContext.commonFunction();
MethodInvokeContext methodInvokeContext=conditionLeftContext.methodInvoke();
ExpEvalContext expEvalContext=conditionLeftContext.expEval();
ExpAllContext expAllContext=conditionLeftContext.expAll();
ExpExistsContext expExistsContext=conditionLeftContext.expExists();
ExpCollectContext expCollectContext=conditionLeftContext.expCollect();
Criteria criteria=new Criteria();
Left left=new Left();
LeftPart leftPart=null;
String variableCategory=null;
String variableLabel=null;
if(variableContext!=null){
variableCategory=variableContext.variableCategory().Identifier().getText();
variableLabel=variableContext.property().getText();
VariableLeftPart part = new VariableLeftPart();
part.setVariableCategory(variableCategory);
part.setVariableLabel(variableLabel);
left.setType(LeftType.variable);
leftPart=part;
}else if(parameterContext!=null){
variableCategory=VariableCategory.PARAM_CATEGORY;
variableLabel=parameterContext.Identifier().getText();
VariableLeftPart part = new VariableLeftPart();
part.setVariableCategory(variableCategory);
part.setVariableLabel(variableLabel);
left.setType(LeftType.variable);
leftPart=part;
}else if(functionInvokeContext!=null){
FunctionLeftPart part=new FunctionLeftPart();
String name=functionInvokeContext.Identifier().getText();
ActionParametersContext parametersContext = functionInvokeContext.actionParameters();
if(parametersContext!=null){
List<Parameter> parameters=new ArrayList<Parameter>();
for(ComplexValueContext complexValueContext:parametersContext.complexValue()){
Parameter parameter=new Parameter();
parameter.setValue(BuildUtils.buildValue(complexValueContext));
parameters.add(parameter);
}
part.setParameters(parameters);
}
part.setName(name);
left.setType(LeftType.function);
leftPart=part;
}else if(commonFunctionContext!=null){
CommonFunctionLeftPart part=new CommonFunctionLeftPart();
String nameorlabel=commonFunctionContext.Identifier().getText();
for(FunctionDescriptor fun:functionDescriptors){
if(nameorlabel.equals(fun.getName())){
part.setName(fun.getName());
part.setLabel(fun.getLabel());
break;
}else if(nameorlabel.equals(fun.getLabel())){
part.setName(fun.getName());
part.setLabel(fun.getLabel());
break;
}
}
if(part.getName()==null){
throw new RuleException("Function["+nameorlabel+"] not exist.");
}
ComplexValueContext value=commonFunctionContext.complexValue();
CommonFunctionParameter param=new CommonFunctionParameter();
param.setObjectParameter(BuildUtils.buildValue(value));
PropertyContext propertyContext=commonFunctionContext.property();
if(propertyContext!=null){
param.setProperty(propertyContext.getText());
}
part.setParameter(param);
left.setType(LeftType.commonfunction);
leftPart=part;
}else if(methodInvokeContext!=null){
MethodLeftPart part=new MethodLeftPart();
BeanMethodContext beanMethodContext=methodInvokeContext.beanMethod();
String beanLabel=beanMethodContext.Identifier(0).getText();
String methodLabel=beanMethodContext.Identifier(1).getText();
part.setBeanLabel(beanLabel);
part.setMethodLabel(methodLabel);
ActionParametersContext parametersContext=methodInvokeContext.actionParameters();
if(parametersContext!=null){
List<Parameter> parameters=new ArrayList<Parameter>();
for(ComplexValueContext complexValueContext:parametersContext.complexValue()){
Parameter parameter=new Parameter();
parameter.setValue(BuildUtils.buildValue(complexValueContext));
parameters.add(parameter);
}
part.setParameters(parameters);
}
left.setType(LeftType.method);
leftPart=part;
}else if(expEvalContext!=null){
EvalLeftPart part=new EvalLeftPart();
ExpressionBodyContext bodyContext=expEvalContext.expressionBody();
part.setExpression(bodyContext.getText());
left.setType(LeftType.eval);
leftPart=part;
}else if(expAllContext!=null){
AllLeftPart part=new AllLeftPart();
VariableContext vc=expAllContext.variable();
ParameterContext pc=expAllContext.parameter();
if(vc!=null){
part.setVariableCategory(vc.variableCategory().getText());
part.setVariableLabel(vc.property().getText());
}else if(pc!=null){
part.setVariableCategory(VariableCategory.PARAM_CATEGORY);
part.setVariableLabel(pc.Identifier().getText());
}
TerminalNode numberNode=expAllContext.NUMBER();
PercentContext percentContext=expAllContext.percent();
if(numberNode!=null){
part.setAmount(Integer.valueOf(numberNode.getText()));
part.setStatisticType(StatisticType.amount);
}else if(percentContext!=null){
part.setPercent(Integer.valueOf(percentContext.NUMBER().getText()));
part.setStatisticType(StatisticType.percent);
}else{
part.setStatisticType(StatisticType.none);
}
ExprConditionContext conditionContext=expAllContext.exprCondition();
MultiCondition condition=buildMultiCondition(conditionContext);
part.setMultiCondition(condition);
left.setType(LeftType.all);
leftPart=part;
}else if(expExistsContext!=null){
ExistLeftPart part=new ExistLeftPart();
VariableContext vc=expExistsContext.variable();
ParameterContext pc=expExistsContext.parameter();
if(vc!=null){
part.setVariableCategory(vc.variableCategory().getText());
part.setVariableLabel(vc.property().getText());
}else if(pc!=null){
part.setVariableCategory(VariableCategory.PARAM_CATEGORY);
part.setVariableLabel(pc.Identifier().getText());
}
TerminalNode numberNode=expExistsContext.NUMBER();
PercentContext percentContext=expExistsContext.percent();
if(numberNode!=null){
part.setAmount(Integer.valueOf(numberNode.getText()));
part.setStatisticType(StatisticType.amount);
}else if(percentContext!=null){
part.setPercent(Integer.valueOf(percentContext.NUMBER().getText()));
part.setStatisticType(StatisticType.percent);
}else{
part.setStatisticType(StatisticType.none);
}
ExprConditionContext conditionContext=expExistsContext.exprCondition();
MultiCondition condition=buildMultiCondition(conditionContext);
part.setMultiCondition(condition);
left.setType(LeftType.exist);
leftPart=part;
}else if(expCollectContext!=null){
CollectLeftPart part=new CollectLeftPart();
VariableContext vc=expCollectContext.variable();
ParameterContext pc=expCollectContext.parameter();
if(vc!=null){
part.setVariableCategory(vc.variableCategory().getText());
part.setVariableLabel(vc.property().getText());
}else if(pc!=null){
part.setVariableCategory(VariableCategory.PARAM_CATEGORY);
part.setVariableLabel(pc.Identifier().getText());
}
ExprConditionContext conditionContext=expCollectContext.exprCondition();
if(conditionContext!=null){
MultiCondition condition=buildMultiCondition(conditionContext);
part.setMultiCondition(condition);
}
if(expCollectContext.property()!=null){
part.setProperty(expCollectContext.property().getText());
if(expCollectContext.SUM()!=null){
part.setPurpose(CollectPurpose.sum);
}else if(expCollectContext.MAX()!=null){
part.setPurpose(CollectPurpose.max);
}else if(expCollectContext.MIN()!=null){
part.setPurpose(CollectPurpose.min);
}else if(expCollectContext.AVG()!=null){
part.setPurpose(CollectPurpose.avg);
}
}else{
part.setPurpose(CollectPurpose.count);
}
left.setType(LeftType.collect);
leftPart=part;
}
left.setLeftPart(leftPart);
criteria.setLeft(left);
Op op=DSLUtils.parseOp(ctx.op());
criteria.setOp(op);
NullValueContext nullValueContext=ctx.nullValue();
if(nullValueContext!=null){
if(op.equals(Op.Equals)){
criteria.setOp(Op.Null);
}else if(op.equals(Op.NotEquals)){
criteria.setOp(Op.NotNull);
}else{
throw new RuleException("'null' value only support '==' or '!=' operator.");
}
}else{
criteria.setValue(BuildUtils.buildValue(ctx.complexValue()));
}
return criteria;
}
private MultiCondition buildMultiCondition(ExprConditionContext conditionContext){
MultiCondition multiCondition=new MultiCondition();
buildPropertyCriteria(conditionContext,multiCondition);
return multiCondition;
}
private void buildPropertyCriteria(ExprConditionContext conditionContext,MultiCondition multiCondition) {
List<JoinContext> joins=conditionContext.join();
if(joins==null || joins.size()==0){
multiCondition.addCondition(newPropertyCriteria(conditionContext));
}else{
JoinContext joinContext=joins.get(0);
if(joinContext.AND()!=null){
multiCondition.setType(JunctionType.and);
}else{
multiCondition.setType(JunctionType.or);
}
List<ParseTree> children=conditionContext.children;
for(ParseTree parseTree:children){
if(parseTree instanceof ExprConditionContext){
ExprConditionContext ecc=(ExprConditionContext)parseTree;
if(ecc.property()==null){
buildPropertyCriteria(ecc,multiCondition);
}else{
multiCondition.addCondition(newPropertyCriteria(ecc));
}
}
}
}
}
private PropertyCriteria newPropertyCriteria(ExprConditionContext conditionContext) {
String property=conditionContext.property().getText();
PropertyCriteria pc=new PropertyCriteria();
pc.setProperty(property);
Op op=DSLUtils.parseOp(conditionContext.op());
pc.setOp(op);
ComplexValueContext complexValueContext=conditionContext.complexValue();
NullValueContext nullValueContext=conditionContext.nullValue();
if(nullValueContext!=null && !op.equals(Op.Equals) && !op.equals(Op.NotEquals)){
throw new RuleException("'$null' value only support '==' or '!=' operator.");
}else{
pc.setValue(BuildUtils.buildValue(complexValueContext));
}
return pc;
}
@Override
public boolean support(ParserRuleContext context) {
return context instanceof SingleConditionContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
functionDescriptors=applicationContext.getBeansOfType(FunctionDescriptor.class).values();
}
}
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.ResourceContext;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.LibraryType;
import org.antlr.v4.runtime.ParserRuleContext;
/**
* @author Jacky.gao
* @since 2015年2月15日
*/
public class LibraryContextBuilder extends AbstractContextBuilder {
@Override
public Library build(ParserRuleContext context) {
ResourceContext ctx=(ResourceContext)context;
if(ctx.importActionLibrary()!=null){
String path=BuildUtils.getSTRINGContent(ctx.importActionLibrary().STRING());
return new Library(path,null,LibraryType.Action);
}else if(ctx.importConstantLibrary()!=null){
String path=BuildUtils.getSTRINGContent(ctx.importConstantLibrary().STRING());
return new Library(path,null,LibraryType.Constant);
}else if(ctx.importVariableLibrary()!=null){
String path=BuildUtils.getSTRINGContent(ctx.importVariableLibrary().STRING());
return new Library(path,null,LibraryType.Variable);
}else if(ctx.importParameterLibrary()!=null){
String path=BuildUtils.getSTRINGContent(ctx.importParameterLibrary().STRING());
return new Library(path,null,LibraryType.Parameter);
}
throw new RuleException("Unsupport context "+ctx.getClass().getName()+"");
}
@Override
public boolean support(ParserRuleContext context) {
return context instanceof ResourceContext;
}
}
@@ -0,0 +1,101 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.dsl.builder;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.dsl.DSLUtils;
import com.itheima.sfbx.framework.rule.dsl.RuleParserParser.*;
import com.itheima.sfbx.framework.rule.model.rule.Op;
import com.itheima.sfbx.framework.rule.model.rule.lhs.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年8月15日
*/
public class NamedConditionBuilder {
public CriteriaUnit buildNamedCriteria(NamedConditionContext namedConditionContext,String variableCategory){
CriteriaUnit unit=null;
if(namedConditionContext instanceof MultiNamedConditionsContext){
unit=visitMultiNamedConditions((MultiNamedConditionsContext)namedConditionContext, variableCategory);
}else if(namedConditionContext instanceof SingleNamedConditionsContext){
unit=visitSingleNamedConditions((SingleNamedConditionsContext)namedConditionContext, variableCategory);
}else if(namedConditionContext instanceof ParenNamedConditionsContext){
unit=visitParenNamedConditions((ParenNamedConditionsContext)namedConditionContext, variableCategory);
}else{
throw new RuleException("Unsupport context : +namedConditionContext+");
}
return unit;
}
private CriteriaUnit visitSingleNamedConditions(SingleNamedConditionsContext ctx,String variableCategory) {
Criteria criteria=new Criteria();
VariableLeftPart leftPart=new VariableLeftPart();
Left left=new Left();
left.setLeftPart(leftPart);
left.setType(LeftType.NamedReference);
criteria.setLeft(left);
String variableName=ctx.property().getText();
leftPart.setVariableLabel(variableName);
leftPart.setVariableCategory(variableCategory);
Op op=DSLUtils.parseOp(ctx.op());
criteria.setOp(op);
if(ctx.complexValue()==null){
if(op.equals(Op.Equals)){
criteria.setOp(Op.Null);
}else if(op.equals(Op.NotEquals)){
criteria.setOp(Op.NotNull);
}else{
throw new RuleException("'null' value only support '==' or '!=' operator.");
}
}else{
criteria.setValue(BuildUtils.buildValue(ctx.complexValue()));
}
CriteriaUnit unit=new CriteriaUnit();
unit.setCriteria(criteria);
return unit;
}
private CriteriaUnit visitMultiNamedConditions(MultiNamedConditionsContext ctx,String variableCategory) {
List<CriteriaUnit> nextUnits=new ArrayList<CriteriaUnit>();
List<NamedConditionContext> namedConditions=ctx.namedCondition();
if(namedConditions!=null){
for(int i=0;i<namedConditions.size();i++){
NamedConditionContext context=namedConditions.get(i);
CriteriaUnit nextUnit=buildNamedCriteria(context, variableCategory);
nextUnits.add(nextUnit);
JoinContext joinContext=ctx.join(i);
if(joinContext!=null){
if(joinContext.AND()!=null){
nextUnit.setJunctionType(JunctionType.and);
}else{
nextUnit.setJunctionType(JunctionType.or);
}
}
}
}
CriteriaUnit unit=new CriteriaUnit();
unit.setNextUnits(nextUnits);
return unit;
}
private CriteriaUnit visitParenNamedConditions(ParenNamedConditionsContext ctx,String variableCategory) {
NamedConditionContext namedConditionContext=ctx.namedCondition();
CriteriaUnit unit=buildNamedCriteria(namedConditionContext, variableCategory);
return unit;
}
}
@@ -0,0 +1,242 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model;
import com.itheima.sfbx.framework.rule.Configure;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.action.*;
import com.itheima.sfbx.framework.rule.model.library.Datatype;
import com.itheima.sfbx.framework.rule.model.rete.JsonUtils;
import com.itheima.sfbx.framework.rule.model.rule.Other;
import com.itheima.sfbx.framework.rule.model.rule.Rhs;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import com.itheima.sfbx.framework.rule.model.rule.lhs.LeftType;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopEnd;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopRule;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopStart;
import com.itheima.sfbx.framework.rule.model.rule.loop.LoopTarget;
import com.itheima.sfbx.framework.rule.model.scorecard.AssignTargetType;
import com.itheima.sfbx.framework.rule.model.scorecard.ScoringType;
import com.itheima.sfbx.framework.rule.model.scorecard.runtime.ScoreRule;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.ObjectMapper;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年10月21日
*/
public abstract class AbstractJsonDeserializer<T> extends JsonDeserializer<T> {
protected Rule parseRule(JsonParser jsonParser,JsonNode node){
SimpleDateFormat sd=new SimpleDateFormat(Configure.getDateFormat());
try {
JsonNode ruleNode=node.get("rule");
if(ruleNode==null){
ruleNode=node;
}
Rule rule=null;
String scoringTypeStr=JsonUtils.getJsonValue(ruleNode, "scoringType");
if(StringUtils.isNotBlank(scoringTypeStr)){
ScoringType scoringType=ScoringType.valueOf(scoringTypeStr);
ScoreRule scoreRule=new ScoreRule();
scoreRule.setScoringType(scoringType);
buildScoreRule(jsonParser,ruleNode,scoreRule);
rule=scoreRule;
}else{
String loopRuleStr=JsonUtils.getJsonValue(ruleNode, "loopRule");
if(loopRuleStr!=null){
boolean isLoopRule=Boolean.valueOf(loopRuleStr);
if(isLoopRule){
LoopRule loopRule=new LoopRule();
buildLoopRule(ruleNode, loopRule);
rule=loopRule;
}else{
rule=new Rule();
}
}else{
rule=new Rule();
}
}
rule.setActivationGroup(JsonUtils.getJsonValue(ruleNode, "activationGroup"));
rule.setAgendaGroup(JsonUtils.getJsonValue(ruleNode, "agendaGroup"));
String autoFocus=JsonUtils.getJsonValue(ruleNode, "autoFocus");
if(autoFocus!=null){
rule.setAutoFocus(Boolean.valueOf(autoFocus));
}
String loop=JsonUtils.getJsonValue(ruleNode, "loop");
if(loop!=null){
rule.setLoop(Boolean.valueOf(loop));
}
String effectiveDateText=JsonUtils.getJsonValue(ruleNode, "effectiveDate");
if(effectiveDateText!=null){
rule.setEffectiveDate(sd.parse(effectiveDateText));
}
String enabled=JsonUtils.getJsonValue(ruleNode, "enabled");
if(enabled!=null){
rule.setEnabled(Boolean.valueOf(enabled));
}
String expiresDateText=JsonUtils.getJsonValue(ruleNode, "expiresDate");
if(expiresDateText!=null){
rule.setExpiresDate(sd.parse(expiresDateText));
}
rule.setName(JsonUtils.getJsonValue(ruleNode, "name"));
rule.setRuleflowGroup(JsonUtils.getJsonValue(ruleNode, "ruleflowGroup"));
String salienceText=JsonUtils.getJsonValue(ruleNode, "salience");
if(salienceText!=null){
rule.setSalience(Integer.valueOf(salienceText));
}
Rhs rhs=new Rhs();
rule.setRhs(rhs);
JsonNode rhsNode=ruleNode.get("rhs");
if(rhsNode!=null){
rhs.setActions(parseActions(rhsNode));
}
JsonNode otherNode=ruleNode.get("other");
if(otherNode!=null){
Other other=new Other();
rule.setOther(other);
other.setActions(parseActions(otherNode));
}
return rule;
} catch (ParseException e) {
throw new RuleException(e);
}
}
private void buildScoreRule(JsonParser jsonParser,JsonNode ruleNode,ScoreRule rule){
rule.setScoringBean(JsonUtils.getJsonValue(ruleNode, "scoringBean"));
AssignTargetType assignTargetType=AssignTargetType.valueOf(JsonUtils.getJsonValue(ruleNode, "assignTargetType"));
rule.setAssignTargetType(assignTargetType);
rule.setVariableCategory(JsonUtils.getJsonValue(ruleNode, "variableCategory"));
rule.setVariableName(JsonUtils.getJsonValue(ruleNode, "variableName"));
rule.setVariableLabel(JsonUtils.getJsonValue(ruleNode, "variableLabel"));
String datatypeStr=JsonUtils.getJsonValue(ruleNode, "datatype");
if(StringUtils.isNotBlank(datatypeStr)){
rule.setDatatype(Datatype.valueOf(datatypeStr));
}
try{
JsonNode knowledgePackageWrapperNode=ruleNode.get("knowledgePackageWrapper");
ObjectMapper mapper = (ObjectMapper)jsonParser.getCodec();
KnowledgePackageWrapper wrapper=mapper.readValue(knowledgePackageWrapperNode, KnowledgePackageWrapper.class);
wrapper.buildDeserialize();
rule.setKnowledgePackageWrapper(wrapper);
}catch(Exception ex){
throw new RuleException(ex);
}
}
private void buildLoopRule(JsonNode ruleNode,LoopRule rule){
JsonNode targetNode=ruleNode.get("loopTarget");
if(targetNode!=null){
LoopTarget target=new LoopTarget();
Value value=JsonUtils.parseValue(targetNode);
target.setValue(value);
rule.setLoopTarget(target);
}
JsonNode loopStartNode=ruleNode.get("loopStart");
if(loopStartNode!=null){
List<Action> actions=parseActions(loopStartNode);
LoopStart start=new LoopStart();
start.setActions(actions);
rule.setLoopStart(start);
}
JsonNode loopEndNode=ruleNode.get("loopEnd");
if(loopEndNode!=null){
List<Action> actions=parseActions(loopEndNode);
LoopEnd end=new LoopEnd();
end.setActions(actions);
rule.setLoopEnd(end);
}
JsonNode knowledgeWrapper=ruleNode.get("knowledgePackageWrapper");
if(knowledgeWrapper!=null){
KnowledgePackageWrapper wrapper=JsonUtils.parseKnowledgePackageWrapper(knowledgeWrapper.toString());
rule.setKnowledgePackageWrapper(wrapper);
}
}
private List<Action> parseActions(JsonNode node){
List<Action> actions=new ArrayList<Action>();
JsonNode nodes=node.get("actions");
if(nodes==null)return actions;
Iterator<JsonNode> iter=nodes.iterator();
while(iter.hasNext()){
JsonNode jsonNode=iter.next();
ActionType actionType=ActionType.valueOf(JsonUtils.getJsonValue(jsonNode, "actionType"));
switch(actionType){
case ConsolePrint:
ConsolePrintAction console=new ConsolePrintAction();
console.setValue(JsonUtils.parseValue(jsonNode));
console.setPriority(Integer.valueOf(JsonUtils.getJsonValue(jsonNode, "priority")));
actions.add(console);
break;
case ExecuteMethod:
ExecuteMethodAction method=new ExecuteMethodAction();
method.setBeanId(JsonUtils.getJsonValue(jsonNode, "beanId"));
method.setBeanLabel(JsonUtils.getJsonValue(jsonNode, "beanLabel"));
method.setMethodLabel(JsonUtils.getJsonValue(jsonNode, "methodLabel"));
method.setPriority(Integer.valueOf(JsonUtils.getJsonValue(jsonNode, "priority")));
method.setMethodName(JsonUtils.getJsonValue(jsonNode, "methodName"));
method.setParameters(JsonUtils.parseParameters(jsonNode));
actions.add(method);
break;
case VariableAssign:
VariableAssignAction assign=new VariableAssignAction();
String type=JsonUtils.getJsonValue(jsonNode, "type");
if(type!=null){
assign.setType(LeftType.valueOf(type));
}
assign.setReferenceName(JsonUtils.getJsonValue(jsonNode, "referenceName"));
assign.setDatatype(Datatype.valueOf(JsonUtils.getJsonValue(jsonNode, "datatype")));
assign.setVariableCategory(JsonUtils.getJsonValue(jsonNode, "variableCategory"));
assign.setVariableLabel(JsonUtils.getJsonValue(jsonNode, "variableLabel"));
assign.setVariableName(JsonUtils.getJsonValue(jsonNode, "variableName"));
assign.setPriority(Integer.valueOf(JsonUtils.getJsonValue(jsonNode, "priority")));
assign.setValue(JsonUtils.parseValue(jsonNode));
actions.add(assign);
break;
case ExecuteCommonFunction:
ExecuteCommonFunctionAction ca=new ExecuteCommonFunctionAction();
ca.setLabel(JsonUtils.getJsonValue(jsonNode, "label"));
ca.setName(JsonUtils.getJsonValue(jsonNode, "name"));
ca.setParameter(JsonUtils.parseCommonFunctionParameter(jsonNode));
ca.setPriority(Integer.valueOf(JsonUtils.getJsonValue(jsonNode, "priority")));
actions.add(ca);
break;
case Scoring:
int rowNumber=Integer.valueOf(JsonUtils.getJsonValue(jsonNode, "rowNumber"));
String name=JsonUtils.getJsonValue(jsonNode, "name");
String weight=JsonUtils.getJsonValue(jsonNode, "weight");
ScoringAction sa=new ScoringAction(rowNumber, name, weight);
sa.setValue(JsonUtils.parseValue(jsonNode));
actions.add(sa);
break;
}
}
return actions;
}
}
@@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Jacky.gao
* @since 2015年10月20日
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExposeAction {
public String value();
}
@@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model;
import com.itheima.sfbx.framework.rule.RuleException;
import org.apache.commons.lang.StringUtils;
import java.util.HashMap;
/**
* @author Jacky.gao
* @since 2016年6月2日
*/
public class GeneralEntity extends HashMap<String, Object>{
private static final long serialVersionUID = 2778576006420277518L;
private String targetClass;
public GeneralEntity(String targetClass) {
if(StringUtils.isBlank(targetClass)){
throw new RuleException("Target class cannot be null.");
}
this.targetClass = targetClass;
}
public String getTargetClass() {
return targetClass;
}
@Override
public boolean equals(Object other) {
boolean classEquals=false;
if(other instanceof GeneralEntity){
GeneralEntity entity=(GeneralEntity)other;
if(targetClass.equals(entity.getTargetClass())){
classEquals=true;
}
}
if(classEquals){
return super.equals(other);
}
return false;
}
}
@@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Jacky.gao
* @since 2016年6月2日
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Label {
String value();
}
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model;
/**
* @author Jacky.gao
* @since 2014年12月25日
*/
public interface Node {
}
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model;
import com.itheima.sfbx.framework.rule.model.rule.Rule;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.ObjectCodec;
import org.codehaus.jackson.map.DeserializationContext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年10月21日
*/
public class RuleJsonDeserializer extends AbstractJsonDeserializer<List<Rule>>{
@Override
public List<Rule> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode jsonNode = oc.readTree(jp);
Iterator<JsonNode> childrenNodesIter=jsonNode.getElements();
List<Rule> rules=new ArrayList<Rule>();
while(childrenNodesIter.hasNext()){
JsonNode childNode=childrenNodesIter.next();
rules.add(parseRule(jp,childNode));
}
return rules;
}
}
@@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.decisiontree;
import com.itheima.sfbx.framework.rule.action.Action;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年2月26日
*/
public class ActionTreeNode extends TreeNode{
private List<Action> actions;
public List<Action> getActions() {
return actions;
}
public void setActions(List<Action> actions) {
this.actions = actions;
}
}
@@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.decisiontree;
import com.itheima.sfbx.framework.rule.model.rule.Op;
import com.itheima.sfbx.framework.rule.model.rule.Value;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年2月26日
*/
public class ConditionTreeNode extends TreeNode{
private Value value;
private Op op;
private List<ConditionTreeNode> conditionTreeNodes;
private List<VariableTreeNode> variableTreeNodes;
private List<ActionTreeNode> actionTreeNodes;
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
public Op getOp() {
return op;
}
public void setOp(Op op) {
this.op = op;
}
public List<ConditionTreeNode> getConditionTreeNodes() {
return conditionTreeNodes;
}
public void setConditionTreeNodes(List<ConditionTreeNode> conditionTreeNodes) {
this.conditionTreeNodes = conditionTreeNodes;
}
public List<VariableTreeNode> getVariableTreeNodes() {
return variableTreeNodes;
}
public void setVariableTreeNodes(List<VariableTreeNode> variableTreeNodes) {
this.variableTreeNodes = variableTreeNodes;
}
public List<ActionTreeNode> getActionTreeNodes() {
return actionTreeNodes;
}
public void setActionTreeNodes(List<ActionTreeNode> actionTreeNodes) {
this.actionTreeNodes = actionTreeNodes;
}
}
@@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.decisiontree;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import java.util.Date;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年2月26日
*/
public class DecisionTree {
private Integer salience;
private Date effectiveDate;
private Date expiresDate;
private Boolean enabled;
private Boolean debug;
private String remark;
private List<Library> libraries;
private VariableTreeNode variableTreeNode;
public Integer getSalience() {
return salience;
}
public void setSalience(Integer salience) {
this.salience = salience;
}
public Date getEffectiveDate() {
return effectiveDate;
}
public void setEffectiveDate(Date effectiveDate) {
this.effectiveDate = effectiveDate;
}
public Date getExpiresDate() {
return expiresDate;
}
public void setExpiresDate(Date expiresDate) {
this.expiresDate = expiresDate;
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public Boolean getDebug() {
return debug;
}
public void setDebug(Boolean debug) {
this.debug = debug;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public List<Library> getLibraries() {
return libraries;
}
public void setLibraries(List<Library> libraries) {
this.libraries = libraries;
}
public VariableTreeNode getVariableTreeNode() {
return variableTreeNode;
}
public void setVariableTreeNode(VariableTreeNode variableTreeNode) {
this.variableTreeNode = variableTreeNode;
}
}
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.decisiontree;
import org.codehaus.jackson.annotate.JsonIgnore;
/**
* @author Jacky.gao
* @since 2016年2月26日
*/
public abstract class TreeNode {
@JsonIgnore
private TreeNode parentNode;
private TreeNodeType nodeType;
public void setParentNode(TreeNode parentNode) {
this.parentNode = parentNode;
}
public TreeNode getParentNode() {
return parentNode;
}
public TreeNodeType getNodeType() {
return nodeType;
}
public void setNodeType(TreeNodeType nodeType) {
this.nodeType = nodeType;
}
}
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.decisiontree;
/**
* @author Jacky.gao
* @since 2016年3月2日
*/
public enum TreeNodeType {
condition,action,variable;
}
@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.decisiontree;
import com.itheima.sfbx.framework.rule.model.rule.lhs.Left;
import java.util.List;
/**
* @author Jacky.gao
* @since 2016年2月26日
*/
public class VariableTreeNode extends TreeNode{
private Left left;
private List<ConditionTreeNode> conditionTreeNodes;
public Left getLeft() {
return left;
}
public void setLeft(Left left) {
this.left = left;
}
public List<ConditionTreeNode> getConditionTreeNodes() {
return conditionTreeNodes;
}
public void setConditionTreeNodes(List<ConditionTreeNode> conditionTreeNodes) {
this.conditionTreeNodes = conditionTreeNodes;
}
}
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowInstance;
/**
* @author Jacky.gao
* @since 2015年2月28日
*/
public class ActionNode extends FlowNode {
private String actionBean;
private FlowNodeType type=FlowNodeType.Action;
public ActionNode() {
}
public ActionNode(String name) {
super(name);
}
@Override
public void enterNode(FlowContext context,FlowInstance instance) {
instance.setCurrentNode(this);
executeNodeEvent(EventType.enter,context,instance);
FlowAction action=(FlowAction)context.getApplicationContext().getBean(actionBean);
action.execute(this,context,instance);
executeNodeEvent(EventType.leave,context,instance);
leave(null, context, instance);
}
@Override
public FlowNodeType getType() {
return type;
}
public String getActionBean() {
return actionBean;
}
public void setActionBean(String actionBean) {
this.actionBean = actionBean;
}
}
@@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.ProcessInstance;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackage;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import com.itheima.sfbx.framework.rule.runtime.KnowledgeSession;
import com.itheima.sfbx.framework.rule.runtime.KnowledgeSessionFactory;
import com.itheima.sfbx.framework.rule.runtime.response.ExecutionResponseImpl;
import com.itheima.sfbx.framework.rule.runtime.response.FlowExecutionResponse;
import com.itheima.sfbx.framework.rule.runtime.response.RuleExecutionResponse;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年4月20日
*/
public abstract class BindingNode extends FlowNode {
private KnowledgePackageWrapper knowledgePackageWrapper;
public BindingNode() {
}
public BindingNode(String name) {
super(name);
}
protected KnowledgeSession executeKnowledgePackage(FlowContext context,ProcessInstance instance){
KnowledgeSession parentSession=(KnowledgeSession)context.getWorkingMemory();
List<Object> facts=parentSession.getAllFacts();
KnowledgePackage knowledgePackage=knowledgePackageWrapper.getKnowledgePackage();
KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage,context.getDebugMessageItems());
for(Object fact:facts){
session.insert(fact);
}
if(knowledgePackage.getFlowMap()==null || knowledgePackage.getFlowMap().size()==0){
RuleExecutionResponse ruleExecutionResponse=session.fireRules(context.getVariables());
((ExecutionResponseImpl)context.getResponse()).addRuleExecutionResponse(ruleExecutionResponse);
}else{
String processId=knowledgePackage.getFlowMap().values().iterator().next().getId();
FlowExecutionResponse flowExecutionResponse=session.startProcess(processId,context.getVariables());
((ExecutionResponseImpl)context.getResponse()).addFlowExecutionResponse(flowExecutionResponse);
}
Map<String,Object> parameters=session.getParameters();
Map<String,Object> variables=context.getVariables();
for(String key:parameters.keySet()){
if(key.equals(DecisionItem.RETURN_VALUE_KEY)){
continue;
}
variables.put(key, parameters.get(key));
}
return session;
}
public KnowledgePackageWrapper getKnowledgePackageWrapper() {
return knowledgePackageWrapper;
}
public void setKnowledgePackageWrapper(KnowledgePackageWrapper knowledgePackageWrapper) {
this.knowledgePackageWrapper = knowledgePackageWrapper;
}
}
@@ -0,0 +1,158 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowInstance;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.LibraryType;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import com.itheima.sfbx.framework.rule.runtime.KnowledgeSession;
import com.itheima.sfbx.framework.rule.runtime.KnowledgeSessionFactory;
import org.codehaus.jackson.annotate.JsonIgnore;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年2月28日
*/
public class Connection {
public static final String RETURN_VALUE_KEY="return_value__";
private String name;
private String toName;
private String script;
private String g;
private KnowledgePackageWrapper knowledgePackageWrapper;
@JsonIgnore
private FlowNode to;
public boolean evaluate(FlowContext context){
if(knowledgePackageWrapper==null){
return true;
}
KnowledgeSession parentSession=(KnowledgeSession)context.getWorkingMemory();
List<Object> facts=parentSession.getAllFacts();
KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackageWrapper.getKnowledgePackage(),context.getDebugMessageItems());
for(Object fact:facts){
session.insert(fact);
}
session.fireRules(context.getVariables());
Object result=session.getParameter(Connection.RETURN_VALUE_KEY);
if(result==null){
return false;
}
return Boolean.valueOf(result.toString());
}
public void buildDeserialize(){
if(knowledgePackageWrapper!=null){
knowledgePackageWrapper.buildDeserialize();
}
}
public void execute(FlowContext context,FlowInstance instance){
to.enter(context, instance);
}
public String buildDSLScript(List<Library> libraries){
StringBuffer sb=new StringBuffer();
if(libraries!=null){
for(Library lib:libraries){
String path=lib.getPath();
if(lib.getVersion()!=null){
path+=":"+lib.getVersion();
}
LibraryType type=lib.getType();
switch(type){
case Action:
sb.append("importActionLibrary \""+path+"\"");
sb.append("\r\n");
break;
case Constant:
sb.append("importConstantLibrary \""+path+"\"");
sb.append("\r\n");
break;
case Parameter:
sb.append("importParameterLibrary \""+path+"\"");
sb.append("\r\n");
break;
case Variable:
sb.append("importVariableLibrary \""+path+"\"");
sb.append("\r\n");
break;
}
}
}
sb.append("rule \"conn\"");
sb.append("\r\n");
sb.append("if");
sb.append("\r\n");
sb.append(script);
sb.append("\r\n");
sb.append("then");
sb.append("\r\n");
sb.append("parameter."+RETURN_VALUE_KEY+"=true");
sb.append("\r\n");
sb.append("end");
return sb.toString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getToName() {
return toName;
}
public void setToName(String toName) {
this.toName = toName;
}
public FlowNode getTo() {
return to;
}
public void setTo(FlowNode to) {
this.to = to;
}
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
public KnowledgePackageWrapper getKnowledgePackageWrapper() {
return knowledgePackageWrapper;
}
public void setKnowledgePackageWrapper(KnowledgePackageWrapper knowledgePackageWrapper) {
this.knowledgePackageWrapper = knowledgePackageWrapper;
}
public String getG() {
return g;
}
public void setG(String g) {
this.g = g;
}
}
@@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
/**
* @author Jacky.gao
* @since 2015年4月20日
*/
public class DecisionItem {
public static final String RETURN_VALUE_KEY="return_to__";
private String script;
private int percent;//值为1-99
private String to;
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public int getPercent() {
return percent;
}
public void setPercent(int percent) {
this.percent = percent;
}
public String buildDSLScript(int index){
StringBuffer sb=new StringBuffer();
sb.append("rule \"r"+index+"\"");
sb.append(" ");
sb.append("if");
sb.append(" ");
sb.append(script);
sb.append(" ");
sb.append("then");
sb.append(" ");
sb.append("parameter."+RETURN_VALUE_KEY+"=\""+to+"\"");
sb.append(" ");
sb.append("end");
return sb.toString();
}
}
@@ -0,0 +1,164 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowInstance;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.LibraryType;
import com.itheima.sfbx.framework.rule.runtime.KnowledgeSession;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
* @author Jacky.gao
* @since 2015年4月20日
*/
public class DecisionNode extends BindingNode {
private final Logger log=Logger.getLogger(DecisionNode.class.getName());
private List<DecisionItem> items;
private FlowNodeType type=FlowNodeType.Decision;
private DecisionType decisionType=DecisionType.Criteria;
public DecisionNode() {
}
public DecisionNode(String name) {
super(name);
}
@Override
public void enterNode(FlowContext context,FlowInstance instance) {
instance.setCurrentNode(this);
if(decisionType.equals(DecisionType.Criteria)){
doCriteria(context, instance);
}else{
doPercent(context, instance);
}
executeNodeEvent(EventType.enter, context, instance);
}
private void doPercent(FlowContext context,FlowInstance instance){
String nodeKey=instance.getProcessDefinition().getId()+"_"+getName();
long total=getAmount(nodeKey, context)+1;
List<PercentItem> percentItems=new ArrayList<PercentItem>();
for(DecisionItem item:items){
PercentItem percent=new PercentItem();
percent.setName(item.getTo());
percent.setPercent(item.getPercent());
String itemKey=nodeKey+"."+item.getTo();
long itemTotal=getAmount(itemKey, context);
percent.setTotal(itemTotal);
percentItems.add(percent);
}
PercentItem percentItem=computePercent(percentItems, total);
setAmount(nodeKey, total, context);
setAmount(nodeKey+"."+percentItem.getName(), percentItem.getTotal()+1, context);
executeNodeEvent(EventType.leave, context, instance);
leave(percentItem.getName(), context, instance);
}
private long getAmount(String key,FlowContext context){
Object value=context.getSessionValue(key);
if(value==null){
return 0;
}
return (Long)value;
}
private void setAmount(String key,long value,FlowContext context){
context.setSessionValue(key, value);
}
private void doCriteria(FlowContext context,FlowInstance instance){
KnowledgeSession session=executeKnowledgePackage(context, instance);
executeNodeEvent(EventType.leave, context, instance);
Object to=session.getParameter(DecisionItem.RETURN_VALUE_KEY);
if(to==null){
log.info("Decision node ["+getName()+"] no matching conditions.");
return;
}
session.getParameters().remove(DecisionItem.RETURN_VALUE_KEY);
leave(to.toString(), context, instance);
}
private PercentItem computePercent(List<PercentItem> items,long total){
BigDecimal totalValue=new BigDecimal(total);
for(PercentItem item:items){
long itemTotal=item.getTotal();
BigDecimal left=new BigDecimal(itemTotal);
BigDecimal newPercent=left.divide(totalValue,20,BigDecimal.ROUND_HALF_EVEN);
BigDecimal defaultPercent=new BigDecimal(item.getPercent());
defaultPercent=defaultPercent.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_EVEN);
int result=newPercent.compareTo(defaultPercent);
if(result==-1){
return item;
}
}
return items.get(0);
}
@Override
public FlowNodeType getType() {
return type;
}
public List<DecisionItem> getItems() {
return items;
}
public void setItems(List<DecisionItem> items) {
this.items = items;
}
public String buildDSLScript(List<Library> libraries){
StringBuffer sb=new StringBuffer();
if(libraries!=null){
for(Library lib:libraries){
String path=lib.getPath();
if(lib.getVersion()!=null){
path+=":"+lib.getVersion();
}
LibraryType type=lib.getType();
switch(type){
case Action:
sb.append("importActionLibrary \""+path+"\"");
sb.append("\r\n");
break;
case Constant:
sb.append("importConstantLibrary \""+path+"\"");
sb.append("\r\n");
break;
case Parameter:
sb.append("importParameterLibrary \""+path+"\"");
sb.append("\r\n");
break;
case Variable:
sb.append("importVariableLibrary \""+path+"\"");
sb.append("\r\n");
break;
}
}
}
for(int i=0;i<items.size();i++){
DecisionItem item=items.get(i);
sb.append(item.buildDSLScript(i));
sb.append("\r\n");
}
return sb.toString();
}
public DecisionType getDecisionType() {
return decisionType;
}
public void setDecisionType(DecisionType decisionType) {
this.decisionType = decisionType;
}
}
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
/**
* @author Jacky.gao
* @since 2015年5月27日
*/
public enum DecisionType {
Criteria,Percent;
}
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowInstance;
/**
* @author Jacky.gao
* @since 2015年4月20日
*/
public class EndNode extends FlowNode{
private FlowNodeType type=FlowNodeType.End;
public EndNode() {
}
@Override
public FlowNodeType getType() {
return type;
}
public EndNode(String name) {
super(name);
}
@Override
public void enterNode(FlowContext context, FlowInstance instance) {
executeNodeEvent(EventType.enter, context, instance);
instance.setCurrentNode(this);
executeNodeEvent(EventType.leave, context, instance);
}
}
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.ProcessInstance;
/**
* @author Jacky.gao
* @since 2015年2月28日
*/
public interface FlowAction {
/**
* @param node 当前节点对象
* @param context 规则流上下文件对象
* @param instance 当前规则流实例对象
*/
void execute(ActionNode node,FlowContext context,ProcessInstance instance);
}
@@ -0,0 +1,178 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.itheima.sfbx.framework.rule.model.flow;
import com.itheima.sfbx.framework.rule.RuleException;
import com.itheima.sfbx.framework.rule.builder.KnowledgeBase;
import com.itheima.sfbx.framework.rule.builder.KnowledgeBuilder;
import com.itheima.sfbx.framework.rule.builder.ResourceBase;
import com.itheima.sfbx.framework.rule.dsl.DSLRuleSetBuilder;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowContext;
import com.itheima.sfbx.framework.rule.model.flow.ins.FlowInstance;
import com.itheima.sfbx.framework.rule.model.flow.ins.ProcessInstance;
import com.itheima.sfbx.framework.rule.model.rule.Library;
import com.itheima.sfbx.framework.rule.model.rule.RuleSet;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackage;
import com.itheima.sfbx.framework.rule.runtime.KnowledgePackageWrapper;
import com.itheima.sfbx.framework.rule.runtime.KnowledgeSession;
import com.itheima.sfbx.framework.rule.runtime.event.impl.ProcessBeforeCompletedEventImpl;
import com.itheima.sfbx.framework.rule.runtime.event.impl.ProcessBeforeStartedEventImpl;
import com.itheima.sfbx.framework.rule.runtime.response.ExecutionResponseImpl;
import com.itheima.sfbx.framework.rule.runtime.service.KnowledgePackageService;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jacky.gao
* @since 2015年1月6日
*/
public class FlowDefinition implements ProcessDefinition {
private String id;
private boolean debug;
@JsonIgnore
private List<Library> libraries;
@JsonDeserialize(using=com.itheima.sfbx.framework.rule.model.flow.FlowNodeJsonDeserializer.class)
private List<FlowNode> nodes;
public ProcessInstance newInstance(FlowContext context){
ExecutionResponseImpl response=(ExecutionResponseImpl)context.getResponse();
response.setFlowId(id);
StartNode startNode=null;
for(FlowNode node:nodes){
if(node instanceof StartNode){
startNode=(StartNode)node;
break;
}
}
if(startNode==null){
throw new RuleException("StartNode must be define.");
}
response.addNodeName(startNode.getName());
FlowInstance instance=new FlowInstance(this,debug);
KnowledgeSession session=(KnowledgeSession)context.getWorkingMemory();
session.fireEvent(new ProcessBeforeStartedEventImpl(instance,session));
startNode.enter(context, instance);
session.fireEvent(new ProcessBeforeCompletedEventImpl(instance,session));
return instance;
}
public void buildConnectionToNode(){
for(FlowNode node:nodes){
List<Connection> connections=node.getConnections();
if(connections==null || connections.size()==0){
continue;
}
for(Connection conn:connections){
String nodeName=conn.getToName();
conn.setTo(getFlowNode(nodeName));
}
}
}
private FlowNode getFlowNode(String nodeName){
for(FlowNode node:nodes){
if(node.getName().equals(nodeName)){
return node;
}
}
throw new RuleException("Flow node ["+nodeName+"] not found.");
}
public void initNodeKnowledgePackage(KnowledgeBuilder knowledgeBuilder,KnowledgePackageService knowledgePackageService,DSLRuleSetBuilder dslRuleSetBuilder) throws IOException{
for(FlowNode node:nodes){
if(node instanceof RuleNode){
ResourceBase resourceBase=knowledgeBuilder.newResourceBase();
RuleNode ruleNode=(RuleNode)node;
resourceBase.addResource(ruleNode.getFile(), ruleNode.getVersion());
KnowledgeBase knowledgeBase=knowledgeBuilder.buildKnowledgeBase(resourceBase);
KnowledgePackage knowledgePackage=knowledgeBase.getKnowledgePackage();
ruleNode.setKnowledgePackageWrapper(new KnowledgePackageWrapper(knowledgePackage));
}else if(node instanceof RulePackageNode){
RulePackageNode rulePackageNode=(RulePackageNode)node;
String packageId=rulePackageNode.getProject()+"/"+rulePackageNode.getPackageId();
KnowledgePackage knowledgePackage=knowledgePackageService.buildKnowledgePackage(packageId);
rulePackageNode.setKnowledgePackageWrapper(new KnowledgePackageWrapper(knowledgePackage));
}else if(node instanceof DecisionNode){
DecisionNode decisionNode=(DecisionNode)node;
if(decisionNode.getDecisionType().equals(DecisionType.Criteria)){
String script=decisionNode.buildDSLScript(libraries);
RuleSet ruleSet=dslRuleSetBuilder.build(script);
KnowledgeBase knowledgeBase=knowledgeBuilder.buildKnowledgeBase(ruleSet);
decisionNode.setKnowledgePackageWrapper(new KnowledgePackageWrapper(knowledgeBase.getKnowledgePackage()));
}
}else if(node instanceof ScriptNode){
ScriptNode scriptNode=(ScriptNode)node;
String script=scriptNode.buildDSLScript(libraries);
RuleSet ruleSet=dslRuleSetBuilder.build(script);
KnowledgeBase knowledgeBase=knowledgeBuilder.buildKnowledgeBase(ruleSet);
scriptNode.setKnowledgePackageWrapper(new KnowledgePackageWrapper(knowledgeBase.getKnowledgePackage()));
}else if(node instanceof ForkNode){
List<Connection> connections=node.getConnections();
for(Connection conn:connections){
String script=conn.getScript();
if(script==null){
continue;
}
script=conn.buildDSLScript(libraries);
RuleSet ruleSet=dslRuleSetBuilder.build(script);
KnowledgeBase knowledgeBase=knowledgeBuilder.buildKnowledgeBase(ruleSet);
conn.setKnowledgePackageWrapper(new KnowledgePackageWrapper(knowledgeBase.getKnowledgePackage()));
}
}
}
}
public void addLibrary(Library lib){
if(libraries==null){
libraries=new ArrayList<Library>();
}
libraries.add(lib);
}
@Override
public List<Library> getLibraries() {
return libraries;
}
public void setLibraries(List<Library> libraries) {
this.libraries = libraries;
}
@Override
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
@Override
public List<FlowNode> getNodes() {
return nodes;
}
public void setNodes(List<FlowNode> nodes) {
this.nodes = nodes;
}
}

Some files were not shown because too many files have changed in this diff Show More