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.reporting;
017
018 import org.springframework.rules.constraint.Constraint;
019 import org.springframework.rules.closure.support.Block;
020 import org.springframework.rules.Rules;
021 import org.springframework.rules.constraint.property.CompoundPropertyConstraint;
022 import org.springframework.rules.constraint.property.PropertyConstraint;
023 import org.springframework.rules.constraint.property.PropertyValueConstraint;
024 import org.springframework.util.Assert;
025
026 /**
027 * @author Keith Donald
028 */
029 public class BeanValidationResultsCollector extends ValidationResultsCollector {
030
031 private Object bean;
032
033 public BeanValidationResultsCollector(Object bean) {
034 super();
035 setBean(bean);
036 }
037
038 public void setBean(Object bean) {
039 Assert.notNull(bean, "bean is required");
040 this.bean = bean;
041 }
042
043 protected BeanValidationResultsBuilder getBeanResultsBuilder() {
044 return (BeanValidationResultsBuilder)getResultsBuilder();
045 }
046
047 public void setResultsBuilder(ValidationResultsBuilder builder) {
048 Assert.isTrue(builder instanceof BeanValidationResultsBuilder,
049 "Builder must be a bean validation results builder");
050 super.setResultsBuilder(builder);
051 }
052
053 public BeanValidationResults collectResults(Rules rules) {
054 Assert.notNull(rules, "rules is required");
055 setResultsBuilder(new BeanValidationResultsBuilder(bean));
056 new Block() {
057 protected void handle(Object beanPropertyConstraint) {
058 collectPropertyResultsInternal((PropertyConstraint)beanPropertyConstraint);
059 }
060 }.forEach(rules.iterator());
061 return getBeanResultsBuilder();
062 }
063
064 public PropertyResults collectPropertyResults(PropertyConstraint propertyRootExpression) {
065 Assert.notNull(propertyRootExpression, "propertyRootExpression is required");
066 setResultsBuilder(new BeanValidationResultsBuilder(this.bean));
067 return collectPropertyResultsInternal(propertyRootExpression);
068 }
069
070 private PropertyResults collectPropertyResultsInternal(PropertyConstraint rootExpression) {
071 getBeanResultsBuilder().setCurrentBeanPropertyExpression(rootExpression);
072 setArgument(getBeanResultsBuilder().getCurrentPropertyValue());
073 boolean result = ((Boolean)visitorSupport.invokeVisit(this, rootExpression)).booleanValue();
074 if (logger.isDebugEnabled()) {
075 logger.debug("Final validation result: " + result);
076 }
077 if (!result)
078 return getBeanResultsBuilder().getResults(rootExpression.getPropertyName());
079
080 return null;
081 }
082
083 Boolean visit(CompoundPropertyConstraint rule) {
084 if (logger.isDebugEnabled()) {
085 logger.debug("Validating compound bean property expression [" + rule + "]...");
086 }
087 return (Boolean)visitorSupport.invokeVisit(this, rule.getPredicate());
088 }
089
090 boolean visit(PropertyConstraint constraint) {
091 if (logger.isDebugEnabled()) {
092 logger.debug("Validating bean properties expression [" + constraint + "]...");
093 }
094 return testBeanPropertyExpression(constraint);
095 }
096
097 private boolean testBeanPropertyExpression(PropertyConstraint constraint) {
098 boolean result = constraint.test(bean);
099 result = applyAnyNegation(result);
100 if (!result) {
101 getBeanResultsBuilder().push(constraint);
102 }
103 if (logger.isDebugEnabled()) {
104 logger.debug("Constraint [" + constraint + "] " + (result ? "passed" : "failed"));
105 }
106 return result;
107 }
108
109 Boolean visit(PropertyValueConstraint valueConstraint) {
110 if (logger.isDebugEnabled()) {
111 logger.debug("Validating property value constraint [" + valueConstraint + "]...");
112 }
113 return (Boolean)visitorSupport.invokeVisit(this, valueConstraint.getConstraint());
114 }
115
116 boolean visit(Constraint constraint) {
117 return super.visit(constraint);
118 }
119 }