Created
May 10, 2013 11:05
-
-
Save anonymous/5553760 to your computer and use it in GitHub Desktop.
Revisions
-
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,150 @@ package com.baidu.cms.thirtpart import util.parsing.combinator.JavaTokenParsers import java.io.FileReader import java.util.regex.Pattern import com.baidu.cms.thirtpart.TransferRuleContext._ import com.baidu.cms.thirtpart.TransferRuleContext.ActivityRef import com.baidu.cms.thirtpart.TransferRuleContext.FieldValueFilter import com.baidu.cms.thirtpart.TransferRuleContext.Rule import com.baidu.cms.thirtpart.TransferRuleContext.OperatorFetchStrategy import scala.collection.JavaConversions._ /** * * User: sunflower * Date: 12-9-14 * Time: 下午8:54 * */ class TransferParser extends JavaTokenParsers { def value: Parser[TransContext] = rep(statement) ^^ { case state => val context: TransContext = new TransContext() state foreach context.interpret context } def statement: Parser[AST] = varDefinition ^^ { case v => v } | rulesDefinition ^^ { case r => RulesDefinition(r) } def varDefinition: Parser[Var] = (ident <~ ":=") ~ (complexValue <~ ",") ^^ { case name ~ value => Var(name, value) } def complexValue: Parser[VarValue] = "class:" ~ """[a-zA-Z][a-zA-Z0-9.]*""".r ^^ { case "class:" ~ classpath => LocalClass(classpath) } | "spring:" ~ """[a-zA-Z][a-zA-Z0-9.]*""".r ^^ { case "spring:" ~ beanId => SpringManagedBean(beanId) } | varValue ^^ { case value => SimpleValue(value) } def varValue = """[^,][0-9a-zA-Z"_\p{InCJKUnifiedIdeographs}:+*/\\.-]*""".r def rulesDefinition: Parser[Set[Rule]] = ("transformRules" <~ ":=") ~ ("{" ~> repsep(ruleDef, ",") <~ "}") ^^ { case "transformRules" ~ rules => Set() ++ rules } def ruleDef: Parser[Rule] = from ~ to ~ opt(props) ^^ { case from ~ to ~ props => { if (props.isEmpty) Rule(from, to, collection.mutable.Map.empty[String, OperatorProp]) else Rule(from, to, props.get) } } def from = "from" ~> activityRef def to = "to" ~> activityRef def activityRef: Parser[ActivityRef] = ("(" ~> ident <~ ":") ~ (varValue <~ ")") ^^ { case id ~ name => ActivityRef(id, name) } def props: Parser[collection.mutable.Map[String, OperatorProp]] = "{" ~> repsep(prop, ",") <~ "}" ^^ { case props => val map = collection.mutable.Map.empty[String, OperatorProp] for (p <- props) { map.update(p.name, p) } map } def prop: Parser[OperatorProp] = "operator" ~ ("{" ~> executorArithmetic <~ "}") ^^ { case "operator" ~ expr => OperatorProp("operator", expr) } | "countersign-users" ~ ("{" ~> executorArithmetic <~ "}") ^^ { case "countersign-users" ~ expr => OperatorProp("countersign-users", expr) } def executorArithmetic: Parser[OperatorFetchExpr] = fetchStrategy ~ rep("+" ~ fetchStrategy | "-" ~ fetchStrategy) ^^ { case fs ~ ms => if (ms.isEmpty) { OperatorFactor(fs) } else { processOperatorArithmetic(ms, OperatorFactor(fs)) } } def fetchStrategy: Parser[OperatorFetchStrategy] = ident ~ repsep(filter,",") ^^ { case strategyName ~ filter => if (filter.isEmpty) OperatorFetchStrategy(strategyName) else { val map = collection.mutable.Map.empty[String, FieldValueFilter] for (f <- filter){ map.update(f.fieldName,f) } OperatorFetchStrategy(strategyName, map) } } def filter: Parser[FieldValueFilter] = ("[" ~> ident) ~ ("=" ~> restriction <~ "]") ^^ { case propName ~ pattern => FieldValueFilter(propName, pattern) } def restriction: Parser[Pattern] = ("Regex" <~ "@@") ~ ("""[^@][^@][a-zA-Z0-9(){}.$*/@+\\_-]+""".r <~ "@@") ^^ { case "Regex" ~ regex => Pattern.compile(regex) } def processOperatorArithmetic(tail: List[~[String, OperatorFetchStrategy]], expr: OperatorFetchExpr): OperatorFetchExpr = tail match { case head :: xs => head match { case "+" ~ strategy => processOperatorArithmetic(xs, OperatorAdd(expr, OperatorFactor(strategy))) case "-" ~ strategy => processOperatorArithmetic(xs, OperatorMinus(expr, OperatorFactor(strategy))) } case Nil => expr } } object ScriptParser extends TransferParser { def doParse(script: String): TransContext = { val reader: FileReader = new FileReader(script) try { parseAll(value, reader) match { case Success(r, next) => { r.checkMandatoryVars() r.init() r } case e@NoSuccess(msg, next) => throw new RuntimeException(e.toString) } } finally { reader.close() } } // test run def main(args: Array[String]) { val context: TransContext = doParse("普通流程-迁移.transfer") val rule: Rule = context.findRule("act64") println(rule) val instance: ActivityInstance = new ActivityInstance("123", "123", rule.from.id, context.processDef.id) val result: java.util.List[ActivityOperator] = OperatorExprEvaluator.evaluate(rule.props.get("countersign-users").fetch, rule,instance, context) println(result) } }