package at.kugel.tool.buildtray.parser;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import at.kugel.tool.buildtray.config.Config;
import at.kugel.tool.buildtray.status.Status;
/**
* Parse content if it matches the fail criteria from the configuration.
*
* @author <a href="http://www.code-cop.org/">Peter Kofler</a>
*/
public class RegexStatusParser implements RegexParser {
private final Config config;
private final DateFormat dateFormat;
private final List<Pattern> excludedProjects;
private final List<Pattern> includedProjects;
private final Matcher statusPatternMatcher;
private String lastName;
private Status lastStatus = Status.OK;
private Date lastDate = new Date(0);
public RegexStatusParser(Config config, String content) {
this.config = config;
dateFormat = config.getDatePattern();
excludedProjects = config.getExcludedProjects();
includedProjects = config.getIncludedProjects();
statusPatternMatcher = config.getStatusPattern().matcher(content);
}
public void parse() throws ParseException {
while (hasProject()) {
processProject();
}
}
private boolean hasProject() {
return statusPatternMatcher.find();
}
private void processProject() throws ParseException {
final String name = parseProjectName();
if (isExcluded(name) || isNotIncluded(name)) {
// skip this project
return;
}
final Status status = parseStatus();
if (status == Status.UNKNOWN) {
// skip this status
return;
}
final Date date = parseBuildDate();
updateLatestFailedBuild(name, status, date);
}
private String parseProjectName() {
return statusPatternMatcher.group(config.getStatusPatternNameGroup());
}
private boolean isExcluded(String name) {
for (Pattern excludes : excludedProjects) {
if (excludes.matcher(name).matches()) {
return true;
}
}
return false;
}
private boolean isNotIncluded(String name) {
if (includedProjects.size() == 0) {
return false;
}
for (Pattern includes : includedProjects) {
if (includes.matcher(name).matches()) {
return false;
}
}
return true;
}
private Status parseStatus() {
String statusStr = statusPatternMatcher.group(config.getStatusPatternStatusGroup());
if (statusStr.matches(config.getSuccessValue())) {
return Status.OK;
} else if (statusStr.matches(config.getFailedValue())) {
return Status.FAILED;
} else {
return Status.UNKNOWN;
}
}
private Date parseBuildDate() throws ParseException {
return dateFormat.parse(statusPatternMatcher.group(config.getStatusPatternDateGroup()));
}
private void updateLatestFailedBuild(String name, Status status, Date date) {
if (date.after(lastDate) && status.sameOrWorseThan(lastStatus)) {
// System.out.println(name + " after " + lastName);
lastName = name;
lastStatus = status;
lastDate = date;
} else if (status.isWorseThan(lastStatus)) {
// System.out.println(name + " worse than " + lastName);
lastName = name;
lastStatus = status;
lastDate = date;
}
}
@Override
public Status getStatus() {
return lastStatus;
}
@Override
public String getProjectName() {
return lastName;
}
@Override
public String getBuildDate() {
return dateFormat.format(lastDate);
}
public String annotate() {
return statusPatternMatcher.replaceAll("___STATUS[[[$0]]]STATUS___($1)___($2)___($3)___");
}
public RegexStatusParser nextParser(Config newConfig, String newContent) {
RegexStatusParser parser = new RegexStatusParser(newConfig, newContent);
parser.lastName = lastName;
parser.lastStatus = lastStatus;
parser.lastDate = lastDate;
return parser;
}
}