001 package edu.nrao.sss.model.resource; 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 ResourceGroup resource groups}. 018 * <p> 019 * <u>Validations Performed for All Purposes</u> 020 * <ol> 021 * <li>No duplicate resource names.</li> 022 * </ol></p> 023 * <p> 024 * <u>Extra Validations Performed for Purpose CERTIFY_READY_TO_USE</u> 025 * <ol> 026 * <li>Validation of contained sources.<sup>1</sup></li> 027 * </ol> 028 * <sup>1</sup><i>The particular validations performed depend on the 029 * validators used by this one to operate on those contained components</i>.</p> 030 * <p> 031 * <b>Version Info:</b> 032 * <table style="margin-left:2em"> 033 * <tr><td>$Revision: 1709 $</td></tr> 034 * <tr><td>$Date: 2008-11-14 11:22:37 -0700 (Fri, 14 Nov 2008) $</td></tr> 035 * <tr><td>$Author: dharland $</td></tr> 036 * </table></p> 037 * 038 * @author David M. Harland 039 * @since 2008-05-01 040 */ 041 public class ResourceGroupValidator 042 extends AbstractValidator<ResourceGroup> 043 { 044 private Validator resourceValidator; 045 046 /** Creates a new instance. */ 047 public ResourceGroupValidator() 048 { 049 super(ResourceGroupValidator.class.getName(), ResourceGroup.class); 050 } 051 052 /* (non-Javadoc) 053 * @see AbstractValidator#makeValidationList(ValidationPurpose) 054 */ 055 @Override 056 protected List<Validation<ResourceGroup>> 057 makeValidationList(ValidationPurpose purpose) 058 { 059 List<Validation<ResourceGroup>> validations = 060 new ArrayList<Validation<ResourceGroup>>(); 061 062 validations.add(new DuplicateMemberNameValidation(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 members 076 Validator resourceVal = getResourceValidator(); 077 078 for (Resource member : target.getAll()) 079 { 080 failures.addAll(resourceVal.validate(member, purpose)); 081 } 082 } 083 084 //============================================================================ 085 // COMPONENT VALIDATORS 086 //============================================================================ 087 088 /** 089 * Sets the validator to use for the resources of the target group. 090 * It is acceptable to use a <i>null</i> parameter, in which case 091 * this validator will contact its manager for a resource validator 092 * or create one itself. 093 * 094 * @param newValidator a validator to use on the resources of this 095 * validator's target group. 096 */ 097 public void setResourceValidator(Validator newValidator) 098 { 099 resourceValidator = newValidator; 100 } 101 102 /** Returns a validator for sources. */ 103 public Validator getResourceValidator() 104 { 105 Validator validator = resourceValidator; 106 107 if (validator == null) 108 { 109 if (manager != null) 110 validator = manager.getValidator(Resource.class); 111 112 if (validator == null) 113 validator = new ResourceValidator(); 114 } 115 116 return validator; 117 } 118 119 //============================================================================ 120 // ENSURE THAT NO TWO MEMBERS HAVE THE SAME NAME 121 //============================================================================ 122 123 class DuplicateMemberNameValidation extends Validation<ResourceGroup> 124 { 125 private Set<String> names; 126 private Map<String, Integer> repeatedNames; 127 128 protected DuplicateMemberNameValidation( 129 AbstractValidator<ResourceGroup> validationContainer, 130 ValidationPurpose reasonForValidation) 131 { 132 super(validationContainer, reasonForValidation); 133 134 severity = FailureSeverity.CONCERN; 135 136 names = new HashSet<String>(); 137 repeatedNames = new HashMap<String, Integer>(); 138 } 139 140 /** This test is passed if no duplicate names are found. */ 141 @Override 142 protected boolean passesTest() 143 { 144 names.clear(); 145 repeatedNames.clear(); 146 147 ResourceGroup group = container.getTarget(); 148 149 for (Resource member : group.getAll()) 150 { 151 String memberName = member.getName(); 152 153 if (names.contains(memberName)) 154 { 155 int nameCount = repeatedNames.containsKey(memberName) ? 156 1 + repeatedNames.get(memberName) : 2; 157 158 repeatedNames.put(memberName, nameCount); 159 } 160 else 161 { 162 names.add(memberName); 163 } 164 } 165 166 return repeatedNames.size() == 0; 167 } 168 169 /* (non-Javadoc) 170 * @see edu.nrao.sss.validation.Validation#displayMessage() 171 */ 172 @Override 173 protected String displayMessage() 174 { 175 ResourceGroup group = container.getTarget(); 176 177 StringBuilder buff = new StringBuilder(group.getName()); 178 179 buff.append(" contains entries with identical names. ") 180 .append("These are the names that appear multiple times, with the ") 181 .append("number of times that name appears shown in parentheses: "); 182 183 for (String name : repeatedNames.keySet()) 184 { 185 buff.append(' ').append(name) 186 .append('(').append(repeatedNames.get(name)).append("),"); 187 } 188 189 int buffLen = buff.length(); 190 buff.replace(buffLen-1, buffLen, ". "); 191 192 buff.append("While having duplicate names is not strictly prohibited, "); 193 buff.append("it may lead to problems with your catalog and is strongly discouraged."); 194 195 return buff.toString(); 196 } 197 198 /* (non-Javadoc) 199 * @see edu.nrao.sss.validation.Validation#debugMessage() 200 */ 201 @Override 202 protected String debugMessage() 203 { 204 return "Duplicate resource names found in " + 205 container.getTarget().getName() + "; repeats = " + 206 repeatedNames; 207 } 208 } 209 }