package edu.kit.pse.ws2013.routekit.history;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import edu.kit.pse.ws2013.routekit.util.Coordinates;
/**
* A {@link History} entry, consisting of
* <ul>
* <li>a {@link #getStart() start point}</li>
* <li>a {@link #getDest() destination point}</li>
* <li>a {@link #getDate() date}</li>
* </ul>
*/
public class HistoryEntry {
private static final DateFormat ISO_FORMAT = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZ");
/**
* The start point.
*/
private final Coordinates start;
/**
* The destination point.
*/
private final Coordinates dest;
/**
* The date.
*/
private final Date date;
/**
* Creates a new {@link HistoryEntry} with the specified attributes.
*
* @param start
* The start point.
* @param dest
* The destination point.
* @param date
* The date.
* @throws IllegalArgumentException
* If start, dest or date are null.
*/
public HistoryEntry(Coordinates start, Coordinates dest, Date date) {
if (start == null) {
throw new IllegalArgumentException("start is null!",
new NullPointerException());
}
if (dest == null) {
throw new IllegalArgumentException("dest is null!",
new NullPointerException());
}
if (date == null) {
throw new IllegalArgumentException("date is null!",
new NullPointerException());
}
this.start = start;
this.dest = dest;
this.date = date;
}
/**
* Gets the start point.
*
* @return The start point.
*/
public Coordinates getStart() {
return start;
}
/**
* Gets the destination point.
*
* @return The destination point.
*/
public Coordinates getDest() {
return dest;
}
/**
* Gets the date.
*
* @return The date.
*/
public Date getDate() {
return date;
}
/**
* <p>
* Returns a string representation of the history entry suitable for parsing
* with {@link #fromString(String)}.
* </p>
* <p>
* The exact format is: {@code date: start -> dest}, where {@code date} is
* the {@link #getDate() date} in ISO 8601 format, e. g.
* {@code 2013-12-27T17:11:00+0100}, {@code start} is the
* {@link #getStart() start} and {@code dest} is the {@link #getDest()
* destination} point.
* </p>
*
* @return A string representation of the history entry.
*/
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
ret.append(ISO_FORMAT.format(date));
ret.append(": ");
ret.append(start.toString());
ret.append(" -> ");
ret.append(dest.toString());
return ret.toString();
}
/**
* Parse a history entry string as returned by {@link #toString()} back into
* a {@link HistoryEntry}.
*
* @param s
* The history entry string.
* @return The {@link HistoryEntry} parsed from the string.
* @throws IllegalArgumentException
* If the history entry string can’t be parsed.
*/
public static HistoryEntry fromString(String s) {
if (s == null) {
throw new IllegalArgumentException("History entry string is null!",
new NullPointerException());
}
try {
Matcher m = Pattern.compile("(.*): (.*) -> (.*)").matcher(s);
if (!m.matches()) { // matches() is necessary because the matcher is
// lazy
throw new IllegalArgumentException("No match found!");
}
Date date = ISO_FORMAT.parse(m.group(1));
Coordinates start = Coordinates.fromString(m.group(2));
Coordinates dest = Coordinates.fromString(m.group(3));
return new HistoryEntry(start, dest, date);
} catch (ParseException | IllegalArgumentException e) {
throw new IllegalArgumentException(
"Can’t parse history entry string!", e);
}
}
}