1
2
3
4
5
6
7
8 package net.kwfgrid.gwes;
9
10 import net.kwfgrid.gwes.jaxen.*;
11 import net.kwfgrid.gwes.util.StringUtils;
12 import net.kwfgrid.gworkflowdl.structure.*;
13 import org.apache.log4j.Logger;
14 import org.jaxen.*;
15 import org.jaxen.jdom.JDOMXPath;
16 import org.jdom.Document;
17
18
19
20
21
22
23
24
25 public class ConditionChecker {
26
27
28
29
30 private final static Logger logger = Logger.getLogger(ConditionChecker.class);
31
32 public final static int CONDITION_TRUE = 1;
33 public final static int CONDITION_FALSE_STATIC = 2;
34 public final static int CONDITION_FALSE_DYNAMIC = 4;
35
36 private final SimpleFunctionContext fnContext;
37 private final SimpleNamespaceContext defaultNsContext;
38
39 private Document context;
40
41
42
43
44
45
46
47 public ConditionChecker() {
48
49 fnContext = new XPathFunctionContext();
50 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "current-dateTimeMs", new CurrentDateTimeMsFunction());
51 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "dateTime2ms", new DateTime2msFunction());
52 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2dateTime", new Ms2dateTimeFunction());
53 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2year", new Ms2yearFunction());
54 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2month", new Ms2monthFunction());
55 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2day", new Ms2dayFunction());
56 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2hour", new Ms2hourFunction());
57 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2minute", new Ms2minuteFunction());
58 fnContext.registerFunction("http://www.gridworkflow.org/gworkflowdl", "ms2second", new Ms2secondFunction());
59
60 defaultNsContext = new SimpleNamespaceContext();
61 defaultNsContext.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
62 defaultNsContext.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
63 defaultNsContext.addNamespace("gwdl", "http://www.gridworkflow.org/gworkflowdl");
64 defaultNsContext.addNamespace("soapenv", "http://www.w3.org/2003/05/soap-envelope");
65 }
66
67
68
69
70
71 public void setContext(Document context) {
72 this.context = context;
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86 public int check(TransitionOccurrence to) throws WorkflowFormatException {
87 int ret = CONDITION_TRUE;
88
89
90
91 setContext(to.getContext());
92
93
94 SimpleNamespaceContext nsContext = defaultNsContext;
95 GenericProperties transProps = to.transition.getProperties();
96 for (Property prop : transProps.getProperties()) {
97 String key = prop.getKey();
98 if (key.startsWith("xmlns:") && key.length() > 6) {
99
100 nsContext.addNamespace(key.substring(6),prop.getValue());
101 }
102 }
103
104
105 for (String condition1 : to.transition.getConditions()) {
106 String condition = StringUtils.expandContextVariables(condition1.trim());
107
108
109 try {
110 if (!check(condition,nsContext)) {
111 if ((ret & CONDITION_TRUE) != 0) ret -= CONDITION_TRUE;
112 if (condition.contains("current-dateTimeMs(")) {
113 ret |= CONDITION_FALSE_DYNAMIC;
114 } else {
115 ret |= CONDITION_FALSE_STATIC;
116 return ret;
117 }
118 }
119 } catch (JaxenException e) {
120 logger.error("exception: "+e, e);
121 throw new WorkflowFormatException("There is an error with condition '" + condition + "':"+ e, e);
122 }
123 }
124
125 return ret;
126 }
127
128 public boolean check(String xpathExpression, NamespaceContext nsContext) throws JaxenException {
129 boolean ret;
130
131 if (xpathExpression.equalsIgnoreCase(Constants.TRUE)) ret = true;
132 else if (xpathExpression.equalsIgnoreCase(Constants.FALSE)) ret = false;
133 else {
134
135 XPath xpath = new JDOMXPath(xpathExpression);
136 xpath.setFunctionContext(fnContext);
137 xpath.setNamespaceContext(nsContext);
138
139 ret = xpath.booleanValueOf(context);
140 }
141
142 if (logger.isDebugEnabled()) {
143 logger.debug("Condition '" + xpathExpression + "' is " + ret);
144 }
145 return ret;
146 }
147
148 }