/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.cf.manifest.v2.utils;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import org.eclipse.orion.server.cf.manifest.v2.ManifestParseTree;
import org.eclipse.orion.server.cf.manifest.v2.Parser;
import org.eclipse.orion.server.cf.manifest.v2.ParserException;
import org.eclipse.osgi.util.NLS;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.error.MarkedYAMLException;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.SequenceNode;
public class ManifestParser implements Parser {
@Override
public ManifestParseTree parse(InputStream inputStream) throws ParserException {
Node snakeRootNode;
try {
snakeRootNode = new Yaml().compose(new InputStreamReader(inputStream));
} catch (MarkedYAMLException e) {
throw new ParserException(e.getMessage(), e.getProblemMark().getLine() + 1);
}
ManifestParseTree root = new ManifestParseTree();
addChild(snakeRootNode, root);
return root;
}
private void addChild(NodeTuple tuple, ManifestParseTree parent) throws ParserException {
ManifestParseTree keyNode = new ManifestParseTree();
Node tupleKeyNode = tuple.getKeyNode();
int lineNumber = tupleKeyNode.getStartMark().getLine() + 1;
if (tupleKeyNode.getNodeId() != NodeId.scalar) {
throw new ParserException(NLS.bind(ManifestConstants.UNSUPPORTED_TOKEN_ERROR, lineNumber), lineNumber);
}
keyNode.setLabel(((ScalarNode) tupleKeyNode).getValue());
keyNode.setLineNumber(lineNumber);
keyNode.setParent(parent);
parent.getChildren().add(keyNode);
addChild(tuple.getValueNode(), keyNode);
}
private void addChild(Node snakeNode, ManifestParseTree parent) throws ParserException {
switch (snakeNode.getNodeId()) {
case sequence:
List<Node> children = ((SequenceNode) snakeNode).getValue();
for (Node child : children) {
ManifestParseTree itemNode = new ManifestParseTree();
itemNode.setItemNode(true);
itemNode.setLabel("-");
itemNode.setLineNumber(child.getStartMark().getLine() + 1);
itemNode.setParent(parent);
parent.getChildren().add(itemNode);
addChild(child, itemNode);
}
break;
case mapping:
List<NodeTuple> toupleChildren = ((MappingNode) snakeNode).getValue();
for (NodeTuple child : toupleChildren) {
addChild(child, parent);
}
break;
case scalar:
ManifestParseTree newNode = new ManifestParseTree();
newNode.setLabel(((ScalarNode) snakeNode).getValue());
newNode.setLineNumber(snakeNode.getStartMark().getLine() + 1);
newNode.setParent(parent);
parent.getChildren().add(newNode);
break;
default:
break;
}
}
}