1 32 33 package com.jeantessier.diff; 34 35 import java.util.*; 36 37 import org.apache.log4j.*; 38 39 import com.jeantessier.classreader.*; 40 import com.jeantessier.dependency.*; 41 42 public class DifferencesFactory { 43 private Validator oldValidator; 44 private Validator newValidator; 45 46 private ClassfileLoader oldJar; 47 private ClassfileLoader newJar; 48 private Classfile oldClass; 49 private Classfile newClass; 50 51 public DifferencesFactory(Validator oldValidator, Validator newValidator) { 52 this.oldValidator = oldValidator; 53 this.newValidator = newValidator; 54 } 55 56 public Differences createJarDifferences(String name, String oldVersion, ClassfileLoader oldJar, String newVersion, ClassfileLoader newJar) { 57 Logger.getLogger(getClass()).debug("Begin " + name + " (" + oldVersion + " -> " + newVersion + ")"); 58 59 JarDifferences jarDifferences = new JarDifferences(name, oldVersion, newVersion); 60 Differences result = jarDifferences; 61 62 this.oldJar = oldJar; 63 this.newJar = newJar; 64 65 Logger.getLogger(getClass()).debug(" Collecting packages ..."); 66 67 Iterator i; 68 69 NodeFactory oldFactory = new NodeFactory(); 70 i = oldJar.getAllClassfiles().iterator(); 71 while (i.hasNext()) { 72 oldFactory.createClass(i.next().toString()); 73 } 74 75 NodeFactory newFactory = new NodeFactory(); 76 i = newJar.getAllClassfiles().iterator(); 77 while (i.hasNext()) { 78 newFactory.createClass(i.next().toString()); 79 } 80 81 Collection packageLevel = new TreeSet(); 82 packageLevel.addAll(oldFactory.getPackages().keySet()); 83 packageLevel.addAll(newFactory.getPackages().keySet()); 84 85 Logger.getLogger(getClass()).debug(" Diff'ing packages ..."); 86 87 i = packageLevel.iterator(); 88 while (i.hasNext()) { 89 String packageName = (String ) i.next(); 90 91 PackageNode oldPackage = (PackageNode) oldFactory.getPackages().get(packageName); 92 PackageNode newPackage = (PackageNode) newFactory.getPackages().get(packageName); 93 94 Differences differences = createPackageDifferences(packageName, oldPackage, newPackage); 95 if (!differences.isEmpty()) { 96 jarDifferences.getPackageDifferences().add(differences); 97 } 98 } 99 100 Logger.getLogger(getClass()).debug("End " + name + " (" + oldVersion + " -> " + newVersion + "): " + (result.isEmpty() ? "empty" : "not empty")); 101 102 return result; 103 } 104 105 public Differences createPackageDifferences(String name, PackageNode oldPackage, PackageNode newPackage) { 106 Logger.getLogger(getClass()).debug("Begin " + name); 107 108 PackageDifferences packageDifferences = new PackageDifferences(name, oldPackage, newPackage); 109 Differences result = packageDifferences; 110 111 if (oldPackage != null && newPackage != null) { 112 113 Collection classLevel = new TreeSet(); 114 Iterator i; 115 116 i = oldPackage.getClasses().iterator(); 117 while (i.hasNext()) { 118 classLevel.add(i.next().toString()); 119 } 120 121 i = newPackage.getClasses().iterator(); 122 while (i.hasNext()) { 123 classLevel.add(i.next().toString()); 124 } 125 126 Logger.getLogger(getClass()).debug(" Diff'ing classes ..."); 127 128 i = classLevel.iterator(); 129 while (i.hasNext()) { 130 String className = (String ) i.next(); 131 132 Classfile oldClass = oldJar.getClassfile(className); 133 Classfile newClass = newJar.getClassfile(className); 134 135 Differences differences = createClassDifferences(className, oldClass, newClass); 136 if (!differences.isEmpty()) { 137 packageDifferences.getClassDifferences().add(differences); 138 } 139 } 140 141 Logger.getLogger(getClass()).debug(" " + name + " has " + packageDifferences.getClassDifferences().size() + " class(es) that changed."); 142 143 if (oldValidator.isAllowed(name) != newValidator.isAllowed(name)) { 144 result = new DocumentableDifferences(result, oldValidator, newValidator); 145 } 146 } 147 148 Logger.getLogger(getClass()).debug("End " + name + ": " + (result.isEmpty() ? "empty" : "not empty")); 149 150 return result; 151 } 152 153 public Differences createClassDifferences(String name, Classfile oldClass, Classfile newClass) { 154 Logger.getLogger(getClass()).debug("Begin " + name); 155 156 ClassDifferences classDifferences; 157 if (((oldClass != null) && oldClass.isInterface()) || ((newClass != null) && newClass.isInterface())) { 158 classDifferences = new InterfaceDifferences(name, oldClass, newClass); 159 } else { 160 classDifferences = new ClassDifferences(name, oldClass, newClass); 161 } 162 Differences result = classDifferences; 163 164 this.oldClass = oldClass; 165 this.newClass = newClass; 166 167 if (oldClass != null && newClass != null) { 168 Logger.getLogger(getClass()).debug(" Collecting fields ..."); 169 170 Map fieldLevel = new TreeMap(); 171 Iterator i; 172 173 i = oldClass.getAllFields().iterator(); 174 while (i.hasNext()) { 175 Field_info field = (Field_info) i.next(); 176 fieldLevel.put(field.getName(), field.getFullSignature()); 177 } 178 179 i = newClass.getAllFields().iterator(); 180 while (i.hasNext()) { 181 Field_info field = (Field_info) i.next(); 182 fieldLevel.put(field.getName(), field.getFullSignature()); 183 } 184 185 Logger.getLogger(getClass()).debug(" Diff'ing fields ..."); 186 187 i = fieldLevel.keySet().iterator(); 188 while (i.hasNext()) { 189 String fieldName = (String ) i.next(); 190 String fieldFullName = (String ) fieldLevel.get(fieldName); 191 192 Field_info oldField = oldClass.getField(fieldName); 193 Field_info newField = newClass.getField(fieldName); 194 195 Differences differences = createFeatureDifferences(fieldFullName, oldField, newField); 196 if (!differences.isEmpty()) { 197 classDifferences.getFeatureDifferences().add(differences); 198 } 199 } 200 201 Logger.getLogger(getClass()).debug(" Collecting methods ..."); 202 203 Map methodLevel = new TreeMap(); 204 205 i = oldClass.getAllMethods().iterator(); 206 while (i.hasNext()) { 207 Method_info method = (Method_info) i.next(); 208 methodLevel.put(method.getSignature(), method.getFullSignature()); 209 } 210 211 i = newClass.getAllMethods().iterator(); 212 while (i.hasNext()) { 213 Method_info method = (Method_info) i.next(); 214 methodLevel.put(method.getSignature(), method.getFullSignature()); 215 } 216 217 Logger.getLogger(getClass()).debug(" Diff'ing methods ..."); 218 219 i = methodLevel.keySet().iterator(); 220 while (i.hasNext()) { 221 String methodName = (String ) i.next(); 222 String methodFullName = (String ) methodLevel.get(methodName); 223 224 Method_info oldMethod = oldClass.getMethod(methodName); 225 Method_info newMethod = newClass.getMethod(methodName); 226 227 Differences differences = createFeatureDifferences(methodFullName, oldMethod, newMethod); 228 if (!differences.isEmpty()) { 229 classDifferences.getFeatureDifferences().add(differences); 230 } 231 } 232 233 Logger.getLogger(getClass()).debug(name + " has " + classDifferences.getFeatureDifferences().size() + " feature(s) that changed."); 234 235 if (oldClass.isDeprecated() != newClass.isDeprecated()) { 236 result = new DeprecatableDifferences(result, oldClass, newClass); 237 } 238 239 if (oldValidator.isAllowed(name) != newValidator.isAllowed(name)) { 240 result = new DocumentableDifferences(result, oldValidator, newValidator); 241 } 242 } 243 244 Logger.getLogger(getClass()).debug("End " + name + ": " + (result.isEmpty() ? "empty" : "not empty")); 245 246 return result; 247 } 248 249 public Differences createFeatureDifferences(String name, Feature_info oldFeature, Feature_info newFeature) { 250 Logger.getLogger(getClass()).debug("Begin " + name); 251 252 FeatureDifferences featureDifferences; 253 if (oldFeature instanceof Field_info || newFeature instanceof Field_info) { 254 featureDifferences = new FieldDifferences(name, oldFeature, newFeature); 255 256 if (featureDifferences.isRemoved() && newClass.locateField(name) != null) { 257 featureDifferences.setInherited(true); 258 } 259 } else { 260 if (((oldFeature instanceof Method_info) && ((Method_info) oldFeature).isConstructor()) || ((newFeature instanceof Method_info) && ((Method_info) newFeature).isConstructor())) { 261 featureDifferences = new ConstructorDifferences(name, oldFeature, newFeature); 262 } else { 263 featureDifferences = new MethodDifferences(name, oldFeature, newFeature); 264 } 265 266 if (featureDifferences.isRemoved()) { 267 Method_info attempt = newClass.locateMethod(name); 268 if ((attempt != null) && (oldFeature.getClassfile().isInterface() == attempt.getClassfile().isInterface())) { 269 featureDifferences.setInherited(true); 270 } 271 } 272 } 273 Differences result = featureDifferences; 274 275 if (oldFeature != null && newFeature != null) { 276 if (oldFeature.isDeprecated() != newFeature.isDeprecated()) { 277 result = new DeprecatableDifferences(result, oldFeature, newFeature); 278 } 279 280 if (oldValidator.isAllowed(name) != newValidator.isAllowed(name)) { 281 result = new DocumentableDifferences(result, oldValidator, newValidator); 282 } 283 } 284 285 Logger.getLogger(getClass()).debug("End " + name + ": " + (result.isEmpty() ? "empty" : "not empty")); 286 287 return result; 288 } 289 } 290 | Popular Tags |