package japicmp.cmp; import com.google.common.base.Optional; import japicmp.model.JApiChangeStatus; import japicmp.model.JApiClass; import japicmp.model.JApiClassType; import japicmp.util.ClassHelper; import japicmp.util.ModifierHelper; import javassist.CtClass; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public class ClassesComparator { private List<JApiClass> classes = new LinkedList<>(); private JarArchiveComparator jarArchiveComparator; private final JarArchiveComparatorOptions options; public ClassesComparator(JarArchiveComparator jarArchiveComparator, JarArchiveComparatorOptions options) { this.jarArchiveComparator = jarArchiveComparator; this.options = options; } public void compare(List<CtClass> oldClassesArg, List<CtClass> newClassesArg) { classes = new LinkedList<>(); Map<String, CtClass> oldClassesMap = createClassMap(oldClassesArg); Map<String, CtClass> newClassesMap = createClassMap(newClassesArg); sortIntoLists(oldClassesMap, newClassesMap); } private void sortIntoLists(Map<String, CtClass> oldClassesMap, Map<String, CtClass> newClassesMap) { for (CtClass oldCtClass : oldClassesMap.values()) { CtClass newCtClass = newClassesMap.get(oldCtClass.getName()); if (newCtClass == null) { JApiClassType classType = new JApiClassType(Optional.of(ClassHelper.getType(oldCtClass)), Optional.<JApiClassType.ClassType>absent(), JApiChangeStatus.REMOVED); JApiClass jApiClass = new JApiClass(this.jarArchiveComparator, oldCtClass.getName(), Optional.of(oldCtClass), Optional.<CtClass>absent(), JApiChangeStatus.REMOVED, classType); if (includeClass(jApiClass)) { classes.add(jApiClass); } } else { JApiChangeStatus changeStatus = JApiChangeStatus.UNCHANGED; JApiClassType.ClassType oldType = ClassHelper.getType(oldCtClass); JApiClassType.ClassType newType = ClassHelper.getType(newCtClass); if (oldType != newType) { changeStatus = JApiChangeStatus.MODIFIED; } JApiClassType classType = new JApiClassType(Optional.of(oldType), Optional.of(newType), changeStatus); JApiClass jApiClass = new JApiClass(this.jarArchiveComparator, oldCtClass.getName(), Optional.of(oldCtClass), Optional.of(newCtClass), changeStatus, classType); if (includeClass(jApiClass)) { classes.add(jApiClass); } } } for (CtClass newCtClass : newClassesMap.values()) { CtClass oldCtClass = oldClassesMap.get(newCtClass.getName()); if (oldCtClass == null) { JApiClassType.ClassType newType = ClassHelper.getType(newCtClass); JApiClassType classType = new JApiClassType(Optional.<JApiClassType.ClassType>absent(), Optional.of(newType), JApiChangeStatus.NEW); JApiClass jApiClass = new JApiClass(this.jarArchiveComparator, newCtClass.getName(), Optional.<CtClass>absent(), Optional.of(newCtClass), JApiChangeStatus.NEW, classType); if (includeClass(jApiClass)) { classes.add(jApiClass); } } } } private boolean includeClass(JApiClass jApiClass) { return ModifierHelper.matchesModifierLevel(jApiClass, options.getAccessModifier()); } private Map<String, CtClass> createClassMap(List<CtClass> oldClassesArg) { Map<String, CtClass> oldClassesMap = new HashMap<String, CtClass>(); for (CtClass ctClass : oldClassesArg) { oldClassesMap.put(ctClass.getName(), ctClass); } return oldClassesMap; } public List<JApiClass> getClasses() { return classes; } }