/**
* Copyright (C) 2015 Valkyrie RCP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.valkyriercp.rules.constraint.property;
import org.springframework.util.Assert;
import org.valkyriercp.binding.PropertyAccessStrategy;
import org.valkyriercp.rules.reporting.TypeResolvable;
/**
* <p>
* Provides a way to trigger rules for propertyB when propertyA satisfies a
* certain condition:
* </p>
*
* <pre>
* if (propertyA satisfies the conditional constraint)
* {
* check the rules for propertyB
* }
* </pre>
*
* with an optional part:
*
* <pre>
* else
* {
* check the rules for propertyC
* }
* </pre>
*
* <p>
* More complex situations are possible by using compound constraints which
* leverages the previous to:
* </p>
*
* <pre>
* if (constraint(propertyA, propertyB,...) == true)
* {
* checkConstraint(property1, property2,...);
* }
* \\ optional part
* else
* {
* checkConstraint(propertyX, propertyY,...);
* }
* </pre>
*
* <p>
* This class can be compared to the {@link org.valkyriercp.rules.constraint.IfTrue} class: it applies the same
* pattern but on different <b>properties</b> instead of on a <b>property value</b>.
* </p>
*
* @author jh
*
*/
public class ConditionalPropertyConstraint extends AbstractPropertyConstraint implements TypeResolvable {
/** The condition which triggers further rules to be checked. */
private final PropertyConstraint ifConstraint;
/** The constraint to be checked when the condition is satisfied. */
private final PropertyConstraint thenConstraint;
/** The constraint to be checked when the condition is <b>NOT</b> satisfied. */
private final PropertyConstraint elseConstraint;
/** Type used to fetch message. */
private String type;
/**
* @see #ConditionalPropertyConstraint(PropertyConstraint, PropertyConstraint, String)
*/
public ConditionalPropertyConstraint(PropertyConstraint ifConstraint, PropertyConstraint thenConstraint) {
this(ifConstraint, thenConstraint, null, null);
}
/**
* Create a constraint which simulates the if...then pattern applied
* on separate properties.
*
* @param ifConstraint the PropertyConstraint that triggers the test
* (satisfying a certain condition).
* @param thenConstraint the PropertyConstraint to test in the specified
* condition.
*/
public ConditionalPropertyConstraint(PropertyConstraint ifConstraint, PropertyConstraint thenConstraint, String type) {
this(ifConstraint, thenConstraint, null, type);
}
/**
* @see #ConditionalPropertyConstraint(PropertyConstraint, PropertyConstraint, PropertyConstraint, String)
*/
public ConditionalPropertyConstraint(PropertyConstraint ifConstraint, PropertyConstraint thenConstraint,
PropertyConstraint elseConstraint) {
this(ifConstraint, thenConstraint, elseConstraint, null);
}
/**
* Create a constraint which simulates the if...then...else pattern applied
* on separate properties.
*
* @param ifConstraint the PropertyConstraint that triggers the test
* (satisfying a certain condition).
* @param thenConstraint the PropertyConstraint to test in the specified
* condition.
* @param elseConstraint the PropertyConstraint to test if the condition is
* <b>NOT</b> satisfied. May be <code>null</code>.
* @param type the messageCode used to fetch the message.
*/
public ConditionalPropertyConstraint(PropertyConstraint ifConstraint, PropertyConstraint thenConstraint,
PropertyConstraint elseConstraint, String type) {
super(ifConstraint.getPropertyName());
Assert.notNull(ifConstraint);
Assert.notNull(thenConstraint);
this.ifConstraint = ifConstraint;
this.thenConstraint = thenConstraint;
this.elseConstraint = elseConstraint;
this.type = type;
}
public boolean isCompoundRule() {
return true;
}
public boolean isDependentOn(String propertyName) {
if (elseConstraint == null)
return ifConstraint.isDependentOn(propertyName) || thenConstraint.isDependentOn(propertyName);
return ifConstraint.isDependentOn(propertyName) || thenConstraint.isDependentOn(propertyName)
|| elseConstraint.isDependentOn(propertyName);
}
protected boolean test(PropertyAccessStrategy domainObjectAccessStrategy) {
if (ifConstraint.test(domainObjectAccessStrategy))
return thenConstraint.test(domainObjectAccessStrategy);
if (elseConstraint != null)
return elseConstraint.test(domainObjectAccessStrategy);
return true;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}