001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.datadictionary.validation.processor; 017 018import org.kuali.rice.core.api.util.RiceKeyConstants; 019import org.kuali.rice.krad.datadictionary.DataObjectEntry; 020import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException; 021import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader; 022import org.kuali.rice.krad.datadictionary.validation.DictionaryObjectAttributeValueReader; 023import org.kuali.rice.krad.datadictionary.validation.ValidationUtils; 024import org.kuali.rice.krad.datadictionary.validation.constraint.Constraint; 025import org.kuali.rice.krad.datadictionary.validation.constraint.ExistenceConstraint; 026import org.kuali.rice.krad.datadictionary.validation.result.ConstraintValidationResult; 027import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult; 028import org.kuali.rice.krad.datadictionary.validation.result.ProcessorResult; 029 030/** 031 * 032 * @author Kuali Rice Team (rice.collab@kuali.org) 033 */ 034public class ExistenceConstraintProcessor extends OptionalElementConstraintProcessor<ExistenceConstraint> { 035 036 private static final String CONSTRAINT_NAME = "existence constraint"; 037 038 /** 039 * @see org.kuali.rice.krad.datadictionary.validation.processor.ConstraintProcessor#process(org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult, Object, org.kuali.rice.krad.datadictionary.validation.constraint.Constraint, org.kuali.rice.krad.datadictionary.validation.AttributeValueReader) \ 040 */ 041 @Override 042 public ProcessorResult process(DictionaryValidationResult result, Object value, ExistenceConstraint constraint, AttributeValueReader attributeValueReader) throws AttributeValidationException { 043 044 // To accommodate the needs of other processors, the ConstraintProcessor.process() method returns a list of ConstraintValidationResult objects 045 // but since a definition that is existence constrained only provides a single isRequired field, there is effectively a single constraint 046 // being imposed. 047 return new ProcessorResult(processSingleExistenceConstraint(result, value, constraint, attributeValueReader)); 048 } 049 050 @Override 051 public String getName() { 052 return CONSTRAINT_NAME; 053 } 054 055 /** 056 * @see org.kuali.rice.krad.datadictionary.validation.processor.ConstraintProcessor#getConstraintType() 057 */ 058 @Override 059 public Class<? extends Constraint> getConstraintType() { 060 return ExistenceConstraint.class; 061 } 062 063 protected ConstraintValidationResult processSingleExistenceConstraint(DictionaryValidationResult result, Object value, ExistenceConstraint constraint, AttributeValueReader attributeValueReader) throws AttributeValidationException { 064 // If it's not set, then there's no constraint 065 if (constraint.isRequired() == null) 066 return result.addNoConstraint(attributeValueReader, CONSTRAINT_NAME); 067 068 if (constraint.isRequired().booleanValue() && !skipConstraint(attributeValueReader)) { 069 // If this attribute is required and the value is null then 070 if (ValidationUtils.isNullOrEmpty(value)) 071 return result.addError(attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_REQUIRED, attributeValueReader.getLabel(attributeValueReader.getAttributeName())); 072 return result.addSuccess(attributeValueReader, CONSTRAINT_NAME); 073 } 074 075 return result.addSkipped(attributeValueReader, CONSTRAINT_NAME); 076 } 077 078 /** 079 * Checks to see if existence constraint should be skipped. Required constraint should be skipped if it is an attribute of a complex 080 * attribute and the complex attribute is not required. 081 * 082 * @param attributeValueReader 083 * @return 084 */ 085 private boolean skipConstraint(AttributeValueReader attributeValueReader) { 086 boolean skipConstraint = false; 087 if (attributeValueReader instanceof DictionaryObjectAttributeValueReader){ 088 DictionaryObjectAttributeValueReader dictionaryValueReader = (DictionaryObjectAttributeValueReader)attributeValueReader; 089 skipConstraint = dictionaryValueReader.isNestedAttribute() && dictionaryValueReader.isParentAttributeNull(); 090 } 091 return skipConstraint; 092 } 093 094 095}