This version of the properties file uses it's own format.
This commit is contained in:
parent
59a81a4f77
commit
42d2d82c74
160
src/jdbernard/timestamper/core/TimelineProperties.java
Normal file
160
src/jdbernard/timestamper/core/TimelineProperties.java
Normal 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 {
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user