in juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/ConfigMap.java [76:200]
private ConfigMap load(String contents) throws IOException {
if (contents == null)
contents = "";
this.contents = contents;
entries.clear();
oentries.clear();
imports.forEach(Import::unregisterAll);
imports.clear();
Map<String,ConfigMap> imports = map();
List<String> lines = linkedList();
try (Scanner scanner = new Scanner(contents)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
char c = firstChar(line);
int c2 = StringUtils.lastNonWhitespaceChar(line);
if (c == '[') {
String l = line.trim();
if (c2 != ']' || ! isValidNewSectionName(l.substring(1, l.length()-1)))
throw new ConfigException("Invalid section name found in configuration: {0}", line);
} else if (c == '<') {
String l = line.trim();
int i = l.indexOf('>');
if (i != -1) {
String l2 = l.substring(1, i);
if (! isValidConfigName(l2))
throw new ConfigException("Invalid import config name found in configuration: {0}", line);
String l3 = l.substring(i+1);
if (! (isEmpty(l3) || firstChar(l3) == '#'))
throw new ConfigException("Invalid import config name found in configuration: {0}", line);
String importName = l2.trim();
try {
if (! imports.containsKey(importName))
imports.put(importName, store.getMap(importName));
} catch (StackOverflowError e) {
throw new IOException("Import loop detected in configuration '"+name+"'->'"+importName+"'");
}
}
}
lines.add(line);
}
}
List<Import> irl = list(imports.size());
forEachReverse(listFrom(imports.values()), x -> irl.add(new Import(x).register(listeners)));
this.imports.addAll(irl);
// Add [blank] section.
boolean inserted = false;
boolean foundComment = false;
for (ListIterator<String> li = lines.listIterator(); li.hasNext();) {
String l = li.next();
char c = firstNonWhitespaceChar(l);
if (c != '#') {
if (c == 0 && foundComment) {
li.set("[]");
inserted = true;
}
break;
}
foundComment = true;
}
if (! inserted)
lines.add(0, "[]");
// Collapse any multi-lines.
ListIterator<String> li = lines.listIterator(lines.size());
String accumulator = null;
while (li.hasPrevious()) {
String l = li.previous();
char c = firstChar(l);
if (c == '\t') {
c = firstNonWhitespaceChar(l);
if (c != '#') {
if (accumulator == null)
accumulator = l.substring(1);
else
accumulator = l.substring(1) + "\n" + accumulator;
li.remove();
}
} else if (accumulator != null) {
li.set(l + "\n" + accumulator);
accumulator = null;
}
}
lines = copyOf(lines);
int last = lines.size()-1;
int S1 = 1; // Looking for section.
int S2 = 2; // Found section, looking for start.
int state = S1;
List<ConfigSection> sections = list();
for (int i = last; i >= 0; i--) {
String l = lines.get(i);
char c = firstChar(l);
if (state == S1) {
if (c == '[') {
state = S2;
}
} else {
if (c != '#' && (c == '[' || l.indexOf('=') != -1)) {
sections.add(new ConfigSection(lines.subList(i+1, last+1)));
last = i + 1;// (c == '[' ? i+1 : i);
state = (c == '[' ? S2 : S1);
}
}
}
sections.add(new ConfigSection(lines.subList(0, last+1)));
for (int i = sections.size() - 1; i >= 0; i--) {
ConfigSection cs = sections.get(i);
if (entries.containsKey(cs.name))
throw new ConfigException("Duplicate section found in configuration: [{0}]", cs.name);
entries.put(cs.name, cs);
}
oentries.putAll(entries);
return this;
}