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.data.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  public class CaseConstraintProcessor extends MandatoryElementConstraintProcessor<CaseConstraint> {
45  
46      private static final String CONSTRAINT_NAME = "case constraint";
47  
48      
49  
50  
51  
52  
53      @Override
54      public ProcessorResult process(DictionaryValidationResult result, Object value, CaseConstraint caseConstraint,
55              AttributeValueReader attributeValueReader) throws AttributeValidationException {
56  
57          
58          if (null == caseConstraint) {
59              return new ProcessorResult(result.addNoConstraint(attributeValueReader, CONSTRAINT_NAME));
60          }
61          AttributeValueReader constraintAttributeReader = attributeValueReader.clone();
62  
63          String operator = (ValidationUtils.hasText(caseConstraint.getOperator())) ? caseConstraint.getOperator() :
64                  "EQUALS";
65          AttributeValueReader fieldPathReader = (ValidationUtils.hasText(caseConstraint.getPropertyName())) ?
66                  getChildAttributeValueReader(caseConstraint.getPropertyName(), attributeValueReader) :
67                  attributeValueReader;
68  
69          Constrainable caseField = (null != fieldPathReader) ? fieldPathReader.getDefinition(
70                  fieldPathReader.getAttributeName()) : null;
71          Object fieldValue = (null != fieldPathReader) ? fieldPathReader.getValue(fieldPathReader.getAttributeName()) :
72                  value;
73          DataType fieldDataType = (null != caseField && caseField instanceof DataTypeConstraint) ?
74                  ((DataTypeConstraint) caseField).getDataType() : null;
75  
76          
77          if (fieldDataType == null) {
78              fieldDataType = DataType.STRING;
79          }
80  
81          
82          if (null == fieldValue) {
83              
84              return new ProcessorResult(result.addSkipped(attributeValueReader, CONSTRAINT_NAME), caseField,
85                      fieldPathReader);
86          }
87  
88          List<Constraint> constraints = new ArrayList<Constraint>();
89          
90          for (WhenConstraint wc : caseConstraint.getWhenConstraint()) {
91              evaluateWhenConstraint(fieldValue, fieldDataType, operator, caseConstraint, wc, attributeValueReader,
92                      constraints);
93          }
94          if (!constraints.isEmpty()) {
95              return new ProcessorResult(result.addSuccess(attributeValueReader, CONSTRAINT_NAME), null,
96                      constraintAttributeReader, constraints);
97          }
98  
99          
100         return new ProcessorResult(result.addSkipped(attributeValueReader, CONSTRAINT_NAME));
101     }
102 
103     
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114     private void evaluateWhenConstraint(Object fieldValue, DataType fieldDataType, String operator,
115             CaseConstraint caseConstraint, WhenConstraint wc, AttributeValueReader attributeValueReader,
116             List<Constraint> constraints) {
117         if (ValidationUtils.hasText(wc.getValuePath())) {
118             Object whenValue = null;
119 
120             
121             AttributeValueReader whenValueReader = getChildAttributeValueReader(wc.getValuePath(),
122                     attributeValueReader);
123             whenValue = whenValueReader.getValue(whenValueReader.getAttributeName());
124 
125             if (ValidationUtils.compareValues(fieldValue, whenValue, fieldDataType, operator,
126                     caseConstraint.isCaseSensitive(), dateTimeService) && null != wc.getConstraint()) {
127                 constraints.add(wc.getConstraint());
128             }
129             
130         } else {
131             List<Object> whenValueList = wc.getValues();
132 
133             for (Object whenValue : whenValueList) {
134                 if (ValidationUtils.compareValues(fieldValue, whenValue, fieldDataType, operator,
135                         caseConstraint.isCaseSensitive(), dateTimeService) && null != wc.getConstraint()) {
136                     constraints.add(wc.getConstraint());
137                     break;
138                 }
139             }
140         }
141     }
142 
143     @Override
144     public String getName() {
145         return CONSTRAINT_NAME;
146     }
147 
148     
149 
150 
151     @Override
152     public Class<? extends Constraint> getConstraintType() {
153         return CaseConstraint.class;
154     }
155 
156     
157 
158 
159 
160 
161 
162 
163 
164     private AttributeValueReader getChildAttributeValueReader(String key,
165             AttributeValueReader attributeValueReader) throws AttributeValidationException {
166         String[] lookupPathTokens = ValidationUtils.getPathTokens(key);
167 
168         AttributeValueReader localAttributeValueReader = attributeValueReader.clone();
169         for (int i = 0; i < lookupPathTokens.length; i++) {
170             for (Constrainable definition : localAttributeValueReader.getDefinitions()) {
171                 String attributeName = definition.getName();
172                 if (attributeName.equals(lookupPathTokens[i])) {
173                     if (i == lookupPathTokens.length - 1) {
174                         localAttributeValueReader.setAttributeName(attributeName);
175                         return localAttributeValueReader;
176                     }
177                     if (definition instanceof HierarchicallyConstrainable) {
178                         String childEntryName = ((HierarchicallyConstrainable) definition).getChildEntryName();
179                         DataDictionaryEntry entry = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary()
180                                 .getDictionaryObjectEntry(childEntryName);
181                         Object value = attributeValueReader.getValue(attributeName);
182                         attributeValueReader.setAttributeName(attributeName);
183                         String attributePath = attributeValueReader.getPath();
184                         localAttributeValueReader = new DictionaryObjectAttributeValueReader(value, childEntryName,
185                                 entry, attributePath);
186                     }
187                     break;
188                 }
189             }
190         }
191         return null;
192     }
193 
194 }