1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
package bjc.utils.configuration;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import javax.lang.model.SourceVersion;
/**
* A config file with support for categories, comments and other thins
*
* @author ben
*
*/
public class ConfigFile {
private static Map<String, ConfigCategory> topLevelCategories;
/**
* A category in a configuration file
* @author ben
*
*/
public static class ConfigCategory {
private Map<String, ConfigCategory> children;
/**
* Create a new config category
*/
public ConfigCategory() {
children = new HashMap<>();
}
public void addChild(String childName, ConfigCategory child) {
children.put(childName, child);
}
}
/**
* Parse the values in a config file from a stream
*
* @param source
* The stream to parse values from
* @return A config file with values parsed from the stream
*/
public static ConfigFile parse(InputStream source) {
Scanner scn = new Scanner(source);
ConfigFile returnedFile = new ConfigFile();
while (scn.hasNextLine()) {
String currentLine = scn.nextLine();
// Ignore blank lines
if (currentLine.equals("")) {
continue;
}
String[] currentTokens = currentLine.split(" ");
// Ignore lines that start with a comment marker
if (isCommentMarker(currentTokens[0])) {
continue;
} else if (SourceVersion.isName(currentTokens[0])
&& currentTokens[1].equals("{")) {
topLevelCategories.put(currentTokens[0], parseCategory(currentTokens[0], scn));
}
}
return returnedFile;
}
private static ConfigCategory parseCategory(String categoryName,
Scanner inputSource) {
ConfigCategory category = new ConfigCategory();
String currentLine = inputSource.nextLine();
String[] tokens = currentLine.split("\\s+ ");
// Parse contents of category
while (!tokens[0].equals("}")) {
// Ignore lines starting with comment marker
if (isCommentMarker(tokens[0])) {
continue;
}
int initialCommandToken = 0;
// Skip over blank tokens from lots of spacing
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
if (token.equals("")) {
continue;
} else {
initialCommandToken = i;
break;
}
}
String[] relevantTokens = Arrays.copyOfRange(tokens,
initialCommandToken, tokens.length);
// Parse child subcategories
if (SourceVersion.isName(relevantTokens[0])
&& relevantTokens[1].equals("{")) {
parseCategory(relevantTokens[0], inputSource);
} else {
// Parse config fields
parseEntry(category, relevantTokens);
}
currentLine = inputSource.nextLine();
tokens = currentLine.split("\\s+ ");
}
return category;
}
private static void parseEntry(ConfigCategory category,
String[] entryParts) {
String entry = String.join("", entryParts);
String[] expParts = entry.split("=");
String[] expSpecifiers = expParts[0].split(":");
String expType = expSpecifiers[0];
String expName = expSpecifiers[1];
switch (expType) {
}
}
private static boolean isCommentMarker(String token) {
switch (token) {
case "#":
case "//":
return true;
default:
return false;
}
}
}
|