1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary.validation.processor;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.kuali.rice.core.api.uif.DataType;
22 import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
23 import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
24 import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader;
25 import org.kuali.rice.krad.datadictionary.validation.DictionaryObjectAttributeValueReader;
26 import org.kuali.rice.krad.datadictionary.validation.ValidationUtils;
27 import org.kuali.rice.krad.datadictionary.validation.capability.Constrainable;
28 import org.kuali.rice.krad.datadictionary.validation.capability.HierarchicallyConstrainable;
29 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
30 import org.kuali.rice.krad.datadictionary.validation.constraint.Constraint;
31 import org.kuali.rice.krad.datadictionary.validation.constraint.DataTypeConstraint;
32 import org.kuali.rice.krad.datadictionary.validation.constraint.WhenConstraint;
33 import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult;
34 import org.kuali.rice.krad.datadictionary.validation.result.ProcessorResult;
35 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
36
37
38
39
40
41
42
43
44
45 public class CaseConstraintProcessor extends MandatoryElementConstraintProcessor<CaseConstraint> {
46
47 private static final String CONSTRAINT_NAME = "case constraint";
48
49
50
51
52
53
54 @Override
55 public ProcessorResult process(DictionaryValidationResult result, Object value, CaseConstraint caseConstraint,
56 AttributeValueReader attributeValueReader) throws AttributeValidationException {
57
58
59 if (null == caseConstraint) {
60 return new ProcessorResult(result.addNoConstraint(attributeValueReader, CONSTRAINT_NAME));
61 }
62 AttributeValueReader constraintAttributeReader = attributeValueReader.clone();
63
64 String operator = (ValidationUtils.hasText(caseConstraint.getOperator())) ? caseConstraint.getOperator() :
65 "EQUALS";
66 AttributeValueReader fieldPathReader = (ValidationUtils.hasText(caseConstraint.getPropertyName())) ?
67 getChildAttributeValueReader(caseConstraint.getPropertyName(), attributeValueReader) :
68 attributeValueReader;
69
70 Constrainable caseField = (null != fieldPathReader) ? fieldPathReader.getDefinition(
71 fieldPathReader.getAttributeName()) : null;
72 Object fieldValue = (null != fieldPathReader) ? fieldPathReader.getValue(fieldPathReader.getAttributeName()) :
73 value;
74 DataType fieldDataType = (null != caseField && caseField instanceof DataTypeConstraint) ?
75 ((DataTypeConstraint) caseField).getDataType() : null;
76
77
78 if (fieldDataType == null) {
79 fieldDataType = DataType.STRING;
80 }
81
82
83 if (null == fieldValue) {
84
85 return new ProcessorResult(result.addSkipped(attributeValueReader, CONSTRAINT_NAME), caseField,
86 fieldPathReader);
87 }
88
89 List<Constraint> constraints = new ArrayList<Constraint>();
90
91 for (WhenConstraint wc : caseConstraint.getWhenConstraint()) {
92 evaluateWhenConstraint(fieldValue, fieldDataType, operator, caseConstraint, wc, attributeValueReader,
93 constraints);
94 }
95 if (!constraints.isEmpty()) {
96 return new ProcessorResult(result.addSuccess(attributeValueReader, CONSTRAINT_NAME), null,
97 constraintAttributeReader, constraints);
98 }
99
100
101 return new ProcessorResult(result.addSkipped(attributeValueReader, CONSTRAINT_NAME));
102 }
103
104 private void evaluateWhenConstraint(Object fieldValue, DataType fieldDataType, String operator,
105 CaseConstraint caseConstraint, WhenConstraint wc, AttributeValueReader attributeValueReader,
106 List<Constraint> constraints) {
107 if (ValidationUtils.hasText(wc.getValuePath())) {
108 Object whenValue = null;
109
110 AttributeValueReader whenValueReader = getChildAttributeValueReader(wc.getValuePath(),
111 attributeValueReader);
112 whenValue = whenValueReader.getValue(whenValueReader.getAttributeName());
113
114 if (ValidationUtils.compareValues(fieldValue, whenValue, fieldDataType, operator,
115 caseConstraint.isCaseSensitive(), dateTimeService) && null != wc.getConstraint()) {
116 constraints.add(wc.getConstraint());
117 }
118 } else {
119 List<Object> whenValueList = wc.getValues();
120
121 for (Object whenValue : whenValueList) {
122 if (ValidationUtils.compareValues(fieldValue, whenValue, fieldDataType, operator,
123 caseConstraint.isCaseSensitive(), dateTimeService) && null != wc.getConstraint()) {
124 constraints.add(wc.getConstraint());
125 break;
126 }
127 }
128 }
129 }
130
131 @Override
132 public String getName() {
133 return CONSTRAINT_NAME;
134 }
135
136
137
138
139 @Override
140 public Class<? extends Constraint> getConstraintType() {
141 return CaseConstraint.class;
142 }
143
144 private AttributeValueReader getChildAttributeValueReader(String key,
145 AttributeValueReader attributeValueReader) throws AttributeValidationException {
146 String[] lookupPathTokens = ValidationUtils.getPathTokens(key);
147
148 AttributeValueReader localAttributeValueReader = attributeValueReader;
149 for (int i = 0; i < lookupPathTokens.length; i++) {
150 for (Constrainable definition : localAttributeValueReader.getDefinitions()) {
151 String attributeName = definition.getName();
152 if (attributeName.equals(lookupPathTokens[i])) {
153 if (i == lookupPathTokens.length - 1) {
154 localAttributeValueReader.setAttributeName(attributeName);
155 return localAttributeValueReader;
156 }
157 if (definition instanceof HierarchicallyConstrainable) {
158 String childEntryName = ((HierarchicallyConstrainable) definition).getChildEntryName();
159 DataDictionaryEntry entry = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary()
160 .getDictionaryObjectEntry(childEntryName);
161 Object value = attributeValueReader.getValue(attributeName);
162 attributeValueReader.setAttributeName(attributeName);
163 String attributePath = attributeValueReader.getPath();
164 localAttributeValueReader = new DictionaryObjectAttributeValueReader(value, childEntryName,
165 entry, attributePath);
166 }
167 break;
168 }
169 }
170 }
171 return null;
172 }
173
174 }