/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.openstack.atlas.api.validation.expectation; import org.openstack.atlas.api.validation.exceptions.ValidationChainExecutionException; import org.openstack.atlas.api.validation.results.ExpectationResult; import org.openstack.atlas.api.validation.results.ExpectationResultBuilder; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; import java.util.LinkedList; import java.util.List; public class ExpectationTarget<T> { private final Method targetMethod; private final List<Expectation> expectations; public ExpectationTarget(Method targetMethod) { this.targetMethod = targetMethod; this.expectations = new LinkedList<Expectation>(); } public synchronized void addExpectation(Expectation ex) { expectations.add(ex); } public synchronized SelfValidationResult isSatisfied() { final StringBuilder strBuff = new StringBuilder(); boolean valid = true; Collections.sort(expectations); for (Expectation ex : expectations) { if (!ex.hasVerifierSet()) { strBuff.append("\nIncomplete: ").append("Expectation #").append(ex.getExpectationId()).append(" - ").append(getTargetName()); valid = false; } } return new SelfValidationResult(strBuff, valid); } public String getTargetName() { return targetMethod == null ? "Root Object" : targetMethod.getName(); } public boolean targets(Method target) { return target == targetMethod; } public synchronized List<ExpectationResult> validate(T target, Object context) { //TODO: Inline? Too complex? final Object objectToValidateAgainst = targetMethod == null ? target : invokeMethod(targetMethod, target); return validateObject(expectations, objectToValidateAgainst, context); } private List<ExpectationResult> validateObject(List<Expectation> expectations, Object objectBeingValidated, Object context) throws ValidationChainExecutionException { final ExpectationResultBuilder resultBuilder = new ExpectationResultBuilder(getTargetName()); final List<ExpectationResult> gatheredResults = new LinkedList<ExpectationResult>(); for (Expectation expectation : expectations) { final List<ValidationResult> validationResults = expectation.validate(objectBeingValidated, context); for (ValidationResult validationResult : validationResults) { if (!validationResult.expectationWasMet()) { resultBuilder.setMessage(validationResult.getMessage()); resultBuilder.setPassed(false); gatheredResults.add(resultBuilder.toResult()); } } } return gatheredResults; } private Object invokeMethod(Method m, T object) throws ValidationChainExecutionException { try { return m.invoke(object); } catch (IllegalAccessException iae) { throw new ValidationChainExecutionException("Fatal exception encountered during validation. Please verify your JVM security model.", iae); } catch (IllegalArgumentException iae) { throw new ValidationChainExecutionException("This shouldn't happen but if it does, you lose. Please report this as a bug.", iae); } catch (InvocationTargetException ite) { final Throwable t = ite.getTargetException(); throw new ValidationChainExecutionException("Exception \"" + t.getMessage() + "\" encountered during validation chain execution. Pump cause for more details.", t); } } }