| 1 20 package net.sf.clirr.core.internal.checks; 21 22 import java.util.Comparator ; 23 24 import net.sf.clirr.core.internal.ClassChangeCheck; 25 import net.sf.clirr.core.internal.AbstractDiffReporter; 26 import net.sf.clirr.core.internal.ApiDiffDispatcher; 27 import net.sf.clirr.core.internal.CoIterator; 28 import net.sf.clirr.core.internal.NameComparator; 29 import net.sf.clirr.core.spi.Field; 30 import net.sf.clirr.core.spi.JavaType; 31 import net.sf.clirr.core.spi.Scope; 32 import net.sf.clirr.core.ApiDifference; 33 import net.sf.clirr.core.Severity; 34 import net.sf.clirr.core.ScopeSelector; 35 import net.sf.clirr.core.Message; 36 37 42 public class FieldSetCheck 43 extends AbstractDiffReporter 44 implements ClassChangeCheck 45 { 46 private static final Message MSG_FIELD_ADDED = new Message(6000); 47 private static final Message MSG_FIELD_REMOVED = new Message(6001); 48 private static final Message MSG_FIELD_NOT_CONSTANT = new Message(6002); 49 private static final Message MSG_FIELD_CONSTANT_CHANGED = new Message(6003); 50 private static final Message MSG_FIELD_TYPE_CHANGED = new Message(6004); 51 private static final Message MSG_FIELD_NOW_NON_FINAL = new Message(6005); 52 private static final Message MSG_FIELD_NOW_FINAL = new Message(6006); 53 private static final Message MSG_FIELD_NOW_NON_STATIC = new Message(6007); 54 private static final Message MSG_FIELD_NOW_STATIC = new Message(6008); 55 private static final Message MSG_FIELD_MORE_ACCESSIBLE = new Message(6009); 56 private static final Message MSG_FIELD_LESS_ACCESSIBLE = new Message(6010); 57 private static final Message MSG_CONSTANT_FIELD_REMOVED = new Message(6011); 58 59 private static final Comparator COMPARATOR = new NameComparator(); 60 private ScopeSelector scopeSelector; 61 62 public FieldSetCheck(ApiDiffDispatcher dispatcher, ScopeSelector scopeSelector) 63 { 64 super(dispatcher); 65 this.scopeSelector = scopeSelector; 66 } 67 68 public final boolean check(JavaType baselineClass, JavaType currentClass) 69 { 70 final Field[] baselineFields = baselineClass.getFields(); 71 final Field[] currentFields = currentClass.getFields(); 72 73 CoIterator iter = new CoIterator( 74 COMPARATOR, baselineFields, currentFields); 75 76 while (iter.hasNext()) 77 { 78 iter.next(); 79 80 Field bField = (Field) iter.getLeft(); 81 Field cField = (Field) iter.getRight(); 82 83 if (bField == null) 84 { 85 if (scopeSelector.isSelected(cField)) 86 { 87 String scope = cField.getDeclaredScope().getDesc(); 88 fireDiff(MSG_FIELD_ADDED, 89 Severity.INFO, currentClass, cField, 90 new String []{scope}); 91 } 92 } 93 else if (cField == null) 94 { 95 if (scopeSelector.isSelected(bField)) 96 { 97 if ((bField.getConstantValue() != null) && bField.isFinal()) 98 { 99 fireDiff(MSG_CONSTANT_FIELD_REMOVED, 107 getSeverity(baselineClass, bField, Severity.WARNING), 108 getSeverity(baselineClass, bField, Severity.ERROR), 109 baselineClass, bField, null); 110 } 111 else 112 { 113 fireDiff(MSG_FIELD_REMOVED, 114 getSeverity(baselineClass, bField, Severity.ERROR), 115 baselineClass, bField, null); 116 } 117 } 118 } 119 else if (scopeSelector.isSelected(bField) || scopeSelector.isSelected(cField)) 120 { 121 checkForModifierChange(bField, cField, currentClass); 122 checkForVisibilityChange(bField, cField, currentClass); 123 checkForTypeChange(bField, cField, currentClass); 124 checkForConstantValueChange(bField, cField, currentClass); 125 } 126 } 127 128 return true; 129 } 130 131 private void checkForConstantValueChange(Field bField, Field cField, JavaType currentClass) 132 { 133 if (!(bField.isStatic() && bField.isFinal() && cField.isStatic() && cField.isFinal())) 134 { 135 return; 136 } 137 138 final Object bVal = bField.getConstantValue(); 139 140 if (bVal != null) 141 { 142 final String bValRep = bVal.toString(); 143 final Object cVal = cField.getConstantValue(); 144 if (cVal == null) 145 { 146 fireDiff(MSG_FIELD_NOT_CONSTANT, 153 getSeverity(currentClass, bField, Severity.WARNING), 154 currentClass, cField, null); 155 return; 156 } 157 158 final String cValRep = String.valueOf(cVal); 159 if (!bValRep.equals(cValRep)) 160 { 161 fireDiff(MSG_FIELD_CONSTANT_CHANGED, 166 getSeverity(currentClass, bField, Severity.WARNING), 167 currentClass, cField, null); 168 } 169 } 170 } 171 172 private void checkForTypeChange(Field bField, Field cField, JavaType currentClass) 173 { 174 final String bSig = bField.getType().toString(); 175 final String cSig = cField.getType().toString(); 176 if (!bSig.equals(cSig)) 177 { 178 fireDiff(MSG_FIELD_TYPE_CHANGED, 179 getSeverity(currentClass, bField, Severity.ERROR), 180 currentClass, bField, 181 new String [] {bSig, cSig}); 182 } 183 } 184 185 private void checkForModifierChange(Field bField, Field cField, JavaType clazz) 186 { 187 if (bField.isFinal() && !cField.isFinal()) 188 { 189 fireDiff(MSG_FIELD_NOW_NON_FINAL, 190 Severity.INFO, clazz, cField, null); 191 } 192 193 if (!bField.isFinal() && cField.isFinal()) 194 { 195 fireDiff(MSG_FIELD_NOW_FINAL, Severity.ERROR, clazz, cField, null); 196 } 197 198 if (bField.isStatic() && !cField.isStatic()) 199 { 200 fireDiff(MSG_FIELD_NOW_NON_STATIC, 201 getSeverity(clazz, bField, Severity.ERROR), 202 clazz, cField, null); 203 } 204 205 if (!bField.isStatic() && cField.isStatic()) 206 { 207 fireDiff(MSG_FIELD_NOW_STATIC, 208 getSeverity(clazz, bField, Severity.ERROR), 209 clazz, cField, null); 210 } 211 212 215 } 217 218 private void checkForVisibilityChange(Field bField, Field cField, JavaType clazz) 219 { 220 Scope bScope = bField.getEffectiveScope(); 221 Scope cScope = cField.getEffectiveScope(); 222 223 if (cScope.isMoreVisibleThan(bScope)) 224 { 225 fireDiff(MSG_FIELD_MORE_ACCESSIBLE, 226 Severity.INFO, clazz, cField, 227 new String [] {bScope.getDesc(), cScope.getDesc()}); 228 } 229 else if (cScope.isLessVisibleThan(bScope)) 230 { 231 fireDiff(MSG_FIELD_LESS_ACCESSIBLE, 232 getSeverity(clazz, bField, Severity.ERROR), 233 clazz, cField, 234 new String [] {bScope.getDesc(), cScope.getDesc()}); 235 } 236 } 237 238 private void fireDiff( 239 Message msg, 240 Severity severity, 241 JavaType clazz, 242 Field field, 243 String [] args) 244 { 245 fireDiff(msg, severity, severity, clazz, field, args); 246 } 247 248 private void fireDiff( 249 Message msg, 250 Severity binarySeverity, 251 Severity sourceSeverity, 252 JavaType clazz, 253 Field field, 254 String [] args) 255 { 256 final String className = clazz.getName(); 257 final ApiDifference diff = 258 new ApiDifference( 259 msg, 260 binarySeverity, sourceSeverity, 261 className, null, field.getName(), args); 262 getApiDiffDispatcher().fireDiff(diff); 263 } 264 } 265 | Popular Tags |