001    package edu.nrao.sss.validation;
002    
003    /**
004     * A validation for empty or unitialized properties.
005     * Subclasses of this validation need only a constructor and 
006     * an implementation of {@link #getCurrentValue()}.
007     * <p>
008     * <b>Version Info:</b>
009     * <table style="margin-left:2em">
010     *   <tr><td>$Revision: 868 $</td></tr>
011     *   <tr><td>$Date: 2007-09-12 13:15:10 -0600 (Wed, 12 Sep 2007) $</td></tr>
012     *   <tr><td>$Author: dharland $</td></tr>
013     * </table></p>
014     * 
015     * @author David M. Harland
016     * @since 2007-02-09
017     */
018    public abstract class DataNotEnteredValidation<T>
019      extends Validation<T>
020    {
021      /**
022       * See {@link #DataNotEnteredValidation(AbstractValidator, ValidationPurpose,
023       * String, String, String) constructor} documentation.
024       */
025      protected String genericTargetName;
026      
027      /**
028       * Instead of a generic concept name, implementing classes can use the
029       * name of a specific instance.  If this value is non-null, it will be
030       * used in the messages in place of <tt>genericTargetName</tt>.
031       * <p>
032       * For instance, a generic name might be "user", whereas the target
033       * of this validation is the specific user "Mother Theresa".  In this
034       * situation, the implementing class would preferentially use
035       * "Mother Theresa", which will make the resulting failure message
036       * easier to understand for a human user.  The best time to set
037       * this value is in the {@link #getCurrentValue()} method.</p>
038       */
039      protected String specificTargetName;
040      
041      /**
042       * See {@link #DataNotEnteredValidation(AbstractValidator, ValidationPurpose,
043       * String, String, String) constructor} documentation.
044       */
045      protected String fieldName;
046    
047      /**
048       * See {@link #DataNotEnteredValidation(AbstractValidator, ValidationPurpose,
049       * String, String, String) constructor} documentation.
050       */
051      protected String defaultValue;
052      
053      /**
054       * Helps create an instance.
055       *
056       * @param validationContainer
057       *   The validator that will use this validation.
058       *   
059       * @param reasonForValidation
060       *   The reason we are doing this validation.
061       *   
062       * @param genericNameOfTarget
063       *   A generic name for the target of the validation.  Examples:
064       *   "User", "Project", "Scheduling Block".
065       *   
066       * @param nameOfField
067       *   The name of the field for which data was not entered.
068       *   A name that is suitable for presentation to a human user is
069       *   suggested.  Examples: "social security number", "last name",
070       *   "LST".
071       *   
072       * @param defaultValueOfField
073       *   The value this field has if it has not been changed from its
074       *   default state.  This validation will fail if the current value
075       *   of the field being checked is <i>null</i>, the empty string
076       *   (<tt>""</tt>), or this default value.
077       */
078      protected DataNotEnteredValidation(AbstractValidator<T> validationContainer,
079                                         ValidationPurpose    reasonForValidation,
080                                         String               genericNameOfTarget,
081                                         String               nameOfField,
082                                         String               defaultValueOfField)
083      {
084        super(validationContainer, reasonForValidation);
085        
086        specificTargetName = null;
087        genericTargetName  = genericNameOfTarget;
088        fieldName          = nameOfField;
089        defaultValue       = defaultValueOfField;
090        
091        severity = 
092          (reasonForValidation == ValidationPurpose.CERTIFY_READY_TO_USE) ?
093            FailureSeverity.ERROR : FailureSeverity.WARNING;
094      }
095      
096      /**
097       *  The current value of the targeted field, in text form.
098       *  If you wish to use a "specific name" (eg, "Scan Abc"
099       *  as opposed to "the scan") in your message, set 
100       *  specificTargetName in this method.
101       */
102      abstract protected String getCurrentValue();
103      
104      /**
105       * Test is passed if current value is non-null, non-empty,
106       * and not in its default state.
107       */
108      @Override
109      protected boolean passesTest()
110      {
111        specificTargetName = null;
112        
113        String cv = getCurrentValue();
114        
115        return (cv != null) && !cv.equals("") && !cv.equals(defaultValue);
116      }
117      
118      /* (non-Javadoc)
119       * @see edu.nrao.sss.validation.Validation#displayMessage()
120       */
121      @Override
122      protected String displayMessage()
123      {
124        StringBuilder buff =
125          new StringBuilder("No value has been entered for the '");
126      
127        buff.append(fieldName).append("' field of ");
128        
129        if (specificTargetName != null)
130        {
131          buff.append('\'').append(specificTargetName).append('\'');
132        }
133        else
134        {
135          buff.append("the ").append(genericTargetName);
136        }
137        buff.append('.');
138    
139        if (purpose == ValidationPurpose.CERTIFY_READY_TO_USE)
140        {
141          buff.append("  You may not use this ").append(genericTargetName);
142          buff.append(" until you enter a value for this field.");
143        }
144        else
145        {
146          buff.append("  While you may leave it in this state for ");
147          buff.append("now, you will need to enter a value before attempting ");
148          buff.append("to use this ").append(genericTargetName).append('.');
149        }
150    
151        return buff.toString();
152      }
153    
154      /* (non-Javadoc)
155       * @see edu.nrao.sss.validation.Validation#debugMessage()
156       */
157      @Override
158      protected String debugMessage()
159      {
160        StringBuilder buff = new StringBuilder("Field '");
161        
162        buff.append(fieldName).append("' of class ")
163            .append(container.target.getClass().getName())
164            .append(" is either null, empty, or in its default state.");
165        
166        return buff.toString();
167      }
168    }