001    package edu.nrao.sss.model.project;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import edu.nrao.sss.validation.AbstractValidator;
007    import edu.nrao.sss.validation.DataNotEnteredValidation;
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 Project projects}.
015     * <p>
016     * <u>Validations Performed for All Purposes</u>
017     * <ol>
018     *   <li>Project has title.</li>
019     *   <li>Project has project code.</li>
020     *   <li>Project has allocated time.</li>
021     *   <li>Project has at least one program block.</li>
022     *   <li>Contained program blocks are valid.<sup>1</sup></li>
023     * </ol>
024     * <sup>1</sup><i>The particular validations performed depend on the
025     * validator used by this one to operate on those contained program
026     * blocks</i>.</p>
027     * <p>
028     * <b>Version Info:</b>
029     * <table style="margin-left:2em">
030     *   <tr><td>$Revision: 2125 $</td></tr>
031     *   <tr><td>$Date: 2009-03-18 10:12:32 -0600 (Wed, 18 Mar 2009) $</td></tr>
032     *   <tr><td>$Author: dharland $</td></tr>
033     * </table></p>
034     * 
035     * @author David M. Harland
036     * @since 2007-02-09
037     */
038    public class ProjectValidator
039      extends AbstractValidator<Project>
040    {
041      private Validator progBlockValidator;
042    
043      /** Creates a new instance. */
044      public ProjectValidator()
045      {
046        super(ProjectValidator.class.getName(), Project.class);
047      }
048    
049      /* (non-Javadoc)
050       * @see AbstractValidator#makeValidationList(ValidationPurpose)
051       */
052      @Override
053      protected List<Validation<Project>>
054        makeValidationList(ValidationPurpose purpose)
055      {
056        List<Validation<Project>> validations =
057          new ArrayList<Validation<Project>>();
058        
059        validations.add(new HasTitle        (this, purpose));
060        validations.add(new HasProjectCode  (this, purpose));
061      //validations.add(new HasAllocatedTime(this, purpose));
062        validations.add(new HasProgramBlock (this, purpose));
063        
064        return validations; 
065      }
066    
067      /* (non-Javadoc)
068       * @see edu.nrao.sss.model.validation.AbstractValidator#validate()
069       */
070      @Override
071      protected void validate()
072      {
073        super.validate();
074        
075        //Validate the program blocks
076        Validator pbVal = getProgramBlockValidator();
077          
078        for (ProgramBlock pb : target.getProgramBlocks())
079          failures.addAll(pbVal.validate(pb, purpose));
080      }
081    
082      //============================================================================
083      // COMPONENT VALIDATORS
084      //============================================================================
085    
086      /**
087       * Sets the validator to use for the program blocks of the target project.
088       * It is acceptable to use a <i>null</i> parameter, in which case
089       * this validator will contact its manager for a program block validator
090       * or create one itself.
091       * 
092       * @param newValidator a validator to use on the program blocks of this
093       *                     validator's target project.
094       */
095      public void setProgramBlockValidator(Validator newValidator)
096      {
097        progBlockValidator = newValidator;
098      }
099    
100      /** Returns a validator for program blocks. */
101      public Validator getProgramBlockValidator()
102      {
103        Validator validator = progBlockValidator;
104        
105        if (validator == null)
106        {
107          if (manager != null)
108            validator = manager.getValidator(ProgramBlock.class);
109        
110          if (validator == null)
111            validator = new ProgramBlockValidator();
112        }
113        
114        return validator;
115      }
116    
117      //============================================================================
118      // UNITIALIZED FIELD VALIDATIONS
119      //============================================================================
120      
121      /** Make sure project has a title. */
122      class HasTitle extends DataNotEnteredValidation<Project>
123      {
124        protected HasTitle(AbstractValidator<Project> validationContainer,
125                           ValidationPurpose          reasonForValidation)
126        {
127          super(validationContainer, reasonForValidation,
128                "project", "title", Project.UNINIT_TITLE);
129        }
130        
131        @Override
132        protected String getCurrentValue()  { return target.getTitle(); }
133      }
134      
135      
136      /** Make sure project has a code. */
137      class HasProjectCode extends DataNotEnteredValidation<Project>
138      {
139        protected HasProjectCode(AbstractValidator<Project> validationContainer,
140                                 ValidationPurpose          reasonForValidation)
141        {
142          super(validationContainer, reasonForValidation,
143                "project", "project code", Project.NO_PROJECT_CODE);
144        }
145        
146        @Override
147        protected String getCurrentValue()  { return target.getProjectCode(); }
148      }
149      
150      
151      /** Make sure project has allocated time. */
152      class HasAllocatedTime extends DataNotEnteredValidation<Project>
153      {
154        protected HasAllocatedTime(AbstractValidator<Project> validationContainer,
155                                   ValidationPurpose          reasonForValidation)
156        {
157          super(validationContainer, reasonForValidation,
158                "project", "allocated time", "0.0");
159        }
160        
161        @Override
162        protected String getCurrentValue()
163        {
164          return Double.toString(target.getAllocatedTime());
165        }
166    
167        /** Overridden to always return true if the project is a test project */
168        @Override
169        protected boolean passesTest()
170        {
171          return target.isTest() || super.passesTest();
172        }
173      }
174      
175      //============================================================================
176      // ENSURE PROJECT HAS PROGRAM BLOCKS
177      //============================================================================
178      
179      /** Make sure project has a title. */
180      class HasProgramBlock extends Validation<Project>
181      {
182        protected HasProgramBlock(AbstractValidator<Project> validationContainer,
183                                  ValidationPurpose          reasonForValidation)
184        {
185          super(validationContainer, reasonForValidation);
186          
187          severity = 
188            (reasonForValidation == ValidationPurpose.CERTIFY_READY_TO_USE) ?
189              FailureSeverity.ERROR : FailureSeverity.WARNING;
190        }
191        
192        /** This test is passed if project has > 0 PBs. */
193        @Override
194        protected boolean passesTest()
195        {
196          return target.getProgramBlocks().size() > 0;
197        }
198        
199        /* (non-Javadoc)
200         * @see edu.nrao.sss.validation.Validation#displayMessage()
201         */
202        @Override
203        protected String displayMessage()
204        {
205          StringBuilder buff = new StringBuilder("Project '");
206          
207          buff.append(target.getTitle())
208               .append("' has no program blocks.  ");
209    
210          if (purpose == ValidationPurpose.CERTIFY_READY_TO_USE)
211          {
212            buff.append("A project must have at least one program block in order ")
213                .append("to be executed.  Please add a program block.");
214          }
215          else
216          {
217            buff.append("This is fine for now, but you will need to add at least ")
218                .append("one program block before this project is ready for ")
219                .append("execution.");
220          }
221    
222          return buff.toString();
223        }
224        
225        /* (non-Javadoc)
226         * @see edu.nrao.sss.validation.Validation#debugMessage()
227         */
228        @Override
229        protected String debugMessage()
230        {
231          StringBuilder buff = new StringBuilder("Project ");
232          
233          buff.append(target.getTitle()).append(" (Code=")
234               .append(target.getProjectCode()).append(") has no program blocks.");
235          
236          return buff.toString();
237        }
238      }
239    
240      //============================================================================
241      // 
242      //============================================================================
243      /*
244      public static void main(String[] args)
245      {
246        Project         project = new Project();
247        ProgramBlock    pb      = new ProgramBlock();
248        SchedulingBlock sb      = new SchedulingBlock();
249        pb.addSchedulingBlock(sb);
250        project.addProgramBlock(pb);
251        
252        ValidationManager validator = new ValidationManager();
253        
254        if (validator.validate(project, ValidationPurpose.SAVE_IN_REPOSITORY))
255          System.out.println("Project is valid.");
256        else
257        {
258          System.out.println("Project NOT valid.");
259          System.out.println();
260          
261          for (ValidationFailure failure : validator.getFailures())
262            System.out.println("Display Msg: " + failure.getDisplayMessage());
263          
264          System.out.println();
265          
266          for (ValidationFailure failure : validator.getNonDisplayableFailures())
267            System.out.println("Debug Msg: " + failure.getDebugMessage());
268        }
269      }
270      */
271    }