415: folyamat/step szerkesztő
authorOmar Sweidan <omar.sweidan@userrendszerhaz.hu>
Tue, 28 Jun 2022 07:49:57 +0000 (09:49 +0200)
committerOmar Sweidan <omar.sweidan@userrendszerhaz.hu>
Tue, 28 Jun 2022 07:50:48 +0000 (09:50 +0200)
server/user.jobengine.osgi.server/src/user/jobengine/server/JobEngineConfiguration.java
server/user.jobengine.osgi.server/src/user/jobengine/server/ast/JSONEncoder.java
server/user.mediacube.gui/js/diagramflowjs.js
server/user.mediacube.gui/js/processVisualizer2.js
server/user.mediacube.gui/pages/parameterEditor2.zul [new file with mode: 0644]
server/user.mediacube.gui/pages/processVisualizer2.zul
server/user.mediacube.gui/pages/stepEditor2.zul [new file with mode: 0644]
server/user.mediacube.gui/src/user/jobengine/zk/model/JobFlowChartModel.java

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