001    package edu.nrao.sss.model.source;
002    
003    import java.util.ArrayList;
004    import java.util.Date;
005    import java.util.List;
006    
007    import edu.nrao.sss.validation.AbstractValidator;
008    import edu.nrao.sss.validation.FailureSeverity;
009    import edu.nrao.sss.validation.Validation;
010    import edu.nrao.sss.validation.ValidationPurpose;
011    import edu.nrao.sss.validation.Validator;
012    
013    /**
014     * A validator of {@link SourceLookupTable source look-up tables}.
015     * <p>
016     * <u>Validations Performed for All Purposes</u>
017     * <ol>
018     *   <li>Table has at least one source.</li>
019     *   <li>Table's earliest date is not in the future.</li>
020     * </ol></p>
021     * <u>Extra Validations Performed for Purpose CERTIFY_READY_TO_USE</u>
022     * <ol>
023     *   <li>Validation of contained sources.<sup>1</sup></li>
024     * </ol>
025     * <sup>1</sup><i>The particular validations performed depend on the
026     * validator used by this one to operate on those contained sources</i>.</p>
027     * <p>
028     * <b>Version Info:</b>
029     * <table style="margin-left:2em">
030     *   <tr><td>$Revision: 332 $</td></tr>
031     *   <tr><td>$Date: 2007-02-08 16:49:14 -0700 (Thu, 08 Feb 2007) $</td></tr>
032     *   <tr><td>$Author: dharland $</td></tr>
033     * </table></p>
034     * 
035     * @author David M. Harland
036     * @since 2007-02-07
037     */
038    public class SourceLookupTableValidator
039      extends AbstractValidator<SourceLookupTable>
040    {
041      private Validator sourceValidator;
042    
043      /** Creates a new instance. */
044      public SourceLookupTableValidator()
045      {
046        super(SourceLookupTableValidator.class.getName(), SourceLookupTable.class);
047      }
048    
049      /* (non-Javadoc)
050       * @see AbstractValidator#makeValidationList(ValidationPurpose)
051       */
052      @Override
053      protected List<Validation<SourceLookupTable>>
054        makeValidationList(ValidationPurpose purpose)
055      {
056        List<Validation<SourceLookupTable>> validations =
057          new ArrayList<Validation<SourceLookupTable>>();
058        
059        validations.add(new NotEmptyValidation (this, purpose));
060        validations.add(new FirstDateValidation(this, purpose));
061        
062        return validations; 
063      }
064    
065      /* (non-Javadoc)
066       * @see edu.nrao.sss.model.validation.AbstractValidator#validate()
067       */
068      @Override
069      protected void validate()
070      {
071        super.validate();
072        
073        //Validate the entries
074        if (purpose == ValidationPurpose.CERTIFY_READY_TO_USE)
075        {
076          Validator sourceVal = getSourceValidator();
077          
078          for (Date key : target.getKeySet())
079            failures.addAll(sourceVal.validate(target.get(key), purpose));
080        }
081      }
082    
083      //============================================================================
084      // COMPONENT VALIDATORS
085      //============================================================================
086    
087      /**
088       * Sets the validator to use for the sources of the target table.
089       * It is acceptable to use a <i>null</i> parameter, in which case
090       * this validator will contact its manager for a source validator
091       * or create one itself.
092       * 
093       * @param newValidator a validator to use on the sources of this
094       *                     validator's target table.
095       */
096      public void setSourceValidator(Validator newValidator)
097      {
098        sourceValidator = newValidator;
099      }
100    
101      /** Returns a validator for sources. */
102      public Validator getSourceValidator()
103      {
104        Validator validator = sourceValidator;
105        
106        if (validator == null)
107        {
108          if (manager != null)
109            validator = manager.getValidator(Source.class);
110        
111          if (validator == null)
112            validator = new SourceValidator();
113        }
114        
115        return validator;
116      }
117      
118      //============================================================================
119      // ENSURE THAT THE LOOKUP TABLE IS NOT EMPTY
120      //============================================================================
121    
122      class NotEmptyValidation extends Validation<SourceLookupTable>
123      {
124        protected NotEmptyValidation(
125                    AbstractValidator<SourceLookupTable> validationContainer,
126                    ValidationPurpose                    reasonForValidation)
127        {
128          super(validationContainer, reasonForValidation);
129          
130          severity = 
131            (reasonForValidation == ValidationPurpose.CERTIFY_READY_TO_USE) ?
132              FailureSeverity.ERROR : FailureSeverity.WARNING;
133        }
134        
135        /** This test is passed if the table is not empty. */
136        @Override
137        protected boolean passesTest()
138        {
139          return target.size() > 0;
140        }
141        
142        /* (non-Javadoc)
143         * @see edu.nrao.sss.validation.Validation#displayMessage()
144         */
145        @Override
146        protected String displayMessage()
147        {
148          StringBuilder buff = new StringBuilder("The source lookup table '");
149          
150          buff.append(target.getName()).append("' contains no entries.");
151    
152          if (purpose == ValidationPurpose.CERTIFY_READY_TO_USE)
153          {
154            buff.append("  You may not use this table until after you have ");
155            buff.append("populated it with at least one source.");
156          }
157          else
158          {
159            buff.append("  While you may leave the table in this state for ");
160            buff.append("now, you will need to add at least one source to it ");
161            buff.append("before attempting to use it.");
162          }
163    
164          return buff.toString();
165        }
166        
167        /* (non-Javadoc)
168         * @see edu.nrao.sss.validation.Validation#debugMessage()
169         */
170        @Override
171        protected String debugMessage()
172        {
173          StringBuilder buff =
174            new StringBuilder("No sources contained in table ");
175          
176          buff.append(target.getName());
177          
178          return buff.toString();
179        }
180      }
181      
182      //============================================================================
183      // EXAMINE THE EARLIEST DATE IN THE TABLE
184      //============================================================================
185    
186      class FirstDateValidation extends Validation<SourceLookupTable>
187      {
188        private Date firstDate;
189        
190        protected FirstDateValidation(
191                    AbstractValidator<SourceLookupTable> validationContainer,
192                    ValidationPurpose                    reasonForValidation)
193        {
194          super(validationContainer, reasonForValidation);
195                            
196          severity = FailureSeverity.CONCERN;
197        }
198        
199        /** Test is passed if the first date in the table is on or before today. */
200        @Override
201        protected boolean passesTest()
202        {
203          firstDate = target.getKeySet().first();
204          
205          return firstDate.compareTo(new Date()) < 1;
206        }
207        
208        /* (non-Javadoc)
209         * @see edu.nrao.sss.validation.Validation#displayMessage()
210         */
211        @Override
212        protected String displayMessage()
213        {
214          StringBuilder buff =
215            new StringBuilder("The first date in source lookup table '");
216        
217          buff.append(target.getName()).append(" is ").append(firstDate);
218          buff.append(". This message was generated because that date is ");
219          buff.append("after the current date.  If the entered date is not what ");
220          buff.append("you intended, please update it.  Otherwise the ");
221          buff.append("will proceed with the date as currently entered.");
222    
223          return buff.toString();
224        }
225    
226        /* (non-Javadoc)
227         * @see edu.nrao.sss.validation.Validation#debugMessage()
228         */
229        @Override
230        protected String debugMessage()
231        {
232          StringBuilder buff =
233            new StringBuilder("The earliest date in source lookup table ");
234          
235          buff.append(target.getName()).append(" is ").append(firstDate);
236          buff.append(".  Current date is ").append(new Date()).append('.');
237          
238          return buff.toString();
239        }
240      }
241    }