001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
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, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.rules.constraint.property;
017    
018    import org.springframework.binding.PropertyAccessStrategy;
019    import org.springframework.rules.constraint.Constraint;
020    import org.springframework.rules.constraint.Required;
021    import org.springframework.util.Assert;
022    
023    /**
024     * Validates a property value as 'required' if some other condition is true.
025     *
026     * @author Seth Ladd
027     * @author Keith Donald
028     */
029    public class RequiredIfTrue extends AbstractPropertyConstraint {
030    
031            private Constraint constraint;
032    
033            /**
034             * Tests that the property is present if the provided predicate is
035             * satisified.
036             *
037             * @param predicate
038             *            the condition
039             */
040            public RequiredIfTrue(String propertyName, Constraint predicate) {
041                    super(propertyName);
042                    setConstraint(predicate);
043            }
044    
045            protected RequiredIfTrue(String propertyName) {
046                    super(propertyName);
047            }
048    
049            public Constraint getConstraint() {
050                    return constraint;
051            }
052    
053            protected void setConstraint(Constraint predicate) {
054                    Assert.notNull(predicate, "predicate is required");
055                    this.constraint = predicate;
056            }
057    
058        /**
059         * Determine if this rule is dependent on the given property name. True if either the
060         * direct poperty (from the contstructor) is equal to the given name, or if the "if
061         * true" predicate is a PropertyConstraint and it is dependent on the given property.
062         * @return true if this rule is dependent on the given property
063         */
064        public boolean isDependentOn(String propertyName) {
065            boolean dependent = false;
066            if( getConstraint() instanceof PropertyConstraint ) {
067                dependent = ((PropertyConstraint) getConstraint()).isDependentOn( propertyName );
068            }
069            return super.isDependentOn( propertyName ) || dependent;
070        }
071    
072            protected boolean test(PropertyAccessStrategy domainObjectAccessStrategy) {
073                    if (constraint.test(domainObjectAccessStrategy)) {
074                            return Required.instance().test(
075                                            domainObjectAccessStrategy
076                                            .getPropertyValue(getPropertyName()));
077                    }
078    
079            return true;
080            }
081    
082            public String toString() {
083                    return "required if (" + constraint + ")";
084            }
085    
086    }