001 package org.hackystat.projectbrowser.page.dailyprojectdata.complexity; 002 003 import java.io.Serializable; 004 import java.util.ArrayList; 005 import java.util.HashMap; 006 import java.util.List; 007 import java.util.Map; 008 import java.util.logging.Logger; 009 010 import org.hackystat.dailyprojectdata.client.DailyProjectDataClient; 011 import org.hackystat.dailyprojectdata.resource.complexity.jaxb.ComplexityDailyProjectData; 012 import org.hackystat.dailyprojectdata.resource.complexity.jaxb.FileData; 013 import org.hackystat.projectbrowser.ProjectBrowserApplication; 014 import org.hackystat.projectbrowser.ProjectBrowserSession; 015 import org.hackystat.projectbrowser.page.dailyprojectdata.DailyProjectDataSession; 016 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 017 import org.hackystat.utilities.stacktrace.StackTrace; 018 import org.hackystat.utilities.tstamp.Tstamp; 019 020 /** 021 * The data model for Complexity DPD display. This data model accommodates multiple Projects. 022 * For each project, the data model indicates the number of methods whose level of complexity 023 * falls into each of five buckets, from 0-10, 11-20, 21-30, 31-40, 41+. 024 * At present, we only get cyclomatic complexity from the JavaNCSS tool. This will change 025 * after we update the DPD client to not require the tool argument. 026 * @author Philip Johnson 027 * 028 */ 029 public class ComplexityDataModel implements Serializable { 030 031 /** Support serialization. */ 032 private static final long serialVersionUID = 1L; 033 034 /** Holds the complexity data, organized by Project.*/ 035 private Map<Project, ComplexityData> complexityDataMap = new HashMap<Project, ComplexityData>(); 036 037 /** 038 * The default ComplexityDataModel, which contains no complexity information. 039 */ 040 public ComplexityDataModel() { 041 // Do nothing. 042 } 043 044 /** 045 * Updates this data model to reflect the complexity information associated with the selected 046 * projects and granularity. 047 */ 048 public void update() { 049 this.clear(); 050 DailyProjectDataClient dpdClient = ProjectBrowserSession.get().getDailyProjectDataClient(); 051 DailyProjectDataSession session = ProjectBrowserSession.get().getDailyProjectDataSession(); 052 List<Project> projects = session.getSelectedProjects(); 053 // Placeholders until we set this programmatically. 054 String complexityType = "Cyclomatic"; 055 String complexityTool = "JavaNCSS"; 056 057 for (Project project : projects) { 058 Logger logger = ((ProjectBrowserApplication)ProjectBrowserApplication.get()).getLogger(); 059 logger.fine("Getting Complexity DPD for project: " + project.getName()); 060 try { 061 ComplexityDailyProjectData classData = dpdClient.getComplexity(project.getOwner(), 062 project.getName(), Tstamp.makeTimestamp(session.getDate().getTime()), complexityType, 063 complexityTool); 064 logger.fine("Finished getting Complexity DPD for project: " + project.getName()); 065 ComplexityData complexityData = this.getComplexityData(project); 066 for (FileData data : classData.getFileData()) { 067 complexityData.addEntry(data); 068 } 069 } 070 catch (Exception e) { 071 session.setFeedback("Exception when getting complexity DPD for project " + project + ": " + 072 StackTrace.toString(e)); 073 } 074 } 075 } 076 077 /** 078 * Sets this model to its empty state. 079 */ 080 public void clear() { 081 this.complexityDataMap.clear(); 082 } 083 084 085 /** 086 * Returns true if this data model contains no information. 087 * Used to figure out if the associated panel should be visible. 088 * @return True if the data model is empty. 089 */ 090 public boolean isEmpty() { 091 return this.complexityDataMap.isEmpty(); 092 } 093 094 /** 095 * Return the ComplexityData instance associated with the specified project. 096 * Creates and returns a new ComplexityData instance if one is not yet present. 097 * @param project The project. 098 * @return The ComplexityData instance for this project. 099 */ 100 public ComplexityData getComplexityData(Project project) { 101 if (!complexityDataMap.containsKey(project)) { 102 complexityDataMap.put(project, new ComplexityData(project)); 103 } 104 return complexityDataMap.get(project); 105 } 106 107 /** 108 * Returns the list of ComplexityData instances, needed for markup. 109 * @return The list of ComplexityData instances. 110 */ 111 public List<ComplexityData> getComplexityDataList() { 112 return new ArrayList<ComplexityData>(this.complexityDataMap.values()); 113 } 114 115 }