package alien4cloud.tosca.parser.impl.advanced;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import alien4cloud.tosca.parser.impl.base.BaseParserFactory;
import org.elasticsearch.common.collect.Maps;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.alien4cloud.tosca.model.types.NodeType;
import org.alien4cloud.tosca.model.templates.SubstitutionMapping;
import org.alien4cloud.tosca.model.templates.SubstitutionTarget;
import org.alien4cloud.tosca.model.templates.Topology;
import alien4cloud.tosca.parser.INodeParser;
import alien4cloud.tosca.parser.ParsingContextExecution;
import alien4cloud.tosca.parser.ParsingError;
import alien4cloud.tosca.parser.impl.ErrorCode;
import alien4cloud.tosca.parser.impl.base.ListParser;
import alien4cloud.tosca.parser.impl.base.ScalarParser;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class SustitutionMappingParser implements INodeParser<SubstitutionMapping> {
private static final String NODE_TYPE = "node_type";
private static final String CAPABILITIES = "capabilities";
private static final String REQUIREMENTS = "requirements";
@Resource
private BaseParserFactory baseParserFactory;
@Resource
private ScalarParser scalarParser;
private ListParser<String> stringListParser;
@PostConstruct
public void init() {
stringListParser = baseParserFactory.getListParser(scalarParser, "string");
}
@Override
public SubstitutionMapping parse(Node node, ParsingContextExecution context) {
Topology topology = (Topology) context.getParent();
if (!(node instanceof MappingNode)) {
// we expect a MappingNode
context.getParsingErrors().add(new ParsingError(ErrorCode.YAML_MAPPING_NODE_EXPECTED, null, node.getStartMark(), null, node.getEndMark(), null));
return null;
}
SubstitutionMapping result = new SubstitutionMapping();
MappingNode mappingNode = ((MappingNode) node);
List<NodeTuple> nodeTuples = mappingNode.getValue();
for (NodeTuple nodeTuple : nodeTuples) {
String key = scalarParser.parse(nodeTuple.getKeyNode(), context);
Node valueNode = nodeTuple.getValueNode();
switch (key) {
case NODE_TYPE:
String nodeTypeName = scalarParser.parse(valueNode, context);
NodeType nodeType = new NodeType();
nodeType.setElementId(nodeTypeName);
result.setSubstitutionType(nodeType);
break;
case CAPABILITIES:
result.setCapabilities(parseSubstitutionTargets(valueNode, context));
break;
case REQUIREMENTS:
result.setRequirements(parseSubstitutionTargets(valueNode, context));
break;
default:
// FIXME add a warning
}
}
return result;
}
private Map<String, SubstitutionTarget> parseSubstitutionTargets(Node valueNode, ParsingContextExecution context) {
if (!(valueNode instanceof MappingNode)) {
// we expect a MappingNode
context.getParsingErrors()
.add(new ParsingError(ErrorCode.YAML_MAPPING_NODE_EXPECTED, null, valueNode.getStartMark(), null, valueNode.getEndMark(), null));
return null;
}
Map<String, SubstitutionTarget> result = Maps.newHashMap();
MappingNode mappingNode = ((MappingNode) valueNode);
List<NodeTuple> nodeTuples = mappingNode.getValue();
for (NodeTuple nodeTuple : nodeTuples) {
String key = scalarParser.parse(nodeTuple.getKeyNode(), context);
SubstitutionTarget target = parseSubstitutionTarget(nodeTuple.getValueNode(), context);
if (target != null) {
result.put(key, target);
}
}
return result;
}
private SubstitutionTarget parseSubstitutionTarget(Node valueNode, ParsingContextExecution context) {
List<String> values = (List<String>) stringListParser.parse(valueNode, context);
if (values.size() != 2) {
// FIXME: throw ex
return null;
}
return new SubstitutionTarget(values.get(0), values.get(1));
}
}