package org.atdl4j.data.validation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.atdl4j.data.ValidationRule;
import org.atdl4j.data.exception.ValidationException;
import org.atdl4j.fixatdl.validation.LogicOperatorT;
import org.atdl4j.ui.Atdl4jWidget;
/**
* ValidationRule that behaves as a composite, using on of the following
* operators: AND, OR, XOR, NOT.
*
* @author renato.gallart
* @author john.shields
*/
public class LogicalOperatorValidationRule
implements ValidationRule
{
private LogicOperatorT operator;
private List<ValidationRule> rules;
public LogicalOperatorValidationRule(LogicOperatorT operator, Object parent)
{
this.operator = operator;
this.rules = new ArrayList<ValidationRule>();
}
public List<ValidationRule> getRules()
{
return rules;
}
public void addRule(ValidationRule rule)
{
this.rules.add( rule );
}
public void validate(Map<String, ValidationRule> rules, Map<String, Atdl4jWidget<?>> targets)
throws ValidationException
{
ValidationException ex = null;
boolean valid = false;
switch ( operator )
{
case OR :
// OR - new interpretation
for ( ValidationRule rule : this.rules )
{
try
{
rule.validate( rules, targets );
valid = true;
break;
}
catch (ValidationException e)
{
ex = e;
}
}
if ( !valid )
{
throw ex;
}
break;
case AND :
// AND - behaves as short circuit
for ( ValidationRule rule : this.rules )
{
try
{
rule.validate( rules, targets );
}
catch (ValidationException e)
{
throw e;
}
}
break;
case XOR :
boolean state = false;
// XOR - defined as true if exactly one argument is true
// TODO: this is overly complex
for ( ValidationRule rule : this.rules )
{
try
{
rule.validate( rules, targets );
if ( state )
{
valid = false;
Atdl4jWidget<?> parameter = getParameterFromRule( rule );
throw new ValidationException( parameter );
}
state = true;
valid = true;
}
catch (ValidationException e)
{
ex = e;
if ( state )
break;
}
}
if ( !valid )
{
throw ex;
}
break;
case NOT :
// NOT - interpreted as 'NOR'; will throw exception if any of the
// rules validate as true
for ( ValidationRule rule : this.rules )
{
try
{
rule.validate( rules, targets );
// if above does not trigger an exception
Atdl4jWidget<?> parameter = getParameterFromRule( rule );
throw new ValidationException( parameter );
}
catch (ValidationException e)
{
ex = e;
}
}
break;
}
}
private Atdl4jWidget<?> getParameterFromRule(ValidationRule rule)
{
Atdl4jWidget<?> parameter = null;
if ( rule instanceof ParameterValidationRule )
{
parameter = ( (ParameterValidationRule) rule ).getParameter();
}
return parameter;
}
}