1 package org.smartcomps.twister.engine.priv.expression.impl;
2
3 import org.smartcomps.twister.engine.priv.expression.ExpressionProcessor;
4 import org.smartcomps.twister.engine.priv.core.dynamic.ProcessInstance;
5 import org.smartcomps.twister.engine.priv.core.dynamic.impl.xao.VariableXAO;
6 import org.smartcomps.twister.engine.priv.core.definition.PropertyAlias;
7 import org.smartcomps.twister.common.persistence.FinderException;
8 import org.smartcomps.twister.engine.exception.XPathEvaluationException;
9 import org.smartcomps.twister.engine.exception.SelectionFailureException;
10 import org.smartcomps.twister.common.persistence.XMLSessionException;
11 import org.smartcomps.twister.common.util.DurationUtil;
12 import org.dom4j.Document;
13 import org.dom4j.DocumentHelper;
14 import org.dom4j.Element;
15 import org.relaxng.datatype.DatatypeException;
16
17 import java.util.Date;
18 import java.util.StringTokenizer;
19 import java.util.Calendar;
20
21 import com.sun.msv.datatype.xsd.DatatypeFactory;
22 import com.sun.msv.datatype.xsd.XSDatatype;
23 import com.sun.msv.datatype.xsd.datetime.BigTimeDurationValueType;
24
25 /***
26 * Implementation of the ExpressionProcessor interface that evaluates BPEL
27 * expressions. Those expressions follow the XPath grammar with the additions
28 * of BPEL functions.
29 */
30 public class BPELExpressionProcessorImpl implements ExpressionProcessor {
31
32 private static final String VARIABLE_PROP_FUNC_PREFIX = "bpws:getVariableProperty(";
33 private static final String VARIABLE_DATA_FUNC_PREFIX = "bpws:getVariableData(";
34
35 public boolean evaluateAsBoolean(ProcessInstance instance, String expression) throws XPathEvaluationException {
36 Boolean result = null;
37 try {
38 result = (Boolean) evaluateAsObject(instance, expression);
39 } catch (ClassCastException e) {
40 throw new XPathEvaluationException("Expression evaluation didn't return a boolean.");
41 }
42 return result.booleanValue();
43 }
44
45 public String evaluateAsString(ProcessInstance instance, String expression) throws XPathEvaluationException {
46 String result = null;
47 try {
48 result = evaluateAsObject(instance, expression).toString();
49 } catch (ClassCastException e) {
50 throw new XPathEvaluationException("Expression evaluation didn't return a String.");
51 }
52 return result;
53 }
54
55 // TODO implement a property evaluation where date can be added with durations
56 public Date evaluateAsDate(ProcessInstance instance, String expression) throws XPathEvaluationException {
57 XSDatatype dateTimeType = null;
58 try {
59 dateTimeType = DatatypeFactory.getTypeByName("dateTime");
60 } catch (DatatypeException e) {
61 throw new XPathEvaluationException("Unable to get msv type classes", e);
62 }
63 String reducedExpr = null;
64 try {
65 reducedExpr = reduceBPELFunctions(instance, expression);
66 } catch (XMLSessionException e) {
67 throw new XPathEvaluationException(e);
68 }
69 if (dateTimeType.isValid(reducedExpr, null)) {
70 return ((Calendar)dateTimeType.createJavaObject(reducedExpr, null)).getTime();
71 } else {
72 throw new XPathEvaluationException("The expression could not be evaluated as a Date : " + expression);
73 }
74 }
75
76 public Date evaluateDurationAsDate(ProcessInstance instance, String expression) throws XPathEvaluationException {
77 XSDatatype durationType = null;
78 try {
79 durationType = DatatypeFactory.getTypeByName("duration");
80 } catch (DatatypeException e) {
81 throw new XPathEvaluationException("Unable to get msv type classes", e);
82 }
83 String reducedExpr = null;
84 try {
85 reducedExpr = reduceBPELFunctions(instance, expression);
86 } catch (XMLSessionException e) {
87 throw new XPathEvaluationException(e);
88 }
89 if (durationType.isValid(reducedExpr, null)) {
90 Calendar cal = Calendar.getInstance();
91 BigTimeDurationValueType duration =
92 (BigTimeDurationValueType) durationType.createJavaObject(reducedExpr, null);
93 DurationUtil.addDuration(cal, duration);
94 return cal.getTime();
95 } else {
96 throw new XPathEvaluationException("The expression could not be evaluated as a Date : " + expression);
97 }
98 }
99
100 private Object evaluateAsObject(ProcessInstance instance, String expression) throws XPathEvaluationException {
101 String reduceExpression = null;
102 try {
103 reduceExpression = reduceBPELFunctions(instance, expression);
104 } catch (XMLSessionException e) {
105 throw new XPathEvaluationException("Could not connect to the xml database when evaluating the " +
106 "xpath expression " + expression, e);
107 }
108 Document testDoc = DocumentHelper.createDocument();
109 Element root = testDoc.addElement("root");
110 Object result = root.selectObject(reduceExpression);
111 return result;
112 }
113
114 private String reduceBPELFunctions(ProcessInstance instance, String expression) throws SelectionFailureException, XMLSessionException {
115 String reducedExpr = expression;
116 int varPropFuncIndex = expression.indexOf(VARIABLE_PROP_FUNC_PREFIX);
117 int varDataFuncIndex = expression.indexOf(VARIABLE_DATA_FUNC_PREFIX);
118 while (varPropFuncIndex > -1 || varDataFuncIndex > -1) {
119 if (varPropFuncIndex > -1) {
120 // Isolating parameters
121 String varPropFuncParam1ToEnd = reducedExpr.substring(varPropFuncIndex + 25, reducedExpr.length());
122 StringTokenizer tokenizer = new StringTokenizer(varPropFuncParam1ToEnd, "'");
123 String variableName = tokenizer.nextToken();
124 tokenizer.nextToken();
125 String propertyName = tokenizer.nextToken();
126
127 // Selecting corresponding value
128 PropertyAlias alias = instance.getProcess().getProperty(propertyName).getAlias();
129 String selectedValue = null;
130 try {
131 selectedValue = VariableXAO.queryVariableValue(instance.getProcess().getName(), variableName,
132 instance.getId(), alias.getPart(), alias.getQuery());
133 } catch (FinderException e) {
134 throw new SelectionFailureException(e);
135 }
136
137 // Reducing the expression with the selected value
138 reducedExpr = reducedExpr.substring(0, varPropFuncIndex) + selectedValue +
139 varPropFuncParam1ToEnd.substring(varPropFuncParam1ToEnd.indexOf(")") + 1,
140 varPropFuncParam1ToEnd.length());
141 }
142 if (varDataFuncIndex > -1) {
143 // Recalculating in case a the expressions has been reduced by the preceding case
144 varDataFuncIndex = expression.indexOf(VARIABLE_DATA_FUNC_PREFIX);
145 // Isolating parameters
146 String varDataFuncParam1ToEnd = reducedExpr.substring(varDataFuncIndex + 21, reducedExpr.length());
147 StringTokenizer tokenizer = new StringTokenizer(varDataFuncParam1ToEnd, "'");
148 String variableName = tokenizer.nextToken();
149 String nextToken = tokenizer.nextToken();
150 String partName = null;
151 String locationPath = null;
152 if (nextToken.trim().startsWith(",")) {
153 partName = tokenizer.nextToken();
154 nextToken = tokenizer.nextToken();
155 if (nextToken.trim().startsWith(",")) {
156 locationPath = tokenizer.nextToken();
157 }
158 }
159
160 // Selecting corresponding values
161 String selectedValue = null;
162 try {
163 if (locationPath != null) {
164 selectedValue = VariableXAO.queryVariableValue(instance.getProcess().getName(), variableName,
165 instance.getId(), partName, locationPath);
166 } else if (partName != null) {
167 selectedValue = VariableXAO.queryVariableValue(instance.getProcess().getName(), variableName,
168 instance.getId(), partName, "/");
169 } else {
170 selectedValue = VariableXAO.queryVariableValue(instance.getProcess().getName(), variableName,
171 instance.getId(), "", "");
172 }
173 } catch (FinderException e) {
174 throw new SelectionFailureException(e);
175 }
176
177 reducedExpr = reducedExpr.substring(0, varDataFuncIndex) + selectedValue +
178 varDataFuncParam1ToEnd.substring(varDataFuncParam1ToEnd.indexOf(")") + 1,
179 varDataFuncParam1ToEnd.length());
180 }
181 varPropFuncIndex = reducedExpr.indexOf(VARIABLE_PROP_FUNC_PREFIX);
182 varDataFuncIndex = reducedExpr.indexOf(VARIABLE_DATA_FUNC_PREFIX);
183 }
184 return reducedExpr;
185 }
186
187 }
This page was automatically generated by Maven