package uk.ac.ox.oucs.vle; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Represents a parsed term code. * The year in an un-parsed termcode is the calendar year and not the academic year. * * @author Matthew Buckett */ class TermCode implements Comparable<TermCode> { // Patterns are threadsafe private static final Pattern pattern = Pattern.compile("(\\w\\w)(\\d\\d)"); /** * Enum for the standard Oxford term. */ public static enum Terms { // Order matters as it's used for sorting. HT("Hilary"),TT("Trinity"), MT("Michaelmas"); private String title; Terms(String title) { this.title = title; } public String title() { return this.title; } } private String source; private Terms term; private Integer year; /** * Create a new termcode by parsing a string. * @param source The source to parse, eg TT10 or MT11 */ public TermCode(String source) { this.source = source; if (source != null) { Matcher matcher = pattern.matcher(source); try { if (matcher.matches()) { term = Terms.valueOf(matcher.group(1)); // Never get exception because of regexp. year = Integer.parseInt(matcher.group(2)); } } catch (IllegalArgumentException iae) { // Just leave it as invalid. } } } /** * Gets a nice display name for a term. * @return User readable name for term or <code>null</code> if it's not a good term. */ public String getName() { if (isValid()) { return String.format("%s %d", term.title(), 2000+year); } return null; } public boolean isValid() { return term != null; } /** * This sorts by year first, then by term and finally by the source (to make it consistent). * {@inheritDoc} */ @Override public int compareTo(TermCode other) { if (! (this.isValid() && other.isValid()) ) { int ret = 0; ret -= (this.isValid()?1:0); ret += (other.isValid()?1:0); if(ret == 0) { // Fallback to the source so we have consistent sorting if (this.source != null && other.source != null) { ret = this.source.compareTo(other.source); } else { ret += (this.source != null)?1:0; ret -= (other.source != null)?1:0; } } return ret; } // All fields will be valid return Integer.signum(this.year.compareTo(other.year)) * 4 + Integer.signum(this.term.compareTo(other.term)) * 2 + Integer.signum(this.source.compareTo(other.source)); } }