1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.edl.components;
17
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.xml.xpath.XPath;
23 import javax.xml.xpath.XPathConstants;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.kuali.rice.kew.edl.EDLContext;
27 import org.kuali.rice.kew.edl.EDLModelComponent;
28 import org.kuali.rice.kew.edl.EDLXmlUtils;
29 import org.kuali.rice.kew.edl.RequestParser;
30 import org.kuali.rice.kew.exception.WorkflowRuntimeException;
31 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
32 import org.kuali.rice.kew.service.KEWServiceLocator;
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.NodeList;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class ValidationComponent extends SimpleWorkflowEDLConfigComponent implements EDLModelComponent {
52
53 private static final String XPATH_TYPE = "xpath";
54 private EDLContext edlContext;
55
56 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
57 if (edlContext.getUserAction().isValidatableAction()) {
58 try {
59 Document edlDef = KEWServiceLocator.getEDocLiteService().getDefinitionXml(edlContext.getEdocLiteAssociation());
60 List<EDLValidation> validations = parseValidations(edlDef);
61 if (!validations.isEmpty()) {
62 XPath xpath = XPathHelper.newXPath(dom);
63 for (EDLValidation validation : validations) {
64 executeValidation(xpath, dom, validation, edlContext);
65 }
66 }
67 } catch (Exception e) {
68 if (e instanceof RuntimeException) {
69 throw (RuntimeException)e;
70 }
71 throw new WorkflowRuntimeException("Failed to execute EDL validations.", e);
72 }
73 }
74 }
75
76 protected List<EDLValidation> parseValidations(Document document) throws Exception {
77 List<EDLValidation> validations = new ArrayList<EDLValidation>();
78 XPath xpath = XPathHelper.newXPath(document);
79 NodeList validationNodes = (NodeList)xpath.evaluate("/edl/validations/validation", document, XPathConstants.NODESET);
80 for (int index = 0; index < validationNodes.getLength(); index++) {
81 Element validationElem = (Element)validationNodes.item(index);
82 EDLValidation validation = new EDLValidation();
83 String type = validationElem.getAttribute("type");
84 String key = validationElem.getAttribute("key");
85 String expression = EDLXmlUtils.getChildElementTextValue(validationElem, "expression");
86 String message = EDLXmlUtils.getChildElementTextValue(validationElem, "message");
87 if (StringUtils.isBlank(type)) {
88 throw new WorkflowRuntimeException("An improperly configured validation was found with an empty type.");
89 }
90 if (StringUtils.isBlank(expression)) {
91 throw new WorkflowRuntimeException("An improperly configured validation was found with an empty expression.");
92 }
93 if (StringUtils.isBlank(message)) {
94 throw new WorkflowRuntimeException("An improperly configured validation was found with an empty message.");
95 }
96 validation.setType(type);
97 validation.setKey(key);
98 validation.setExpression(expression);
99 validation.setMessage(message);
100 validations.add(validation);
101 }
102 return validations;
103 }
104
105 protected void executeValidation(XPath xpath, Document dom, EDLValidation validation, EDLContext edlContext) throws Exception {
106
107 if (XPATH_TYPE.equals(validation.getType())) {
108 Boolean result = (Boolean)xpath.evaluate(validation.getExpression(), dom, XPathConstants.BOOLEAN);
109
110 if (!result) {
111 String key = validation.getKey();
112 if (!StringUtils.isEmpty(key)) {
113 Map<String, String> fieldErrors = (Map<String, String>)edlContext.getRequestParser().getAttribute(RequestParser.GLOBAL_FIELD_ERRORS_KEY);
114 fieldErrors.put(key, validation.getMessage());
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 } else {
138 List globalErrors = (List)edlContext.getRequestParser().getAttribute(RequestParser.GLOBAL_ERRORS_KEY);
139 globalErrors.add(validation.getMessage());
140 }
141 edlContext.setInError(true);
142 }
143 } else {
144 throw new WorkflowRuntimeException("Illegal validation type specified. Only 'xpath' is currently supported.");
145 }
146 }
147
148
149 }