View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.datadictionary.validation.processor;
17  
18  import org.kuali.rice.core.api.util.RiceKeyConstants;
19  import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
20  import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader;
21  import org.kuali.rice.krad.datadictionary.validation.DictionaryObjectAttributeValueReader;
22  import org.kuali.rice.krad.datadictionary.validation.ValidationUtils;
23  import org.kuali.rice.krad.datadictionary.validation.constraint.Constraint;
24  import org.kuali.rice.krad.datadictionary.validation.constraint.ExistenceConstraint;
25  import org.kuali.rice.krad.datadictionary.validation.result.ConstraintValidationResult;
26  import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult;
27  import org.kuali.rice.krad.datadictionary.validation.result.ProcessorResult;
28  
29  /**
30   * @author Kuali Rice Team (rice.collab@kuali.org)
31   */
32  public class ExistenceConstraintProcessor extends OptionalElementConstraintProcessor<ExistenceConstraint> {
33  
34      private static final String CONSTRAINT_NAME = "existence constraint";
35  
36      /**
37       * @see org.kuali.rice.krad.datadictionary.validation.processor.ConstraintProcessor#process(org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult,
38       *      Object, org.kuali.rice.krad.datadictionary.validation.constraint.Constraint,
39       *      org.kuali.rice.krad.datadictionary.validation.AttributeValueReader) \
40       */
41      @Override
42      public ProcessorResult process(DictionaryValidationResult result, Object value, ExistenceConstraint constraint,
43              AttributeValueReader attributeValueReader) throws AttributeValidationException {
44  
45          // To accommodate the needs of other processors, the ConstraintProcessor.process() method returns a list of ConstraintValidationResult objects
46          // but since a definition that is existence constrained only provides a single isRequired field, there is effectively a single constraint
47          // being imposed.
48          return new ProcessorResult(processSingleExistenceConstraint(result, value, constraint, attributeValueReader));
49      }
50  
51      @Override
52      public String getName() {
53          return CONSTRAINT_NAME;
54      }
55  
56      /**
57       * @see org.kuali.rice.krad.datadictionary.validation.processor.ConstraintProcessor#getConstraintType()
58       */
59      @Override
60      public Class<? extends Constraint> getConstraintType() {
61          return ExistenceConstraint.class;
62      }
63  
64      protected ConstraintValidationResult processSingleExistenceConstraint(DictionaryValidationResult result,
65              Object value, ExistenceConstraint constraint,
66              AttributeValueReader attributeValueReader) throws AttributeValidationException {
67          // If it's not set, then there's no constraint
68          if (constraint.isRequired() == null) {
69              return result.addNoConstraint(attributeValueReader, CONSTRAINT_NAME);
70          }
71  
72          if (constraint.isRequired().booleanValue() && !skipConstraint(attributeValueReader)) {
73              // If this attribute is required and the value is null then
74              if (ValidationUtils.isNullOrEmpty(value)) {
75                  String errorParameter = attributeValueReader.getLabel(attributeValueReader.getAttributeName());
76                  if (ValidationUtils.isNullOrEmpty(errorParameter)) {
77                      errorParameter = attributeValueReader.getAttributeName();
78                  }
79                  return result.addError(attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_REQUIRED,
80                          errorParameter);
81              }
82              return result.addSuccess(attributeValueReader, CONSTRAINT_NAME);
83          }
84  
85          return result.addSkipped(attributeValueReader, CONSTRAINT_NAME);
86      }
87  
88      /**
89       * Checks to see if existence constraint should be skipped.  Required constraint should be skipped if it is an
90       * attribute of a complex
91       * attribute and the complex attribute is not required.
92       *
93       * @param attributeValueReader
94       * @return true if the constraint should be skipped
95       */
96      private boolean skipConstraint(AttributeValueReader attributeValueReader) {
97          boolean skipConstraint = false;
98          if (attributeValueReader instanceof DictionaryObjectAttributeValueReader) {
99              DictionaryObjectAttributeValueReader dictionaryValueReader =
100                     (DictionaryObjectAttributeValueReader) attributeValueReader;
101             skipConstraint = dictionaryValueReader.isNestedAttribute() && dictionaryValueReader.isParentAttributeNull();
102         }
103         return skipConstraint;
104     }
105 
106 }