blob: 9cf1630ae711c571cc13be7b3b38d5e6ce3f9fe5 [file] [log] [blame]
package org.apache.airavata.k8s.api.server.service.util;
import org.apache.airavata.k8s.api.resources.task.TaskInputResource;
import org.apache.airavata.k8s.api.resources.task.TaskOutPortResource;
import org.apache.airavata.k8s.api.resources.task.TaskOutputResource;
import org.apache.airavata.k8s.api.resources.task.TaskResource;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
/**
* TODO: Class level comments please
*
* @author dimuthu
* @since 1.0.0-SNAPSHOT
*/
public class GraphParser {
public static ParseResult parse(String content) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new InputSource(new StringReader(content)));
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("root");
Node rootNode = nList.item(0);
NodeList elementNodeList = rootNode.getChildNodes();
ParseResult result = new ParseResult();
for (int temp = 0; temp < elementNodeList.getLength(); temp++) {
Node nNode = elementNodeList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if ("ProcessingElement".equals(eElement.getTagName())) {
TaskResource taskResource = new TaskResource();
NamedNodeMap attributes = eElement.getAttributes();
int id = -1;
for (int i = 0; i < attributes.getLength(); i++) {
Node attr = attributes.item(i);
if ("name".equals(attr.getNodeName())) {
taskResource.setName(attr.getNodeValue());
} else if ("Type".equals(attr.getNodeName())) {
taskResource.setTaskTypeId(Long.parseLong(attr.getNodeValue()));
} else if (attr.getNodeName().startsWith("in-") || attr.getNodeName().startsWith("out-")) {
} else if ("id".equals(attr.getNodeName())) {
id = Integer.parseInt(attr.getNodeValue());
} else if (attr.getNodeName().startsWith("output-")) {
TaskOutputResource outputResource = new TaskOutputResource();
outputResource.setName(attr.getNodeName().substring(7));
outputResource.setValue(attr.getNodeValue());
} else {
TaskInputResource inputResource = new TaskInputResource();
inputResource.setName(attr.getNodeName());
inputResource.setValue(attr.getNodeValue());
taskResource.getInputs().add(inputResource);
}
}
Task task = new Task();
task.id = id;
task.taskResource = taskResource;
result.tasks.put(id, task);
} else if ("Operation".equals(eElement.getTagName())) {
NamedNodeMap attributes = eElement.getAttributes();
int id = -1;
String name = null;
for (int i = 0; i < attributes.getLength(); i++) {
Node attr = attributes.item(i);
if ("name".equals(attr.getNodeName())) {
name = attr.getNodeValue();
} else if ("id".equals(attr.getNodeName())) {
id = Integer.parseInt(attr.getNodeValue());
}
}
Operation operation = new Operation();
operation.id = id;
operation.name = name;
result.operations.put(id, operation);
} else if ("InPort".equals(eElement.getTagName())) {
int id = Integer.parseInt(eElement.getAttribute("id"));
String name = eElement.getAttribute("name");
Element mxCell = null;
NodeList childNodes = eElement.getChildNodes();
for (int i = 0 ; i < childNodes.getLength(); i++) {
Node tempInPort = childNodes.item(i);
if (tempInPort.getNodeType() == Node.ELEMENT_NODE) {
Element tmpInElement = (Element) tempInPort;
if ("mxCell".equals(tmpInElement.getTagName())) {
mxCell = tmpInElement;
break;
}
}
}
int parentId = Integer.parseInt(mxCell.getAttribute("parent"));
InPort inPort = new InPort();
inPort.id = id;
inPort.name = name;
result.portCache.put(id, inPort);
if (result.tasks.containsKey(parentId)) {
inPort.parentTask = result.tasks.get(parentId);
result.tasks.get(parentId).inPorts.put(id, inPort);
} else if (result.operations.containsKey(parentId)) {
inPort.parentOperation = result.operations.get(parentId);
result.operations.get(parentId).inPorts.put(id, inPort);
} else {
throw new Exception("Failed to find parent id " + parentId + " for in port " + id);
}
} else if ("OutPort".equals(eElement.getTagName())) {
int id = Integer.parseInt(eElement.getAttribute("id"));
String name = eElement.getAttribute("name");
NamedNodeMap attributes = eElement.getAttributes();
Element mxCell = null;
NodeList childNodes = eElement.getChildNodes();
for (int i = 0 ; i < childNodes.getLength(); i++) {
Node tempOutPort = childNodes.item(i);
if (tempOutPort.getNodeType() == Node.ELEMENT_NODE) {
Element tmpOutElement = (Element) tempOutPort;
if ("mxCell".equals(tmpOutElement.getTagName())) {
mxCell = tmpOutElement;
break;
}
}
}
int parentId = Integer.parseInt(mxCell.getAttribute("parent"));
OutPort outPort = new OutPort();
outPort.id = id;
outPort.name = name;
result.portCache.put(id, outPort);
if (result.tasks.containsKey(parentId)) {
outPort.parentTask = result.tasks.get(parentId);
result.tasks.get(parentId).outPorts.put(id, outPort);
result.tasks.get(parentId).getTaskResource().getOutPorts()
.add(new TaskOutPortResource()
.setName(outPort.name)
.setReferenceId(outPort.id));
} else if (result.operations.containsKey(parentId)) {
outPort.parentOperation = result.operations.get(parentId);
result.operations.get(parentId).outPorts.put(id, outPort);
} else {
throw new Exception("Failed to find parent id " + parentId + " for out port " + id);
}
} else if ("mxCell".equals(eElement.getTagName())) {
if (eElement.hasAttribute("edge") && eElement.hasAttribute("source") && eElement.hasAttribute("target")) {
int sourceId = Integer.parseInt(eElement.getAttribute("source"));
int targetId = Integer.parseInt(eElement.getAttribute("target"));
if (result.portCache.containsKey(targetId) && result.portCache.containsKey(sourceId)) {
InPort inPort = (InPort) result.portCache.get(targetId);
OutPort outPort = (OutPort) result.portCache.get(sourceId);
outPort.nextPort = inPort;
inPort.previousPorts.put(outPort.id, outPort);
result.edgeCache.put(outPort, inPort);
} else {
throw new Exception("Invalid connection with source id " + sourceId + " target id " + targetId);
}
}
}
}
}
return result;
}
public static class ParseResult {
private Map<Integer, Task> tasks = new HashMap<>();
private Map<Integer, Operation> operations = new HashMap<>();
private Map<Integer, Object> portCache = new HashMap<>();
private Map<OutPort, InPort> edgeCache = new HashMap<>();
public Map<Integer, Task> getTasks() {
return tasks;
}
public ParseResult setTasks(Map<Integer, Task> tasks) {
this.tasks = tasks;
return this;
}
public Map<Integer, Operation> getOperations() {
return operations;
}
public ParseResult setOperations(Map<Integer, Operation> operations) {
this.operations = operations;
return this;
}
public Map<Integer, Object> getPortCache() {
return portCache;
}
public ParseResult setPortCache(Map<Integer, Object> portCache) {
this.portCache = portCache;
return this;
}
public Map<OutPort, InPort> getEdgeCache() {
return edgeCache;
}
public ParseResult setEdgeCache(Map<OutPort, InPort> edgeCache) {
this.edgeCache = edgeCache;
return this;
}
}
public static class Task {
private int id;
private TaskResource taskResource;
private Map<Integer, InPort> inPorts = new HashMap<>();
private Map<Integer, OutPort> outPorts = new HashMap<>();
public int getId() {
return id;
}
public Task setId(int id) {
this.id = id;
return this;
}
public TaskResource getTaskResource() {
return taskResource;
}
public Task setTaskResource(TaskResource taskResource) {
this.taskResource = taskResource;
return this;
}
public Map<Integer, InPort> getInPorts() {
return inPorts;
}
public Task setInPorts(Map<Integer, InPort> inPorts) {
this.inPorts = inPorts;
return this;
}
public Map<Integer, OutPort> getOutPorts() {
return outPorts;
}
public Task setOutPorts(Map<Integer, OutPort> outPorts) {
this.outPorts = outPorts;
return this;
}
}
public static class OutPort {
private InPort nextPort;
private Task parentTask;
private Operation parentOperation;
private String name;
private int id;
public InPort getNextPort() {
return nextPort;
}
public OutPort setNextPort(InPort nextPort) {
this.nextPort = nextPort;
return this;
}
public Task getParentTask() {
return parentTask;
}
public OutPort setParentTask(Task parentTask) {
this.parentTask = parentTask;
return this;
}
public Operation getParentOperation() {
return parentOperation;
}
public OutPort setParentOperation(Operation parentOperation) {
this.parentOperation = parentOperation;
return this;
}
public String getName() {
return name;
}
public OutPort setName(String name) {
this.name = name;
return this;
}
public int getId() {
return id;
}
public OutPort setId(int id) {
this.id = id;
return this;
}
}
public static class InPort {
private Map<Integer, OutPort> previousPorts = new HashMap<>();
private Task parentTask;
private Operation parentOperation;
private String name;
private int id;
public Map<Integer, OutPort> getPreviousPorts() {
return previousPorts;
}
public InPort setPreviousPorts(Map<Integer, OutPort> previousPorts) {
this.previousPorts = previousPorts;
return this;
}
public Task getParentTask() {
return parentTask;
}
public InPort setParentTask(Task parentTask) {
this.parentTask = parentTask;
return this;
}
public Operation getParentOperation() {
return parentOperation;
}
public InPort setParentOperation(Operation parentOperation) {
this.parentOperation = parentOperation;
return this;
}
public String getName() {
return name;
}
public InPort setName(String name) {
this.name = name;
return this;
}
public int getId() {
return id;
}
public InPort setId(int id) {
this.id = id;
return this;
}
}
public static class Operation {
private int id;
private String name;
private Map<Integer, InPort> inPorts = new HashMap<>();
private Map<Integer, OutPort> outPorts = new HashMap<>();
public int getId() {
return id;
}
public Operation setId(int id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Operation setName(String name) {
this.name = name;
return this;
}
public Map<Integer, InPort> getInPorts() {
return inPorts;
}
public Operation setInPorts(Map<Integer, InPort> inPorts) {
this.inPorts = inPorts;
return this;
}
public Map<Integer, OutPort> getOutPorts() {
return outPorts;
}
public Operation setOutPorts(Map<Integer, OutPort> outPorts) {
this.outPorts = outPorts;
return this;
}
}
}