This version of the properties file uses it's own format.

This commit is contained in:
Jonathan Bernard 2009-10-15 23:12:55 -05:00
parent 59a81a4f77
commit 42d2d82c74

View File

@ -0,0 +1,160 @@
package jdbernard.timestamper.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;
/**
*
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
*/
public class TimelineProperties {
private Timeline timeline;
private TimelineSource timelineSource;
private LinkedList<SyncTarget> syncTargets = new LinkedList<SyncTarget>();
public TimelineProperties(InputStream in) throws IOException {
parseConfig(in);
}
private static enum ReadingState {
LocalTimelineDef, // expecting LOCAL TIMELINE definition
NewSync, // expecting a SYNC TO def
NewSyncOrOptions // either a NewDef, or a block of options
}
private void parseConfig(InputStream is) throws IOException {
Scanner in = new Scanner(is);
URI sourceURI;
// read the information for the local timeline
if (!nextExtendedToken(in, "LOCAL TIMELINE:")) {
throw new IOException("Missing 'LOCAL TIMELINE:' definition."
+ " This must be the first line of the options file.");
}
// parse the source URI
timelineSource = parseSource(in);
// load timeline from source
timeline = timelineSource.read(); // TODO: authentication
// add as many Syncs as we find
for (SyncTarget st = parseSync(in); st != null; st = parseSync(in))
syncTargets.add(st);
}
private SyncTarget parseSync(Scanner in) throws IOException {
SyncTarget st;
String token;
if (!nextExtendedToken(in, "SYNC WITH:")) { return null; }
st = new SyncTarget(parseSource(in), timeline);
while (true) {
if (nextExtendedToken(in, "PULL ONLY")) {
st.enablePull(true);
st.enablePush(false);
}
else if (nextExtendedToken(in, "PUSH ONLY")) {
st.enablePull(false);
st.enablePush(true);
}
else if (nextExtendedToken(in, "PUSH AND PULL") ||
nextExtendedToken(in, "PULL AND PUSH")) {
st.enablePull(true);
st.enablePush(true);
}
else if (nextExtendedToken(in, "SYNC ON EXIT")) {
st.enableSyncOnExit(true);
}
else if (nextExtendedToken(in, "UPDATE EVERY")) {
long updateAmount = 1;
// parse the time amount if present
token = in.next("\\d+");
if (token != null) { updateAmount = Long.parseLong(token); }
token = in.next();
if ("seconds".startsWith(token.toLowerCase()))
updateAmount *= 1000;
else if ("minutes".startsWith(token.toLowerCase()))
updateAmount *= 1000 * 60;
else if ("hours".startsWith(token.toLowerCase()))
updateAmount *= 1000 * 60 * 60;
else if ("days".startsWith(token.toLowerCase()))
updateAmount *= 1000 * 60 * 60 * 24;
else if ("weeks".startsWith(token.toLowerCase()))
updateAmount *= 1000 * 60 * 60 * 24 * 7;
else throw new IOException("'" + token + "' is not a supported"
+ " measure of time. The supported measures are "
+ "'seconds', 'minutes', 'hours', 'days', and 'weeks'.");
}
else return st;
}
}
private TimelineSource parseSource(Scanner in) throws IOException {
String strURI;
URI sourceURI;
if (!in.hasNext()) {
throw new IOException("Expected the URI of a timeline source, but "
+ "ran out of input.");
}
strURI = in.next();
try { sourceURI = new URI(strURI); }
catch (URISyntaxException urise) {
throw new IOException("The source link '" + strURI + "' is not a"
+ " valid URI.", urise);
}
return TimelineSourceFactory.newInstance(sourceURI);
}
private static boolean nextExtendedToken(Scanner in, String expectedToken)
throws IOException {
StringTokenizer st = new StringTokenizer(expectedToken);
if (st.countTokens() < 1 || !in.hasNext()) { return false; }
// read one token
String curToken = st.nextToken();
String inToken = in.next("(?i)\\Q" + curToken + "\\E");
if (inToken == null) return false;
while (st.hasMoreTokens()) {
curToken = st.nextToken();
if (!in.hasNext()) {
throw new IOException("Ran out of input while expecting '"
+ curToken + "' from '" + expectedToken + "'.");
}
inToken = in.next("(?i)\\Q" + curToken + "\\E");
if (inToken == null) {
throw new IOException("Found '" + in.next() + "' but expected '"
+ curToken + "' from '" + expectedToken + "'.");
}
}
return true;
}
public void writeToStream(OutputStream out) throws IOException {
}
}