/** * 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.reporting; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.style.ToStringCreator; import org.valkyriercp.rules.closure.Closure; import org.valkyriercp.rules.constraint.*; import org.valkyriercp.util.ReflectiveVisitorHelper; import java.util.Iterator; /** * @author Keith Donald */ public class ValidationResultsCollector { protected static final Log logger = LogFactory .getLog(ValidationResultsCollector.class); protected ReflectiveVisitorHelper visitorSupport = new ReflectiveVisitorHelper(); private ValidationResultsBuilder resultsBuilder; private ValidationResults results; private boolean collectAllErrors; private Object argument; public ValidationResultsCollector() { } public ValidationResults collect(final Object argument, final Constraint constraint) { this.resultsBuilder = new ValidationResultsBuilder() { public void constraintSatisfied() { } public void constraintViolated(Constraint constraint) { results = new ValueValidationResults(argument, constraint); } }; if (results == null) { results = new ValueValidationResults(argument); } this.argument = argument; visitorSupport.invokeVisit(this, constraint); return results; } public void setCollectAllErrors(boolean collectAllErrors) { this.collectAllErrors = collectAllErrors; } protected ValidationResultsBuilder getResultsBuilder() { return resultsBuilder; } protected void setResultsBuilder(ValidationResultsBuilder resultsBuilder) { this.resultsBuilder = resultsBuilder; } protected void setArgument(Object argument) { this.argument = argument; } boolean visit(And and) { resultsBuilder.pushAnd(); if (logger.isDebugEnabled()) { logger.debug("Starting [and]..."); } boolean result = true; Iterator it = and.iterator(); while (it.hasNext()) { boolean test = ((Boolean)visitorSupport.invokeVisit( ValidationResultsCollector.this, it.next())).booleanValue(); if (!test) { if (!collectAllErrors) { resultsBuilder.pop(false); return false; } if (result) { result = false; } } } if (logger.isDebugEnabled()) { logger.debug("Finished [and]..."); } resultsBuilder.pop(result); return result; } boolean visit(Or or) { resultsBuilder.pushOr(); if (logger.isDebugEnabled()) { logger.debug("Starting [or]..."); } Iterator it = or.iterator(); while (it.hasNext()) { boolean result = ((Boolean)visitorSupport.invokeVisit( ValidationResultsCollector.this, it.next())).booleanValue(); if (result) { resultsBuilder.pop(result); return true; } } if (logger.isDebugEnabled()) { logger.debug("Finished [or]..."); } resultsBuilder.pop(false); return false; } Boolean visit(Not not) { resultsBuilder.pushNot(); if (logger.isDebugEnabled()) { logger.debug("Starting [not]..."); } Boolean result = (Boolean)visitorSupport.invokeVisit(this, not .getConstraint()); if (logger.isDebugEnabled()) { logger.debug("Finished [not]..."); } resultsBuilder.pop(result.booleanValue()); return result; } Boolean visit(ClosureResultConstraint ofConstraint) { Closure f = ofConstraint.getFunction(); if (logger.isDebugEnabled()) { logger.debug("Invoking function with argument " + argument); } setArgument(f.call(argument)); return (Boolean)visitorSupport.invokeVisit(this, ofConstraint .getPredicate()); } boolean visit(Constraint constraint) { if (logger.isDebugEnabled()) { logger.debug("Testing constraint [" + constraint + "] with argument '" + argument + "']"); } boolean result = constraint.test(argument); result = applyAnyNegation(result); if (!result) { resultsBuilder.push(constraint); } if (logger.isDebugEnabled()) { logger.debug("Constraint [" + constraint + "] " + (result ? "passed" : "failed")); } return result; } protected boolean applyAnyNegation(boolean result) { boolean negated = resultsBuilder.negated(); if (logger.isDebugEnabled()) { if (negated) { logger.debug("[negate result]"); } else { logger.debug("[no negation]"); } } return negated ? !result : result; } public String toString() { return new ToStringCreator(this).append("collectAllErrors", collectAllErrors).append("validationResultsBuilder", resultsBuilder).toString(); } }