001    package edu.nrao.sss.model.resource;
002    
003    import java.util.ArrayList;
004    import java.util.HashSet;
005    import java.util.List;
006    import java.util.Set;
007    import java.util.SortedSet;
008    
009    import edu.nrao.sss.validation.AbstractValidator;
010    import edu.nrao.sss.validation.FailureSeverity;
011    import edu.nrao.sss.validation.Validation;
012    import edu.nrao.sss.validation.ValidationFailure;
013    import edu.nrao.sss.validation.ValidationManager;
014    import edu.nrao.sss.validation.ValidationPurpose;
015    import edu.nrao.sss.validation.Validator;
016    
017    /**
018     * A validator of {@link Resource resources}.
019     * <p>
020     * <u>Validations Performed for All Purposes</u>
021     * <ol>
022     *   <li>Selected receivers belong to chosen telescope.</li>
023     *   <li>Selected receivers represent a valid combination.</li>
024     *   <li>Validation of contained backends.<sup>1</sup></li>
025     * </ol>
026     * <sup>1</sup><i>The particular validations performed depend on the
027     * validator used by this one to operate on those contained backends</i>.</p>
028     * <p>
029     * <b>Version Info:</b>
030     * <table style="margin-left:2em">
031     *   <tr><td>$Revision: 1357 $</td></tr>
032     *   <tr><td>$Date: 2008-06-18 10:56:42 -0600 (Wed, 18 Jun 2008) $</td></tr>
033     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
034     * </table></p>
035     * 
036     * @author David M. Harland
037     * @since 2008-05-01
038     */
039    public class ResourceValidator
040      extends AbstractValidator<Resource>
041    {
042      /** Creates a new instance. */
043      public ResourceValidator()
044      {
045        super(ResourceValidator.class.getName(), Resource.class);
046      }
047    
048      /* (non-Javadoc)
049       * @see AbstractValidator#makeValidationList(ValidationPurpose)
050       */
051      @Override
052      protected List<Validation<Resource>>
053        makeValidationList(ValidationPurpose purpose)
054      {
055        List<Validation<Resource>> validations =
056          new ArrayList<Validation<Resource>>();
057        
058        validations.add(new TelescopeReceiverComboValidation(this, purpose));
059        
060        return validations; 
061      }
062    
063      /* (non-Javadoc)
064       * @see edu.nrao.sss.model.validation.AbstractValidator#validate()
065       */
066      @Override
067      protected void validate()
068      {
069        super.validate();
070        
071        //Validate backends
072        if (manager == null)
073          manager = new ValidationManager();
074        
075        for (TelescopeBackend tbe : target.getBackends())
076        {
077          Validator tbeVal = manager.getValidator(tbe.getClass());
078        
079          if (tbeVal != null)
080          {
081            List<ValidationFailure> backendFailures = tbeVal.validate(tbe, purpose);
082            
083            for (ValidationFailure beFailure : backendFailures)
084            {
085              beFailure.setDisplayMessage(beFailure.getDisplayMessage() +
086                                          " [Configuration \"" +
087                                          target.getName() + "\"]");
088            }
089            
090            failures.addAll(backendFailures);
091          }
092        }
093      }
094      
095      //============================================================================
096      // 
097      //============================================================================
098      
099      class TelescopeReceiverComboValidation extends Validation<Resource>
100      {
101        Set<ReceiverBand> invalidReceivers;
102        Set<ReceiverBand> invalidCombo;
103        
104        protected TelescopeReceiverComboValidation(
105                    AbstractValidator<Resource> validationContainer,
106                    ValidationPurpose            reasonForValidation)
107        {
108          super(validationContainer, reasonForValidation);
109          
110          severity = FailureSeverity.ERROR;
111          
112          invalidReceivers = new HashSet<ReceiverBand>();
113          invalidCombo     = new HashSet<ReceiverBand>();
114        }
115        
116        /* (non-Javadoc)
117         * @see edu.nrao.sss.validation.Validation#passesTest()
118         */
119        @Override
120        protected boolean passesTest()
121        {
122          boolean passes = true;
123          
124          invalidReceivers.clear();
125          invalidCombo.clear();
126          
127          SortedSet<ReceiverBand> selectedReceivers =
128            target.getAntennaElectronics().getActiveReceivers();
129          
130          TelescopeType telescope = target.getTelescope();
131    
132          Set<ReceiverBand> validReceivers = telescope.getReceivers();
133          
134          //Make sure each selected receiver is a valid option
135          for (ReceiverBand rb : selectedReceivers)
136          {
137            if (!validReceivers.contains(rb))
138            {
139              passes = false;
140              invalidReceivers.add(rb);
141            }
142          }
143          
144          //If all receivers were valid, make sure the combination is also valid
145          if (passes && selectedReceivers.size() > 1)
146          {
147            passes = false;
148            
149            for (Set<ReceiverBand> validCombo : telescope.getValidReceiverCombinations())
150            {
151              if (selectedReceivers.equals(validCombo))
152              {
153                passes = true;
154                break;
155              }
156            }
157          }
158          
159          return passes;
160        }
161        
162        /* (non-Javadoc)
163         * @see edu.nrao.sss.validation.Validation#displayMessage()
164         */
165        @Override
166        protected String displayMessage()
167        {
168          StringBuilder msg = new StringBuilder();
169          
170          if (invalidReceivers.size() > 0)
171          {
172            msg.append("You selected the following receivers to use with the ");
173            msg.append(target.getTelescope()).append(" telescope:");
174            for (ReceiverBand rb : target.getAntennaElectronics().getActiveReceivers())
175              msg.append(' ').append(rb).append(',');
176            int msgLen = msg.length();
177            msg.replace(msgLen-1, msgLen, ". ");
178            msg.append("However, the following receivers are not allowed with that telescope:");
179            for (ReceiverBand rb : invalidReceivers)
180              msg.append(' ').append(rb).append(',');
181            msgLen = msg.length();
182            msg.replace(msgLen-1, msgLen, ". ");
183            msg.append("Please remove the disallowed receivers.");
184          }
185          else if (invalidCombo.size() > 0)
186          {
187            msg.append("You selected the following receivers to use with the ");
188            msg.append(target.getTelescope()).append(" telescope:");
189            for (ReceiverBand rb : target.getAntennaElectronics().getActiveReceivers())
190              msg.append(' ').append(rb).append(',');
191            int msgLen = msg.length();
192            msg.replace(msgLen-1, msgLen, ". ");
193            msg.append("However, this combination is not allowed with that telescope. ");
194            msg.append("Please adjust your selection.");
195          }
196          else
197          {
198            msg.append("A validation failure relating to the combination of ")
199               .append("telescope and receiver(s) was detected, but the nature ")
200               .append("of the failure is unknown.  Contact NRAO.");
201          }
202          
203          return msg.toString();
204        }
205        
206        /* (non-Javadoc)
207         * @see edu.nrao.sss.validation.Validation#debugMessage()
208         */
209        @Override
210        protected String debugMessage()
211        {
212          StringBuilder msg = new StringBuilder();
213          
214          if (invalidReceivers.size() > 0)
215          {
216            msg.append("Telescope=").append(target.getTelescope());
217            msg.append(", receivers=")
218               .append(target.getAntennaElectronics().getActiveReceivers());
219            msg.append(", invalid=").append(invalidReceivers);
220          }
221          else if (invalidCombo.size() > 0)
222          {
223            msg.append("Telescope=").append(target.getTelescope());
224            msg.append(", receivers=")
225               .append(target.getAntennaElectronics().getActiveReceivers());
226            msg.append(".  Combo is invalid.");
227          }
228          else
229          {
230            msg.append("Both receivers and combo are fine.");
231          }
232          
233          return msg.toString();
234        }
235      }
236    }