001 package edu.nrao.sss.validation; 002 003 import java.util.List; 004 005 /** 006 * An individual test run by a {@link Validator}. 007 * Instances of this class are not generally needed by clients who request 008 * validation, but are instead used by specific implementations of validators. 009 * <p> 010 * <b>Version Info:</b> 011 * <table style="margin-left:2em"> 012 * <tr><td>$Revision: 868 $</td></tr> 013 * <tr><td>$Date: 2007-09-12 13:15:10 -0600 (Wed, 12 Sep 2007) $</td></tr> 014 * <tr><td>$Author: dharland $</td></tr> 015 * </table></p> 016 * 017 * @author David M. Harland 018 * @since 2007-02-05 019 */ 020 public abstract class Validation<T> 021 { 022 /** The validator of which this validation is a part. */ 023 protected AbstractValidator<T> container; 024 025 /** A measure of the consequences of failing this validation. */ 026 protected FailureSeverity severity; 027 028 /** The reason for doing this validation. */ 029 protected ValidationPurpose purpose; 030 031 /** 032 * Helps create a new instance. 033 * 034 * @param validationContainer the validator that holds this validation. 035 * @param reasonForValidation the reason this validation is being performed. 036 */ 037 protected Validation(AbstractValidator<T> validationContainer, 038 ValidationPurpose reasonForValidation) 039 { 040 container = validationContainer; 041 purpose = reasonForValidation; 042 severity = FailureSeverity.CONCERN; 043 } 044 045 /** 046 * Runs this validation and places any failures in the given list. 047 * 048 * @param failures the destination for any failures encountered while 049 * running this validation. 050 * 051 * @return <i>true</i> if this validation was successful, <i>false</i> 052 * otherwise. 053 */ 054 protected boolean run(List<ValidationFailure> failures) 055 { 056 boolean success = true; 057 058 if (container == null) 059 { 060 failures.add(noContainer()); 061 success = false; 062 } 063 else if (!passesTest()) 064 { 065 failures.add(failure()); 066 success = false; 067 } 068 069 return success; 070 } 071 072 /** 073 * Returns the name of this test. 074 * <p> 075 * This default implementation returns the fully qualified class name of 076 * the validation class. Implementing subclasses may choose to override 077 * this default and use some other name.</p> 078 * 079 * @return the name of this test. 080 */ 081 protected String getName() 082 { 083 return getClass().getName(); 084 } 085 086 /** 087 * Creates and returns a failure to be used if the target object fails 088 * this validation. 089 * 090 * @return a failure to be used if the target object fails this validation. 091 */ 092 private ValidationFailure failure() 093 { 094 return new ValidationFailure 095 ( 096 displayMessage(), 097 debugMessage(), 098 severity, 099 container.getTarget(), 100 container.getName(), 101 getName() 102 ); 103 } 104 105 /** 106 * Creates and returns a failure to be used if this validation has no 107 * container. 108 * 109 * @return a failure to be used if this validation has no container. 110 */ 111 private ValidationFailure noContainer() 112 { 113 return new ValidationFailure 114 ( 115 "", 116 "PROGRAMMER ERROR: Validation '" + 117 getClass().getName() + "' has no container.", 118 FailureSeverity.ERROR, 119 null, 120 "", 121 "no container" 122 ); 123 } 124 125 //============================================================================ 126 // OBLIGATIONS OF SUBCLASSES 127 //============================================================================ 128 129 /** 130 * Returns <i>true</i> if the target object passes this validation. 131 * @return <i>true</i> if the target object passes this validation. 132 */ 133 abstract protected boolean passesTest(); 134 135 /** 136 * Returns a user-friendly message to be used if this validation fails. 137 * @return a user-friendly message to be used if this validation fails. 138 */ 139 abstract protected String displayMessage(); 140 141 /** 142 * Returns a technical message to be used if this validation fails. 143 * @return a technical message to be used if this validation fails. 144 */ 145 abstract protected String debugMessage(); 146 }