package org.trianacode.shiwaall.converter;
import org.apache.commons.lang.ArrayUtils;
import org.trianacode.enactment.AddonUtils;
import org.trianacode.enactment.addon.ConversionAddon;
import org.trianacode.gui.hci.GUIEnv;
import org.trianacode.gui.main.TaskGraphPanel;
import org.trianacode.shiwaall.dax.FileUnit;
import org.trianacode.shiwaall.dax.JobUnit;
import org.trianacode.shiwaall.iwir.execute.Executable;
import org.trianacode.taskgraph.*;
import org.trianacode.taskgraph.imp.TaskFactoryImp;
import org.trianacode.taskgraph.imp.TaskImp;
import org.trianacode.taskgraph.imp.ToolImp;
import org.trianacode.taskgraph.proxy.ProxyInstantiationException;
import org.trianacode.taskgraph.proxy.java.JavaProxy;
import org.trianacode.taskgraph.tool.Tool;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
// TODO: Auto-generated Javadoc
/**
* Created by IntelliJ IDEA.
* User: Ian Harvey
* Date: 28/10/2011
* Time: 15:16
* To change this template use File | Settings | File Templates.
*/
public class DaxifyTaskGraph implements ConversionAddon {
/** The file unit class. */
private Class fileUnitClass;
/** The job unit class. */
private Class jobUnitClass;
/** The file iterator. */
int fileIterator = 0;
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return getServiceName();
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.CLIaddon#getUsageString()
*/
@Override
public String getUsageString() {
return "";
}
/**
* Convert.
*
* @param fileUnitClass the file unit class
* @param jobUnitClass the job unit class
* @param taskGraph the task graph
* @return the task graph
*/
public TaskGraph convert(Class fileUnitClass, Class jobUnitClass, TaskGraph taskGraph) {
this.fileUnitClass = fileUnitClass;
this.jobUnitClass = jobUnitClass;
try {
return daxifyTaskGraph(taskGraph, TaskFactory.DEFAULT_FACTORY_NAME, false, false, false);
} catch (TaskGraphException e) {
e.printStackTrace();
}
return null;
}
/**
* Convert.
*
* @param taskGraph the task graph
* @return the task graph
*/
public TaskGraph convert(TaskGraph taskGraph) {
fileUnitClass = FileUnit.class;
jobUnitClass = JobUnit.class;
try {
return daxifyTaskGraph(taskGraph, TaskFactory.DEFAULT_FACTORY_NAME, false, false, false);
} catch (TaskGraphException e) {
e.printStackTrace();
}
return null;
}
/**
* Ungroup all.
*
* @param taskGraph the task graph
*/
private void ungroupAll(TaskGraph taskGraph) {
for (Task task : taskGraph.getTasks(false)) {
if (task instanceof TaskGraph) {
TaskGraph inner = (TaskGraph) task;
ungroupAll(inner);
try {
taskGraph.unGroupTask(inner.getToolName());
} catch (TaskGraphException e) {
e.printStackTrace();
}
}
}
}
/**
* Daxify task graph.
*
* @param taskgraph the taskgraph
* @param factorytype the factorytype
* @param presclone the presclone
* @param prestasks the prestasks
* @param clonecontrol the clonecontrol
* @return the task graph
* @throws TaskGraphException the task graph exception
*/
private TaskGraph daxifyTaskGraph(TaskGraph taskgraph, String factorytype, boolean presclone,
boolean prestasks, boolean clonecontrol) throws TaskGraphException {
ungroupAll(taskgraph);
try {
TaskGraph clone = TaskGraphManager.createTaskGraph(taskgraph, factorytype, presclone);
if (taskgraph.getToolName() != null) {
clone.setToolName(taskgraph.getToolName());
}
Task[] tasks = taskgraph.getTasks(false);
for (Task task1 : tasks) {
if (task1 instanceof TaskGraph) {
clone.createTask(daxifyTaskGraph((TaskGraph) task1, TaskFactory.DEFAULT_FACTORY_NAME, false, false, false));
} else {
Task daxTask = initDaxTask(task1, jobUnitClass);
clone.createTask(daxTask, prestasks);
}
}
System.out.println("Daxified taskgraph has " + clone.getTasks(false).length + " tasks.");
Cable[] cables = TaskGraphUtils.getInternalCables(tasks);
System.out.println("Cables " + ArrayUtils.toString(cables));
Task task;
Node sendnode;
Node recnode;
try {
for (int count = 0; count < cables.length; count++) {
task = clone.getTask(taskgraph.getTask(cables[count].getSendingNode()).getToolName());
if (cables[count].getSendingNode().isParameterNode()) {
sendnode = task.getParameterOutputNode(cables[count].getSendingNode().getNodeIndex());
} else {
sendnode = task.getDataOutputNode(cables[count].getSendingNode().getNodeIndex());
}
task = clone.getTask(taskgraph.getTask(cables[count].getReceivingNode()).getToolName());
if (cables[count].getReceivingNode().isParameterNode()) {
recnode = task.getParameterInputNode(cables[count].getReceivingNode().getNodeIndex());
} else {
recnode = task.getDataInputNode(cables[count].getReceivingNode().getNodeIndex());
}
addFileUnit(sendnode, recnode, clone);
// clone.connect(sendnode, recnode);
}
} catch (CableException e) {
e.printStackTrace();
}
TaskGraph group = taskgraph;
Node nodes[] = group.getDataInputNodes();
Node node;
Node clonenode;
try {
for (int count = 0; count < nodes.length; count++) {
// if (taskgraph.isControlTaskConnected()) {
// node = TaskGraphUtils.getControlNode(nodes[count]).getCable().getReceivingNode();
// } else {
node = nodes[count].getParentNode();
// }
if (node.isParameterNode()) {
clonenode = clone.getTask(taskgraph.getTask(node).getToolName())
.getParameterInputNode(node.getNodeIndex());
} else {
clonenode = clone.getTask(taskgraph.getTask(node).getToolName())
.getDataInputNode(node.getNodeIndex());
}
clone.setGroupNodeParent(clone.getDataInputNode(count), clonenode);
}
} catch (Exception e) {
e.printStackTrace();
}
nodes = group.getDataOutputNodes();
try {
for (int count = 0; count < nodes.length; count++) {
// if (taskgraph.isControlTaskConnected()) {
// node = TaskGraphUtils.getControlNode(nodes[count]).getCable().getSendingNode();
// } else {
node = nodes[count].getParentNode();
// }
if (node.isParameterNode()) {
clonenode = clone.getTask(taskgraph.getTask(node).getToolName())
.getParameterOutputNode(node.getNodeIndex());
} else {
clonenode = clone.getTask(taskgraph.getTask(node).getToolName())
.getDataOutputNode(node.getNodeIndex());
}
clone.setGroupNodeParent(clone.getDataOutputNode(count), clonenode);
}
} catch (Exception e) {
e.printStackTrace();
}
if (taskgraph.isControlTask() && clonecontrol) {
clone.createControlTask(taskgraph.getControlTask(), prestasks);
//
// if (taskgraph.isControlTaskConnected()) {
// connectControlTask(clone);
// }
}
TaskGraphContext context = taskgraph.getContext();
Collection<String> keys = context.getKeys();
for (String key : keys) {
clone.setContextProperty(key, context.getProperty(key));
}
if (clone.getInputNodeCount() > 0) {
for (Node inputNode : clone.getInputNodes()) {
addFileUnit(null, inputNode.getTopLevelNode(), clone);
}
}
if (clone.getOutputNodeCount() > 0) {
for (Node outputNode : clone.getOutputNodes()) {
addFileUnit(outputNode.getTopLevelNode(), null, clone);
}
}
Node childNode = getTaskgraphChildNode(clone);
if (childNode != null) {
//
ToolImp creatorTool = new ToolImp(clone.getProperties());
initTool(creatorTool, "DaxCreator", "org.trianacode.shiwaall.gui.guiUnits", 1, 0);
// if (daxFilePath != null) {
// creatorTool.setParameter("fileName", daxFilePath);
// }
Task creatorTask = clone.createTask(creatorTool);
//sensible location on the taskgraph
TPoint childPoint = TaskLayoutUtils.getPosition(childNode.getTask());
TPoint creatorPoint = new TPoint(childPoint.getX() + 1.5, childPoint.getY());
TaskLayoutUtils.setPosition(creatorTask, creatorPoint);
clone.connect(childNode, creatorTask.getDataInputNode(0));
}
return clone;
} catch (ClassCastException except) {
except.printStackTrace();
throw (new TaskGraphException("cloningError" + ": " + "NodeError", except));
} catch (TaskGraphException except) {
except.printStackTrace();
throw (new TaskGraphException("cloningError" + ": " + except.getMessage(), except));
}
}
/**
* Inits the tool.
*
* @param tool the tool
* @param unitName the unit name
* @param unitPackage the unit package
* @param inNodes the in nodes
* @param outNodes the out nodes
*/
private static void initTool(ToolImp tool, String unitName, String unitPackage, int inNodes, int outNodes) {
tool.setToolName(unitName);
try {
tool.setDataInputNodeCount(inNodes);
tool.setDataOutputNodeCount(outNodes);
tool.setToolPackage(unitPackage);
tool.setProxy(new JavaProxy(unitName, unitPackage));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Adds the file unit.
*
* @param sendnode the sendnode
* @param recnode the recnode
* @param clone the clone
* @throws CableException the cable exception
*/
private void addFileUnit(Node sendnode, Node recnode, TaskGraph clone) throws CableException {
try {
Task fileTask = new TaskImp(
AddonUtils.makeTool(fileUnitClass, "Interim_" + fileIterator, clone.getProperties()),
new TaskFactoryImp(),
false
);
Task task = clone.createTask(fileTask, false);
if (sendnode != null) {
Node inNode = task.addDataInputNode();
clone.connect(sendnode, inNode);
}
if (recnode != null) {
Node outNode = task.addDataOutputNode();
clone.connect(outNode, recnode);
}
TPoint taskPoint = null;
if(sendnode != null){
//Place interim file task after producing executable task
TPoint sendingpoint = TaskLayoutUtils.getPosition(sendnode.getTask());
// taskPoint = new TPoint(sendingpoint.getX() + 1.5, sendingpoint.getY());
int outputNodeCount = sendnode.getTask().getOutputNodeCount();
int thisNodeNumber = sendnode.getTask().getAbsoluteNodeIndex(sendnode);
double y = thisNodeNumber - (outputNodeCount/2);
taskPoint = new TPoint(sendingpoint.getX() + 1.5, sendingpoint.getY() + y);
} else if( recnode != null) {
// If no producing task (ie its an input file) place it before the consuming task.
//Put it either in front of it, or above if there's no space
TPoint recpoint = TaskLayoutUtils.getPosition(recnode.getTask());
if(recpoint.getX() - 1.5 > 0){
taskPoint = new TPoint(recpoint.getX() - 1.5, recpoint.getY());
} else {
taskPoint = new TPoint(recpoint.getX(), recpoint.getY() - 1);
}
}
if(taskPoint != null){
TaskGraphPanel panel = GUIEnv.getApplicationFrame().getSelectedDesktopView().getTaskgraphPanel();
TaskLayoutUtils.setPosition(task, taskPoint);
// moveTask(panel, task, taskPoint);
}
fileIterator++;
} catch (TaskException e) {
e.printStackTrace();
} catch (ProxyInstantiationException e) {
e.printStackTrace();
}
}
// private void moveTask(TaskGraphPanel panel, Task task, TPoint taskPoint){
// Rectangle taskBounds = panel.getTaskComponent(task).getComponent().getBounds();
// for(TaskComponent overlap : panel.getTaskComponents()) {
// Rectangle overlapRect = overlap.getComponent().getBounds();
// if(taskBounds.intersects(overlapRect)){
// taskPoint.setY(taskPoint.getY() + 1);
// TaskLayoutUtils.setPosition(task, taskPoint);
// moveTask(panel, task, taskPoint);
// }
// }
// }
/**
* Inits the dax task.
*
* @param task the task
* @param jobUnitClass the class for job units
* @return the task
*/
private Task initDaxTask(Task task, Class jobUnitClass) {
Tool tool = null;
try {
tool = AddonUtils.makeTool(jobUnitClass, task.getToolName(), task.getProperties());
} catch (ProxyInstantiationException e) {
e.printStackTrace();
} catch (TaskException e) {
e.printStackTrace();
}
try {
Task daxTask = new TaskImp(tool, new TaskFactoryImp(), false);
setParameters(task, daxTask);
return daxTask;
} catch (TaskException e) {
e.printStackTrace();
}
return null;
}
/**
* Sets the parameters.
*
* @param task the task
* @param daxTask the dax task
*/
private void setParameters(Task task, Task daxTask) {
int count = 0;
while (count < task.getInputNodeCount()) {
try {
daxTask.addDataInputNode();
} catch (NodeException e) {
e.printStackTrace();
}
count++;
}
count = 0;
while (count < task.getOutputNodeCount()) {
try {
daxTask.addDataOutputNode();
} catch (NodeException e) {
e.printStackTrace();
}
count++;
}
Executable executable = null;
if(task.isParameterName(Executable.EXECUTABLE)){
executable = (Executable) task.getParameter(Executable.EXECUTABLE);
if(executable != null){
task.setParameter("jobName", executable.getPrimaryExec());
task.setParameter("args", Arrays.toString(executable.getArgs()));
task.setParameter("numberOfJobs", 1);
task.setParameter("execLocation", executable.getWorkingDir().getAbsolutePath());
}
} else {
daxTask.setParameter("jobName", ((JavaProxy) task.getProxy()).getFullUnitName());
}
daxTask.setParameter(JobUnit.TRIANA_TOOL, task.getQualifiedToolName());
for (String paramName : task.getParameterNames()) {
Object value = task.getParameter(paramName);
daxTask.setParameter(paramName, value);
}
//Todo - probably something technical and frustrating...
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.CLIaddon#getServiceName()
*/
@Override
public String getServiceName() {
return "Triana Dax Template";
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.CLIaddon#getLongOption()
*/
@Override
public String getLongOption() {
return "taskgraph-to-daxJobs";
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.CLIaddon#getShortOption()
*/
@Override
public String getShortOption() {
return "dax";
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.CLIaddon#getDescription()
*/
@Override
public String getDescription() {
return "An intermediary stage between a taskgraph and a dax, where units must input/output files.";
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.ConversionAddon#toolToWorkflow(org.trianacode.taskgraph.tool.Tool)
*/
@Override
public Object toolToWorkflow(Tool tool) {
return null;
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.ConversionAddon#workflowToTool(java.lang.Object)
*/
@Override
public Tool workflowToTool(Object workflowObject) {
return null;
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.ConversionAddon#processWorkflow(org.trianacode.taskgraph.tool.Tool)
*/
@Override
public Tool processWorkflow(Tool workflow) {
return convert((TaskGraph) workflow);
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.ConversionAddon#toolToWorkflowFile(org.trianacode.taskgraph.tool.Tool, java.io.File, java.lang.String)
*/
@Override
public File toolToWorkflowFile(Tool tool, File configFile, String filePath) {
return null;
}
/* (non-Javadoc)
* @see org.trianacode.enactment.addon.ConversionAddon#toolToWorkflowFileInputStream(org.trianacode.taskgraph.tool.Tool)
*/
@Override
public InputStream toolToWorkflowFileInputStream(Tool tool) {
return null;
}
/**
* Gets the taskgraph child node.
*
* @param taskGraph the task graph
* @return the taskgraph child node
*/
private static Node getTaskgraphChildNode(TaskGraph taskGraph) {
// Find a child task on the taskgraph to attach the daxCreator to, and connect it
Node childNode = null;
try {
Task[] tasks = taskGraph.getTasks(false);
ArrayList<Task> childTasks = new ArrayList<Task>();
for (Task task : tasks) {
if (task.getDataOutputNodeCount() == 0) {
childTasks.add(task);
}
}
System.out.println("These are the child tasks of the taskgraph (will use the first discovered): ");
for (Task task : childTasks) {
System.out.println(task.getToolName());
}
if (childTasks.size() > 0) {
childNode = childTasks.get(0).addDataOutputNode();
} else {
if (taskGraph.getOutputNodeCount() > 0) {
childNode = taskGraph.getOutputNode(0).getTopLevelTask().addDataOutputNode();
}
}
} catch (Exception e) {
System.out.println("Failed to add node to child leaf of taskgraph");
}
System.out.println("Child node " + childNode);
return childNode;
}
}