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.constraint;
017
018import org.kuali.rice.krad.datadictionary.parse.BeanTag;
019import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
020import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
021
022import java.util.ArrayList;
023import java.util.List;
024
025/**
026 * {@code WhenConstraint} is a child of a {@link CaseConstraint}
027 *
028 * <p>It provides a specific additional constraint that should be processed when
029 * the condition itself is true.</p>
030 *
031 * <p>So a case constraint on country, might have a when constraint with value='USA', and another with value='Canada'.
032 * Each of these
033 * {@code WhenConstraint}'s would define a constraint of their own that would only be processed when the country was
034 * USA, or when the country
035 * was Canada.</p>
036 *
037 * <p>A {@code WhenConstraint} either specifies an attribute path whose value it then provides or a constraint.
038 * The parent @{CaseConstraint} is defined on the field on which the constraints are desired to take effect.</p>
039 *
040 * @author Kuali Rice Team (rice.collab@kuali.org)
041 * @since 1.1
042 */
043@BeanTag(name = "whenConstraint", parent = "WhenConstraint")
044public class WhenConstraint implements Constraint {
045    protected List<Object> values;
046    protected String valuePath;
047    protected Constraint constraint;
048
049    /**
050     * List of values to check for this constraint
051     *
052     * @return a list of values for which to activate the associated constraint
053     */
054    @BeanTagAttribute
055    public List<Object> getValues() {
056        return values;
057    }
058
059    /**
060     * setter for values
061     *
062     * @param values - the values to set
063     */
064    public void setValues(List<Object> values) {
065        this.values = values;
066    }
067
068    /**
069     * The value to check for this when constraint.  This is a convenience method that is the first value of the
070     * values array.
071     *
072     * @return the first value checking on, otherwise null
073     */
074    public Object getValue(){
075        if(values != null && !values.isEmpty()){
076            return values.get(0);
077        }
078        else{
079            return null;
080        }
081    }
082
083    /**
084     * Sets a single value to check for this constraint.  This is a convenience method.
085     *
086     * @param value - a values for which to activate the associated constraint
087     */
088    public void setValue(Object value) {
089        values = new ArrayList<Object>();
090        values.add(value);
091    }
092
093    /**
094     * Path that can retrieve an attributes value
095     *
096     * @return a string representation of specifically which attribute (at some depth) is being accessed
097     */
098    @BeanTagAttribute(name = "valuePath")
099    public String getValuePath() {
100        return valuePath;
101    }
102
103    /**
104     * setter for the value path
105     *
106     * @param valuePath - the value path to set
107     */
108    public void setValuePath(String valuePath) {
109        this.valuePath = valuePath;
110    }
111
112    /**
113     * The constraint to apply to the field when the {@code WhenConstraint} value/values match
114     *
115     * @return the constraint
116     */
117    @BeanTagAttribute(name = "constraint", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
118    public Constraint getConstraint() {
119        return constraint;
120    }
121
122    /**
123     * setter for constraint
124     *
125     * @param constraint - the constraint to set
126     */
127    public void setConstraint(Constraint constraint) {
128        this.constraint = constraint;
129    }
130
131    /**
132     * Validates different requirements of component compiling a series of reports detailing information on errors
133     * found in the component.  Used by the RiceDictionaryValidator.
134     *
135     * @param tracer Record of component's location
136     */
137    public void completeValidation(ValidationTrace tracer) {
138        tracer.addBean("WhenConstraint", ValidationTrace.NO_BEAN_ID);
139
140        if (getConstraint() == null) {
141            String currentValues[] = {"constraint = " + getConstraint()};
142            tracer.createWarning("Constraint must be set", currentValues);
143        }
144
145        if (getValuePath() == null || getValues() == null) {
146            String currentValues[] = {"valuePath = " + getValuePath(), "values = " + getValues()};
147            tracer.createWarning("Value Path or Values must be set", currentValues);
148        }
149    }
150}