/*
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
*
* Copyright 2011-2014 Peter Güttinger
*
*/
package ch.njol.skript.config.validate;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map.Entry;
import ch.njol.skript.Skript;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.config.EntryNode;
import ch.njol.skript.config.Node;
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.log.SkriptLogger;
import ch.njol.util.Setter;
/**
* @author Peter Güttinger
*/
public class SectionValidator implements NodeValidator {
private final static class NodeInfo {
public NodeValidator v;
public boolean optional;
public NodeInfo(final NodeValidator v, final boolean optional) {
this.v = v;
this.optional = optional;
}
}
private final HashMap<String, NodeInfo> nodes = new HashMap<String, NodeInfo>();
private boolean allowUndefinedSections = false;
private boolean allowUndefinedEntries = false;
public SectionValidator() {}
public SectionValidator addNode(final String name, final NodeValidator v, final boolean optional) {
assert name != null;
assert v != null;
nodes.put(name.toLowerCase(Locale.ENGLISH), new NodeInfo(v, optional));
return this;
}
public SectionValidator addEntry(final String name, final boolean optional) {
addNode(name, new EntryValidator(), optional);
return this;
}
public SectionValidator addEntry(final String name, final Setter<String> setter, final boolean optional) {
addNode(name, new EntryValidator(setter), optional);
return this;
}
public <T> SectionValidator addEntry(final String name, final Parser<? extends T> parser, final Setter<T> setter, final boolean optional) {
addNode(name, new ParsedEntryValidator<T>(parser, setter), optional);
return this;
}
public SectionValidator addSection(final String name, final boolean optional) {
addNode(name, new SectionValidator().setAllowUndefinedEntries(true).setAllowUndefinedSections(true), optional);
return this;
}
@Override
public boolean validate(final Node node) {
if (!(node instanceof SectionNode)) {
notASectionError(node);
return false;
}
boolean ok = true;
for (final Entry<String, NodeInfo> e : nodes.entrySet()) {
final Node n = ((SectionNode) node).get(e.getKey());
if (n == null && !e.getValue().optional) {
Skript.error("Required entry '" + e.getKey() + "' is missing in " + (node.getParent() == null ? node.getConfig().getFileName() : "'" + node.getKey() + "' (" + node.getConfig().getFileName() + ", starting at line " + node.getLine() + ")"));
ok = false;
} else if (n != null) {
ok &= e.getValue().v.validate(n);
}
}
SkriptLogger.setNode(null);
if (allowUndefinedSections && allowUndefinedEntries)
return ok;
for (final Node n : (SectionNode) node) {
final String key = n.getKey();
assert key != null;
if (!nodes.containsKey(key.toLowerCase(Locale.ENGLISH))) {
if (n instanceof SectionNode && allowUndefinedSections || n instanceof EntryNode && allowUndefinedEntries)
continue;
SkriptLogger.setNode(n);
Skript.error("Unexpected entry '" + n.getKey() + "'. Check whether it's spelled correctly or remove it.");
ok = false;
}
}
SkriptLogger.setNode(null);
return ok;
}
public final static void notASectionError(final Node node) {
SkriptLogger.setNode(node);
Skript.error("'" + node.getKey() + "' is not a section (like 'name:', followed by one or more indented lines)");
}
public SectionValidator setAllowUndefinedSections(final boolean b) {
allowUndefinedSections = b;
return this;
}
public SectionValidator setAllowUndefinedEntries(final boolean b) {
allowUndefinedEntries = b;
return this;
}
}