1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.edl.impl.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.edl.impl.EDLContext;
27  import org.kuali.rice.edl.impl.EDLModelComponent;
28  import org.kuali.rice.edl.impl.EDLXmlUtils;
29  import org.kuali.rice.edl.impl.RequestParser;
30  import org.kuali.rice.edl.impl.service.EdlServiceLocator;
31  import org.kuali.rice.kew.api.WorkflowRuntimeException;
32  import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
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 = EdlServiceLocator.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 }