Skip to content

Commit 4aedede

Browse files
committed
@210 Implemented parsing of expressions.
Pending: expression with one boolean value, finish IfNode, implement ListNode
1 parent 9ec18f3 commit 4aedede

File tree

16 files changed

+480
-99
lines changed

16 files changed

+480
-99
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.javalite.templator;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* @author Eric Nielsen
7+
*/
8+
class AndExp extends Exp {
9+
private final Exp leftExp;
10+
private final Exp rightExp;
11+
12+
AndExp(Exp leftExp, Exp rightExp) {
13+
this.leftExp = leftExp;
14+
this.rightExp = rightExp;
15+
}
16+
17+
@Override
18+
boolean resultWith(Map values) {
19+
if (leftExp.resultWith(values)) {
20+
return rightExp.resultWith(values);
21+
} else {
22+
return false;
23+
}
24+
}
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.javalite.templator;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* @author Eric Nielsen
7+
*/
8+
class Comparison extends Exp {
9+
private final Identifiers leftIdent;
10+
private final Op op;
11+
private final Identifiers rightIdent;
12+
13+
Comparison(Identifiers leftIdent, Op op, Identifiers rightIdent) {
14+
this.leftIdent = leftIdent;
15+
this.op = op;
16+
this.rightIdent = rightIdent;
17+
}
18+
19+
@Override
20+
boolean resultWith(Map values) {
21+
return op.resultWith(leftIdent.valueFrom(values), rightIdent.valueFrom(values));
22+
}
23+
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.javalite.templator;
22

3+
import java.io.IOException;
34
import java.util.Map;
45

56
/**
@@ -8,20 +9,20 @@
89
* @author Igor Polevoy
910
* @author Eric Nielsen
1011
*/
11-
class ConstNode extends TemplateNode {
12+
class ConstNode extends Node {
1213
private final String value;
1314

14-
public ConstNode(String value) {
15+
ConstNode(String value) {
1516
this.value = value;
1617
}
1718

1819
@Override
19-
public void process(Map values, Appendable appendable) throws Exception {
20+
void process(Map values, Appendable appendable) throws IOException {
2021
appendable.append(value);
2122
}
2223

2324
@Override
24-
public String toString(){
25+
public String toString() {
2526
return value;
2627
}
2728
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.javalite.templator;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* @author Eric Nielsen
7+
*/
8+
abstract class Exp {
9+
abstract boolean resultWith(Map values);
10+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.javalite.templator;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import org.javalite.templator.TemplateException;
6+
import static org.javalite.common.Inflector.capitalize;
7+
8+
/**
9+
* @author Eric Nielsen
10+
*/
11+
class Identifiers {
12+
private final String firstIdentifier;
13+
private final List<String> identifiers;
14+
15+
Identifiers(String firstIdentifier, List<String> identifiers) {
16+
this.firstIdentifier = firstIdentifier;
17+
this.identifiers = identifiers;
18+
}
19+
20+
private Object valueOf(Object obj, String propertyName) {
21+
try {
22+
if (propertyName.endsWith("()")) {
23+
return obj.getClass().getMethod(propertyName.substring(0, propertyName.length() - 2)).invoke(obj);
24+
}
25+
} catch (Exception e) {
26+
throw new TemplateException(e);
27+
}
28+
if (obj instanceof Map) {
29+
return ((Map) obj).get(propertyName);
30+
}
31+
try {
32+
// try generic get method
33+
return obj.getClass().getMethod("get", String.class).invoke(obj, propertyName);
34+
} catch (Exception e) {
35+
try {
36+
// try javabean property
37+
return obj.getClass().getMethod("get" + capitalize(propertyName)).invoke(obj);
38+
} catch (Exception e1) {
39+
// try public field
40+
try {
41+
return obj.getClass().getDeclaredField(propertyName).get(obj);
42+
} catch (Exception e2) {
43+
}
44+
}
45+
}
46+
return null;
47+
}
48+
49+
Object valueFrom(Map values) {
50+
Object obj = values.get(firstIdentifier);
51+
for (String identifier : identifiers) {
52+
obj = valueOf(obj, identifier);
53+
}
54+
return obj;
55+
}
56+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.javalite.templator;
2+
3+
import java.io.IOException;
4+
import java.util.Map;
5+
6+
/**
7+
* This terminal node represents a variable chunk of text in template.
8+
*
9+
* @author Eric Nielsen
10+
*/
11+
class IfNode extends ParentNode {
12+
private final Exp exp;
13+
14+
IfNode(Exp exp) {
15+
this.exp = exp;
16+
}
17+
18+
@Override
19+
void process(Map values, Appendable appendable) throws IOException {
20+
appendable.append(String.valueOf(exp.resultWith(values)));
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package org.javalite.templator;
22

3+
import java.io.IOException;
34
import java.util.Map;
45

56
/**
67
* @author Igor Polevoy
78
* @author Eric Nielsen
89
*/
9-
abstract class TemplateNode {
10-
abstract void process(Map values, Appendable appendable) throws Exception;
10+
abstract class Node {
11+
abstract void process(Map values, Appendable appendable) throws IOException;
1112
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.javalite.templator;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* @author Eric Nielsen
7+
*/
8+
class NotExp extends Exp {
9+
private final Exp exp;
10+
11+
NotExp(Exp exp) {
12+
this.exp = exp;
13+
}
14+
15+
@Override
16+
boolean resultWith(Map values) {
17+
return !exp.resultWith(values);
18+
}
19+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.javalite.templator;
2+
3+
/**
4+
* @author Eric Nielsen
5+
*/
6+
enum Op {
7+
eq {
8+
@Override boolean resultWith(Object obj1, Object obj2) {
9+
return obj1 == null ? obj2 == null : (obj2 == null ? false : obj1.equals(obj2));
10+
}
11+
},
12+
gt {
13+
@Override boolean resultWith(Object obj1, Object obj2) {
14+
return compare(obj1, obj2) > 0;
15+
}
16+
},
17+
gte {
18+
@Override boolean resultWith(Object obj1, Object obj2) {
19+
return compare(obj1, obj2) >= 0;
20+
}
21+
},
22+
lt {
23+
@Override boolean resultWith(Object obj1, Object obj2) {
24+
return compare(obj1, obj2) < 0;
25+
}
26+
},
27+
lte {
28+
@Override boolean resultWith(Object obj1, Object obj2) {
29+
return compare(obj1, obj2) <= 0;
30+
}
31+
},
32+
neq {
33+
@Override boolean resultWith(Object obj1, Object obj2) {
34+
return obj1 == null ? obj2 != null : (obj2 == null ? true : !obj1.equals(obj2));
35+
}
36+
};
37+
38+
boolean resultWith(Object obj1, Object obj2) {
39+
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
40+
}
41+
42+
int compare(Object obj1, Object obj2) {
43+
return ((Comparable) obj1).compareTo(obj2);
44+
}
45+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.javalite.templator;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* @author Eric Nielsen
7+
*/
8+
class OrExp extends Exp {
9+
private final Exp leftExp;
10+
private final Exp rightExp;
11+
12+
OrExp(Exp leftExp, Exp rightExp) {
13+
this.leftExp = leftExp;
14+
this.rightExp = rightExp;
15+
}
16+
17+
@Override
18+
boolean resultWith(Map values) {
19+
if (leftExp.resultWith(values)) {
20+
return true;
21+
} else {
22+
return rightExp.resultWith(values);
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)