From 319f7cf8570bb34c2574b507e76d33d58d4a773f Mon Sep 17 00:00:00 2001 From: Omar Sweidan Date: Tue, 28 Jun 2022 09:49:57 +0200 Subject: [PATCH] =?utf8?q?415:=20folyamat/step=20szerkeszt=C5=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../server/JobEngineConfiguration.java | 48 +-- .../jobengine/server/ast/JSONEncoder.java | 10 +- server/user.mediacube.gui/js/diagramflowjs.js | 286 +++++++------ .../js/processVisualizer2.js | 20 +- .../pages/parameterEditor2.zul | 49 +++ .../pages/processVisualizer2.zul | 66 ++- .../user.mediacube.gui/pages/stepEditor2.zul | 40 ++ .../jobengine/zk/model/JobFlowChartModel.java | 387 +++++++++++++++++- 8 files changed, 700 insertions(+), 206 deletions(-) create mode 100644 server/user.mediacube.gui/pages/parameterEditor2.zul create mode 100644 server/user.mediacube.gui/pages/stepEditor2.zul diff --git a/server/user.jobengine.osgi.server/src/user/jobengine/server/JobEngineConfiguration.java b/server/user.jobengine.osgi.server/src/user/jobengine/server/JobEngineConfiguration.java index 2e984ae6..1c44347b 100644 --- a/server/user.jobengine.osgi.server/src/user/jobengine/server/JobEngineConfiguration.java +++ b/server/user.jobengine.osgi.server/src/user/jobengine/server/JobEngineConfiguration.java @@ -239,6 +239,11 @@ public class JobEngineConfiguration implements IJobEngineConfiguration { return programs; } + /** + * Visszadja az ütemezett feladatokat tartalmazó collection-t (a + * scheduledjobs.json fájl tartalmát) + * + */ @Override public ArrayList> getSchedules() { return schedules; @@ -397,7 +402,7 @@ public class JobEngineConfiguration implements IJobEngineConfiguration { Encoder encoder = new Encoder(); IProgram program = (IProgram) encoder.visitJobTemplate(template, null); programs.put(fileName, program); - logger.info("Job template loaded {}", fileName); + logger.info("Program loaded {}", fileName); } catch (FileNotFoundException e) { logger.error("Fájl nem található: {}", fileName); } catch (IOException e) { @@ -486,21 +491,23 @@ public class JobEngineConfiguration implements IJobEngineConfiguration { BasicDBList jobList = new BasicDBList(); for (int i = 0; i < schedules.size(); i++) { BasicDBObject temp = new BasicDBObject(); - if (schedules.get(i).getValue().get("name") != null) { - temp.append("name", schedules.get(i).getValue().get("name")); + BasicDBObject value = schedules.get(i).getValue(); + + if (value.get("name") != null) { + temp.append("name", value.get("name")); } - temp.append("template", schedules.get(i).getValue().get("template")); - if (schedules.get(i).getValue().get("active") != null) { - temp.append("active", schedules.get(i).getValue().get("active")); + temp.append("template", value.get("template")); + if (value.get("active") != null) { + temp.append("active", value.get("active")); } - if (schedules.get(i).getValue().get("executeimmediate") != null) { - temp.append("executeimmediate", schedules.get(i).getValue().get("executeimmediate")); + if (value.get("executeimmediate") != null) { + temp.append("executeimmediate", value.get("executeimmediate")); } - if (schedules.get(i).getValue().get("cronexpression") != null) { - temp.append("cronexpression", schedules.get(i).getValue().get("cronexpression")); + if (value.get("cronexpression") != null) { + temp.append("cronexpression", value.get("cronexpression")); } - if (schedules.get(i).getValue().get("parameters") != null) { - temp.append("parameters", new BasicDBList(schedules.get(i).getValue().get("parameters"))); + if (value.get("parameters") != null) { + temp.append("parameters", new BasicDBList(((BasicDBList) value.get("parameters")).toArray())); } jobList.add(temp); } @@ -542,26 +549,15 @@ public class JobEngineConfiguration implements IJobEngineConfiguration { if (templateToSave.getFileName() != null) { filePath = templatesPath.toString() + FileSystems.getDefault().getSeparator() + templateToSave.getFileName(); - if (Files.isWritable(Paths.get(filePath))) { - logger.info("{} is writable", filePath); - } else { - logger.info("{} is not writable", filePath); - DosFileAttributeView dos = Files.getFileAttributeView(Paths.get(filePath), - DosFileAttributeView.class); - if (dos != null) { - try { - dos.setReadOnly(false); - } catch (IOException e) { - logger.info("IOException: {}", e.getCause()); - } - } - } + setFileAsWritable(Paths.get(filePath)); FileOutputStream fos = new FileOutputStream(filePath); logger.info("Saving job template to {}", filePath); if (templateToSave != null) { XMLEncoder xmlEncoder = new XMLEncoder(); writeXml((Document) xmlEncoder.visitJobTemplate(templateToSave, null), fos); } + } else { + logger.info("templateToSave.getFileName() == null"); } } catch (FileNotFoundException e) { logger.error("File not found: {}", filePath); diff --git a/server/user.jobengine.osgi.server/src/user/jobengine/server/ast/JSONEncoder.java b/server/user.jobengine.osgi.server/src/user/jobengine/server/ast/JSONEncoder.java index 896c5a09..5e6549cf 100644 --- a/server/user.jobengine.osgi.server/src/user/jobengine/server/ast/JSONEncoder.java +++ b/server/user.jobengine.osgi.server/src/user/jobengine/server/ast/JSONEncoder.java @@ -14,7 +14,7 @@ public class JSONEncoder implements Visitor { BasicDBList inputs = new BasicDBList(); BasicDBList outputs = null; // az inputs és az outputs elemei egyenként vannak hozzáadva, mert csak - // Stringgé konvertálva tudja a JS oldal feldolgozni + // String-gé konvertálva tudja a JS oldal feldolgozni (az addAll() nem működne) List inputParameters = command.getInputParameterSequence().getParameters(); for (int i = 0; i < inputParameters.size(); i++) { BasicDBObject input = new BasicDBObject(); @@ -36,10 +36,10 @@ public class JSONEncoder implements Visitor { } } - newNode.append("name", command.getType().replace("Step.java", "")).append("y", 75).append("w", 100) - .append("h", 100).append("connectors", "connectorsForStep") - .append("text", command.getType().replace("Step.java", "")).append("fillStyle", "green") - .append("figure", "RectangleWithGradient").append("inputs", inputs); + newNode.append("name", command.getType().replace(".java", "")).append("y", 75).append("w", 100).append("h", 100) + .append("connectors", "connectorsForStep").append("text", command.getType().replace(".java", "")) + .append("fillStyle", "green").append("figure", "RectangleWithGradient").append("inputs", inputs) + .append("weight", command.getWeight()); if (outputs != null) { newNode.append("outputs", outputs); } diff --git a/server/user.mediacube.gui/js/diagramflowjs.js b/server/user.mediacube.gui/js/diagramflowjs.js index 7d5a3769..7b0a656d 100644 --- a/server/user.mediacube.gui/js/diagramflowjs.js +++ b/server/user.mediacube.gui/js/diagramflowjs.js @@ -1,14 +1,26 @@ -const DIAGRAMFLOW_ARROW_SIZE=15; +/** + Változtatások a gyárihoz képest: + 1. params, és variables tömb, illetve paraméter/változó hozzáadó függvények hozzáadása + 2. selNode változó hozzáadása mouse-hoz + 3. addLink változtatása: megvizsgáljuk, hogy létezik-e az adott node-ok között link + 4. zk.Widget.fire hozzáadása a highlight, és a mouse.down függvényhez + 5. elem kiválasztásánál ellenőrizzük, hogy az új kiválasztott elem + azonos-e a korábban kiválasztott elemmel + 6. rough opció eltávolítása + 7. csak output-ból lehet input-ba húzni link-et +*/ -var model={ - ctx:null, - nodes:[], - links:[], - params:[], - variables:[], - myCanvas:null, - rough:false, +const DIAGRAMFLOW_ARROW_SIZE=15; +var model= { + ctx: null, + nodes: [], + links: [], + params: [], + variables: [], + selNode: null, + myCanvas: null, + addNode: function(node){ this.nodes.push(node); }, @@ -60,7 +72,7 @@ var model={ } if (mouse.selNode!=null && this.nodes[mouse.selNode] != null){ - this.nodes[mouse.selNode].highlight(this.ctx); + this.nodes[mouse.selNode].highlight(this.ctx); } }, @@ -99,6 +111,8 @@ var model={ } } } + this.selNode= selIndex; + return selIndex; }, @@ -234,7 +248,7 @@ var model={ }; }, - node: function(x, y, w, h, connectors, text, fillStyle, figure, inputs, outputs, args) { + node: function(x, y, w, h, connectors, text, fillStyle, figure, inputs, outputs, weight, args) { this.textfill=function(ctx) { var fontSize = 12; var lines = new Array(); @@ -281,6 +295,7 @@ var model={ this.connectors=connectors; this.inputs=inputs; this.outputs=outputs; + this.weight= weight; this.anchors=[ new model.anchor(0,0,"nw-resize"), new model.anchor(.5,0,"n-resize"), @@ -360,6 +375,7 @@ var model={ this.anchors.forEach(element => { element.draw(ctx,this.x,this.y,this.w,this.h); }); + zk.Widget.$('$nodeSelectedListener').fire('onNodeSelected', { model }, {toServer : true}); } }, @@ -536,16 +552,10 @@ var model={ var dy = toy - fromy; var angle = Math.atan2(dy, dx); - if (model.rough){ - const rc=rough.canvas(document.getElementById(context.canvas.id)); - rc.line(fromx,fromy,tox,toy); - } - else{ - context.beginPath(); - context.moveTo(fromx, fromy); - context.lineTo(tox, toy); - context.stroke(); - } + context.beginPath(); + context.moveTo(fromx, fromy); + context.lineTo(tox, toy); + context.stroke(); context.beginPath(); context.fillStyle="black"; @@ -687,19 +697,22 @@ var model={ }; var mouse={ - dragging:false, - dragOrigin:{}, - dragNode:null, - selNode:null, - selAnchor:null, - selConnector:null, - selLink:null, - editText:false, - mouseCoords:function(ev){ + dragging: false, + dragOrigin: {}, + dragNode: null, + newselNode: null, + selNode: null, + selAnchor: null, + selConnector: null, + selLink: null, + editText: false, + + mouseCoords: function(ev){ var rect = model.myCanvas.getBoundingClientRect(); - return {x:ev.clientX-rect.left,y:ev.clientY-rect.top}; + return {x:ev.clientX-rect.left, y:ev.clientY-rect.top}; }, - down:function(ev){ + + down: function(ev){ if (mouse.editText) { mouse.editText=false; @@ -707,85 +720,89 @@ var mouse={ ed.style.display="none"; } mouse.selLink=null; - var mouseC=mouse.mouseCoords(ev); - var newselNode=model.findNode(mouseC); - - if (mouse.selConnector!=null) - { + var mouseC= mouse.mouseCoords(ev); + newselNode= model.findNode(mouseC); + + if (mouse.selConnector != null) + { mouse.dragging="newlink"; - return + return; } - if (mouse.selAnchor!=null){ - mouse.dragging="anchor"; + + if (mouse.selAnchor != null) { + mouse.dragging= "anchor"; model.draw(); return; } - if (newselNode!=null){ - mouse.selNode=newselNode; + + if (newselNode != null) { + zk.Widget.$('$nodeSelectedListener').fire('onNodeSelected', { model }, {toServer : true}); + + mouse.selNode= newselNode; // Dispatch/Trigger/Fire the event var event = new CustomEvent("selectionChanged", { "detail": mouse.selNode }); document.dispatchEvent(event); - mouse.dragOrigin={ - x:mouseC.x-model.nodes[mouse.selNode].x, - y:mouseC.y-model.nodes[mouse.selNode].y - }; - if (mouse.selAnchor!=null) - { - mouse.dragging="anchor"; - model.draw(); - return; - } - else{ + mouse.dragOrigin= { + x:mouseC.x-model.nodes[mouse.selNode].x, + y:mouseC.y-model.nodes[mouse.selNode].y + }; + + if (mouse.selAnchor!=null) { + mouse.dragging="anchor"; + model.draw(); + return; + } + else { model.nodes[mouse.selNode].highlight(model.ctx); - mouse.selAnchor=model.nodes[mouse.selNode].nearestAnchor(mouseC); - mouse.dragging="move"; + mouse.selAnchor= model.nodes[mouse.selNode].nearestAnchor(mouseC); + mouse.dragging= "move"; - this.nodesToMove=[]; - this.linksToMove=[]; + this.nodesToMove= []; + this.linksToMove= []; for (let j = 0; j < model.links.length; j++) { - const elementLinked=model.links[j]; - if (elementLinked.to==mouse.selNode || elementLinked.from==mouse.selNode){ + const elementLinked= model.links[j]; + if (elementLinked.to == mouse.selNode || elementLinked.from == mouse.selNode){ this.linksToMove.push(j); } - }; + } - var hostNode=model.nodes[mouse.selNode]; + var hostNode= model.nodes[mouse.selNode]; for (let i = 0; i < model.nodes.length; i++) { - const element = model.nodes[i]; - var elemDragOrigin={x:mouseC.x-element.x,y:mouseC.y-element.y}; + const node = model.nodes[i]; + var elemDragOrigin={x: mouseC.x-node.x, y: mouseC.y-node.y}; - if (i!=mouse.selNode && element.x>=hostNode.x && element.x+element.w<=hostNode.x+hostNode.w && element.y>=hostNode.y && element.y+element.h<=hostNode.y+hostNode.h) + if (i != mouse.selNode && node.x >= hostNode.x && node.x+node.w <= hostNode.x+hostNode.w + && node.y >= hostNode.y && node.y+node.h <= hostNode.y+hostNode.h) { - this.nodesToMove.push({index:i,elemDragOrigin:elemDragOrigin}); + this.nodesToMove.push({index: i, elemDragOrigin: elemDragOrigin}); for (let j = 0; j < model.links.length; j++) { - const elementLinked=model.links[j]; - if (elementLinked.to==i || elementLinked.from==i){ + const elementLinked= model.links[j]; + if (elementLinked.to == i || elementLinked.from == i){ this.linksToMove.push(j); } - }; + } } } - } model.draw(); } else { - if (mouse.selAnchor==null){ + if (mouse.selAnchor == null){ //deselect - mouse.selNode=null; - mouse.dragging=null; + mouse.selNode= null; + mouse.dragging= null; model.draw(); //CHECK LINKS for (let index = 0; index < model.links.length; index++) { - const element = model.links[index]; - if (element.isOverLink({x:mouseC.x,y:mouseC.y})==true){ - element.highlight(model.ctx); - mouse.dragging="linkedit"; - mouse.selLink=index; + const link = model.links[index]; + if (link.isOverLink({x: mouseC.x, y: mouseC.y}) == true){ + link.highlight(model.ctx); + mouse.dragging= "linkedit"; + mouse.selLink= index; break; } } @@ -796,8 +813,8 @@ var mouse={ } } - if (mouse.dragging==null){ - mouse.dragging="all"; + if (mouse.dragging == null) { + mouse.dragging= "all"; this.nodesToMove=[]; for (let i = 0; i < model.nodes.length; i++) { const element = model.nodes[i]; @@ -805,19 +822,19 @@ var mouse={ this.nodesToMove.push({index:i,elemDragOrigin:elemDragOrigin}); } - } //console.log(mouse.selNode + " " + mouse.selAnchor + " " + mouse.dragging) }, - move:function(ev){ - var mouseC=mouse.mouseCoords(ev); + + move: function(ev){ + var mouseC= mouse.mouseCoords(ev); switch (mouse.dragging) { case "all": this.nodesToMove.forEach(nodeLinked => { const element = model.nodes[nodeLinked.index]; - element.x=mouseC.x-nodeLinked.elemDragOrigin.x; - element.y=mouseC.y-nodeLinked.elemDragOrigin.y; + element.x= mouseC.x-nodeLinked.elemDragOrigin.x; + element.y= mouseC.y-nodeLinked.elemDragOrigin.y; }); model.links.forEach(link => { link.reSegment(); @@ -825,6 +842,7 @@ var mouse={ model.draw(); break; case "newlink": + console.log("mouse.selConnectorNode: ", mouse.selConnectorNode); model.draw(); model.ctx.beginPath(); var aC=model.nodes[mouse.selConnectorNode].connectorCoords(mouse.selConnector); @@ -835,22 +853,28 @@ var mouse={ mouse.linkDestNode=null; //CHECK DESTINATION connector for (let j = 0; j < model.nodes.length; j++) { - if (j!=mouse.selConnectorNode) + if (j != mouse.selConnectorNode) { - const element = model.nodes[j]; + const node = model.nodes[j]; - var i=element.isInsideConnectors(mouseC); - if (i!=null){ - if (element.connectors[i].options.dropAllowed && - (element.connectors[i].mode != - model.nodes[mouse.selConnectorNode].connectors[mouse.selConnector].mode - || element.connectors[i].mode=="mixed")) - { - mouse.linkDestNode=j; - mouse.linkDestConnector=i; - element.connectors[i].highlight(model.ctx,element.x,element.y,element.w,element.h); - } - break; + var i= node.isInsideConnectors(mouseC); + if (i != null){ + var connector= node.connectors[i]; + if(connector != null){ + if (connector.options.dropAllowed && + (connector.mode == "input" && + model.nodes[mouse.selConnectorNode].connectors[mouse.selConnector].mode == "output" + || connector.mode=="mixed")) + { + mouse.linkDestNode=j; + mouse.linkDestConnector=i; + connector.highlight(model.ctx, node.x, node.y, node.w, node.h); + } + break; + } + else { + console.log("connector == null"); + } } } } @@ -922,44 +946,45 @@ var mouse={ model.draw(); break; default: - if (mouse.selNode!=null){ - var element=model.nodes[mouse.selNode]; - + if (mouse.selNode != null) { + var element= model.nodes[mouse.selNode]; + //in anchor - var i=element.isInsideAnchors(mouseC.x,mouseC.y); - if (i!=null){ - mouse.selAnchor=i; - model.myCanvas.style.cursor=element.anchors[i].cursorClass; - element.anchors[i].highlight(model.ctx,element.x,element.y,element.w,element.h); + var i= element.isInsideAnchors(mouseC.x, mouseC.y); + if (i != null) { + mouse.selAnchor= i; + model.myCanvas.style.cursor= element.anchors[i].cursorClass; + element.anchors[i].highlight(model.ctx, element.x, element.y, element.w, element.h); } - else{ - if (mouse.selAnchor!=null){ + else { + if(mouse.selAnchor != null) { model.draw(); } - mouse.selAnchor=null; - mouse.dragging=null; - model.myCanvas.style.cursor="auto"; + mouse.selAnchor= null; + mouse.dragging= null; + model.myCanvas.style.cursor= "auto"; } //CHECK CONNECTOR - var found=false; + var found= false; for (let j = 0; j < model.nodes.length; j++) { - const element = model.nodes[j]; + const element= model.nodes[j]; - var i=element.isInsideConnectors(mouseC); - if (i!=null){ + var i= element.isInsideConnectors(mouseC); + if (i != null){ if (element.connectors[i].options.dragAllowed){ - mouse.selConnector=i; - mouse.selConnectorNode=j; - element.connectors[mouse.selConnector].highlight(model.ctx,element.x,element.y,element.w,element.h); - found=true; + mouse.selConnector= i; + mouse.selConnectorNode= j; + element.connectors[mouse.selConnector].highlight(model.ctx, element.x, + element.y, element.w, element.h); + found= true; break; } } } if (!found){ - mouse.selConnector=null; - mouse.selConnectorNode=null; + mouse.selConnector= null; + mouse.selConnectorNode= null; model.draw(); } } @@ -969,20 +994,21 @@ var mouse={ for (let j = 0; j < model.nodes.length; j++) { const element = model.nodes[j]; - var i=element.isInsideConnectors(mouseC); - if (i!=null){ + var i= element.isInsideConnectors(mouseC); + if (i != null){ if (element.connectors[i].options.dragAllowed){ - mouse.selConnector=i; - mouse.selConnectorNode=j; - element.connectors[mouse.selConnector].highlight(model.ctx,element.x,element.y,element.w,element.h); - found=true; + mouse.selConnector= i; + mouse.selConnectorNode= j; + element.connectors[mouse.selConnector].highlight(model.ctx, + element.x, element.y, element.w, element.h); + found= true; break; } } } if (!found){ - mouse.selConnector=null; - mouse.selConnectorNode=null; + mouse.selConnector= null; + mouse.selConnectorNode= null; model.draw(); } // mouse.selConnector=null; @@ -990,7 +1016,7 @@ var mouse={ break; } }, - up:function(ev){ + up: function(ev){ //var mouseC=mouse.mouseCoords(ev); if (mouse.dragging!=null){ diff --git a/server/user.mediacube.gui/js/processVisualizer2.js b/server/user.mediacube.gui/js/processVisualizer2.js index c2e38f3b..ac5e4c42 100644 --- a/server/user.mediacube.gui/js/processVisualizer2.js +++ b/server/user.mediacube.gui/js/processVisualizer2.js @@ -60,8 +60,8 @@ var connectorsForEnd=[ model.init("myCanvas"); model.draw(); - function setFlowchartData(data) { - var arrays= JSON.parse(data); +function setFlowchartData(data) { + var arrays= JSON.parse(data); var nodes= arrays.nodes; var links= arrays.links; var params= arrays.params; @@ -69,15 +69,15 @@ model.draw(); var xOfNewNode= 30; // start node - model.addNode(new model.node(xOfNewNode, 75, 25, 25, connectorsForStart, "", "black", "Circle", null, null)); + model.addNode(new model.node(xOfNewNode, 75, 25, 25, connectorsForStart, "", "black", "Circle", null, null, null)); xOfNewNode+= 150; for (let i = 0; i < nodes.length; i++) { - model.addNode(new model.node(xOfNewNode, 75, 100, 100, connectorsForStep, nodes[i].text, "", "RectangleWithGradient", nodes[i].inputs, nodes[i].outputs)); + model.addNode(new model.node(xOfNewNode, 75, 100, 100, connectorsForStep, nodes[i].text, "", "RectangleWithGradient", nodes[i].inputs, nodes[i].outputs, nodes[i].weight)); xOfNewNode+= 150; } // end node - model.addNode(new model.node(xOfNewNode, 75, 25, 25, connectorsForEnd, "", "black", "Circle", null, null)); + model.addNode(new model.node(xOfNewNode, 75, 25, 25, connectorsForEnd, "", "black", "Circle", null, null, null)); //adding links model.addLink(new model.link(0, 1, 0, 0, "", "straight")); @@ -90,17 +90,21 @@ model.draw(); model.draw(); for (let i = 0; i < params.length; i++) { - model.addParam(new model.param(params[i].name, params[i].type)); + if(!model.params.includes(params[i])) { + model.addParam(new model.param(params[i].name, params[i].type)); + } } for (let i = 0; i < variables.length; i++) { - model.addVariable(new model.variable(variables[i].name, variables[i].type)); + if(!model.variables.includes(variables[i])){ + model.addVariable(new model.variable(variables[i].name, variables[i].type)); + } } } function getFlowchartData(){ console.log("getFlowchartData"); - zk.Widget.$('$flowchartDataListener').fire('onFlowchartDataChanged', { model }, {toServer : true}); + zk.Widget.$('$flowchartDataListener').fire('onSaveFlowchartData', { model }, {toServer : true}); } function deleteSelectedElement(){ diff --git a/server/user.mediacube.gui/pages/parameterEditor2.zul b/server/user.mediacube.gui/pages/parameterEditor2.zul new file mode 100644 index 00000000..9022957e --- /dev/null +++ b/server/user.mediacube.gui/pages/parameterEditor2.zul @@ -0,0 +1,49 @@ + + + + + diff --git a/server/user.mediacube.gui/pages/processVisualizer2.zul b/server/user.mediacube.gui/pages/processVisualizer2.zul index 571495fb..47322736 100644 --- a/server/user.mediacube.gui/pages/processVisualizer2.zul +++ b/server/user.mediacube.gui/pages/processVisualizer2.zul @@ -1,21 +1,49 @@ - -
- - - -
- -
-
- -
-
-
- - + + +
+
+ +
+ + + +
+ + +
+
+ +
+
+
+
+ + +
+
+ + + +
+ + + + + + + + + + + + + + +
+
+
diff --git a/server/user.mediacube.gui/pages/stepEditor2.zul b/server/user.mediacube.gui/pages/stepEditor2.zul new file mode 100644 index 00000000..6d304770 --- /dev/null +++ b/server/user.mediacube.gui/pages/stepEditor2.zul @@ -0,0 +1,40 @@ + + + +
+
+
+
\ No newline at end of file diff --git a/server/user.mediacube.gui/src/user/jobengine/zk/model/JobFlowChartModel.java b/server/user.mediacube.gui/src/user/jobengine/zk/model/JobFlowChartModel.java index 5e6b1401..1f4abdc2 100644 --- a/server/user.mediacube.gui/src/user/jobengine/zk/model/JobFlowChartModel.java +++ b/server/user.mediacube.gui/src/user/jobengine/zk/model/JobFlowChartModel.java @@ -1,17 +1,35 @@ package user.jobengine.zk.model; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import org.zkoss.bind.BindUtils; import org.zkoss.bind.annotation.AfterCompose; import org.zkoss.bind.annotation.BindingParam; import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.ContextParam; import org.zkoss.bind.annotation.ContextType; import org.zkoss.bind.annotation.GlobalCommand; +import org.zkoss.bind.annotation.NotifyChange; import org.zkoss.json.JSONArray; import org.zkoss.json.JSONObject; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.InputEvent; import org.zkoss.zk.ui.event.SelectEvent; @@ -19,11 +37,15 @@ import org.zkoss.zk.ui.select.Selectors; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Tab; +import com.ibm.nosql.json.api.BasicDBList; import com.ibm.nosql.json.api.BasicDBObject; -import user.commons.xml.XMLUtils; +import user.commons.nosql.NoSQLUtils; +import user.jobengine.gui.ComponentBinder; +import user.jobengine.server.IJobEngine; import user.jobengine.server.ast.CallJobStepCommand; import user.jobengine.server.ast.CommandSequence; +import user.jobengine.server.ast.Declaration; import user.jobengine.server.ast.DeclarationSequence; import user.jobengine.server.ast.InputParameter; import user.jobengine.server.ast.InputParameterSequence; @@ -35,22 +57,42 @@ import user.jobengine.server.ast.ParameterExpression; import user.jobengine.server.ast.VariableDeclaration; import user.jobengine.server.ast.VariableExpression; import user.jobengine.server.ast.VariableName; -import user.jobengine.server.ast.XMLEncoder; public class JobFlowChartModel extends BaseModel { private static final Logger logger = LogManager.getLogger(); private String selectedTabID = "tab0"; private BasicDBObject selectedJob; + private JobTemplate jobTemplate; + private BasicDBObject editingJob; private String selectedNewStep = ""; + private JSONObject selectedStep = new JSONObject(); + private ArrayList steps; + private IJobEngine jobEngine; + private ArrayList inputTypes = new ArrayList(2); + private String changedInputName; @AfterCompose + @NotifyChange({ "steps" }) public void afterCompose(@ContextParam(ContextType.VIEW) Component view) { Selectors.wireComponents(view, this, false); + jobEngine = (IJobEngine) Executions.getCurrent().getArg().get("jobEngine"); + if (jobEngine == null) + jobEngine = ComponentBinder.getJobEngine(); + + steps = jobEngine.getJobEngineConfiguration().getSteps(); + initializeInputTypes(); + } + + private void initializeInputTypes() { + getInputTypes().add("variable"); + getInputTypes().add("param"); } @GlobalCommand + @NotifyChange("selectedJob") public void selectedJobChanged(@BindingParam("selectedJob") BasicDBObject selectedJob) { - setSelectedJob(selectedJob); + this.selectedJob = selectedJob; + this.jobTemplate = StringToJobTemplate((String) selectedJob.get("xml")); if (selectedTabID.equals("tab2")) { visualizeSelectedJob(); @@ -63,12 +105,32 @@ public class JobFlowChartModel extends BaseModel { } @Command - public void onFlowchartDataChanged(@ContextParam(ContextType.TRIGGER_EVENT) Event event) { - logger.info("onFlowchartDataChanged"); - XMLEncoder xmlEncoder = new XMLEncoder(); - JobTemplate jobTemplate = JSONObjectToJobtemplate((JSONObject) ((JSONObject) event.getData()).get("model")); - Document document = (Document) xmlEncoder.visitJobTemplate(jobTemplate, null); - logger.info("converted document: {}", XMLUtils.getStringFromDocument(document)); + @NotifyChange("selectedStep") + public void onNodeSelected(@BindingParam("evt") Event event) { + if (event == null) { + logger.info("event == null"); + return; + } + JSONObject model = (JSONObject) ((JSONObject) event.getData()).get("model"); + Integer selectedIndex = (Integer) model.get("selNode"); + if (selectedIndex != null) { + selectedStep = (JSONObject) ((JSONObject) event.getData()).get("model"); + BindUtils.postNotifyChange(null, null, selectedStep, "selectedStep"); + } + } + + @Command + public void onSaveFlowchartData(@ContextParam(ContextType.TRIGGER_EVENT) Event event) { + logger.info("onSaveFlowchartData"); + try { + jobEngine.getJobEngineConfiguration().saveSchedulesJson(selectedJob, editingJob); + jobTemplate.setFileName(editingJob.getString("template")); + jobEngine.getJobEngineConfiguration().saveTemplateXml(jobTemplate); + selectedJob = NoSQLUtils.deepCopy(editingJob); + editingJob = null; + } catch (Exception e) { + logger.info("e: {}", e.getMessage()); + } } @Command @@ -76,7 +138,108 @@ public class JobFlowChartModel extends BaseModel { logger.info("addNewStep"); if (!selectedNewStep.isEmpty()) { Clients.evalJavaScript("model.addNode(new model.node(100, 100, 100, 100, connectorsForStep, \"" - + selectedNewStep + "\", \"\", \"RectangleWithGradient\", null, null));\r\n model.draw();"); + + selectedNewStep + "\", \"\", \"RectangleWithGradient\", null, null, 1 ));\r\n model.draw();"); + } + } + + @Command + public void onInputNameChanged(@BindingParam("name") String name, @BindingParam("evt") InputEvent event) { + logger.info("onInputNameChanged"); + changedInputName = (String) event.getPreviousValue(); + setParameterProperty(changedInputName, event, "name"); + setParamNameInTemplate(event); + setParamNameInProgram(event); + changedInputName = (String) event.getValue(); + } + + private void setParamNameInProgram(InputEvent event) { + BasicDBList nodes = (BasicDBList) ((BasicDBObject) editingJob.get("program")).get("nodes"); + for (int i = 0; i < nodes.size(); i++) { + BasicDBObject node = (BasicDBObject) nodes.get(i); + BasicDBList inputs = (BasicDBList) node.get("inputs"); + + for (int j = 0; j < inputs.size(); j++) { + BasicDBObject input = (BasicDBObject) inputs.get(j); + if (input.get("name").equals(changedInputName)) { + input.put("name", event.getValue()); + break; + } + } + } + } + + private void setParamNameInTemplate(InputEvent event) { + List declarations = jobTemplate.getDeclarationSequence().getDeclarations(); + for (int i = 0; i < declarations.size(); i++) { + Declaration declaration = declarations.get(i); + if (declaration.getName().equals(changedInputName)) { + declaration.setName(event.getValue()); + break; + } + } + + List commands = jobTemplate.getCommandSequence().getCommands(); + for (int i = 0; i < commands.size(); i++) { + CallJobStepCommand cjs = (CallJobStepCommand) commands.get(i); + InputParameterSequence ips = (InputParameterSequence) cjs.getInputParameterSequence(); + for (int j = 0; j < ips.getParameters().size(); j++) { + InputParameter inputParameter = (InputParameter) ips.getParameters().get(j); + if (inputParameter.getExpression().getName().equals(changedInputName)) { + inputParameter.getExpression().setName(event.getValue()); + break; + } + } + OutputParameterSequence ops = (OutputParameterSequence) cjs.getOutputParameterSequence(); + if (ops != null) { + for (int j = 0; j < ops.getParameters().size(); j++) { + OutputParameter outputParameter = (OutputParameter) ops.getParameters().get(j); + if (outputParameter.getVariableName().getName().equals(changedInputName)) { + outputParameter.getVariableName().setName(event.getValue()); + break; + } + } + } + + } + } + + @Command + public void onInputValueChanged(@BindingParam("name") String name, @BindingParam("evt") InputEvent event) { + logger.info("onInputValueChanged"); + if (changedInputName == null) { + changedInputName = name; + } + setParameterProperty(changedInputName, event, "value"); + } + + @Command + public void onInputTypeChanged(@BindingParam("name") String name, @BindingParam("evt") InputEvent event) { + logger.info("onInputTypeChanged"); + if (changedInputName == null) { + changedInputName = name; + } + setParameterProperty(changedInputName, event, "type"); + List declarations = jobTemplate.getDeclarationSequence().getDeclarations(); + for (int i = 0; i < declarations.size(); i++) { + Declaration declaration = declarations.get(i); + if (declaration.getName().equals(changedInputName)) { + declaration.setType(event.getValue()); + break; + } + } + } + + private void setParameterProperty(String name, InputEvent event, String propertyName) { + if (editingJob == null) { + editingJob = NoSQLUtils.deepCopy(selectedJob); + } + BasicDBList parameters = (BasicDBList) editingJob.get("parameters"); + for (int i = 0; i < parameters.size(); i++) { + BasicDBObject item = (BasicDBObject) parameters.get(i); + if (item.get("name").equals(changedInputName)) { + item.put(propertyName, event.getValue()); + break; + } } } @@ -117,16 +280,19 @@ public class JobFlowChartModel extends BaseModel { for (int i = 0; i < steps.size(); i++) { JSONObject node = (JSONObject) steps.get(i); - if (!node.get("text").toString().isEmpty()) { + String type = node.get("text").toString(); + if (!type.isEmpty()) { + Integer weight = (Integer) node.get("weight"); JSONArray inputs = (JSONArray) node.get("inputs"); InputParameterSequence ips = new InputParameterSequence(); if (inputs != null) { for (int j = 0; j < inputs.size(); j++) { JSONObject input = (JSONObject) inputs.get(j); + String name = input.get("name").toString(); if (input.get("type").toString().equals("param")) { - ips.addParameter(new InputParameter(new ParameterExpression(input.get("name").toString()))); + ips.addParameter(new InputParameter(new ParameterExpression(name))); } else { - ips.addParameter(new InputParameter(new VariableExpression(input.get("name").toString()))); + ips.addParameter(new InputParameter(new VariableExpression(name))); } } } @@ -146,8 +312,12 @@ public class JobFlowChartModel extends BaseModel { if (ops != null) { command.setOutputParameterSequence(ops); } - command.setType(node.get("text").toString().concat("Step.java")); - command.setWeight(1); + if (type.contains(".java")) { + command.setType(type); + } else { + command.setType(type.concat(".java")); + } + command.setWeight(weight); cs.addCommand(command); } } @@ -171,12 +341,17 @@ public class JobFlowChartModel extends BaseModel { } private void drawSelectedJob() { - BasicDBObject program = (BasicDBObject) selectedJob.get("program"); - Clients.evalJavaScript("setFlowchartData('" + program.toString() + "');"); + if (selectedJob != null) { + BasicDBObject program = (BasicDBObject) selectedJob.get("program"); + Clients.evalJavaScript("setFlowchartData('" + program.toString() + "');"); + } else { + logger.info("selectedJob == null"); + } } private void initializeCanvas() { - String js = "mouse.selNode= null;\r\n mouse.selLink= null;\r\n model.clear();\r\n model.clean();\r\n model.draw();"; + String js = "mouse.selNode= null;\r\n mouse.selLink= null;\r\n model.clear();\r\n " + + "model.clean();\r\n model.draw();"; Clients.evalJavaScript(js); } @@ -184,7 +359,183 @@ public class JobFlowChartModel extends BaseModel { this.selectedTabID = selectedTabID; } + public BasicDBObject getSelectedJob() { + return selectedJob; + } + public void setSelectedJob(BasicDBObject selectedJob) { this.selectedJob = selectedJob; } + + public JSONObject getSelectedStep() { + return selectedStep; + } + + public void setSelectedStep(JSONObject selectedStep) { + this.selectedStep = selectedStep; + } + + public ArrayList getSteps() { + return steps; + } + + public ArrayList getInputTypes() { + return inputTypes; + } + + public JobTemplate StringToJobTemplate(String str) { + JobTemplate template = new JobTemplate(); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + Document document = null; + try { + builder = factory.newDocumentBuilder(); + byte[] bytes = str.getBytes(); + ByteBuffer bb = ByteBuffer.wrap(bytes); + + byte[] bom = new byte[3]; + // get the first 3 bytes + bb.get(bom, 0, bom.length); + + // remaining content + byte[] contentAfterFirst3Bytes = new byte[bytes.length - 3]; + bb.get(contentAfterFirst3Bytes, 0, contentAfterFirst3Bytes.length); + + String str1 = new String(contentAfterFirst3Bytes, StandardCharsets.UTF_8); + document = builder.parse(new InputSource(new StringReader(str1))); + for (int i = 0; i < document.getChildNodes().getLength(); i++) { + Node node = document.getChildNodes().item(i); + if (node.getNodeName().equals("jobtemplate")) { + String useSessionLog = node.getAttributes().getNamedItem("useSessionLog").getNodeValue(); + template.setUseSessionLog(Boolean.parseBoolean(useSessionLog)); + + if (node.getAttributes().getNamedItem("multiInstance") != null) { + String multiInstance = node.getAttributes().getNamedItem("multiInstance").getNodeValue(); + template.setMultiInstance(Boolean.parseBoolean(multiInstance)); + } + + for (int j = 0; j < node.getChildNodes().getLength(); j++) { + Node item = node.getChildNodes().item(j); + String nodeName = item.getNodeName(); + if (nodeName.equals("declarations")) { + addDeclarations(template, item); + } else if (nodeName.equals("commands")) { + addCommands(template, item); + } + } + } + } + } catch (Exception e) { + logger.info("exception: {}", e.getMessage()); + } + return template; + } + + private void addCommands(JobTemplate template, Node commands) { + CommandSequence cs = new CommandSequence(); + template.setCommandSequence(cs); + for (int i = 0; i < commands.getChildNodes().getLength(); i++) { + Node command = commands.getChildNodes().item(i); + if (command.getNodeName().equals("calljobstep")) { + appendCommand(command, template); + } + } + } + + private void appendCommand(Node command, JobTemplate template) { + CallJobStepCommand cjs = new CallJobStepCommand(); + cjs.setType(command.getAttributes().getNamedItem("type").getNodeValue()); + cjs.setWeight(Integer.parseInt(command.getAttributes().getNamedItem("weight").getNodeValue())); + + Node inputs = command.getChildNodes().item(1); + InputParameterSequence ips = new InputParameterSequence(); + for (int i = 0; i < inputs.getChildNodes().getLength(); i++) { + Node child = inputs.getChildNodes().item(i); + if (child.getNodeName().equals("input")) { + Node input = child.getChildNodes().item(1); + if (input.getNodeName().equals("variable")) { + ips.addParameter(new InputParameter( + new VariableExpression(input.getAttributes().getNamedItem("name").getNodeValue()))); + } + if (input.getNodeName().equals("parameter")) { + ips.addParameter(new InputParameter( + new ParameterExpression(input.getAttributes().getNamedItem("name").getNodeValue()))); + } + } + } + if (!ips.getParameters().isEmpty()) { + cjs.setInputParameterSequence(ips); + } + + Node outputs = command.getChildNodes().item(3); + if (outputs != null) { + OutputParameterSequence ops = new OutputParameterSequence(); + cjs.setOutputParameterSequence(ops); + for (int i = 0; i < outputs.getChildNodes().getLength(); i++) { + Node child = outputs.getChildNodes().item(i); + if (child.getNodeName().equals("output")) { + Node variable = child.getChildNodes().item(1); + ops.addParameter(new OutputParameter( + new VariableName(variable.getAttributes().getNamedItem("name").getNodeValue()))); + } + } + } + if (!template.getCommandSequence().getCommands().contains(cjs)) { + template.getCommandSequence().addCommand(cjs); + } + } + + private void addDeclarations(JobTemplate template, Node declarations) { + DeclarationSequence ds = new DeclarationSequence(); + template.setDeclarationSequence(ds); + for (int i = 0; i < declarations.getChildNodes().getLength(); i++) { + Node pv = declarations.getChildNodes().item(i); + if (pv.getNodeName().equals("variables")) { + appendVariableDeclarations(pv, template); + } else if (pv.getNodeName().equals("parameters")) { + appendParameterDeclarations(pv, template); + } + } + } + + private void appendVariableDeclarations(Node pv, JobTemplate template) { + for (int i = 0; i < pv.getChildNodes().getLength(); i++) { + Node variable = pv.getChildNodes().item(i); + if (variable.getAttributes() != null) { + template.getDeclarationSequence().addDeclaration( + new VariableDeclaration(variable.getAttributes().getNamedItem("name").getNodeValue(), + variable.getAttributes().getNamedItem("type").getNodeValue())); + } + } + } + + private void appendParameterDeclarations(Node pv, JobTemplate template) { + for (int i = 0; i < pv.getChildNodes().getLength(); i++) { + Node parameter = pv.getChildNodes().item(i); + if (parameter.getAttributes() != null) { + template.getDeclarationSequence().addDeclaration( + new ParameterDeclaration(parameter.getAttributes().getNamedItem("name").getNodeValue(), + parameter.getAttributes().getNamedItem("type").getNodeValue())); + } + } + } + + private boolean containsBOM(String str) throws IOException { + boolean result = false; + + byte[] bom = new byte[3]; + try (InputStream is = IOUtils.toInputStream(str)) { + + // read 3 bytes of a file. + is.read(bom); + + // BOM encoded as EF BB BF + String content = new String(Hex.encodeHex(bom)); + if ("efbbbf".equalsIgnoreCase(content)) { + result = true; + } + } + + return result; + } } \ No newline at end of file -- 2.54.0