Skip to content

Commit e5f541a

Browse files
committed
Initial commit
0 parents  commit e5f541a

35 files changed

+1589
-0
lines changed

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Michael Scharf (Github)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

gr.scharf.rules/.classpath

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="src"/>
4+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
5+
<classpathentry combineaccessrules="false" kind="src" path="/gr.scharf.expr.parser"/>
6+
<classpathentry kind="output" path="bin"/>
7+
</classpath>

gr.scharf.rules/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/bin/

gr.scharf.rules/.project

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>gr.scharf.rules</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>

gr.scharf.rules/.settings/org.eclipse.jdt.core.prefs

Lines changed: 297 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
eclipse.preferences.version=1
2+
formatter_profile=_Eclipse [built-in] MSA
3+
formatter_settings_version=12
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package gr.scharf.rules;
2+
3+
import gr.scharf.rules.actions.IAction;
4+
import gr.scharf.rules.expression.ExpressionException;
5+
import gr.scharf.rules.expression.ExpressionParser;
6+
import gr.scharf.rules.expression.IExpression;
7+
8+
public class Rule {
9+
private IExpression condition;
10+
private IAction action;
11+
12+
public Rule(IExpression condition, IAction action) {
13+
this.condition = condition;
14+
this.action = action;
15+
}
16+
17+
public Rule(String condition, IAction action) throws ExpressionException {
18+
this.condition = new ExpressionParser().parseExpression(condition);
19+
this.action = action;
20+
}
21+
22+
public void setStore(StateStore store) throws ExpressionException {
23+
condition.setStore(store);
24+
action.setStore(store);
25+
}
26+
27+
/**
28+
* @return true if the condition has matched
29+
* @throws ExpressionException
30+
*/
31+
public boolean execute() throws ExpressionException {
32+
if (condition.test()) {
33+
System.out.println(this);
34+
35+
action.run();
36+
return true;
37+
}
38+
return false;
39+
}
40+
41+
@Override
42+
public String toString() {
43+
return condition.toString() + " -> " + action.toString();
44+
}
45+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package gr.scharf.rules;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import gr.scharf.rules.expression.ExpressionException;
7+
8+
public class RuleEngine {
9+
private StateStore store = new StateStore();
10+
private List<Rule> rules = new ArrayList<Rule>();
11+
12+
public RuleEngine() {
13+
super();
14+
}
15+
16+
public void runOnce() throws ExpressionException {
17+
List<Rule> currentRules = new ArrayList<Rule>(rules);
18+
List<Rule> nextRules = new ArrayList<Rule>();
19+
for (int i = 0; i < 5; i++) {
20+
store.clearDirtyState();
21+
for (Rule rule : currentRules) {
22+
boolean matched = rule.execute();
23+
if (!matched) {
24+
nextRules.add(rule);
25+
}
26+
}
27+
28+
if (!store.isDirtyState()) {
29+
break;
30+
}
31+
currentRules = nextRules;
32+
nextRules = new ArrayList<Rule>();
33+
}
34+
}
35+
36+
public void run() throws ExpressionException {
37+
for (int i = 0; i < 5; i++) {
38+
store.clearDirtyState();
39+
for (Rule rule : rules) {
40+
rule.execute();
41+
}
42+
43+
if (!store.isDirtyState()) {
44+
break;
45+
}
46+
}
47+
}
48+
49+
public void addRule(Rule rule) throws ExpressionException {
50+
rule.setStore(store);
51+
rules.add(rule);
52+
}
53+
54+
public void defineState(String name, State state) {
55+
store.define(name, state);
56+
}
57+
58+
public StateStore getStore() {
59+
return store;
60+
}
61+
62+
@Override
63+
public String toString() {
64+
StringBuilder b = new StringBuilder();
65+
for (Rule rule : rules) {
66+
b.append(rule.toString());
67+
b.append("\n");
68+
}
69+
return b.toString();
70+
}
71+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package gr.scharf.rules;
2+
3+
import gr.scharf.rules.actions.SetValueExpression;
4+
import gr.scharf.rules.expression.ExpressionException;
5+
import gr.scharf.rules.expression.ExpressionParser;
6+
7+
public class RuleMain {
8+
9+
public static void main(String[] args) throws ExpressionException {
10+
RuleEngine ruleEngine = createStore();
11+
System.out.println("");
12+
System.out.println("Run");
13+
System.out.println(ruleEngine.getStore());
14+
System.out.println("-----------------------------------------------------------------------------");
15+
ruleEngine.run();
16+
System.out.println("-----------------------------------------------------------------------------");
17+
System.out.println(ruleEngine.getStore());
18+
19+
ruleEngine = createStore();
20+
System.out.println("-----------------------------------------------------------------------------");
21+
System.out.println("");
22+
System.out.println("Run each rule at most one time:");
23+
System.out.println(ruleEngine.getStore());
24+
System.out.println("-----------------------------------------------------------------------------");
25+
ruleEngine.runOnce();
26+
System.out.println("-----------------------------------------------------------------------------");
27+
System.out.println(ruleEngine.getStore());
28+
29+
System.out.println("-----------------------------------------------------------------------------");
30+
ruleEngine = new RuleEngine();
31+
new ExpressionParser().parseRules(ruleEngine, "define x = 2; x<3: set x 3; x<10: print(x*2);");
32+
System.out.println(ruleEngine.getStore());
33+
System.out.println("-----------------------------------------------------------------------------");
34+
ruleEngine.runOnce();
35+
}
36+
37+
private static RuleEngine createStore() throws ExpressionException {
38+
RuleEngine ruleEngine = new RuleEngine();
39+
40+
System.out.println("");
41+
System.out.println("");
42+
ruleEngine.defineState("SVNR", new State(42));
43+
ruleEngine.defineState("Background", new State("blue"));
44+
ruleEngine.defineState("style", new State("male"));
45+
ruleEngine.defineState("counter", new State(1));
46+
ruleEngine.defineState("n", new State(null));
47+
System.out.println("");
48+
ruleEngine.addRule(new Rule("SVNR==44", new SetValueExpression("SVNR", "42")));
49+
ruleEngine.addRule(new Rule("SVNR==43", new SetValueExpression("SVNR", "44")));
50+
ruleEngine.addRule(new Rule("SVNR==42", new SetValueExpression("Background", "'red'")));
51+
ruleEngine.addRule(new Rule("SVNR!=42", new SetValueExpression("Background", "'blue'")));
52+
ruleEngine.addRule(new Rule("SVNR==42", new SetValueExpression("SVNR", "43")));
53+
ruleEngine.addRule(new Rule("SVNR>=44", new SetValueExpression("SVNR", "100")));
54+
ruleEngine.addRule(new Rule("Background == 'red'", new SetValueExpression("style", "'female'")));
55+
ruleEngine.addRule(new Rule("counter<5 and SVNR>43", new SetValueExpression("counter", "counter+1")));
56+
ruleEngine.addRule(new Rule("counter<5", new SetValueExpression("Background", "n.matches('')")));
57+
return ruleEngine;
58+
}
59+
60+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package gr.scharf.rules;
2+
3+
public class State {
4+
Object value;
5+
6+
public State(Object value) {
7+
this.value = value;
8+
}
9+
10+
public Object get() {
11+
return value;
12+
}
13+
14+
public void set(Object value) {
15+
this.value = value;
16+
}
17+
18+
@Override
19+
public String toString() {
20+
return "" + value;
21+
}
22+
}

0 commit comments

Comments
 (0)