package tc.oc.pgm.regions;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import org.jdom2.Element;
import tc.oc.api.docs.SemanticVersion;
import tc.oc.commons.core.util.Streams;
import tc.oc.pgm.features.LegacyFeatureParser;
import tc.oc.pgm.map.MapModule;
import tc.oc.pgm.map.MapProto;
import tc.oc.pgm.map.MapRootParser;
import tc.oc.pgm.map.ProtoVersions;
import tc.oc.pgm.xml.InvalidXMLException;
import tc.oc.pgm.xml.Node;
import static tc.oc.commons.core.exception.LambdaExceptionUtils.rethrowFunction;
public class RegionParser extends LegacyFeatureParser<Region> implements MapModule, MapRootParser {
@Inject protected @MapProto SemanticVersion proto;
@Override
public void parse() throws InvalidXMLException {
defineBuiltInRegions();
}
protected void defineBuiltInRegions() throws InvalidXMLException {
if(!legacy) {
features.define("everywhere", new EverywhereRegion());
features.define("nowhere", new EmptyRegion());
}
}
@Override
protected boolean canIgnore(Element el) throws InvalidXMLException {
return "apply".equals(el.getName()) || super.canIgnore(el);
}
public List<Region> parseReferenceAndChildren(Element el) throws InvalidXMLException {
return Stream.concat(Streams.compact(Node.tryAttr(el, propertyName())
.map(rethrowFunction(this::parseReference))),
parseChildren(el))
.collect(Collectors.toList());
}
public Region parseReferenceAndChildUnion(Element el) throws InvalidXMLException {
return Union.of(parseReferenceAndChildren(el));
}
@Override
public RegionPropertyBuilder property(Element element) {
return new RegionPropertyBuilder(element, propertyName());
}
@Override
public RegionPropertyBuilder property(Element element, String name) {
return new RegionPropertyBuilder(element, name);
}
public class RegionPropertyBuilder extends PropertyBuilder<RegionPropertyBuilder> {
private boolean legacy;
public RegionPropertyBuilder(Element element, String name) {
super(element, name);
}
public RegionPropertyBuilder legacy() {
legacy = true;
return this;
}
@Override
protected Optional<List<Region>> parseParent() throws InvalidXMLException {
// Legacy syntax for several modules with regions directly under the parent element
if(legacy && proto.isOlderThan(ProtoVersions.MODULE_SUBELEMENT_VERSION)) {
return Optional.of(parseReferenceAndChildren(element));
} else {
return super.parseParent();
}
}
public Region union() throws InvalidXMLException {
return Union.of(multi());
}
public Optional<Region> optionalUnion() throws InvalidXMLException {
return optionalMulti().map(Union::of);
}
public Region optionalUnion(Region def) throws InvalidXMLException {
return optionalUnion().orElse(def);
}
}
}