Created and finished initial version of timeline implementation.
committer: Jonathan Bernard <jdbernard@jdbernard-desktop.(none)>
This commit is contained in:
commit
5582c44608
77
src/jdbernard/timestamper/Test.java
Normal file
77
src/jdbernard/timestamper/Test.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package jdbernard.timestamper;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
Timeline t = new Timeline();
|
||||||
|
String choice;
|
||||||
|
Scanner in = new Scanner(System.in);
|
||||||
|
|
||||||
|
boolean loop = true;
|
||||||
|
|
||||||
|
while(loop) {
|
||||||
|
System.out.println("[N]ew Timestamp, [S]ave, [L]oad, [P]rint, [Q]uit: ");
|
||||||
|
choice = in.nextLine();
|
||||||
|
String filename;
|
||||||
|
|
||||||
|
switch (choice.toLowerCase().charAt(0)) {
|
||||||
|
case 'n':
|
||||||
|
System.out.println("Enter time (HH:mm:ss) ");
|
||||||
|
Date d = new Date();
|
||||||
|
d.setHours(0);
|
||||||
|
d.setMinutes(0);
|
||||||
|
d.setSeconds(0);
|
||||||
|
d.setTime(d.getTime() + Timeline.shortFormat.parse(in.nextLine()).getTime());
|
||||||
|
|
||||||
|
System.out.println("Enter mark ('EOM' to end) ");
|
||||||
|
String line = "";
|
||||||
|
StringBuilder mark = new StringBuilder();
|
||||||
|
line = in.nextLine();
|
||||||
|
while (!line.endsWith("EOM")) {
|
||||||
|
mark.append(line);
|
||||||
|
line = in.nextLine();
|
||||||
|
}
|
||||||
|
mark.append(line.substring(0, line.length() - 3));
|
||||||
|
|
||||||
|
System.out.println("Enter notes ('EON' to end) ");
|
||||||
|
StringBuilder notes = new StringBuilder();
|
||||||
|
line = in.nextLine();
|
||||||
|
while (!line.endsWith("EON")) {
|
||||||
|
notes.append(line);
|
||||||
|
line = in.nextLine();
|
||||||
|
}
|
||||||
|
notes.append(line.substring(0, line.length() - 3));
|
||||||
|
|
||||||
|
t.addMarker(d, mark.toString(), notes.toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
System.out.print("Enter filename to save: ");
|
||||||
|
filename = in.nextLine();
|
||||||
|
|
||||||
|
Timeline.writeToFile(filename, t);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
System.out.println("Enter filename to load: ");
|
||||||
|
filename = in.nextLine();
|
||||||
|
|
||||||
|
t = Timeline.readFromFile(filename);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
Timeline.writeToStream(System.out, t);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
loop = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
234
src/jdbernard/timestamper/Timeline.java
Normal file
234
src/jdbernard/timestamper/Timeline.java
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
package jdbernard.timestamper;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jonathan Bernard <jdbernard@gmail.com>
|
||||||
|
* A Timeline object represents a series of markers at specific points in time.
|
||||||
|
* The markers have a name or symbol (the 'mark') and notes associated with that
|
||||||
|
* mark.
|
||||||
|
*/
|
||||||
|
public class Timeline implements Iterable<Timeline.TimelineMarker> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents a marker on the timeline.
|
||||||
|
* The date of the marker and the mark cannot be changed once assigned.
|
||||||
|
*/
|
||||||
|
public class TimelineMarker implements Comparable<TimelineMarker> {
|
||||||
|
private final Date timestamp;
|
||||||
|
private final String mark;
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
public TimelineMarker(Date timestamp, String mark, String notes) {
|
||||||
|
if (timestamp == null || mark == null)
|
||||||
|
throw new IllegalArgumentException("Null timestamp or mark"
|
||||||
|
+ " is not permitted.");
|
||||||
|
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.mark = mark;
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTimestamp() { return timestamp; }
|
||||||
|
|
||||||
|
public String getMark() { return mark; }
|
||||||
|
|
||||||
|
public String getNotes() { return notes; }
|
||||||
|
|
||||||
|
public void setNotes(String notes) { this.notes = notes; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(TimelineMarker that) {
|
||||||
|
if (that == null) return Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
return this.timestamp.compareTo(that.timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object that) {
|
||||||
|
if (that == null) return false;
|
||||||
|
if (!(that instanceof TimelineMarker)) return false;
|
||||||
|
|
||||||
|
return this.timestamp.equals(((TimelineMarker)that).timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static enum ReadingState {
|
||||||
|
NewMarker,
|
||||||
|
StartMark,
|
||||||
|
ReadMark,
|
||||||
|
StartNotes,
|
||||||
|
ReadNotes,
|
||||||
|
EndMarker
|
||||||
|
};
|
||||||
|
|
||||||
|
public static SimpleDateFormat shortFormat = new SimpleDateFormat("HH:mm:ss");
|
||||||
|
public static SimpleDateFormat longFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
|
||||||
|
|
||||||
|
private static int lineWrap = 78;
|
||||||
|
private TreeSet<TimelineMarker> timelineList;
|
||||||
|
|
||||||
|
public Timeline() {
|
||||||
|
timelineList = new TreeSet<TimelineMarker>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMarker(Date timestamp, String name, String notes) {
|
||||||
|
timelineList.add(new TimelineMarker(timestamp, name, notes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName(Date timestamp) {
|
||||||
|
//TODO:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastNotes(Date timestamp) {
|
||||||
|
//TODO:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimelineMarker getLastMarker(Date timestamp) {
|
||||||
|
//TODO:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMarker(TimelineMarker marker) {
|
||||||
|
timelineList.remove(marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<TimelineMarker> iterator() {
|
||||||
|
return timelineList.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeToStream(OutputStream stream, Timeline timeline)
|
||||||
|
throws IOException {
|
||||||
|
Writer out = new OutputStreamWriter(stream);
|
||||||
|
for (TimelineMarker tm : timeline.timelineList) {
|
||||||
|
|
||||||
|
// write timestamp
|
||||||
|
out.write(longFormat.format(tm.getTimestamp()) + "\n");
|
||||||
|
|
||||||
|
// write mark
|
||||||
|
String mark = tm.getMark().replace('\n', '\u0000');
|
||||||
|
if (mark.length() < lineWrap) out.write(mark + "\n");
|
||||||
|
else {
|
||||||
|
// wrap lines if neccessary
|
||||||
|
int i;
|
||||||
|
for (i = 0; (i + lineWrap) < mark.length(); i+=lineWrap)
|
||||||
|
out.write(mark.substring(i, i+lineWrap) + "\\\n");
|
||||||
|
if (i < mark.length())
|
||||||
|
out.write(mark.substring(i, mark.length()) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// write notes
|
||||||
|
String notes = tm.getNotes().replace('\n', '\u0000');
|
||||||
|
if (notes.length() < lineWrap) out.write(notes + "\n");
|
||||||
|
else {
|
||||||
|
// wrap lines if neccessary
|
||||||
|
int i;
|
||||||
|
for (i = 0; (i + lineWrap) < notes.length(); i+=lineWrap)
|
||||||
|
out.write(notes.substring(i, i+lineWrap) + "\\\n");
|
||||||
|
if (i < notes.length())
|
||||||
|
out.write(notes.substring(i, notes.length()) + "\n");
|
||||||
|
}
|
||||||
|
out.write("\n");
|
||||||
|
}
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeToFile(String filename, Timeline timeline)
|
||||||
|
throws IOException, FileNotFoundException {
|
||||||
|
OutputStream out = new FileOutputStream(filename);
|
||||||
|
writeToStream(out, timeline);
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Timeline readFromStream(InputStream stream)
|
||||||
|
throws IOException, FileNotFoundException {
|
||||||
|
Scanner in = new Scanner(stream);
|
||||||
|
Timeline timeline = new Timeline();
|
||||||
|
|
||||||
|
ReadingState readingState = ReadingState.NewMarker;
|
||||||
|
Date d = null;
|
||||||
|
StringBuilder mark = null;
|
||||||
|
StringBuilder notes = null;
|
||||||
|
String line;
|
||||||
|
int lineNumber = 0;
|
||||||
|
|
||||||
|
while (in.hasNextLine()) {
|
||||||
|
line = in.nextLine();
|
||||||
|
lineNumber++;
|
||||||
|
|
||||||
|
switch (readingState) {
|
||||||
|
|
||||||
|
case NewMarker:
|
||||||
|
try { d = longFormat.parse(line); }
|
||||||
|
catch (ParseException pe) {
|
||||||
|
throw new IOException("Error parsing timeline file at line "
|
||||||
|
+ lineNumber + ": expected a new marker date but could not parse"
|
||||||
|
+ " the date. Error: " + pe.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
readingState = ReadingState.StartMark;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StartMark:
|
||||||
|
mark = new StringBuilder();
|
||||||
|
// fall through to ReadMark
|
||||||
|
case ReadMark:
|
||||||
|
if (line.endsWith("\\")) {
|
||||||
|
readingState = ReadingState.ReadMark;
|
||||||
|
line = line.substring(0, line.length() - 1);
|
||||||
|
}
|
||||||
|
else readingState = ReadingState.StartNotes;
|
||||||
|
mark.append(line);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StartNotes:
|
||||||
|
notes = new StringBuilder();
|
||||||
|
// fall through to ReadNotes
|
||||||
|
case ReadNotes:
|
||||||
|
if (line.endsWith("\\")) {
|
||||||
|
readingState = ReadingState.ReadNotes;
|
||||||
|
line = line.substring(0, line.length() - 1);
|
||||||
|
}
|
||||||
|
else readingState = ReadingState.EndMarker;
|
||||||
|
notes.append(line);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EndMarker:
|
||||||
|
String sMark = mark.toString().replace('\u0000', '\n');
|
||||||
|
String sNotes = notes.toString().replace('\u0000', '\n');
|
||||||
|
timeline.addMarker(d, sMark, sNotes);
|
||||||
|
readingState = ReadingState.NewMarker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (readingState != ReadingState.NewMarker)
|
||||||
|
//TODO: warning of invalid marker file
|
||||||
|
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Timeline readFromFile(String filename)
|
||||||
|
throws IOException, FileNotFoundException {
|
||||||
|
InputStream in = new FileInputStream(filename);
|
||||||
|
Timeline t = readFromStream(in);
|
||||||
|
in.close();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user