001 package org.hackystat.dailyprojectdata.resource.issue; 002 003 import java.util.Arrays; 004 import java.util.List; 005 import java.util.logging.Logger; 006 import javax.xml.datatype.XMLGregorianCalendar; 007 import org.hackystat.dailyprojectdata.resource.issue.jaxb.IssueData; 008 import org.hackystat.sensorbase.resource.sensordata.jaxb.Property; 009 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData; 010 import org.hackystat.utilities.tstamp.Tstamp; 011 012 /** 013 * Parser for the issue sensordata to IssueData. 014 * @author Shaoxuan Zhang 015 * 016 */ 017 public class IssueDataParser { 018 019 //static String copied from org.hackystat.sensor.ant.issue.IssueEntry 020 /** property key of ID. */ 021 protected static final String ID_PROPERTY_KEY = "Id"; 022 /** property key of TYPE. */ 023 protected static final String TYPE_PROPERTY_KEY = "Type"; 024 /** property key of STATUS. */ 025 protected static final String STATUS_PROPERTY_KEY = "Status"; 026 /** property key of PRIORITY. */ 027 protected static final String PRIORITY_PROPERTY_KEY = "Priority"; 028 /** property key of MILESTONE. */ 029 protected static final String MILESTONE_PROPERTY_KEY = "Milestone"; 030 /** property key of OWNER. */ 031 protected static final String OWNER_PROPERTY_KEY = "Owner"; 032 033 /** timestamp separator in property value. */ 034 protected static final String TIMESTAMP_SEPARATOR = "--"; 035 036 private Logger logger; 037 private List<String> openIssueStatus = Arrays.asList(new String[]{"New", "Accepted", "Started"}); 038 039 /** 040 * @param logger the logger. 041 */ 042 public IssueDataParser(final Logger logger) { 043 this.logger = logger; 044 } 045 046 /** 047 * Determine if the status value means open. 048 * @param statusValue the status value. 049 * @return true if it is open. 050 */ 051 public boolean isOpenStatus(String statusValue) { 052 return statusValue != null && openIssueStatus.contains(statusValue); 053 } 054 055 /** 056 * Get the state of the issue on the given time. 057 * @param issueSensorData the given sensordata. 058 * @param timestamp the time. 059 * @return the IssueData. 060 */ 061 public IssueData getIssueDpd(SensorData issueSensorData, final XMLGregorianCalendar timestamp) { 062 IssueData issueDpd = new IssueData(); 063 064 //get id 065 for (Property property : issueSensorData.getProperties().getProperty()) { 066 if (ID_PROPERTY_KEY.equals(property.getKey())) { 067 issueDpd.setId(Integer.valueOf(property.getValue())); 068 break; 069 } 070 } 071 072 //get latest type 073 issueDpd.setType(this.getValueWithKeyWhen(issueSensorData, TYPE_PROPERTY_KEY, timestamp)); 074 075 //get latest status 076 issueDpd.setStatus(this.getValueWithKeyWhen(issueSensorData, STATUS_PROPERTY_KEY, timestamp)); 077 078 //get latest priority 079 issueDpd.setPriority( 080 this.getValueWithKeyWhen(issueSensorData, PRIORITY_PROPERTY_KEY, timestamp)); 081 082 //get latest milestone 083 issueDpd.setMilestone( 084 this.getValueWithKeyWhen(issueSensorData, MILESTONE_PROPERTY_KEY, timestamp)); 085 086 //get latest owner 087 issueDpd.setOwner(this.getValueWithKeyWhen(issueSensorData, OWNER_PROPERTY_KEY, timestamp)); 088 089 return issueDpd; 090 } 091 092 /** 093 * Return the value with the given key in the given time within the given sensordata. 094 * @param issueSensorData the sensordata. 095 * @param key the property key 096 * @param timestamp the time. 097 * @return the latest value, null if not found. 098 */ 099 public String getValueWithKeyWhen(SensorData issueSensorData, String key, 100 XMLGregorianCalendar timestamp) { 101 XMLGregorianCalendar latestTime = null; 102 String value = null; 103 for (Property property : issueSensorData.getProperties().getProperty()) { 104 if (key.equals(property.getKey())) { 105 XMLGregorianCalendar newTimestamp = null; 106 try { 107 newTimestamp = extractTimestamp(property.getValue()); 108 } 109 catch (Exception e) { 110 logger.warning("Error when extracting timestamp from [" + property.getValue() + "]"); 111 } 112 if (newTimestamp != null && !Tstamp.greaterThan(newTimestamp, timestamp) && 113 (latestTime == null || Tstamp.lessThan(latestTime, newTimestamp))) { 114 latestTime = newTimestamp; 115 value = extractValue(property.getValue()); 116 } 117 } 118 } 119 return value; 120 } 121 122 /** 123 * Extract timestamp from formatted string. 124 * @param value the string. 125 * @return the timestamp. 126 * @throws Exception if the string is not formatted. 127 */ 128 private static XMLGregorianCalendar extractTimestamp(String value) throws Exception { 129 int startIndex = value.indexOf(TIMESTAMP_SEPARATOR) + TIMESTAMP_SEPARATOR.length(); 130 return Tstamp.makeTimestamp(value.substring(startIndex)); 131 } 132 133 /** 134 * Extract value from formatted string. 135 * @param string the string. 136 * @return the value. 137 */ 138 private static String extractValue(String string) { 139 return string.substring(0, string.indexOf(TIMESTAMP_SEPARATOR)); 140 } 141 }