org.raml.parser.visitor.YamlDocumentValidator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of raml-parser Show documentation
Show all versions of raml-parser Show documentation
Java implementation of the raml parser taken from https://github.com/raml-org/raml-java-parser and adjusted
/*
* Copyright 2013 (c) MuleSoft, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package org.raml.parser.visitor;
import static org.raml.parser.rule.ValidationMessage.NON_SCALAR_KEY_MESSAGE;
import static org.raml.parser.rule.ValidationResult.createErrorResult;
import static org.raml.parser.visitor.TupleType.KEY;
import static org.raml.parser.visitor.TupleType.VALUE;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import org.raml.parser.rule.DefaultTupleRule;
import org.raml.parser.rule.NodeRule;
import org.raml.parser.rule.NodeRuleFactory;
import org.raml.parser.rule.SequenceRule;
import org.raml.parser.rule.TupleRule;
import org.raml.parser.rule.ValidationResult;
import org.raml.parser.tagresolver.ContextPath;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.SequenceNode;
import org.yaml.snakeyaml.nodes.Tag;
public class YamlDocumentValidator implements YamlValidator
{
private Class> documentClass;
private Stack> ruleContext = new Stack>();
private List messages = new ArrayList();
private NodeRuleFactory nodeRuleFactory;
private ContextPath contextPath;
protected YamlDocumentValidator(Class> documentClass)
{
this(documentClass, new NodeRuleFactory());
}
protected YamlDocumentValidator(Class> documentClass, NodeRuleFactory nodeRuleFactory)
{
this.documentClass = documentClass;
this.nodeRuleFactory = nodeRuleFactory;
}
protected Stack> getRuleContext()
{
return ruleContext;
}
@Override
public boolean onMappingNodeStart(MappingNode node, TupleType tupleType)
{
if (tupleType == KEY)
{
addMessage(createErrorResult(NON_SCALAR_KEY_MESSAGE, node));
}
return true;
}
@Override
public void onMappingNodeEnd(MappingNode node, TupleType tupleType)
{
}
@Override
@SuppressWarnings("unchecked")
public boolean onSequenceStart(SequenceNode node, TupleType tupleType)
{
if (tupleType == KEY)
{
addMessage(createErrorResult(NON_SCALAR_KEY_MESSAGE, node));
}
else
{
NodeRule peek = (NodeRule) ruleContext.peek();
addMessages(peek.validateValue(node));
}
return true;
}
@Override
public void onSequenceEnd(SequenceNode node, TupleType tupleType)
{
}
@Override
@SuppressWarnings("unchecked")
public void onScalar(ScalarNode node, TupleType tupleType)
{
List result;
NodeRule> peek = ruleContext.peek();
if (tupleType == VALUE)
{
result = ((NodeRule) peek).validateValue(node);
}
else
{
result = ((TupleRule) peek).validateKey(node);
}
addMessages(result);
}
private void addMessages(List result)
{
for (ValidationResult validationResult : result)
{
validationResult.setIncludeContext(contextPath);
messages.add(validationResult);
}
}
private void addMessage(ValidationResult errorResult)
{
addMessages(Collections.singletonList(errorResult));
}
@Override
public boolean onDocumentStart(MappingNode node)
{
ruleContext.push(buildDocumentRule());
return true;
}
@Override
public void onDocumentEnd(MappingNode node)
{
NodeRule> pop = ruleContext.pop();
List onRuleEnd = pop.onRuleEnd();
addMessages(onRuleEnd);
}
@Override
public void onTupleEnd(NodeTuple nodeTuple)
{
NodeRule> rule = ruleContext.pop();
if (rule != null)
{
List onRuleEnd = rule.onRuleEnd();
addMessages(onRuleEnd);
}
else
{
throw new IllegalStateException("Unexpected ruleContext state");
}
}
@Override
public boolean onTupleStart(NodeTuple nodeTuple)
{
TupleRule, ?> tupleRule = (TupleRule, ?>) ruleContext.peek();
if (tupleRule != null)
{
TupleRule, ?> rule = tupleRule.getRuleForTuple(nodeTuple);
ruleContext.push(rule);
}
else
{
throw new IllegalStateException("Unexpected ruleContext state");
}
return true;
}
@Override
public void onSequenceElementStart(Node sequenceNode)
{
NodeRule peek = ruleContext.peek();
if (!(peek instanceof SequenceRule))
{
ruleContext.push(peek);
}
else
{
ruleContext.push(((SequenceRule) peek).getItemRule());
}
}
@Override
public void onSequenceElementEnd(Node sequenceNode)
{
NodeRule> rule = ruleContext.pop();
List validationResults = rule.onRuleEnd();
addMessages(validationResults);
}
@Override
public void onCustomTagStart(Tag tag, Node originalValueNode, Node node)
{
}
@Override
public void onCustomTagEnd(Tag tag, Node originalValueNode, Node node)
{
}
@Override
public void onCustomTagError(Tag tag, Node node, String message)
{
addMessages(Arrays.asList(createErrorResult(message, node.getStartMark(), node.getEndMark())));
}
private DefaultTupleRule buildDocumentRule()
{
return nodeRuleFactory.createDocumentRule(documentClass);
}
@Override
public List getMessages()
{
return messages;
}
@Override
public void setContextPath(ContextPath contextPath)
{
this.contextPath = contextPath;
}
@Override
public ContextPath getContextPath()
{
return contextPath;
}
}