/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2016 Open Source Geospatial Foundation (OSGeo)
* (C) 2014-2016 Boundless Spatial
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*/
package org.geotools.ysld.validate;
import org.geotools.ysld.parse.ZoomContextFinder;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.error.MarkedYAMLException;
import org.yaml.snakeyaml.events.AliasEvent;
import org.yaml.snakeyaml.events.Event;
import org.yaml.snakeyaml.events.MappingEndEvent;
import org.yaml.snakeyaml.events.MappingStartEvent;
import org.yaml.snakeyaml.events.ScalarEvent;
import org.yaml.snakeyaml.events.SequenceEndEvent;
import org.yaml.snakeyaml.events.SequenceStartEvent;
import java.io.IOException;
import java.io.Reader;
import java.util.Collections;
import java.util.EmptyStackException;
import java.util.List;
/**
* Validates a YSLD style
*/
public class YsldValidator {
List<ZoomContextFinder> zCtxtFinders = Collections.emptyList();
/**
* Validate the passed style
* @param input Reader for the style
* @return List of {@link MarkedYAMLException} representing any errors, or an empty list if the style is valid
* @throws IOException
*/
public List<MarkedYAMLException> validate(Reader input) throws IOException {
YsldValidateContext context = new YsldValidateContext();
context.zCtxtFinders = this.zCtxtFinders;
context.push(new RootValidator());
try {
Yaml yaml = new Yaml();
for (Event evt : yaml.parse(input)) {
YsldValidateHandler h = context.peek();
if (evt instanceof MappingStartEvent) {
h.mapping((MappingStartEvent) evt, context);
} else if (evt instanceof MappingEndEvent) {
h.endMapping((MappingEndEvent) evt, context);
} else if (evt instanceof SequenceStartEvent) {
h.sequence((SequenceStartEvent) evt, context);
} else if (evt instanceof SequenceEndEvent) {
h.endSequence((SequenceEndEvent) evt, context);
} else if (evt instanceof ScalarEvent) {
h.scalar((ScalarEvent) evt, context);
} else if (evt instanceof AliasEvent) {
h.alias((AliasEvent) evt, context);
}
}
;
} catch (MarkedYAMLException e) {
context.error(e);
} catch (EmptyStackException e) {
// The ECQLParser uses java.util.Stack for parsing. If we get an exception from here,
// we can narrow the cause down to CQL.
throw new RuntimeException("Error parsing CQL expression", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
return context.errors();
}
public void setZCtxtFinders(List<ZoomContextFinder> zCtxtFinders) {
if (zCtxtFinders == null)
throw new NullPointerException("zCtxtFinders can not be null");
this.zCtxtFinders = zCtxtFinders;
}
}