1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.gridsystems.nextgrid.api.pom.expr;
19
20 import java.io.Serializable;
21 import java.util.Iterator;
22 import java.util.Map;
23
24 import org.apache.commons.jxpath.JXPathContext;
25 import org.apache.commons.jxpath.Variables;
26
27 import com.gridsystems.nextgrid.api.env.AbstractTransientAttribute;
28
29 import nextgrid.api.env.ProcessEnvironment;
30 import nextgrid.api.pom.Expression;
31 import nextgrid.api.pom.ExpressionException;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public final class XPathExpression extends Expression {
50
51
52
53
54 private static final long serialVersionUID = -3368997983579800617L;
55
56
57
58
59 private int minValues;
60
61
62
63
64 private int maxValues;
65
66
67
68
69
70
71
72 public XPathExpression(String text) throws ExpressionException {
73 this(text, 1, Integer.MAX_VALUE);
74 }
75
76
77
78
79
80
81
82
83
84 public XPathExpression(String text, int min, int max) throws ExpressionException {
85 super("XPath", text);
86 this.minValues = min;
87 this.maxValues = max;
88 }
89
90
91
92
93 @Override public void validate() throws ExpressionException {
94
95 }
96
97
98
99
100 @SuppressWarnings("unchecked")
101 @Override public boolean boolEval(ProcessEnvironment env, Object o)
102 throws ExpressionException {
103 JXPathContext root = getRootContext(env);
104 JXPathContext context = JXPathContext.newContext(root, o);
105
106 context.setLenient(true);
107 Iterator it = context.iterate(this.getText());
108
109 int count = 0;
110 while (it.hasNext()) {
111 count++;
112 it.next();
113 }
114
115 return (count >= minValues) && (count <= maxValues);
116 }
117
118
119
120
121
122
123
124
125
126 public synchronized JXPathContext getRootContext(ProcessEnvironment env) {
127 Serializable attr = env.getAttribute("XPathExpression.rootContext");
128 ContextHolder holder = null;
129 if (attr instanceof ContextHolder) {
130 holder = (ContextHolder)attr;
131 } else {
132 holder = new ContextHolder();
133 env.setAttribute("XPathExpression.rootContext", holder);
134 }
135
136 return holder.getValue(env);
137 }
138
139
140
141
142 static class ContextHolder extends AbstractTransientAttribute<JXPathContext> {
143
144
145
146
147 private static final long serialVersionUID = -4973174396783312256L;
148
149
150
151
152 @Override public JXPathContext createValue(ProcessEnvironment env) {
153 JXPathContext ctx = JXPathContext.newContext(null);
154
155
156 Variables vars = ctx.getVariables();
157 for (Map.Entry<String, Serializable> entry : env.getAttributes().entrySet()) {
158 vars.declareVariable(entry.getKey(), entry.getValue());
159 }
160
161
162 vars.declareVariable("true", Integer.valueOf(1));
163 vars.declareVariable("false", Integer.valueOf(0));
164
165 return ctx;
166 }
167 }
168 }