001    package edu.nrao.sss.model.source;
002    
003    import java.util.ArrayList;
004    import java.util.HashMap;
005    import java.util.HashSet;
006    import java.util.List;
007    import java.util.Map;
008    import java.util.Set;
009    
010    import edu.nrao.sss.validation.AbstractValidator;
011    import edu.nrao.sss.validation.FailureSeverity;
012    import edu.nrao.sss.validation.Validation;
013    import edu.nrao.sss.validation.ValidationPurpose;
014    import edu.nrao.sss.validation.Validator;
015    
016    /**
017     * A validator of {@link SourceCatalog source catalogs}.
018     * <p>
019     * <u>Validations Performed for All Purposes</u>
020     * <ol>
021     *   <li>No duplicate group names.</li>
022     *   <li>Validation of each contained group.<sup>1</sup></li>
023     * </ol>
024     * <sup>1</sup><i>The particular validations performed on the groups depend on
025     * the type of validator used by this one to validate the contained groups.
026     * This validator gets its group validator from either an external client,
027     * the {@link edu.nrao.sss.validation.ValidationManager},
028     * or its own hard-wired default.</i></p>
029     * <p>
030     * <b>Version Info:</b>
031     * <table style="margin-left:2em">
032     *   <tr><td>$Revision: 1358 $</td></tr>
033     *   <tr><td>$Date: 2008-06-18 14:49:00 -0600 (Wed, 18 Jun 2008) $</td></tr>
034     *   <tr><td>$Author: dharland $</td></tr>
035     * </table></p>
036     * 
037     * @author David M. Harland
038     * @since 2007-02-07
039     */
040    public class SourceCatalogValidator
041      extends AbstractValidator<SourceCatalog>
042    {
043      private Validator groupValidator;
044    
045      /** Creates a new instance. */
046      public SourceCatalogValidator()
047      {
048        super(SourceCatalogValidator.class.getName(), SourceCatalog.class);
049      }
050    
051      /* (non-Javadoc)
052       * @see AbstractValidator#makeValidationList(ValidationPurpose)
053       */
054      @Override
055      protected List<Validation<SourceCatalog>>
056        makeValidationList(ValidationPurpose purpose)
057      {
058        List<Validation<SourceCatalog>> validations =
059          new ArrayList<Validation<SourceCatalog>>();
060        
061        validations.add(new DuplicateGroupNameValidation(this, purpose));
062        
063        return validations; 
064      }
065    
066      /* (non-Javadoc)
067       * @see edu.nrao.sss.model.validation.AbstractValidator#validate()
068       */
069      @Override
070      protected void validate()
071      {
072        super.validate();
073        
074        //Use a group validator to validate this catalog
075        failures.addAll(getGroupValidator().validate(target.toGroup(), purpose));
076      }
077      
078      //============================================================================
079      // COMPONENT VALIDATORS
080      //============================================================================
081    
082      /**
083       * Sets the validator to use for the groups of the target catalog.
084       * It is acceptable to use a <i>null</i> parameter, in which case
085       * this validator will contact its manager for a group validator
086       * or create one itself.
087       * 
088       * @param newValidator a validator to use on the groups of this
089       *                     validator's target catalog.
090       */
091      public void setGroupValidator(Validator newValidator)
092      {
093        groupValidator = newValidator;
094      }
095    
096      /** Returns a validator for source groups. */
097      public Validator getGroupValidator()
098      {
099        Validator validator = groupValidator;
100        
101        if (validator == null)
102        {
103          if (manager != null)
104            validator = manager.getValidator(SourceGroup.class);
105        
106          if (validator == null)
107            validator = new SourceGroupValidator();
108        }
109        
110        return validator;
111      }
112      
113      //============================================================================
114      // ENSURE THAT NO TWO GROUPS HAVE THE SAME NAME
115      //============================================================================
116    
117      class DuplicateGroupNameValidation extends Validation<SourceCatalog>
118      {
119        private Set<String>          names;
120        private Map<String, Integer> repeatedNames;
121        
122        protected DuplicateGroupNameValidation(
123                    AbstractValidator<SourceCatalog> validationContainer,
124                    ValidationPurpose                reasonForValidation)
125        {
126          super(validationContainer, reasonForValidation);
127          
128          severity = FailureSeverity.ERROR;
129    
130          names         = new HashSet<String>();
131          repeatedNames = new HashMap<String, Integer>();
132        }
133        
134        /** This test is passed if no duplicate names are found. */
135        @Override
136        protected boolean passesTest()
137        {
138          names.clear();
139          repeatedNames.clear();
140          
141          SourceCatalog catalog = container.getTarget();
142          
143          for (SourceGroup group : catalog.getGroups())
144          {
145            String groupName = group.getName();
146            
147            if (names.contains(groupName))
148            {
149              int nameCount = repeatedNames.containsKey(groupName) ?
150                              1 + repeatedNames.get(groupName) : 2;
151    
152              repeatedNames.put(groupName, nameCount);
153            }
154            else
155            {
156              names.add(groupName);
157            }
158          }
159    
160          return repeatedNames.size() == 0;
161        }
162        
163        /* (non-Javadoc)
164         * @see edu.nrao.sss.validation.Validation#displayMessage()
165         */
166        protected String displayMessage()
167        {
168          SourceCatalog catalog = container.getTarget();
169          
170          StringBuilder buff = new StringBuilder("Catalog ");
171          
172          buff.append(catalog.getName())
173              .append(" contains groups with identical names. ")
174              .append("These are the names that appear multiple times, with the ")
175              .append("number of times that name appears shown in parentheses: ");
176          
177          for (String name : repeatedNames.keySet())
178          {
179            buff.append(name)
180                .append('(').append(repeatedNames.get(name)).append(")");
181          }
182          
183          int buffLen = buff.length();
184          buff.replace(buffLen-1, buffLen, ".");
185          
186          buff.append("Each group must have a unique name. ");
187          buff.append("Please change the names of the groups so that no two have the same.");
188    
189          return buff.toString();
190        }
191        
192        /* (non-Javadoc)
193         * @see edu.nrao.sss.validation.Validation#debugMessage()
194         */
195        protected String debugMessage()
196        {
197          return "Duplicate group names found in catalog " +
198                 container.getTarget().getName() + "; repeats = " +
199                 repeatedNames;
200        }
201      }
202    }