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