blob: 674799c0289b2311f9b782fa5e56b124f71e3499 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2022 The University of York.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Ionut Predoaia - initial API and implementation
******************************************************************************/
package org.eclipse.epsilon.emc.yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Map.Entry;
import java.util.Set;
import java.util.List;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
public class YamlNodeUtility {
public static Collection<Entry> getNodes(Object yamlContent, YamlProperty yamlProperty, boolean areAllNodes) {
Collection<Entry> nodes = new ArrayList<>();
setNodes(yamlContent, nodes, yamlProperty, areAllNodes);
return nodes;
}
private static void setNodes(Object yamlContent, Collection<Entry> nodes, YamlProperty yamlProperty, boolean areAllNodes) {
if (yamlContent instanceof List) {
setNodes((List)yamlContent, nodes, yamlProperty, areAllNodes);
}
else if (yamlContent instanceof Map) {
setNodes((Map)yamlContent, nodes, yamlProperty, areAllNodes);
}
}
private static void setNodes(List listNode, Collection<Entry> nodes, YamlProperty yamlProperty, boolean areAllNodes) {
for (Object node: listNode) {
if (node instanceof Map) {
setNodes((Map) node, nodes, yamlProperty, areAllNodes);
}
}
}
private static void setNodes(Map mappingNode, Collection<Entry> nodes, YamlProperty yamlProperty, boolean areAllNodes) {
Set<Entry> entries = (Set<Entry>) mappingNode.entrySet();
for (Entry entry: entries) {
setNodes(entry, nodes, yamlProperty, areAllNodes);
}
}
private static void setNodes(Entry entry, Collection<Entry> nodes, YamlProperty yamlProperty, boolean areAllNodes) {
Object entryValue = entry.getValue();
if (entryValue instanceof List) {
if (yamlProperty.isListNode()) {
addNodeIfNecessary(entry, yamlProperty, nodes);
}
if (areAllNodes) {
setNodes((List) entryValue, nodes, yamlProperty, areAllNodes);
}
}
else if (entryValue instanceof Map) {
if (yamlProperty.isMappingNode()) {
addNodeIfNecessary(entry, yamlProperty, nodes);
}
if (areAllNodes) {
setNodes((Map) entryValue, nodes, yamlProperty, areAllNodes);
}
}
else {
if (yamlProperty.isScalarNode()) {
addNodeIfNecessary(entry, yamlProperty, nodes);
}
}
}
private static void addNodeIfNecessary(Entry entry, YamlProperty yamlProperty, Collection<Entry> nodes) {
String property = yamlProperty.getProperty();
if (property == null) {
nodes.add(entry);
}
else {
if (entry.getKey().equals(property)) {
nodes.add(entry);
}
}
}
public static Object getQueryResult(Collection<Entry> queryResult, YamlProperty yamlProperty) {
if (queryResult == null || queryResult.isEmpty()) {
return null;
}
else {
return yamlProperty.isMany() ? queryResult : queryResult.iterator().next();
}
}
public static boolean isListNode(List list) {
for (Object object : list) {
if (!(object instanceof LinkedHashMap))
return false;
}
return true;
}
public static YamlNodeType getNodeType(String type) {
YamlNodeType nodeType;
try {
nodeType = YamlNodeType.valueOf(type);
}
catch(Exception ex) {
nodeType = null;
}
return nodeType;
}
public static YamlNodeType getNodeType(Entry node) {
Object nodeValue = node.getValue();
YamlNodeType nodeType = null;
if (nodeValue instanceof Map) {
nodeType = YamlNodeType.MappingNode;
}
else if (nodeValue instanceof List) {
nodeType = YamlNodeType.ListNode;
}
else {
nodeType = YamlNodeType.ScalarNode;
}
return nodeType;
}
private static Entry getNode(YamlProperty yamlProperty, Collection<Object> parameters) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
switch(yamlProperty.getType()) {
case ScalarNode:
return getScalarNode(yamlProperty, new ArrayList(parameters));
case MappingNode:
return getMappingNode(yamlProperty, new ArrayList(parameters));
case ListNode:
return getListNode(yamlProperty, new ArrayList(parameters));
}
return map.entrySet().iterator().next();
}
public static Entry getNode(String type, int indexOfSeparator, Collection<Object> parameters) {
YamlProperty yamlProperty = YamlProperty.parse(type, indexOfSeparator);
return YamlNodeUtility.getNode(yamlProperty, parameters);
}
private static Entry getScalarNode(YamlProperty yamlProperty, List parameters) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
String nodeName = getNameParameter(yamlProperty, parameters, YamlNodeType.ScalarNode);
Object nodeValue = getValueParameter(yamlProperty, parameters);
map.put(nodeName, nodeValue);
return map.entrySet().iterator().next();
}
private static Entry getListNode(YamlProperty yamlProperty, List parameters) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
String nodeName = getNameParameter(yamlProperty, parameters, YamlNodeType.ListNode);
Object valueParameter = getValueParameter(yamlProperty, parameters);
int listSize = (int) YamlTypeConverter.cast(valueParameter.toString(), YamlDataType.INTEGER);
List list = new ArrayList<>();
for(int i=0; i < listSize; i++) {
list.add(new LinkedHashMap());
}
map.put(nodeName, list);
return map.entrySet().iterator().next();
}
private static Entry getMappingNode(YamlProperty yamlProperty, List parameters) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
String nodeName = getNameParameter(yamlProperty, parameters, YamlNodeType.MappingNode);
map.put(nodeName, new LinkedHashMap<String, Object>());
return map.entrySet().iterator().next();
}
private static String getNameParameter(YamlProperty yamlProperty, List parameters, YamlNodeType yamlNodeType) {
String nodeName;
if(yamlProperty.getProperty() != null) {
nodeName = yamlProperty.getProperty();
}
else if(parameters.size() > 0) {
nodeName = parameters.get(0).toString();
}
else {
nodeName = yamlNodeType.toString();
}
return nodeName;
}
private static Object getValueParameter(YamlProperty yamlProperty, List parameters) {
int indexOfValueParameter = (yamlProperty.getProperty() != null) ? 0 : 1;
Object nodeValue = (parameters.size() > indexOfValueParameter) ? parameters.get(indexOfValueParameter) : "";
return nodeValue;
}
public static boolean deleteNode(Object yamlContent, List<Entry> createdNodes, Entry instance) {
boolean isCreatedNode = createdNodes.contains(instance);
if (isCreatedNode) {
createdNodes.remove(instance);
return true;
}
else {
YamlObject yamlObject = new YamlObject(instance);
findYamlObject(yamlContent, yamlObject);
if(yamlObject.isFound()) {
yamlObject.getParentNode().remove(instance.getKey());
return true;
}
else {
return false;
}
}
}
public static boolean ownsYamlObject(Object yamlContent, List<Entry> createdNodes, Object instance) {
boolean isOwnYamlObject = ownsYamlObject(yamlContent, instance);
boolean isCreated = (!isOwnYamlObject) ? isCreatedYamlObject(createdNodes, new YamlObject(instance)) : false;
return isOwnYamlObject || isCreated;
}
private static boolean ownsYamlObject(Object yamlContent, Object instance) {
if (instance instanceof List) {
return ownsYamlObjects(yamlContent, (List)instance);
}
else {
YamlObject yamlObject = null;
if (instance instanceof YamlModel) {
yamlObject = new YamlObject(((YamlModel)instance).getYamlContent());
}
else if (instance instanceof Entry) {
Entry entry = (Entry) instance;
yamlObject = (YamlProperty.PROPERTY_ROOT.equals(entry.getKey())) ? new YamlObject(entry.getValue()) : new YamlObject(instance);
}
else {
yamlObject = new YamlObject(instance);
}
return ownsYamlObject(yamlContent, yamlObject);
}
}
private static boolean ownsYamlObjects(Object yamlContent, List yamlObjects) {
for (Object yamlObject : yamlObjects) {
boolean isOwnYamlObject = (yamlObject instanceof List) ? ownsYamlObjects(yamlContent, (List)yamlObject) : ownsYamlObject(yamlContent, new YamlObject(yamlObject));
if (!isOwnYamlObject) {
return false;
}
}
return true;
}
private static boolean ownsYamlObject(Object yamlContent, YamlObject yamlObject) {
findYamlObject(yamlContent, yamlObject);
return yamlObject.isFound();
}
private static void findYamlObject(Object yamlContent, YamlObject yamlObject) {
if (Objects.equals(yamlContent, yamlObject.getValue())) {
yamlObject.setIsFound(true);
}
else {
if (yamlContent instanceof List) {
findYamlObject((List)yamlContent, yamlObject);
}
else if (yamlContent instanceof Map) {
findYamlObject((Map)yamlContent, yamlObject);
}
}
}
private static void findYamlObject(List listNode, YamlObject yamlObject) {
for (Object node: listNode) {
if (!yamlObject.isFound()) {
findYamlObject(node, yamlObject);
}
else {
break;
}
}
}
private static void findYamlObject(Map mappingNode, YamlObject yamlObject) {
Set<Entry> entries = (Set<Entry>) mappingNode.entrySet();
for (Entry entry: entries) {
if (!yamlObject.isFound()) {
if (entry.equals(yamlObject.getValue())) {
yamlObject.setParentNode(mappingNode);
}
else {
findYamlObject(entry.getValue(), yamlObject);
}
}
else {
break;
}
}
}
private static boolean isCreatedYamlObject(List<Entry> createdNodes, YamlObject yamlObject) {
for (Entry createdNode : createdNodes) {
if (createdNode.equals(yamlObject.getValue())) {
return true;
}
else {
boolean isCreatedYamlObject = ownsYamlObject(createdNode.getValue(), yamlObject);
if (isCreatedYamlObject) {
return true;
}
}
}
return false;
}
public static String getPrefixOfType(YamlNodeType yamlNodeType) {
String prefix;
switch(yamlNodeType) {
case ScalarNode:
prefix = String.valueOf(YamlProperty.PROPERTY_SCALAR);
break;
case MappingNode:
prefix = String.valueOf(YamlProperty.PROPERTY_MAPPING);
break;
case ListNode:
prefix = String.valueOf(YamlProperty.PROPERTY_LIST);
break;
default:
prefix = null;
}
return prefix + YamlProperty.PROPERTY_SEPARATOR;
}
public static String getTypeNameOf(Entry node) {
YamlNodeType yamlNodeType = getNodeType(node);
return getPrefixOfType(yamlNodeType);
}
public static Object getYamlContent(File file) throws FileNotFoundException, IOException {
Object yamlContent = null;
Yaml yaml = new Yaml();
try(InputStream inputStream = new FileInputStream(file)) {
yamlContent = yaml.load(inputStream);
}
return yamlContent;
}
public static Object getYamlContent(String yamlContent) {
Yaml yaml = new Yaml();
return yaml.load(yamlContent);
}
public static void storeYamlContent(File file, Object yamlContent) throws IOException {
try(FileWriter writer = new FileWriter(file)) {
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setPrettyFlow(true);
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions);
yaml.dump(yamlContent, writer);
}
}
public static Entry getRootNode(Object yamlContent) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put(YamlProperty.PROPERTY_ROOT, yamlContent);
return map.entrySet().iterator().next();
}
}