All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.epsilon.emc.yaml.YamlNodeUtility Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * 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 getNodes(Object yamlContent, YamlProperty yamlProperty, boolean areAllNodes) {
		Collection nodes = new ArrayList<>();
		setNodes(yamlContent, nodes, yamlProperty, areAllNodes);
		return nodes;
	}
	
	private static void setNodes(Object yamlContent, Collection 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 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 nodes, YamlProperty yamlProperty, boolean areAllNodes) {	
		Set entries = (Set) mappingNode.entrySet();	
		for (Entry entry: entries) {
			setNodes(entry, nodes, yamlProperty, areAllNodes);	
		}			
	}
	
	private static void setNodes(Entry entry, Collection 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 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 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 parameters) {
		Map map = new LinkedHashMap();
		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 parameters) {
		YamlProperty yamlProperty = YamlProperty.parse(type, indexOfSeparator);
		return YamlNodeUtility.getNode(yamlProperty, parameters);		
	}
	
	private static Entry getScalarNode(YamlProperty yamlProperty, List parameters) {
		Map map = new LinkedHashMap();
		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 map = new LinkedHashMap();
		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 map = new LinkedHashMap();
		String nodeName = getNameParameter(yamlProperty, parameters, YamlNodeType.MappingNode);
		map.put(nodeName, new LinkedHashMap());
		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 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 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 entries = (Set) 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 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 map = new LinkedHashMap();
		map.put(YamlProperty.PROPERTY_ROOT, yamlContent);
		return map.entrySet().iterator().next();	
	}
}