/** * Create an internalTaskFlow job with the given task flow job (user) * * @param userJob the user job that will be used to create the internal job. * @return the created internal job. * @throws JobCreationException an exception if the factory cannot create the given job. */ private static InternalJob createJob(TaskFlowJob userJob) throws JobCreationException { if (userJob.getTasks().size() == 0) { logger.info("Job '" + userJob.getName() + "' must contain tasks !"); throw new JobCreationException("This job must contains tasks !"); } // validate taskflow List<FlowChecker.Block> blocks = new ArrayList<>(); FlowError err = FlowChecker.validate(userJob, blocks); if (err != null) { String e = ""; e += "Invalid taskflow: " + err.getMessage() + "; context: " + err.getTask(); logger.error(e); throw new JobCreationException(e, err); } InternalJob job = new InternalTaskFlowJob(); // keep an initial job content job.setTaskFlowJob(userJob); Map<Task, InternalTask> tasksList = new LinkedHashMap<>(); boolean hasPreciousResult = false; for (Task t : userJob.getTasks()) { tasksList.put(t, createTask(userJob, t)); if (!hasPreciousResult) { hasPreciousResult = t.isPreciousResult(); } } for (Entry<Task, InternalTask> entry : tasksList.entrySet()) { if (entry.getKey().getDependencesList() != null) { for (Task t : entry.getKey().getDependencesList()) { entry.getValue().addDependence(tasksList.get(t)); } } job.addTask(entry.getValue()); } // tag matching blocks in InternalTasks for (InternalTask it : tasksList.values()) { for (FlowChecker.Block block : blocks) { if (it.getName().equals(block.start.element.getName())) { it.setMatchingBlock(block.end.element.getName()); } if (it.getName().equals(block.end.element.getName())) { it.setMatchingBlock(block.start.element.getName()); } } } // create if/else/join weak dependencies for (InternalTask it : tasksList.values()) { // it performs an IF action if (it.getFlowScript() != null && it.getFlowScript().getActionType().equals(FlowActionType.IF.toString())) { String ifBranch = it.getFlowScript().getActionTarget(); String elseBranch = it.getFlowScript().getActionTargetElse(); String join = it.getFlowScript().getActionContinuation(); List<InternalTask> joinedBranches = new ArrayList<>(); // find the ifBranch task for (InternalTask it2 : tasksList.values()) { if (it2.getName().equals(ifBranch)) { it2.setIfBranch(it); String match = it2.getMatchingBlock(); // find its matching block task if (match == null) { // no match: single task joinedBranches.add(it2); } else { for (InternalTask it3 : tasksList.values()) { if (it3.getName().equals(match)) { joinedBranches.add(it3); break; } } } break; } } // find the elseBranch task for (InternalTask it2 : tasksList.values()) { if (it2.getName().equals(elseBranch)) { it2.setIfBranch(it); String match = it2.getMatchingBlock(); // find its matching block task if (match == null) { // no match: single task joinedBranches.add(it2); } else { for (InternalTask it3 : tasksList.values()) { if (it3.getName().equals(match)) { joinedBranches.add(it3); break; } } } break; } } // find the joinBranch task for (InternalTask it2 : tasksList.values()) { if (it2.getName().equals(join)) { it2.setJoinedBranches(joinedBranches); } } } } return job; }
/** * Creates a flow control element for the given task <element name="controlFlow"> * * @return the xml Element corresponding to the flow control, if the task contains a flow control, * null otherwise */ private Element createFlowControlElement(Document doc, Task task) { Element controlFlowE = null; // <ref name="block"/> if (task.getFlowBlock() != FlowBlock.NONE) { controlFlowE = doc.createElementNS(Schemas.SCHEMA_LATEST.namespace, XMLTags.FLOW.getXMLName()); setAttribute(controlFlowE, XMLAttributes.FLOW_BLOCK, task.getFlowBlock().toString()); } FlowScript flowScript = task.getFlowScript(); if (flowScript != null) { Element flowActionE = null; // flowActionE can be if, loop, replicate or null. // if not null, it contains a script element // <ref name="actionIf"/> // <ref name="actionReplicate"/> // <ref name="actionLoop"/> // </choice> // *** if *** // <element name="if"> if (flowScript.getActionType().equals(FlowActionType.IF.toString())) { flowActionE = doc.createElementNS(Schemas.SCHEMA_LATEST.namespace, XMLTags.FLOW_IF.getXMLName()); setAttribute(flowActionE, XMLAttributes.FLOW_TARGET, flowScript.getActionTarget(), true); setAttribute(flowActionE, XMLAttributes.FLOW_ELSE, flowScript.getActionTargetElse(), true); setAttribute( flowActionE, XMLAttributes.FLOW_CONTINUATION, flowScript.getActionContinuation(), true); } // *** loop *** // <element name="loop"> if (flowScript.getActionType().equals(FlowActionType.LOOP.toString())) { flowActionE = doc.createElementNS(Schemas.SCHEMA_LATEST.namespace, XMLTags.FLOW_LOOP.getXMLName()); setAttribute(flowActionE, XMLAttributes.FLOW_TARGET, flowScript.getActionTarget(), true); } // *** replicate *** // <element name="replicate"> if (flowScript.getActionType().equals(FlowActionType.REPLICATE.toString())) { flowActionE = doc.createElementNS( Schemas.SCHEMA_LATEST.namespace, XMLTags.FLOW_REPLICATE.getXMLName()); } if (flowActionE != null) { if (controlFlowE == null) { controlFlowE = doc.createElementNS(Schemas.SCHEMA_LATEST.namespace, XMLTags.FLOW.getXMLName()); } Element scriptE = createScriptElement(doc, flowScript); flowActionE.appendChild(scriptE); controlFlowE.appendChild(flowActionE); } } // flowScript !=null return controlFlowE; }