package hudson.plugins.violations.model; import java.util.TreeSet; import java.util.Map; import java.util.HashMap; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.Collection; import java.io.File; import hudson.plugins.violations.render.FileModelProxy; /** * A model of the violations of the build used during rendering time. */ public class BuildModel { private File xmlRoot; private Map<String, FileModelProxy> fileModelMap = new HashMap<String, FileModelProxy>(); private SortedMap<String, SortedSet<FileCount>> typeMap = new TreeMap<String, SortedSet<FileCount>>(); private SortedMap<String, TypeCount> typeCountMap; /** * Create a model of the violations. * @param xmlFile the file used to create this (used to * get the directory for parsing the per file * xml files on demand). */ public BuildModel(File xmlFile) { this.xmlRoot = xmlFile.getParentFile(); } /** * Get the map of type to file counts. * @return the map of type to file counts. */ public SortedMap<String, SortedSet<FileCount>> getTypeMap() { return typeMap; } /** * Get the file model map. * @return a map of name to file model proxy. */ public Map<String, FileModelProxy> getFileModelMap() { return fileModelMap; } /** * Get the collection of type counts. * @return the collection of type counts. */ public Collection<TypeCount> getTypeCounts() { if (typeCountMap == null) { typeCountMap = new TreeMap<String, TypeCount>(); for (String t: typeMap.keySet()) { int count = 0; for (FileCount fc: typeMap.get(t)) { count += fc.getCount(); } typeCountMap.put( t, new TypeCount(t, typeMap.get(t).size(), count)); } } return typeCountMap.values(); } /** * Get the type count map. * @return the type count map. */ public Map<String, TypeCount> getTypeCountMap() { getTypeCounts(); return typeCountMap; } /** * A class used in displaying number of violations and files * in violation. */ public static class TypeCount { private final String name; private final int count; private final int numberFiles; /** * Constructor for TypeCount. * @param name the type name. * @param numberFiles the number of files in violation. * @param count the number of violations. */ public TypeCount(String name, int numberFiles, int count) { this.name = name; this.numberFiles = numberFiles; this.count = count; } /** * Get the type name. * @return the type name. */ public String getName() { return name; } /** * Get the number of violations of this type. * @return the number. */ public int getCount() { return count; } /** * Get the number of file that contain violations of this type. * @return the number. */ public int getNumberFiles() { return numberFiles; } } /** * get a set of file counts for a type. * @param type the type to ge for. * @return a set of file counts. */ public SortedSet<FileCount> getFileCounts(String type) { SortedSet<FileCount> ret = typeMap.get(type); if (ret == null) { ret = new TreeSet<FileCount>(); typeMap.put(type, ret); } return ret; } private FileModelProxy getFileNameProxy(String name) { FileModelProxy proxy = fileModelMap.get(name); if (proxy != null) { return proxy; } File xmlFile = new File( xmlRoot, "file/" + name + ".xml"); fileModelMap.put(name, new FileModelProxy(xmlFile)); return proxy; } /** * Add a file count. * @param type the type. * @param name the filename. * @param count the number of violations. */ public void addFileCount(String type, String name, int[] count) { FileModelProxy proxy = getFileNameProxy(name); getFileCounts(type).add(new FileCount(name, count, proxy)); } /** * A class of file name to count mapping. */ public static class FileCount implements Comparable<FileCount> { private final String name; private final int totalCount; private final int[] counts; private final FileModelProxy proxy; /** * Create a FileCount object. * @param name the name of the file. * @param counts the numbers of violations (of a particular type) in the * file. * @param proxy the associated file proxy (used during rendering). */ public FileCount(String name, int[] counts, FileModelProxy proxy) { this.name = name; this.counts = counts; int t = 0; for (int i = 0; i < counts.length; ++i) { t += counts[i]; } this.totalCount = t; this.proxy = proxy; } /** * Get the name of the file. * @return the filename. */ public String getName() { return name; } /** * Get the number of violations. * @return the number. */ public int getCount() { return totalCount; } /** * Get the number of high severity violations. * @return the number. */ public int getHigh() { return counts[Severity.HIGH_VALUE]; } /** * Get the number of medium severity violations. * @return the number. */ public int getMedium() { return counts[Severity.MEDIUM_HIGH_VALUE] + counts[Severity.MEDIUM_VALUE] + counts[Severity.MEDIUM_LOW_VALUE]; } /** * Get the number of low severity violations. * @return the number. */ public int getLow() { return counts[Severity.LOW_VALUE]; } /** * Get the associated file model proxy. * @return the file model proxy. */ public FileModel getFileModel() { return proxy.getFileModel(); } /** * Compare to another FileCount object. * @param other the other file count object. * @return 0 if they are the same, -1 if count is greater * 1 if count is less, if counts are the same * use the name for comparison. */ public int compareTo(FileCount other) { if (this == other) { return 0; } if (totalCount > other.totalCount) { return -1; } else if (totalCount < other.totalCount) { return 1; } return name.compareTo(other.name); } } }