--- /dev/null
+{\r
+ "info" : \r
+ {\r
+ "name" : "org.argeo.ria.sample",\r
+\r
+ "summary" : "Sample RIA Application",\r
+ "description" : "Basic RIA Implementation for documentation purposes",\r
+ \r
+ "homepage" : "http://www.argeo.org/",\r
+\r
+ "license" : "LGPL",\r
+ "authors" : \r
+ [\r
+ {\r
+ "name" : "Charles du Jeu",\r
+ "email" : "charles.dujeu@gmail.com"\r
+ }\r
+ ],\r
+\r
+ "version" : "trunk",\r
+ "qooxdoo-versions": ["0.8"]\r
+ },\r
+ \r
+ "provides" : \r
+ {\r
+ "namespace" : "org.argeo.ria.sample",\r
+ "encoding" : "utf-8",\r
+ "class" : "class",\r
+ "resource" : "resource",\r
+ "translation" : "translation",\r
+ "type" : "library"\r
+ }\r
+}\r
+\r
--- /dev/null
+/**
+ * A simple Hello World applet for documentation purpose.
+ * The only associated command is the "Close" command.
+ */
+qx.Class.define("org.argeo.ria.sample.Applet",
+{
+ extend : qx.ui.container.Composite,
+ implement : [org.argeo.ria.components.IView],
+
+ construct : function(){
+ this.base(arguments);
+ this.setLayout(new qx.ui.layout.VBox());
+ this.passedStatus = "PASSED";
+ this.failedStatus = "FAILED";
+ },
+
+ properties :
+ {
+ /**
+ * The viewPane inside which this applet is added.
+ */
+ view : {
+ init : null
+ },
+ /**
+ * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
+ */
+ commands : {
+ init : {
+ "close" : {
+ label : "Close Result",
+ icon : "resource/slc/window-close.png",
+ shortcut : "Control+w",
+ enabled : true,
+ menu : "Applet",
+ toolbar : "result",
+ callback : function(e){
+ // Call service to delete
+ this.getView().empty();
+ },
+ command : null
+ }
+ }
+ },
+ viewSelection : {
+ nullable:false,
+ check:"org.argeo.ria.components.ViewSelection"
+ },
+ instanceId : {init:"Hello Applet"},
+ instanceLabel : {init:"Hello"}
+
+ },
+
+ members :
+ {
+ /**
+ * Called at applet creation. Just registers viewPane.
+ * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
+ */
+ init : function(viewPane, data){
+ this.setView(viewPane);
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
+ this.data = data;
+ this.setInstanceId(data[0]);
+ this.setInstanceLabel("Hello applet #"+data[0]);
+ },
+
+ /**
+ * Load a given row : the data passed must be a simple data array.
+ * @param data {Element} The text xml description.
+ */
+ load : function(){
+ this.createHtmlGui("<b>Hello World ! Data ID is : "+this.getInstanceId()+"</b>");
+ },
+
+ addScroll : function(){
+ return false;
+ },
+
+ close : function(){
+ return false;
+ },
+
+ /**
+ * Create a simple HtmlElement and and insert the html string..
+ * Not used but sample.
+ * @param htmlText {String} Html code to display.
+ */
+ createHtmlGui : function(htmlText){
+ var htmlElement = new qx.ui.embed.Html(htmlText);
+ htmlElement.setOverflowX("auto");
+ htmlElement.setOverflowY("auto");
+ this.add(htmlElement, {flex:1});
+ }
+
+ }
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * A Basic IView implementation displaying a fake list of result and opening \r
+ * an org.argeo.ria.sample.Applet\r
+ */\r
+qx.Class.define("org.argeo.ria.sample.List",\r
+{\r
+ extend : qx.ui.container.Composite,\r
+ implement : [org.argeo.ria.components.IView], \r
+\r
+ construct : function(){\r
+ this.base(arguments, new qx.ui.layout.VBox()); \r
+ var model = new qx.ui.table.model.Simple();\r
+ model.setColumns(["Test Case", "Date"]);\r
+ this.table = new qx.ui.table.Table(model, {\r
+ tableColumnModel: function(obj){\r
+ return new qx.ui.table.columnmodel.Resize(obj)\r
+ }\r
+ });\r
+ },\r
+\r
+ properties : \r
+ {\r
+ /**\r
+ * The viewPane containing this applet.\r
+ */\r
+ view : {\r
+ init : null\r
+ },\r
+ /**\r
+ * The applet commands.\r
+ */\r
+ commands : {\r
+ init : {\r
+ "opentest" : {\r
+ label : "Open", \r
+ icon : "resource/slc/media-playback-start.png",\r
+ shortcut : "Control+o",\r
+ enabled : false,\r
+ menu : "Selection",\r
+ toolbar : "selection",\r
+ callback : function(e){\r
+ var viewsManager = org.argeo.ria.components.ViewsManager.getInstance();\r
+ var classObj = org.argeo.ria.sample.Applet;\r
+ var rowData = viewsManager.getViewPaneSelection("list").getNodes();\r
+ var iView = viewsManager.initIViewClass(classObj, "applet", rowData[0]);\r
+ iView.load();\r
+ },\r
+ selectionChange : function(viewId, rowData){\r
+ if(viewId != "list") return;\r
+ this.setEnabled(false);\r
+ if(rowData == null || !rowData.length) return;\r
+ this.setEnabled(true);\r
+ },\r
+ command : null\r
+ }\r
+ }\r
+ },\r
+ viewSelection : {\r
+ nullable:false, \r
+ check:"org.argeo.ria.components.ViewSelection"\r
+ },\r
+ instanceId : {init:"0"},\r
+ instanceLabel : {init:"Sample List"} \r
+ },\r
+ \r
+ members : {\r
+ init : function(viewPane, data){\r
+ this.setView(viewPane);\r
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));\r
+ \r
+ },\r
+ load : function(){\r
+ //\r
+ // Customize table appearance\r
+ //\r
+ this.table.set({ \r
+ statusBarVisible: false,\r
+ showCellFocusIndicator:false,\r
+ columnVisibilityButtonVisible:false,\r
+ contextMenu : org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["opentest", "download", "copytocollection", "deletetest"]),\r
+ decorator : new qx.ui.decoration.Background("#fff")\r
+ });\r
+ \r
+ // \r
+ // Link table selection changes to the standard viewSelection mechanism\r
+ //\r
+ var selectionModel = this.table.getSelectionManager().getSelectionModel();\r
+ selectionModel.addListener("changeSelection", function(e){\r
+ var viewSelection = this.getViewSelection();\r
+ viewSelection.clear();\r
+ if(!selectionModel.getSelectedCount()){\r
+ return;\r
+ }\r
+ var ranges = selectionModel.getSelectedRanges();\r
+ var rowData = this.table.getTableModel().getRowData(ranges[0].minIndex);\r
+ viewSelection.addNode(rowData);\r
+ }, this); \r
+ \r
+ //\r
+ // Add table to the GUI component\r
+ // \r
+ this.add(this.table, {flex:1});\r
+\r
+ //\r
+ // Now create fake rows\r
+ // \r
+ var model = this.table.getTableModel();\r
+ model.addRows([\r
+ ["Id 1","Sample 1"], \r
+ ["Id 2","Sample 2"],\r
+ ["Id 3","Sample 3"]\r
+ ]);\r
+ },\r
+ \r
+ addScroll : function(){\r
+ return false;\r
+ },\r
+ \r
+ close : function(){\r
+ \r
+ }\r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
+ */\r
+qx.Class.define("org.argeo.ria.sample.Perspective",\r
+{\r
+ extend : qx.core.Object,\r
+ implement : [org.argeo.ria.components.IPerspective], \r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ },\r
+ \r
+ members : {\r
+ \r
+ initViewPanes : function(viewsManager){\r
+ \r
+ this.splitPane = new qx.ui.splitpane.Pane("horizontal");\r
+ var topLeft = new org.argeo.ria.components.ViewPane("list", "Sample List", {\r
+ orientation : "horizontal",\r
+ min : 36\r
+ });\r
+ topLeft.set({width:300});\r
+ viewsManager.registerViewPane(topLeft);\r
+ \r
+ this.splitPane.add(topLeft, 0);\r
+ var rightPane = new org.argeo.ria.components.ViewPane("applet", "Sample Applet"); \r
+ viewsManager.registerViewPane(rightPane);\r
+ this.splitPane.add(rightPane, 1);\r
+ \r
+ viewsManager.getViewPanesContainer().add(this.splitPane, {flex:1});\r
+ \r
+ },\r
+ \r
+ initViews : function(viewsManager){\r
+ var view = viewsManager.initIViewClass(org.argeo.ria.sample.List, "list");\r
+ view.load();\r
+ },\r
+ \r
+ remove : function(viewsManager){\r
+ viewsManager.getViewPaneById("list").empty();\r
+ viewsManager.getViewPaneById("applet").empty();\r
+ viewsManager.getViewPanesContainer().remove(this.splitPane);\r
+ }\r
+ \r
+ }\r
+\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Specific classes used for training by the Argeo RIA documentation\r
+ */
\ No newline at end of file
--- /dev/null
+{\r
+ "info" : \r
+ {\r
+ "name" : "org.argeo.slc.web",\r
+\r
+ "summary" : "Slc Web Application",\r
+ "description" : "RIA Implementation for SLC Web",\r
+ \r
+ "homepage" : "http://www.argeo.org/",\r
+\r
+ "license" : "LGPL",\r
+ "authors" : \r
+ [\r
+ {\r
+ "name" : "Charles du Jeu",\r
+ "email" : "charles.dujeu@gmail.com"\r
+ }\r
+ ],\r
+\r
+ "version" : "trunk",\r
+ "qooxdoo-versions": ["0.8"]\r
+ },\r
+ \r
+ "provides" : \r
+ {\r
+ "namespace" : "org.argeo.slc.web",\r
+ "encoding" : "utf-8",\r
+ "class" : "class",\r
+ "resource" : "resource",\r
+ "translation" : "translation",\r
+ "type" : "library"\r
+ }\r
+}\r
+\r
--- /dev/null
+/**\r
+ * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
+ */\r
+qx.Class.define("org.argeo.slc.web.LauncherPerspective",\r
+{\r
+ extend : qx.core.Object,\r
+ implement : [org.argeo.ria.components.IPerspective], \r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ org.argeo.ria.util.Element.DEFAULT_NAMESPACE_MAP = {slc:"http://argeo.org/projects/slc/schemas"};\r
+ },\r
+\r
+ statics : {\r
+ LABEL : "Slc Execution",\r
+ ICON : "resource/slc/utilities-terminal.png"\r
+ },\r
+ \r
+ members : {\r
+ \r
+ _rightPane : null,\r
+ \r
+ initViewPanes : function(viewsManager){\r
+\r
+ this._splitPane = new qx.ui.splitpane.Pane("horizontal");\r
+ var topLeft = new org.argeo.ria.components.ViewPane("form", "Execution Launcher", {\r
+ orientation : "horizontal",\r
+ min : 36\r
+ });\r
+ topLeft.set({width:290});\r
+ viewsManager.registerViewPane(topLeft);\r
+ \r
+ this._splitPane.add(topLeft, 0);\r
+ var rightPane = new org.argeo.ria.components.ViewPane("main", "Executions Log"); \r
+ viewsManager.registerViewPane(rightPane);\r
+ this._splitPane.add(rightPane, 1);\r
+ \r
+ viewsManager.getViewPanesContainer().add(this._splitPane, {flex:1});\r
+ \r
+ },\r
+ \r
+ initViews : function(viewsManager){\r
+ var formApplet = viewsManager.initIViewClass(org.argeo.slc.ria.NewLauncherApplet, "form");\r
+ formApplet.load();\r
+ \r
+ var logger = viewsManager.initIViewClass(org.argeo.slc.ria.SlcExecLoggerApplet, "main");\r
+ logger.load();\r
+ },\r
+ \r
+ remove : function(viewsManager){\r
+ viewsManager.getViewPaneById("main").empty();\r
+ viewsManager.getViewPaneById("form").empty();\r
+ viewsManager.getViewPanesContainer().remove(this._splitPane); \r
+ } \r
+ \r
+ }\r
+\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
+ */\r
+qx.Class.define("org.argeo.slc.web.Perspective",\r
+{\r
+ extend : qx.core.Object,\r
+ implement : [org.argeo.ria.components.IPerspective], \r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ org.argeo.ria.util.Element.DEFAULT_NAMESPACE_MAP = {slc:"http://argeo.org/projects/slc/schemas"};\r
+ },\r
+ \r
+ statics : {\r
+ LABEL : "Test Results",\r
+ ICON : "resource/slc/office-chart.png"\r
+ },\r
+ \r
+ members : {\r
+ _splitPane : null, \r
+ \r
+ initViewPanes : function(viewsManager){\r
+ \r
+ this._splitPane = new qx.ui.splitpane.Pane("horizontal");\r
+ var topLeft = new org.argeo.ria.components.ViewPane("list", "Collection", {\r
+ orientation : "horizontal",\r
+ min : 36\r
+ });\r
+ topLeft.set({width:300});\r
+ viewsManager.registerViewPane(topLeft);\r
+ \r
+ this._splitPane.add(topLeft, 0);\r
+ var rightPane = new org.argeo.ria.components.TabbedViewPane("applet", "Test Detail"); \r
+ viewsManager.registerViewPane(rightPane);\r
+ this._splitPane.add(rightPane, 1);\r
+ \r
+ viewsManager.getViewPanesContainer().add(this._splitPane, {flex:1});\r
+ \r
+ },\r
+ \r
+ initViews : function(viewsManager){\r
+ var view = viewsManager.initIViewClass(org.argeo.slc.web.TestList, "list");\r
+ view.load();\r
+ view.loadCollections();\r
+ view.loadList();\r
+ },\r
+ \r
+ remove : function(viewsManager){\r
+ viewsManager.getViewPaneById("list").empty();\r
+ viewsManager.getViewPaneById("applet").empty();\r
+ viewsManager.getViewPanesContainer().remove(this._splitPane); \r
+ }\r
+ \r
+ }\r
+\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Basic IView implementation for displaying the test results list, by collection.\r
+ * \r
+ * This component creates a Table object and feed it with the results. It adds a collection chooser to its viewPane header.\r
+ * \r
+ * It creates the following commands : "loadtestlist", "polllistloading", "opentest", "download", "copytocollection", "deletetest".\r
+ */\r
+qx.Class.define("org.argeo.slc.web.TestList",\r
+{\r
+ extend : qx.ui.container.Composite,\r
+ implement : [org.argeo.ria.components.IView], \r
+\r
+ construct : function(){\r
+ this.base(arguments, new qx.ui.layout.VBox()); \r
+ var model = new qx.ui.table.model.Simple();\r
+ model.setColumns(["Test Case", "Date"]);\r
+ this.table = new qx.ui.table.Table(model, {\r
+ tableColumnModel: function(obj){\r
+ return new qx.ui.table.columnmodel.Resize(obj)\r
+ }\r
+ });\r
+ },\r
+\r
+ properties : \r
+ {\r
+ /**\r
+ * The viewPane containing this applet.\r
+ */\r
+ view : {\r
+ init : null\r
+ },\r
+ viewSelection : {\r
+ nullable:false, \r
+ check:"org.argeo.ria.components.ViewSelection"\r
+ }, \r
+ instanceId : {init:""},\r
+ instanceLabel : {init:""},\r
+ /**\r
+ * The load list of available collection (Map of ids => labels)\r
+ */\r
+ collectionList : {\r
+ init : {},\r
+ check : "Map"\r
+ },\r
+ /**\r
+ * The current collection id selected.\r
+ */\r
+ collectionId:{\r
+ init : 'My Collection',\r
+ check : "String"\r
+ },\r
+ /**\r
+ * The applet commands.\r
+ */\r
+ commands : {\r
+ init : {\r
+ "loadtestlist" : {\r
+ label : "Load Collection", \r
+ icon : "resource/slc/view-refresh.png",\r
+ shortcut : "Control+l",\r
+ enabled : true,\r
+ menu : "Collection",\r
+ toolbar : "collection",\r
+ callback : function(e){\r
+ this.loadList();\r
+ }, \r
+ command : null\r
+ },\r
+ "polllistloading" : {\r
+ label : "Auto load", \r
+ icon : "resource/slc/document-open-recent.png",\r
+ shortcut : "Control+l",\r
+ enabled : true,\r
+ toggle : true,\r
+ menu : "Collection",\r
+ toolbar : "collection",\r
+ callback : function(event){\r
+ this.pollListLoading(event.getTarget().getUserData("slc.command.toggleState"));\r
+ }, \r
+ command : null\r
+ },\r
+ /*\r
+ "copyfullcollection" : {\r
+ label : "Copy to...", \r
+ icon : "resource/slc/edit-copy.png",\r
+ shortcut : null,\r
+ enabled : false,\r
+ menu : "Collection",\r
+ toolbar : "collection",\r
+ callback : function(e){\r
+ // Call service to copy\r
+ },\r
+ submenu : {},\r
+ submenuCallback : function(commandId){\r
+ this.copySelectionToCollection(commandId, "current_collection");\r
+ },\r
+ init : function(){\r
+ // Call at command creation\r
+ org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(event){\r
+ if(event.getDataType() == "collection" || event.getDataType() == "test_cases"){\r
+ var testList = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("list").getContent();\r
+ testList.collectionListToMenu(this);\r
+ }\r
+ }, this);\r
+ },\r
+ command : null\r
+ },\r
+ */\r
+ "opentest" : {\r
+ label : "Open", \r
+ icon : "resource/slc/media-playback-start.png",\r
+ shortcut : "Control+o",\r
+ enabled : false,\r
+ menu : "Selection",\r
+ toolbar : "selection",\r
+ callback : function(e){\r
+ var viewsManager = org.argeo.ria.components.ViewsManager.getInstance();\r
+ var classObj = org.argeo.slc.ria.Applet;\r
+ var xmlNodes = viewsManager.getViewPaneSelection("list").getNodes();\r
+ var iView = viewsManager.initIViewClass(classObj, "applet", xmlNodes[0]);\r
+ iView.load(xmlNodes[0]);\r
+ },\r
+ selectionChange : function(viewId, xmlNodes){\r
+ if(viewId != "list") return;\r
+ this.setEnabled(false);\r
+ if(xmlNodes == null || !xmlNodes.length) return;\r
+ this.setEnabled(true);\r
+ },\r
+ command : null\r
+ },\r
+ "download" : {\r
+ label : "Download as...", \r
+ icon : "resource/slc/go-down.png",\r
+ shortcut : null,\r
+ enabled : false,\r
+ menu : "Selection",\r
+ toolbar : "selection",\r
+ callback : function(e){ },\r
+ command : null,\r
+ submenu : [\r
+ {'label':"Xsl", 'icon':'resource/slc/mime-xsl.png', 'commandId':'xsl'},\r
+ {'label':"Xml", 'icon':'resource/slc/mime-xml.png', 'commandId':'xml'},\r
+ {'label':"Excel", 'icon':'resource/slc/mime-xls.png', 'commandId':'xls'},\r
+ {'label':"Pdf", 'icon':'resource/slc/mime-pdf.png', 'commandId':'pdf'}\r
+ ],\r
+ submenuCallback : function(commandId){\r
+ var uuid = this.extractTestUuid();\r
+ var urls = {\r
+ xsl : "resultView.xslt",\r
+ xml : "resultViewXml.xslt",\r
+ xls : "resultView.xls",\r
+ pdf : "resultView.pdf"\r
+ };\r
+ var url = "../"+urls[commandId]+"?uuid="+uuid;\r
+ if(commandId == "xls" || commandId == "pdf"){\r
+ document.location.href = url;\r
+ }else{\r
+ var win = window.open(url);\r
+ }\r
+ },\r
+ selectionChange : function(viewId, xmlNodes){\r
+ if(viewId!="list")return;\r
+ //this.clearMenus();\r
+ this.setEnabled(false);\r
+ if(xmlNodes == null || !xmlNodes.length) return;\r
+ this.setEnabled(true);\r
+ }\r
+ },\r
+ "copytocollection" : {\r
+ label : "Copy to...", \r
+ icon : "resource/slc/edit-copy.png",\r
+ shortcut : "Control+c",\r
+ enabled : false,\r
+ menu : "Selection",\r
+ toolbar : "selection",\r
+ callback : function(e){\r
+ // Call service to copy\r
+ },\r
+ submenu : {},\r
+ submenuCallback : function(commandId){\r
+ this.copySelectionToCollection(commandId, "current_selection"); \r
+ },\r
+ init : function(){\r
+ // Call at command creation\r
+ org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(event){\r
+ if(event.getDataType() == "collection" || event.getDataType() == "test_cases"){\r
+ var testList = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("list").getContent();\r
+ testList.collectionListToMenu(this, true);\r
+ }\r
+ }, this);\r
+ },\r
+ selectionChange : function(viewId, xmlNodes){\r
+ if(viewId != "list") return;\r
+ this.setEnabled(false);\r
+ if(xmlNodes == null || !xmlNodes.length) return;\r
+ this.setEnabled(true); \r
+ },\r
+ command : null\r
+ },\r
+ "deletetest" : {\r
+ label : "Delete", \r
+ icon : "resource/slc/edit-delete.png",\r
+ shortcut : "Control+d",\r
+ enabled : false,\r
+ menu : "Selection",\r
+ toolbar : "selection",\r
+ callback : function(e){\r
+ var modal = new org.argeo.ria.components.Modal("Confirm", null);\r
+ modal.addConfirm("Are you sure you want to delete<br> test " + this.extractTestUuid() + "?");\r
+ modal.addListener("ok", function(){\r
+ var request = org.argeo.slc.ria.SlcApi.getRemoveResultService(this.getCollectionId(), this.extractTestUuid());\r
+ request.addListener("completed", function(response){\r
+ this.loadCollections();\r
+ this.loadList();\r
+ this.info("Test was successfully deleted");\r
+ }, this);\r
+ request.send(); \r
+ }, this);\r
+ modal.attachAndShow();\r
+ },\r
+ selectionChange : function(viewId, xmlNodes){\r
+ if(viewId != "list") return;\r
+ this.setEnabled(false);\r
+ if(xmlNodes == null || !xmlNodes.length) return;\r
+ this.setEnabled(true); \r
+ },\r
+ command : null\r
+ }\r
+ }\r
+ }\r
+ },\r
+ \r
+ members : {\r
+ init : function(viewPane, data){\r
+ this.setView(viewPane);\r
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId())); \r
+ },\r
+ load : function(){\r
+ this.table.set({ \r
+ statusBarVisible: false,\r
+ showCellFocusIndicator:false,\r
+ columnVisibilityButtonVisible:false,\r
+ contextMenu : org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["opentest", "download", "copytocollection", "deletetest"]),\r
+ decorator : new qx.ui.decoration.Background("#fff")\r
+ });\r
+ var viewPane = this.getView();\r
+ this.table.addListener("dblclick", function(e){\r
+ org.argeo.ria.event.CommandsManager.getInstance().executeCommand("opentest");\r
+ }, this);\r
+ var columnModel = this.table.getTableColumnModel(); \r
+ columnModel.getBehavior().setWidth(0, "60%");\r
+ var renderer = new org.argeo.slc.web.XmlRenderer();\r
+ columnModel.setDataCellRenderer(0, renderer);\r
+ columnModel.setDataCellRenderer(1, renderer);\r
+ \r
+ this.table.getSelectionManager().getSelectionModel().addListener("changeSelection", function(e){\r
+ var viewSelection = this.getViewSelection();\r
+ viewSelection.clear();\r
+ var selectionModel = this.table.getSelectionManager().getSelectionModel();\r
+ if(!selectionModel.getSelectedCount()){\r
+ return;\r
+ }\r
+ var ranges = this.table.getSelectionManager().getSelectionModel().getSelectedRanges();\r
+ var xmlNode = this.table.getTableModel().getRowData(ranges[0].minIndex);\r
+ viewSelection.addNode(xmlNode);\r
+ //viewPane.setViewSelection(viewSelection);\r
+ }, this); \r
+ \r
+ var select = new qx.ui.form.SelectBox();\r
+ this.getView().addHeaderComponent(select);\r
+ this.getView().setViewTitle("");\r
+ this.add(this.table, {flex:1});\r
+\r
+ select.addListener("changeValue", this.collectionSelectorListener, this);\r
+\r
+ org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(event){\r
+ if(event.getDataType()!="collection") return;\r
+ select.removeListener("changeValue", this.collectionSelectorListener, this);\r
+ var collectionList = event.getContent();\r
+ select.removeAll();\r
+ for(key in collectionList){\r
+ var item = new qx.ui.form.ListItem(collectionList[key], "resource/slc/folder.png", key);\r
+ select.add(item);\r
+ if(key == this.getCollectionId()){\r
+ select.setSelected(item);\r
+ }\r
+ }\r
+ if(qx.lang.Object.getLength(collectionList)){\r
+ this.setCollectionId(select.getSelected().getValue());\r
+ }\r
+ select.addListener("changeValue", this.collectionSelectorListener, this);\r
+ }, this);\r
+ \r
+ },\r
+ \r
+ /**\r
+ * Use SlcApi to load the available collections.\r
+ */\r
+ loadCollections : function(){\r
+ var request = org.argeo.slc.ria.SlcApi.getListCollectionsService();\r
+ var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
+ request.addListener("completed", function(response){\r
+ var xml = response.getContent();\r
+ var collections = {};\r
+ var nodes = org.argeo.ria.util.Element.selectNodes(xml, "//slc:ref", NSMap);\r
+ for(var i=0;i<nodes.length;i++){\r
+ var collId = qx.xml.Element.getSingleNodeText(nodes[i], ".");\r
+ collections[collId] = collId;\r
+ }\r
+ this.setCollectionList(collections);\r
+ org.argeo.ria.remote.RequestManager.getInstance().fireReloadEvent("collection", this.getCollectionList());\r
+ }, this);\r
+ request.setAsynchronous(false);\r
+ request.send();\r
+ },\r
+ \r
+ /**\r
+ * Load the results of the currently selected collection.\r
+ */\r
+ loadList : function(){\r
+ var model = this.table.getTableModel();\r
+ model.removeRows(0, model.getRowCount());\r
+ var commandManager = org.argeo.ria.event.CommandsManager.getInstance();\r
+ var request = org.argeo.slc.ria.SlcApi.getListResultsService(this.getCollectionId(), null, [commandManager.getCommandById("loadtestlist"), this.getView()]);\r
+ var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
+ request.addListener("completed", function(response){\r
+ var xml = response.getContent();\r
+ this.debug("Successfully loaded XML");\r
+ var nodes = org.argeo.ria.util.Element.selectNodes(xml, "//slc:result-attributes", NSMap);\r
+ //model.addRows(nodes);\r
+ \r
+ for(var i=0; i<nodes.length;i++){ \r
+ model.addRows([nodes[i]]);\r
+ } \r
+ }, request);\r
+ request.send(); \r
+ },\r
+ \r
+ /**\r
+ * Enable/disable the automatic reloading of the list.\r
+ * @param state {Boolean} Whether the automatic reloading must be started or stopped.\r
+ */\r
+ pollListLoading : function(state){\r
+ if(!this.timer){\r
+ this.timer = new qx.event.Timer(5000);\r
+ this.timer.addListener("interval", this.loadList, this);\r
+ }\r
+ if(state){\r
+ this.loadList();\r
+ this.timer.start();\r
+ }else{\r
+ this.timer.stop();\r
+ }\r
+ },\r
+ \r
+ /**\r
+ * Creates a menu gui component from the currently loaded collectionList.\r
+ * @param command {qx.event.Command} The command on which to attach the created menu. \r
+ * @param checkSelection {Boolean} Whether at the end, we must check the current viewSelection to enable/disable the command accordingly. \r
+ */\r
+ collectionListToMenu : function(command, checkSelection){\r
+ command.setEnabled(false);\r
+ command.clearMenus();\r
+ var collectionList = this.getCollectionList();\r
+ if(!collectionList) return;\r
+ var submenus = [];\r
+ for(var key in collectionList){\r
+ if(this.getCollectionId() && key == this.getCollectionId()) continue;\r
+ submenus.push({\r
+ "label":collectionList[key], \r
+ "icon":"resource/slc/folder.png", \r
+ "commandId":key\r
+ });\r
+ } \r
+ submenus.push({'separator':true});\r
+ submenus.push({"label":"New...", "icon":"resource/slc/folder-new.png", "commandId":"slc.client.create"});\r
+ command.setMenu(submenus);\r
+ if(checkSelection){\r
+ var viewSelection = this.getView().getViewSelection();\r
+ if(viewSelection.getCount()) command.setEnabled(true);\r
+ }else{\r
+ command.setEnabled(true);\r
+ }\r
+ },\r
+ /**\r
+ * Use SlcApi "addResult" service to add selected results to a given collection.\r
+ * If collectionId is "slc.client.create", first triggers a modal dialog to enter a new collection name, then retrigger itself with the new id.\r
+ * @param collectionId {String} The id of the destination collection, or "slc.client.create".\r
+ * @param selectionType {String} "current_collection"|"current_selection". The first adds the whole collection content to the destination, the second only selected results.\r
+ */\r
+ copySelectionToCollection:function(collectionId, selectionType){\r
+ if(collectionId == "slc.client.create"){\r
+ var modal = new org.argeo.ria.components.Modal("Create collection", "resource/slc/folder-new.png");\r
+ modal.makePromptForm("Enter the new collection name", function(value){\r
+ if(value == ""){\r
+ alert("Please enter a name for the new collection!");\r
+ return false;\r
+ }\r
+ else {\r
+ // Create the collection now, then recall the callback with the new name. \r
+ this.copySelectionToCollection(value, selectionType);\r
+ return true;\r
+ }\r
+ }, this);\r
+ modal.attachAndShow();\r
+ return;\r
+ }\r
+\r
+ var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
+ if(currentFocus.getViewId() == "applet"){\r
+ alert("Should copy data from the applet - command was " + collectionId);\r
+ return;\r
+ }\r
+ \r
+ if(selectionType == "current_collection"){\r
+ this.error("Not implemented yet!"); \r
+ }else if(selectionType == "current_selection"){\r
+ // get selection ID\r
+ var request = org.argeo.slc.ria.SlcApi.getAddResultService(collectionId,this.extractTestUuid());\r
+ request.addListener("completed", function(response){\r
+ this.info("Result successfully copied to collection!");\r
+ this.loadCollections();\r
+ }, this);\r
+ request.send(); \r
+ }\r
+ },\r
+ \r
+ /**\r
+ * Utilitary function to extract test unique id from the currently selected node.\r
+ * @return {String} The test unique id.\r
+ */\r
+ extractTestUuid: function(){\r
+ var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
+ var xmlNodes = this.getView().getViewSelection().getNodes();\r
+ var uuid = qx.dom.Node.getText(org.argeo.ria.util.Element.selectSingleNode(xmlNodes[0], "slc:uuid"));\r
+ return uuid;\r
+ },\r
+ \r
+ /**\r
+ * Listener of the collection selector (select box added to the viewpane header). \r
+ * @param event {qx.event.type.Event} The event.\r
+ */\r
+ collectionSelectorListener : function(event){\r
+ this.setCollectionId(event.getData());\r
+ this.loadList(); \r
+ },\r
+ \r
+ addScroll : function(){\r
+ return false;\r
+ },\r
+ \r
+ close : function(){\r
+ if(this.timer){\r
+ this.pollListLoading(false);\r
+ }\r
+ }\r
+ \r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Basic helper for SLC XML results to be displayed in a qx.ui.table.\r
+ * Overrides the html of the standard qx.ui.table.cellrenderer.String\r
+ * \r
+ * TODO : put in org.argeo.slc.ria package\r
+ * \r
+ */\r
+qx.Class.define("org.argeo.slc.web.XmlRenderer",\r
+{\r
+ extend : qx.ui.table.cellrenderer.String,\r
+\r
+ /*\r
+ *****************************************************************************\r
+ MEMBERS\r
+ *****************************************************************************\r
+ */\r
+\r
+ members :\r
+ {\r
+ /**\r
+ * Overrides the parent method.\r
+ * @param cellInfo {Map} The current cell data \r
+ * @return {String}\r
+ */\r
+ _getContentHtml : function(cellInfo) {\r
+ var xmlNode = cellInfo.rowData;\r
+ if(!xmlNode) return "";\r
+ var xPath;\r
+ var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
+ switch(cellInfo.col){\r
+ case 0 :\r
+ xPath = "slc:uuid";\r
+ var nameParam = org.argeo.ria.util.Element.selectSingleNode(xmlNode, xPath, NSMap);\r
+ var value = qx.bom.String.escape(qx.dom.Node.getText(nameParam) || "Not Found");\r
+ break;\r
+ case 1 : \r
+ xPath = "slc:close-date";\r
+ var nameParam = org.argeo.ria.util.Element.selectSingleNode(xmlNode, xPath, NSMap);\r
+ var value = qx.bom.String.escape(qx.dom.Node.getText(nameParam) || "NOT CLOSED");\r
+ if(value == "NOT CLOSED") return value;\r
+ var splits = value.split(".");\r
+ value = splits[0].replace("T", " "); \r
+ var dateFormat = new qx.util.format.DateFormat("yyyy-MM-dd HH:mm:ss");\r
+ try {\r
+ var date = dateFormat.parse(value);\r
+ var dateFormat2 = new qx.util.format.DateFormat("MMM d, yy HH:mm:ss");\r
+ return dateFormat2.format(date);\r
+ }catch(e){}\r
+ break;\r
+ default :\r
+ return "";\r
+ break;\r
+ }\r
+ \r
+ return value;\r
+ },\r
+ \r
+ // overridden\r
+ /**\r
+ * Overrides parent method\r
+ * @param cellInfo {Map} Current cell data\r
+ * @return {String}\r
+ */\r
+ _getCellClass : function(cellInfo) {\r
+ return this.base(arguments, cellInfo);\r
+ }\r
+ \r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Specific classes used by the SLC-WEB RIA application.\r
+ */
\ No newline at end of file
--- /dev/null
+{\r
+ "info" : \r
+ {\r
+ "name" : "org.argeo.slc.ria",\r
+\r
+ "summary" : "Slc Ria library",\r
+ "description" : "Utilities for SLC RIA",\r
+ \r
+ "homepage" : "http://www.argeo.org/",\r
+\r
+ "license" : "LGPL",\r
+ "authors" : \r
+ [\r
+ {\r
+ "name" : "Charles du Jeu",\r
+ "email" : "charles.dujeu@gmail.com"\r
+ }\r
+ ],\r
+\r
+ "version" : "trunk",\r
+ "qooxdoo-versions": ["0.8"]\r
+ },\r
+ \r
+ "provides" : \r
+ {\r
+ "namespace" : "org.argeo.slc.ria",\r
+ "encoding" : "utf-8",\r
+ "class" : "class",\r
+ "resource" : "resource",\r
+ "translation" : "translation",\r
+ "type" : "library"\r
+ }\r
+}\r
+\r
--- /dev/null
+/**
+ * The canonical SLC applet for test result viewing. It will display a TreeTestResult in a TreeVirtual component
+ * composed of four columns : test name, state (passed/failed/error), message and date.
+ *
+ * It makes use of the StatusCellRenderer class for the "state" cell being a background-colored cell, the color depending on the FAILED or PASSED state message.
+ * The only associated command is the "Close" command.
+ */
+qx.Class.define("org.argeo.slc.ria.Applet",
+{
+ extend : qx.ui.container.Composite,
+ implement : [org.argeo.ria.components.IView],
+
+ construct : function(){
+ this.base(arguments);
+ this.setLayout(new qx.ui.layout.VBox());
+ this.passedStatus = "PASSED";
+ this.failedStatus = "FAILED";
+ this.loaded = false;
+ },
+
+ properties :
+ {
+ /**
+ * The viewPane inside which this applet is added.
+ */
+ view : {
+ init : null
+ },
+ viewSelection : {
+ nullable:false,
+ check:"org.argeo.ria.components.ViewSelection"
+ },
+ instanceId : {
+ init : ""
+ },
+ instanceLabel : {
+ init : ""
+ },
+ /**
+ * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
+ */
+ commands : {
+ init : {
+ "close" : {
+ label : "Close Current",
+ icon : "resource/slc/window-close.png",
+ shortcut : "Control+w",
+ enabled : true,
+ menu : "Test",
+ toolbar : "result",
+ callback : function(e){
+ this.getView().closeCurrent();
+ //this.getView().empty();
+
+ },
+ command : null
+ }
+ /*,
+ "copytocollection" : {
+ shared : true,
+ selectionChange : function(viewId, xmlNode){
+ if(viewId != "applet") return;
+ if(!xmlNode){
+ this.setEnabled(false);
+ }else{
+ this.setEnabled(true);
+ }
+ }
+ },
+ "deletetest" : {
+ shared : true,
+ callback : function(e){
+ //this.debug(this);
+ alert("Should delete applet selection in " + this.getInstanceId());
+ },
+ selectionChange : function(viewId, xmlNode){
+ if(viewId != "applet") return;
+ if(!xmlNode){
+ this.setEnabled(false);
+ }else{
+ this.setEnabled(true);
+ }
+ }
+ }
+ */
+ }
+ }
+ },
+
+ members :
+ {
+ init : function(viewPane, xmlNode){
+ this.setView(viewPane);
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
+ this.data = xmlNode;
+ if(this.data){
+ this.testId = org.argeo.ria.util.Element.getSingleNodeText(this.data, "slc:uuid");
+ this.setInstanceId("test:"+this.testId);
+ this.setInstanceLabel("Test " + this.testId.substring(0,4)+"...");
+ }
+ },
+
+ load : function(){
+ if(!this.data) return;
+ if(this.loaded) return;
+ // Load XML or Whatever
+ var service;
+ //this.testId = qx.dom.Node.getText(org.argeo.ria.util.Element.selectSingleNode(this.data, "slc:uuid"));
+ this.getView().setViewTitle("Test "+this.testId);
+ var request = org.argeo.slc.ria.SlcApi.getLoadResultService(this.testId);
+ request.addListener("completed", function(response){
+ this.createXmlGui(response.getContent());
+ this.getView().setOnLoad(false);
+ this.loaded = true;
+ }, this);
+ this.getView().setOnLoad(true);
+ request.send();
+
+ },
+
+ addScroll : function(){
+ return false;
+ },
+
+ close : function(){
+
+ },
+
+ /**
+ * Creates the GUI.
+ * @param responseXml {Document} The xml response of the "load" query.
+ */
+ createXmlGui : function(responseXml){
+ var NSMap = {
+ "slc" : "http://argeo.org/projects/slc/schemas"
+ }
+ if(!qx.Class.hasMixin(qx.ui.treevirtual.TreeVirtual, qx.ui.treevirtual.MNode)){
+ qx.Class.include(qx.ui.treevirtual.TreeVirtual,qx.ui.treevirtual.MNode);
+ }
+ this.tree = new qx.ui.treevirtual.TreeVirtual(["Test", "State", "Message", "Id"]);
+ this.tree.getTableColumnModel().setDataCellRenderer(0, new org.argeo.ria.util.TreeDataCellRenderer());
+ this.tree.getDataRowRenderer().setHighlightFocusRow(false); // Default row renderer
+ this.tree.setRowHeight(18);
+ this.tree.setStatusBarVisible(false);
+ this.tree.setDecorator(new qx.ui.decoration.Background("#fff"));
+ var model = this.tree.getDataModel();
+ var resNodes = org.argeo.ria.util.Element.selectNodes(responseXml, "//slc:result-part", NSMap);
+ var resultParts = {};
+ var addedPaths = {};
+ for(var i=0;i<resNodes.length;i++){
+ var currentParentId = null;
+ var node = resNodes[i];
+ var pathAttr = qx.xml.Element.getSingleNodeText(node, "@path");
+ var pathParts = pathAttr.split("/");
+ if(pathParts[0] == ""){
+ pathParts.shift();
+ }
+ var crtPath = "";
+ for(var j=0;j<pathParts.length;j++){
+ //if(pathParts[j] == "") continue;
+ crtPath = crtPath.concat("/", pathParts[j]);
+ if(addedPaths[crtPath]) {
+ currentParentId = addedPaths[crtPath];
+ continue; // Node already exists, set as parent and go to next!
+ }
+ var element = org.argeo.ria.util.Element.selectSingleNode(responseXml, '//slc:element[@path="'+crtPath+'"]', NSMap);
+ var label;
+ if(element != null){
+ label = org.argeo.ria.util.Element.getSingleNodeText(element, "*/slc:label", NSMap);
+ }else{
+ label = crtPath;
+ }
+ var simpleResults = org.argeo.ria.util.Element.selectNodes(node, "slc:part-sub-list/slc:parts/slc:simple-result-part", NSMap);
+
+ var newId;
+ //newId = model.addBranch(currentParentId, label, false);
+
+ // Test Leaf Node
+ if(!simpleResults || !simpleResults.length){
+ newId = model.addBranch(currentParentId, label, false);
+ addedPaths[crtPath] = newId;
+ currentParentId = newId;
+ continue;
+ }
+ if(simpleResults.length == 1){
+ //newId = model.addBranch(currentParentId, label, false);
+ var sResNode = simpleResults[0];
+ newId = model.addBranch(currentParentId, label);
+ model.setColumnData(newId, 3, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:test-run-uuid", NSMap));
+ model.setColumnData(newId, 2, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:message", NSMap));
+ var status = org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:status", NSMap);
+ if(status != "PASSED"){
+ status = this.failedStatus ;
+ this._setParentBranchAsFailed(newId);
+ }else{
+ status = this.passedStatus;
+ }
+ model.setColumnData(newId, 1, status);
+ addedPaths[crtPath] = newId;
+ currentParentId = newId;
+ continue;
+ }
+ newId = model.addBranch(currentParentId, label, false);
+ for(var k=0;k<simpleResults.length;k++){
+ var sResNode = simpleResults[k];
+ resId = model.addLeaf(currentParentId, label);
+ model.setColumnData(resId, 3, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:test-run-uuid", NSMap));
+ model.setColumnData(resId, 2, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:message", NSMap));
+ var status = org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:status", NSMap);
+ if(status != "PASSED"){
+ status = this.failedStatus ;
+ this._setParentBranchAsFailed(resId);
+ }else{
+ status = this.passedStatus;
+ }
+ model.setColumnData(resId, 1, status);
+ }
+
+ addedPaths[crtPath] = newId;
+ currentParentId = newId;
+ }
+ }
+ this._refineLeaves(this.tree, 0);
+ this.add(this.tree, {flex:1});
+ model.setData();
+ var columnModel = this.tree.getTableColumnModel();
+ var resize = columnModel.getBehavior();
+ resize.set(0, {width:250, minWidth:250});
+ resize.set(1, {width:55});
+ resize.set(2, {width:"1*"});
+ resize.set(3, {width:150});
+ columnModel.setDataCellRenderer(1, new org.argeo.slc.ria.StatusCellRenderer());
+
+ this.tree.getSelectionManager().getSelectionModel().addListener("changeSelection", function(e){
+ var viewSelection = this.getViewSelection();
+ viewSelection.clear();
+ var nodes = this.tree.getDataModel().getSelectedNodes();
+ if(nodes.length){
+ viewSelection.addNode(nodes[0]);
+ }
+ this.getView().focus();
+ }, this);
+
+ var contextMenu = org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["close"]);
+ this.tree.setContextMenu(contextMenu);
+
+ },
+
+ /**
+ * Goes up the parents recursively to set a whole tree branch in "failed" mode.
+ * @param id {Integer} The id of the child node.
+ */
+ _setParentBranchAsFailed : function(id){
+ var model = this.tree.getDataModel();
+ while(id != null && id!=0){
+ var node = this.tree.nodeGet(id);
+ id = node.parentNodeId;
+ if(id != null && id!=0){
+ model.setColumnData(id, 1, this.failedStatus);
+ this.tree.nodeSetOpened(id, true);
+ }
+ }
+ },
+
+ /**
+ * Recursively make sur the last children are of qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF type.
+ *
+ * @param tree {qx.ui.treevirtual.TreeVirtual} The main tree of the applet.
+ * @param nodeId {Integer} Current node id.
+ */
+ _refineLeaves : function(tree, nodeId){
+ var node = tree.nodeGet(nodeId);
+ if(node.children && node.children.length){
+ for(var i=0;i<node.children.length;i++){
+ this._refineLeaves(tree, node.children[i]);
+ }
+ }else{
+ node.type = qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF;
+ }
+ },
+
+ /**
+ * Alternatively to the createXmlGui, create a simple HtmlElement and append the query responseText.
+ * Not used but sample.
+ * @param responseText {String} Html code to display.
+ */
+ createHtmlGui : function(responseText){
+ var htmlElement = new qx.ui.embed.Html(responseText);
+ htmlElement.setOverflowX("auto");
+ htmlElement.setOverflowY("auto");
+ this.add(htmlElement, {flex:1});
+ }
+
+ }
+});
\ No newline at end of file
--- /dev/null
+/**
+ * A simple Hello World applet for documentation purpose.
+ * The only associated command is the "Close" command.
+ */
+qx.Class.define("org.argeo.slc.ria.LauncherApplet",
+{
+ extend : qx.ui.container.Composite,
+ implement : [org.argeo.ria.components.IView],
+
+ construct : function(){
+ this.base(arguments);
+ this.setLayout(new qx.ui.layout.Dock());
+
+ this.COMMON_FORM_HEADER_LABEL = "Choose Agent";
+ this.CHOOSE_AGENT_LABEL = "Agent Uuid";
+ this.CHOOSE_FORM_PART_LABEL = "Test Type";
+ },
+
+ properties :
+ {
+ /**
+ * The viewPane inside which this applet is added.
+ */
+ view : {
+ init : null
+ },
+ viewSelection : {
+ nullable:false,
+ check:"org.argeo.ria.components.ViewSelection"
+ },
+ instanceId : {init:""},
+ instanceLabel : {init:""},
+ /**
+ * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
+ */
+ commands : {
+ init : {
+ "submitform" : {
+ label : "Execute",
+ icon : "resource/slc/media-playback-start.png",
+ shortcut : "Control+e",
+ enabled : true,
+ menu : "Launcher",
+ toolbar : "launcher",
+ callback : function(e){
+ this.submitForm();
+ },
+ command : null
+ },
+ "reloadagents" : {
+ label : "Reload Agents",
+ icon : "resource/slc/view-refresh.png",
+ shortcut : "Control+r",
+ enabled : true,
+ menu : "Launcher",
+ toolbar : "launcher",
+ callback : function(e){
+ var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
+ req.send();
+ },
+ command : null
+ }
+ }
+ },
+ /**
+ * A map containing all currently registered agents.
+ */
+ registeredTopics : {
+ init : {},
+ check : "Map",
+ event : "changeRegisteredTopics"
+ }
+ },
+
+ members :
+ {
+ /**
+ * Called at applet creation. Just registers viewPane.
+ * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
+ */
+ init : function(viewPane){
+ this.setView(viewPane);
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
+ this._createLayout();
+ this._createForm();
+ this._amqClient = org.argeo.ria.remote.JmsClient.getInstance();
+ this._amqClient.startPolling();
+ },
+
+ /**
+ *
+ */
+ load : function(){
+ this.getView().setViewTitle("Execution Launcher");
+ this.addListener("changeRegisteredTopics", function(event){
+ //this._refreshTopicsSubscriptions(event);
+ this._feedSelector(event);
+ }, this);
+ var reloadHandler = function(message){
+ // Delay reload to be sure the jms was first integrated by the db, then ask the db.
+ qx.event.Timer.once(function(){
+ org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadagents").execute();
+ }, this, 1000);
+ }
+ this._amqClient.addListener("agentregister", "topic://agent.register", reloadHandler, this);
+ this._amqClient.addListener("agentunregister", "topic://agent.unregister", reloadHandler, this);
+ reloadHandler();
+ },
+
+ addScroll : function(){
+ return false;
+ },
+
+ close : function(){
+ this._amqClient.removeListener("agentregister", "topic://agent.register");
+ this._amqClient.removeListener("agentunregister", "topic://agent.unregister");
+
+ this.setRegisteredTopics({});
+ this._amqClient.stopPolling();
+ },
+
+ /**
+ * Creates the main applet layout.
+ */
+ _createLayout : function(){
+ this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
+ this.scroll = new qx.ui.container.Scroll(this.formPane);
+ this.formPane.setPadding(10);
+ this.add(this.scroll, {edge:'center'});
+
+ },
+
+ /**
+ * Creates the form.
+ */
+ _createForm : function(){
+ this.fields = {};
+ this.hiddenFields = {};
+ this.freeFields = [];
+
+ var execButtonPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
+ var execButton = new qx.ui.form.Button(
+ "Execute",
+ "resource/slc/media-playback-start-32.png"
+ )
+ execButton.addListener("click", function(){
+ this.submitForm();
+ }, this);
+ execButtonPane.setPadding(10, 80);
+ execButtonPane.add(execButton, {edge:"center"});
+ this.formPane.add(execButtonPane);
+
+ this.agentSelector = new qx.ui.form.SelectBox();
+ var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();
+ serviceManager.addListener("reload", function(reloadEvent){
+ if(reloadEvent.getDataType()!= "agents") return ;
+ var xmlDoc = reloadEvent.getContent();
+ var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
+ var newTopics = {};
+ for(var i=0;i<nodes.length;i++){
+ var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
+ var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
+ newTopics[uuid] = host+" ("+uuid+")";
+ }
+ this.setRegisteredTopics(newTopics);
+ }, this);
+
+ var commonForm = {pane:this.formPane};
+ this._addFormHeader(commonForm, this.COMMON_FORM_HEADER_LABEL);
+ this._addFormEntry(commonForm, new qx.ui.basic.Label(this.CHOOSE_AGENT_LABEL), this.agentSelector);
+ this._createFormVariableParts();
+ if(!this.parts) return;
+ if(qx.lang.Object.getLength(this.parts) > 1){
+ // Add chooser
+ this.partChooser = new qx.ui.form.SelectBox();
+ for(var key in this.parts){
+ this.partChooser.add(new qx.ui.form.ListItem(this.parts[key].label, null, key));
+ }
+ this._addFormEntry(commonForm, new qx.ui.basic.Label(this.CHOOSE_FORM_PART_LABEL), this.partChooser);
+ this.partChooser.addListener("changeValue", function(ev){
+ this._showSelectedPart(ev.getData());
+ }, this);
+ }
+ this._showSelectedPart(qx.lang.Object.getKeys(this.parts)[0]);
+ },
+
+ /**
+ * Show a form part given its id.
+ * @param partId {String} The part id
+ */
+ _showSelectedPart : function(partId){
+ if(!this.parts) return;
+ if(!this.partsContainer){
+ this.partsContainer = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
+ this.formPane.add(this.partsContainer);
+ }
+ for(var i in this.parts){
+ var formObject = this.parts[i];
+ if(!formObject.added){
+ this.partsContainer.add(formObject.pane, {top:0, left:0});
+ formObject.added = true;
+ }
+ formObject.pane.hide();
+ }
+ if(this.parts[partId]){
+ this.parts[partId].pane.show();
+ }
+ },
+
+ /**
+ * Init a form part : creates a pane, a set of fields, etc.
+ * @param formId {String} A unique ID
+ * @param label {String} A label
+ * @return {Map} The form part.
+ */
+ _initFormPart : function(formId, label){
+ if(!this.parts) this.parts = {};
+ var formObject = {};
+ formObject.hiddenFields = {};
+ formObject.freeFields = [];
+ formObject.fields = {};
+ formObject.id = formId;
+ formObject.label = label;
+ this.parts[formId] = formObject;
+ formObject.pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
+ return formObject;
+ },
+
+ /**
+ * To be overriden by this class children.
+ */
+ _createFormVariableParts : function(){
+ var standard = this._initFormPart("standard", "Canonical");
+ this._createStandardForm(standard);
+ var simple = this._initFormPart("simple", "SLC Sample");
+ this._createSimpleForm(simple);
+ },
+
+ /**
+ * Creates a form for SLC demo
+ * @param formObject {Map} The form part
+ */
+ _createSimpleForm : function(formObject){
+
+ this._addFormInputText(formObject, "ant.file", "File", "Category1/SubCategory2/build.xml");
+ var moreButton = new qx.ui.basic.Image("resource/slc/list-add.png");
+ moreButton.setToolTip(new qx.ui.tooltip.ToolTip("Add a parameter"));
+ moreButton.setCursor("pointer");
+ moreButton.addListener("click", function(){
+ this._addFormInputText(formObject);
+ }, this);
+ this._addFormHeader(formObject, "Add optionnal parameters", moreButton);
+ this._addFormInputText(formObject);
+ this._addFormInputText(formObject);
+
+ },
+
+ /**
+ * Create a canonical form.
+ * @param formObject {Map} The form part
+ */
+ _createStandardForm : function(formObject){
+
+ this._addFormHeader(formObject, "Set Execution Parameters");
+ this._addFormInputText(formObject, "status", "Status", "STARTED");
+ this._addFormInputText(formObject, "host", "Host", "localhost");
+ this._addFormInputText(formObject, "user", "User", "user");
+
+ var moreButton = new qx.ui.basic.Image("resource/slc/list-add.png");
+ moreButton.setToolTip(new qx.ui.tooltip.ToolTip("Add a parameter"));
+ moreButton.setCursor("pointer");
+ moreButton.addListener("click", function(){
+ this._addFormInputText(formObject);
+ }, this);
+ this._addFormHeader(formObject, "Add optionnal parameters", moreButton);
+ this._addFormInputText(formObject);
+ this._addFormInputText(formObject);
+ },
+
+ /**
+ * Add an hidden field to the form
+ * @param formObject {Map} The form part
+ * @param fieldName {String} Name
+ * @param fieldValue {String} Value
+ */
+ _addFormHiddenField : function(formObject, fieldName, fieldValue){
+ formObject.hiddenFields[fieldName] = fieldValue;
+ },
+
+ /**
+ * Creates a simple label/input form entry.
+ * @param formObject {Map} The form part
+ * @param fieldName {String} Name
+ * @param fieldLabel {String} Label of the field
+ * @param defaultValue {String} The default value
+ * @param choiceValues {Map} An map of values
+ */
+ _addFormInputText : function(formObject, fieldName, fieldLabel, defaultValue, choiceValues){
+ var labelElement;
+ if(choiceValues){
+ var fieldElement = new qx.ui.form.SelectBox();
+ for(var key in choiceValues){
+ fieldElement.add(new qx.ui.form.ListItem(choiceValues[key], null, key));
+ }
+ }else{
+ var fieldElement = new qx.ui.form.TextField();
+ }
+ if(defaultValue){
+ fieldElement.setValue(defaultValue);
+ }
+ if(fieldName && fieldLabel){
+ labelElement = new qx.ui.basic.Label(fieldLabel);
+ formObject.fields[fieldName] = fieldElement;
+ }else{
+ labelElement = new qx.ui.form.TextField();
+ formObject.freeFields.push({
+ labelEl:labelElement,
+ valueEl:fieldElement
+ });
+ }
+ this._addFormEntry(formObject, labelElement, fieldElement);
+ },
+
+ /**
+ * Add an header
+ * @param formObject {Map} The form part
+ * @param content {Mixed} Content to add.
+ * @param additionnalButton {Mixed} Any widget to add on the east.
+ */
+ _addFormHeader : function(formObject, content, additionnalButton){
+ var header = new qx.ui.basic.Label('<b>'+content+'</b>');
+ header.setRich(true);
+ if(!additionnalButton){
+ header.setPaddingTop(10);
+ formObject.pane.add(header);
+ }else{
+ var pane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
+ pane.setPaddingTop(10);
+ pane.setPaddingRight(10);
+ pane.add(header, {edge:'center'});
+ pane.add(additionnalButton, {edge:'east'});
+ formObject.pane.add(pane);
+ }
+ },
+
+ /**
+ * Adds a label/input like entry in the form.
+ * @param formObject {Map} The form part
+ * @param labelElement {Object} Either a label or an input
+ * @param fieldElement {Object} Any form input.
+ */
+ _addFormEntry : function(formObject, labelElement, fieldElement){
+ var entryPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));
+ labelElement.setWidth(100);
+ labelElement.setTextAlign("right");
+ entryPane.add(labelElement);
+ entryPane.add(new qx.ui.basic.Label(':'));
+ fieldElement.setWidth(150);
+ entryPane.add(fieldElement);
+ formObject.pane.add(entryPane);
+ },
+
+ /*
+ _refreshTopicsSubscriptions : function(changeTopicsEvent){
+ var oldTopics = changeTopicsEvent.getOldData() || {};
+ var newTopics = changeTopicsEvent.getData();
+ var removed = [];
+ var added = [];
+ for(var key in oldTopics){
+ if(!newTopics[key]) {
+ //this._removeAmqListener(key);
+ }
+ }
+ for(var key in newTopics){
+ if(!oldTopics[key]) {
+ //this._addAmqListener(key);
+ }
+ }
+ },
+ */
+
+ /**
+ * Refresh the selector when the topics are updated.
+ * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
+ */
+ _feedSelector : function(changeTopicsEvent){
+ var topics = changeTopicsEvent.getData();
+ this.agentSelector.removeAll();
+ var emptyItem = new qx.ui.form.ListItem("", null, "");
+ this.agentSelector.add(emptyItem);
+ this.agentSelector.setSelected(emptyItem);
+ for(var key in topics){
+ var listItem = new qx.ui.form.ListItem(topics[key], null, key);
+ this.agentSelector.add(listItem);
+ }
+ },
+
+ /*
+ _addAmqListener: function(uuid){
+ this._amqClient.addListener("slcExec", "topic://agent."+uuid+".newExecution", function(response){
+ var message = org.argeo.ria.util.Element.selectSingleNode(response, "slc:slc-execution");
+ var slcExec = new org.argeo.slc.ria.SlcExecutionMessage(message.getAttribute("uuid"));
+ slcExec.fromXml(message);
+ this.logModel.addRows([
+ [new Date().toString(), slcExec.getHost()+' ('+slcExec.getUuid()+')', slcExec.getStatus()]
+ ]);
+ }, this);
+ },
+
+ _removeAmqListener : function(uuid){
+ this._amqClient.removeListener("slcExec", "topic://agent."+uuid+".newExecution");
+ },
+ */
+
+ /**
+ * Make an SlcExecutionMessage from the currently displayed form.
+ * @param crtPartId {String} The form part currently displayed
+ * @param slcExec {org.argeo.slc.ria.SlcExecutionMessage} The message to fill.
+ * @param fields {Map} The fields of the form
+ * @param hiddenFields {Map} The hidden ones
+ * @param freeFields {Array} The free fields.
+ */
+ _prepareSlcExecutionMessage : function(crtPartId, slcExec, fields, hiddenFields, freeFields){
+ if(crtPartId == "standard"){
+ slcExec.setStatus(fields.status.getValue());
+ slcExec.setHost(fields.host.getValue());
+ slcExec.setUser(fields.user.getValue());
+ }else{
+ slcExec.addAttribute("ant.file", fields["ant.file"].getValue());
+ }
+ for(var i=0;i<freeFields.length;i++){
+ var fF = freeFields[i];
+ if(fF.labelEl.getValue() != "" && fF.valueEl.getValue() != ""){
+ slcExec.addAttribute(fF.labelEl.getValue(), fF.valueEl.getValue());
+ }
+ }
+ },
+
+ /**
+ * Called when the user clicks the "Execute" button.
+ */
+ submitForm : function(){
+ var currentUuid = this.agentSelector.getValue();
+ if(!currentUuid) return;
+ var slcExec = new org.argeo.slc.ria.SlcExecutionMessage();
+
+ var fields = {};
+ var hiddenFields = {};
+ var freeFields = {};
+ var crtPartId = "";
+ if(this.parts){
+ if(this.partChooser){
+ crtPartId = this.partChooser.getValue();
+ }else{
+ crtPartId = qx.lang.Object.getKeys(this.parts)[0];
+ }
+ var crtPart = this.parts[crtPartId];
+ fields = crtPart.fields;
+ hiddenFields = crtPart.hiddenFields;
+ freeFields = crtPart.freeFields;
+ }
+
+ this._prepareSlcExecutionMessage(crtPartId, slcExec, fields, hiddenFields, freeFields);
+
+ this._amqClient.sendMessage(
+ "topic://agent.newExecution",
+ slcExec.toXml(),
+ {"slc-agentId":currentUuid}
+ );
+ // Force logs refresh right now!
+ qx.event.Timer.once(function(){
+ var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
+ if(command){
+ command.execute();
+ }
+ }, this, 2000);
+ }
+
+ }
+});
\ No newline at end of file
--- /dev/null
+/**
+ * A simple Hello World applet for documentation purpose.
+ * The only associated command is the "Close" command.
+ */
+qx.Class.define("org.argeo.slc.ria.NewLauncherApplet",
+{
+ extend : qx.ui.container.Composite,
+ implement : [org.argeo.ria.components.IView],
+
+ construct : function(){
+ this.base(arguments);
+ this.setLayout(new qx.ui.layout.Dock());
+ },
+
+ properties :
+ {
+ /**
+ * The viewPane inside which this applet is added.
+ */
+ view : {
+ init : null
+ },
+ viewSelection : {
+ nullable:false,
+ check:"org.argeo.ria.components.ViewSelection"
+ },
+ instanceId : {init:""},
+ instanceLabel : {init:""},
+ /**
+ * A boolean registering whether the SpecEditor must autoOpen or not when a spec is added to the Batch.
+ */
+ autoOpen : {
+ init : true,
+ check : "Boolean"
+ },
+ /**
+ * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
+ */
+ commands : {
+ init : {
+ "submitform" : {
+ label : "Execute Batch On...",
+ icon : "resource/slc/media-playback-start.png",
+ shortcut : null,
+ enabled : true,
+ menu : "Launcher",
+ toolbar : null,
+ callback : function(e){},
+ submenu : [],
+ submenuCallback : function(commandId){
+ //alert("Execute Batch on Agent "+commandId);
+ this.executeBatchOnAgent(commandId);
+ },
+ command : null
+ },
+ "addtobatch" : {
+ label : "Add to batch",
+ icon : "resource/slc/list-add.png",
+ shortcut : null,
+ enabled : true,
+ menu : null,
+ toolbar : null,
+ callback : function(e){
+ this._addFlowToBatch();
+ },
+ selectionChange : function(viewId, selection){
+ if(viewId != "form:tree") return;
+ if(!selection || selection.length != 1) return;
+ var item = selection[0];
+ this.setEnabled(false);
+ if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.TreeFile)){
+ this.setEnabled(true);
+ }
+
+ },
+ command : null
+ },
+ "toggleopenonadd" : {
+ label : "Auto Open",
+ icon : "resource/slc/document-open.png",
+ shortcut : null,
+ enabled : true,
+ toggle : true,
+ toggleInitialState : true,
+ menu : "Launcher",
+ toolbar : "launcher",
+ callback : function(event){
+ var state = event.getTarget().getUserData("slc.command.toggleState");
+ this.setAutoOpen(state);
+ },
+ command : null
+ },
+ "editexecutionspecs" : {
+ label : "Edit Execution Specs",
+ icon : "resource/slc/document-open.png",
+ shortcut : null,
+ enabled : false,
+ menu : "Launcher",
+ toolbar : null,
+ callback : function(e){
+ var sel = this.list.getSortedSelection();
+ var item = sel[0];
+ var specEditor = new org.argeo.slc.ria.execution.SpecEditor(item.getUserData("batchEntrySpec"));
+ specEditor.attachAndShow();
+ },
+ selectionChange : function(viewId, selection){
+ if(viewId != "form:list") return;
+ this.setEnabled(false);
+ if((selection && selection.length == 1)) this.setEnabled(true);
+ },
+ command : null
+ },
+ "removefrombatch" : {
+ label : "Remove from batch",
+ icon : "resource/slc/edit-delete.png",
+ shortcut : null,
+ enabled : false,
+ menu : "Launcher",
+ toolbar : null,
+ callback : function(e){
+ var sel = this.list.getSortedSelection();
+ var modal = new org.argeo.ria.components.Modal("Confirm", null);
+ modal.addConfirm("Are you sure you want to remove<br> the selected test" + (sel.length>1?"s":"") + " from the Batch?");
+ modal.addListener("ok", function(){
+ for(var i=0;i<sel.length;i++){
+ this.list.remove(sel[i]);
+ }
+ }, this);
+ modal.attachAndShow();
+ },
+ selectionChange : function(viewId, selection){
+ if(viewId != "form:list") return;
+ this.setEnabled(false);
+ if((selection && selection.length > 0)) this.setEnabled(true);
+ },
+ command : null
+ },
+ "reloadagents" : {
+ label : "Reload Agents",
+ icon : "resource/slc/view-refresh.png",
+ shortcut : "Control+r",
+ enabled : true,
+ menu : "Launcher",
+ toolbar : "launcher",
+ callback : function(e){
+ var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
+ req.send();
+ },
+ command : null
+ },
+ "reloadtree" : {
+ label : "Reload",
+ icon : "resource/slc/view-refresh.png",
+ shortcut : "Control+m",
+ enabled : false,
+ menu : "Launcher",
+ toolbar : "launcher",
+ callback : function(e){
+ var selected = this.tree.getSelectedItem();
+ if(selected.classname == "org.argeo.ria.components.DynamicTreeFolder"){
+ if(selected.getUserData("moduleData")){
+ // It's a "module" node, first trigger the reloadBundle.service
+ selected.setUserData("dataModel", {});
+ selected.setEnabled(false);
+ selected.setOpen(false);
+ var moduleData = selected.getUserData("moduleData");
+ var bundleService = org.argeo.slc.ria.SlcApi.getReloadBundleService(moduleData.name, moduleData.version);
+ bundleService.addListener("completed", function(response){
+ selected.setEnabled(true);
+ selected.setOpen(true);
+ selected.reload();
+ }, this);
+ //bundleService.send();
+ //Do not send, not implemented yet, false timer instead.
+ qx.event.Timer.once(function(response){
+ selected.setEnabled(true);
+ selected.setOpen(true);
+ selected.reload();
+ }, this, 2000);
+ }else{
+ selected.reload();
+ }
+ }
+ },
+ selectionChange : function(viewId, selection){
+ if(viewId != "form:tree") return;
+ if(!selection || selection.length != 1) return;
+ var item = selection[0];
+ if(!qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.AbstractTreeItem)) return;
+ this.setEnabled(false);
+ if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), org.argeo.ria.components.DynamicTreeFolder)){
+ this.setEnabled(true);
+ }
+ },
+ command : null
+ }
+ }
+ },
+ /**
+ * A map containing all currently registered agents.
+ */
+ registeredTopics : {
+ init : {},
+ check : "Map",
+ event : "changeRegisteredTopics"
+ }
+ },
+
+ statics : {
+ /**
+ * Loader for the "flow" level : takes a folder containing "moduleData" and create its children.
+ * @param folder {qx.ui.tree.TreeFolder} A Tree folder containing in the key "moduleData" of its user data a map containing the keys {name,version}
+ */
+ flowLoader : function(folder){
+ var moduleData = folder.getUserData("moduleData");
+ //var pathStub = ["", "/test/toto/zobi", "loop"];
+ //var indexStub = 0;
+
+ var req = org.argeo.slc.ria.SlcApi.getLoadExecutionDescriptorService(moduleData.name, moduleData.version);
+ req.addListener("completed", function(response){
+ var executionModule = new org.argeo.slc.ria.execution.Module();
+ executionModule.setXmlNode(response.getContent());
+ var execFlows = executionModule.getExecutionFlows();
+ for(var key in execFlows){
+ var file = new qx.ui.tree.TreeFile(key);
+ var path = execFlows[key].getPath();
+ //path = pathStub[indexStub];
+ //indexStub ++;
+ file.setUserData("executionModule", executionModule);
+ file.setUserData("executionFlow", execFlows[key]);
+ org.argeo.slc.ria.NewLauncherApplet.attachNodeByPath(folder, path, file);
+ folder.appendDragData(file);
+ }
+ folder.setLoaded(true);
+ });
+ req.send();
+ },
+
+ /**
+ * Loader for the "modules" level : takes any tree folder, currently the root folder.
+ * @param folder {qx.ui.tree.TreeFolder} The root folder
+ */
+ modulesLoader : function(folder){
+ var req = org.argeo.slc.ria.SlcApi.getListModulesService();
+ req.addListener("completed", function(response){
+ var descriptors = org.argeo.ria.util.Element.selectNodes(response.getContent(), "slc:object-list/slc:execution-module-descriptor");
+ var mods = {};
+ for(var i=0;i<descriptors.length; i++){
+ var name = org.argeo.ria.util.Element.getSingleNodeText(descriptors[i], "slc:name");
+ var version = org.argeo.ria.util.Element.getSingleNodeText(descriptors[i], "slc:version");
+ if(!mods[name]) mods[name] = [];
+ mods[name].push(version);
+ }
+ var flowLoader = org.argeo.slc.ria.NewLauncherApplet.flowLoader;
+ for(var key in mods){
+ for(var i=0;i<mods[key].length;i++){
+ var versionFolder = new org.argeo.ria.components.DynamicTreeFolder(
+ key + ' ('+mods[key][i]+')',
+ flowLoader,
+ "Loading Flows",
+ folder.getDragData()
+ );
+ folder.add(versionFolder);
+ versionFolder.setUserData("moduleData", {name:key, version:mods[key][i]});
+ }
+ folder.setLoaded(true);
+ }
+ });
+ req.send();
+ },
+
+ /**
+ * Parse a string path and search if there is a root node.
+ * @param rootNode {qx.ui.tree.AbstractTreeItem} The parent node (containing data model)
+ * @param path {String} The path of the node to attach.
+ */
+ attachNodeByPath : function(rootNode, path, childNode){
+ if(!path || path=="" || path == "/" ){
+ rootNode.add(childNode);
+ return;
+ }
+ var model = rootNode.getUserData("dataModel");
+ if(!model){
+ model = {};
+ rootNode.setUserData("dataModel", model);
+ }
+ var parts = path.split("/");
+ var keys = qx.lang.Object.getKeys(model);
+ var crtPath = "/";
+ var crtFolder = rootNode;
+ for(var i=0;i<parts.length;i++){
+ if(parts[i] == "") continue;
+ crtPath += parts[i];
+ if(!model[parts[i]]) {
+ var virtualFolder = new qx.ui.tree.TreeFolder(parts[i]);
+ model[parts[i]] = virtualFolder;
+ crtFolder.add(virtualFolder);
+ crtFolder = virtualFolder;
+ }else{
+ crtFolder = model[parts[i]];
+ }
+ }
+ crtFolder.add(childNode);
+ }
+ },
+
+ members :
+ {
+ /**
+ * Called at applet creation. Just registers viewPane.
+ * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
+ */
+ init : function(viewPane){
+ this.setView(viewPane);
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
+ this._amqClient = org.argeo.ria.remote.JmsClient.getInstance();
+ this._amqClient.uri = "/org.argeo.slc.webapp/amq";
+ this._amqClient.startPolling();
+ },
+
+ /**
+ *
+ */
+ load : function(){
+ this._createLayout();
+ this.getView().setViewTitle("Execution Launcher");
+ org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(reloadEvent){
+ if(reloadEvent.getDataType()!= "agents") return ;
+ var xmlDoc = reloadEvent.getContent();
+ var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
+ var newTopics = {};
+ for(var i=0;i<nodes.length;i++){
+ var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
+ var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
+ newTopics[uuid] = host+" ("+uuid+")";
+ }
+ this.setRegisteredTopics(newTopics);
+ }, this);
+ this.addListener("changeRegisteredTopics", function(event){
+ //this._refreshTopicsSubscriptions(event);
+ this._feedSelector(event);
+ }, this);
+ var reloadHandler = function(message){
+ // Delay reload to be sure the jms was first integrated by the db, then ask the db.
+ qx.event.Timer.once(function(){
+ org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadagents").execute();
+ }, this, 1000);
+ }
+ this._amqClient.addListener("agentregister", "topic://agent.register", reloadHandler, this);
+ this._amqClient.addListener("agentunregister", "topic://agent.unregister", reloadHandler, this);
+ reloadHandler();
+ },
+
+ addScroll : function(){
+ return false;
+ },
+
+ close : function(){
+ this._amqClient.removeListener("agentregister", "topic://agent.register");
+ this._amqClient.removeListener("agentunregister", "topic://agent.unregister");
+ this._amqClient.removeListener("modulesResponse", "topic://modulesManager.response");
+ this.setRegisteredTopics({});
+ this._amqClient.stopPolling();
+ },
+
+ /**
+ * Creates the main applet layout.
+ */
+ _createLayout : function(){
+
+ var splitPane = new qx.ui.splitpane.Pane("vertical");
+ splitPane.setDecorator(null);
+ this.add(splitPane);
+
+ this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
+ this.scroll = new qx.ui.container.Scroll(this.formPane);
+ this.formPane.setPadding(10);
+
+ this.tree = new qx.ui.tree.Tree();
+ this.tree.setDecorator(null);
+ var dragData = {
+ "file" : {
+ "type" : ["items"],
+ "action":["move"]
+ }
+ };
+
+ var root = new org.argeo.ria.components.DynamicTreeFolder(
+ "All Tests",
+ this.self(arguments).modulesLoader,
+ "Loading Modules",
+ dragData
+ );
+ this.tree.setRoot(root);
+ root.setOpen(true);
+ this.tree.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["addtobatch", "reloadtree"]));
+
+ this.tree.addListener("changeSelection", function(e){
+ var viewSelection = this.getViewSelection();
+ viewSelection.setViewId("form:tree");
+ viewSelection.clear();
+ var sel = this.tree.getSortedSelection();
+ for(var i=0;i<sel.length;i++){
+ viewSelection.addNode(sel[i]);
+ }
+ }, this);
+
+ this.listPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
+ var listToolBar = new qx.ui.toolbar.ToolBar();
+ var toolGroup = new qx.ui.toolbar.Part();
+ listToolBar.add(toolGroup);
+
+ var execButton = this.getCommands()["submitform"].command.getToolbarButton();
+ toolGroup.add(execButton);
+
+ listToolBar.addSpacer();
+ listToolBar.setPaddingRight(4);
+ var delButton = this.getCommands()["removefrombatch"].command.getToolbarButton();
+ var formButton = this.getCommands()["editexecutionspecs"].command.getToolbarButton();
+ delButton.setShow("icon");
+ formButton.setShow("icon");
+ listToolBar.add(formButton);
+ listToolBar.add(delButton);
+
+ this.listPane.add(listToolBar, {edge:"north"});
+
+ var indicator = new qx.ui.core.Widget();
+ indicator.setDecorator(new qx.ui.decoration.Single().set({top:[1,"solid","#33508D"]}));
+ indicator.setHeight(0);
+ indicator.setOpacity(0.5);
+ indicator.setZIndex(100);
+ indicator.setLayoutProperties({left:-1000,top:-1000});
+ org.argeo.ria.Application.INSTANCE.getRoot().add(indicator);
+
+
+ this.list = new qx.ui.form.List();
+ this.list.setDecorator(null);
+ this.list.setSelectionMode("multi");
+ this.list.setDroppable(true);
+ this.list.setDraggable(true);
+ this.list.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["editexecutionspecs", "removefrombatch"]));
+
+
+ this.list.addListener("dragstart", function(e){
+ e.addType(["items"]);
+ e.addAction(["move"]);
+ },this);
+ this.list.addListener("dragend", function(e){
+ indicator.setDomPosition(-1000,-1000);
+ });
+ this.list.addListener("dragover", function(e){
+ var orig = e.getOriginalTarget();
+ var origCoords = orig.getContainerLocation();
+ indicator.setWidth(orig.getBounds().width);
+ indicator.setDomPosition(origCoords.left, origCoords.bottom);
+ });
+ this.list.addListener("drag", function(e){
+ var orig = e.getOriginalTarget();
+ var origCoords = orig.getContainerLocation();
+ indicator.setWidth(orig.getBounds().width);
+ indicator.setDomPosition(origCoords.left, origCoords.bottom);
+ });
+
+ this.list.addListener("drop", function(e){
+ var target = e.getRelatedTarget();
+ var afterItem = e.getOriginalTarget();
+ indicator.setDomPosition(-1000,-1000);
+ if(afterItem.classname != "qx.ui.form.ListItem") afterItem = null;
+ if(!target){
+ target = this.list.getSortedSelection()[0];
+ }
+ this._addFlowToBatch(target, afterItem);
+ }, this);
+ this.listPane.add(this.list, {edge:"center"});
+
+ this.list.addListener("changeSelection", function(e){
+ var viewSelection = this.getViewSelection();
+ viewSelection.setViewId("form:list");
+ viewSelection.clear();
+ var listSel = this.list.getSortedSelection();
+ for(var i=0;i<listSel.length;i++){
+ viewSelection.addNode(listSel[i]);
+ }
+ }, this);
+
+ splitPane.add(this.tree, 0);
+ splitPane.add(this.listPane, 1);
+ },
+
+ /**
+ * Adds a given ExecutionFlow to the batch
+ * @param target {mixed} The dropped target, can be a TreeFile (add) or a ListItem (reorder).
+ * @param after {qx.ui.form.ListItem} Optional list item : if set, the flow will be added as a new list item positionned after this one.
+ */
+ _addFlowToBatch : function(target, after){
+ //this.debug(target);
+ if(!target){
+ target = this.tree.getSelectedItem();
+ if(!target) return;
+ }else if(target.classname == "qx.ui.form.ListItem"){
+ if(!after) return;
+ if(after == "first") this.list.addAt(target, 0);
+ else this.list.addAfter(target, after);
+ return;
+ }
+ var executionModule = target.getUserData("executionModule");
+ var executionFlow = target.getUserData("executionFlow");
+ var batchEntry = new org.argeo.slc.ria.execution.BatchEntrySpec(executionModule, executionFlow);
+ var label = batchEntry.getLabel();
+ var icon = target.getIcon();
+ var item = new qx.ui.form.ListItem(label, icon);
+ item.addListener("dblclick", function(e){
+ this.getCommands()["editexecutionspecs"].command.execute();
+ }, this);
+ item.setUserData("batchEntrySpec", batchEntry);
+ item.setPaddingTop(1);
+ item.setPaddingBottom(2);
+ if(after){
+ if(after == "first") this.list.addAt(item, 0);
+ else this.list.addAfter(item, after);
+ }else{
+ this.list.add(item);
+ }
+ this.list.select(item);
+ if(this.getAutoOpen()){
+ this.getCommands()["editexecutionspecs"].command.execute();
+ }
+ },
+
+ /**
+ * Refresh the selector when the topics are updated.
+ * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
+ */
+ _feedSelector : function(changeTopicsEvent){
+ var topics = changeTopicsEvent.getData();
+ var command = this.getCommands()["submitform"].command;
+ command.setEnabled(false);
+ var menu = [];
+ for(var key in topics){
+ var submenu = {"label":topics[key],"icon":"resource/slc/mime-xsl.png", "commandId":key};
+ menu.push(submenu);
+ }
+ // FAKE!!
+ if(!menu.length){
+ menu.push({"label":"Fake Agent", "icon":"resource/slc/mime-xsl.png", "commandId":"fake_agent_uuid"});
+ }
+ command.clearMenus();
+ command.setMenu(menu);
+ if(menu.length) command.setEnabled(true);
+ },
+
+
+ /**
+ * Called at execution
+ * @param agentUuid {String} The id of the target agent
+ */
+ executeBatchOnAgent : function(agentUuid){
+ var selection = this.list.getChildren();
+ if(!selection.length) return;
+ var slcExecMessage = new org.argeo.slc.ria.execution.Message();
+ for(var i=0;i<selection.length;i++){
+ var batchEntrySpec = selection[i].getUserData("batchEntrySpec");
+ slcExecMessage.addBatchEntrySpec(batchEntrySpec);
+ }
+ this._amqClient.sendMessage(
+ "topic://agent.newExecution",
+ slcExecMessage.toXml(),
+ {"slc-agentId":agentUuid}
+ );
+ // Force logs refresh right now!
+ qx.event.Timer.once(function(){
+ var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
+ if(command){
+ command.execute();
+ }
+ }, this, 2000);
+ }
+
+ }
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * SLC API Client implementation :\r
+ * This class encapsulate the various SLC services available. It just creates the Request object\r
+ * and return them, it does not execute them. \r
+ * Available services are : \r
+ * + loadResult / removeResult / addResult\r
+ * + listCollection / listResults\r
+ * When using it, be sure the static constant DEFAULT_CONTEXT is pointing to the right URL.\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.SlcApi",\r
+{\r
+ extend : qx.core.Object,\r
+ \r
+ statics : {\r
+ DEFAULT_CONTEXT : "/org.argeo.slc.webapp",\r
+ \r
+ REMOVE_RESULT_FROM_COLL_SERVICE : "removeResultFromCollection.service",\r
+ ADD_RESULT_TO_COLL_SERVICE : "addResultToCollection.service",\r
+ LIST_COLLECTIONS_SERVICE : "listCollectionRefs.service",\r
+ COPY_COLLECTION_TO_COLL_SERVICE : "copyCollectionToCollection.service",\r
+ LIST_RESULTS_SERVICE : "listResultAttributes.service",\r
+ GET_RESULT_SERVICE : "getResult.service",\r
+ LIST_SLCEXEC_SERVICE : "listSlcExecutions.service",\r
+ \r
+ LIST_AGENTS_SERVICE : "listAgents.service",\r
+ LIST_MODULES_SERVICE : "listModulesDescriptors.service",\r
+ GET_EXECUTION_DESC_SERVICE : "getExecutionDescriptor.service",\r
+ RELOAD_BUNDLE_SERVICE : "reloadBundle.service",\r
+ AMQ_SERVICE : "amq",\r
+ \r
+ /**\r
+ * Standard Request getter\r
+ * @param serviceName {String} The name of the service to call (without base context)\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getServiceRequest:function(serviceName, fireReloadEventType, iLoadStatusables){\r
+ var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();\r
+ return serviceManager.getRequest(\r
+ org.argeo.slc.ria.SlcApi.DEFAULT_CONTEXT+"/"+serviceName,\r
+ "GET",\r
+ "application/xml",\r
+ fireReloadEventType,\r
+ iLoadStatusables\r
+ );\r
+ },\r
+ \r
+ /**\r
+ * Remove a result from a collection\r
+ * @param collectionId {String} Id of the destination collection\r
+ * @param resultId {String} Id of the test result to remove\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getRemoveResultService : function(collectionId, resultId, fireReloadEventType, iLoadStatusables){\r
+ var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.REMOVE_RESULT_FROM_COLL_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables\r
+ );\r
+ request.setParameter("collectionId", collectionId);\r
+ request.setParameter("resultUuid", resultId);\r
+ return request;\r
+ },\r
+ \r
+ /**\r
+ * Remove a set of results from a collection. Either filtered by a given pattern, or the whole collection.\r
+ * @param collectionId {String} The id of the collection\r
+ * @param patternAttribute {String} An optional attribute name on which to filter\r
+ * @param patternValue {String} The pattern to use for filtering a subset of result\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request} The Request object\r
+ */\r
+ getRemoveFromCollectionService : function(collectionId, patternAttribute, patternValue, fireReloadEventType, iLoadStatusables){\r
+ var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.REMOVE_RESULT_FROM_COLL_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables\r
+ );\r
+ request.setParameter("collectionId", collectionId);\r
+ if(patternAttribute && patternValue){\r
+ request.setParameter("attrName", patternAttribute);\r
+ request.setParameter("attrPattern", patternValue);\r
+ }\r
+ return request;\r
+ },\r
+ \r
+ /**\r
+ * Add a result to a given collection\r
+ * @param collectionId {String} Id of the destination collection\r
+ * @param resultId {String} Id of the test result to add\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getAddResultService : function(collectionId, resultId, fireReloadEventType, iLoadStatusables){\r
+ var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.ADD_RESULT_TO_COLL_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables\r
+ );\r
+ request.setParameter("collectionId", collectionId);\r
+ request.setParameter("resultUuid", resultId);\r
+ return request;\r
+ },\r
+ \r
+ /**\r
+ * List current collections\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getListCollectionsService : function(fireReloadEventType, iLoadStatusables){\r
+ return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.LIST_COLLECTIONS_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables\r
+ );\r
+ },\r
+ \r
+ /**\r
+ * Copy a whole collection or a subset of it to another collection. If a new id is provided for the target, it will be created.\r
+ * @param sourceCollectionId {String} The current collection from which to copy\r
+ * @param targetCollectionId {String} The target collection. If unknown, it will be created.\r
+ * @param patternAttribute {String} An optional attribute on which a filter can be applied to create a subset.\r
+ * @param patternValue {String} The associated pattern to filter on the atttribute's value.\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request} The request object\r
+ */\r
+ getCopyCollectionService : function(sourceCollectionId, targetCollectionId, patternAttribute, patternValue, fireReloadEventType, iLoadStatusables){\r
+ var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.COPY_COLLECTION_TO_COLL_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables \r
+ );\r
+ request.setParameter("sourceCollectionId", sourceCollectionId);\r
+ request.setParameter("targetCollectionId", targetCollectionId);\r
+ if(patternAttribute && patternValue){\r
+ request.setParameter("attrName", patternAttribute);\r
+ request.setParameter("attrPattern", patternValue);\r
+ }\r
+ return request;\r
+ },\r
+ \r
+ /**\r
+ * List all results or results of a given collection \r
+ * @param collectionId {String} Id of the collection to load\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getListResultsService : function(collectionId, fireReloadEventType, iLoadStatusables){\r
+ var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.LIST_RESULTS_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables\r
+ );\r
+ if(collectionId){\r
+ request.setParameter("id", collectionId);\r
+ }\r
+ return request;\r
+ },\r
+ \r
+ /**\r
+ * Load a result test\r
+ * @param resultId {String} Id of the test result to load\r
+ * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getLoadResultService : function(resultId, fireReloadEventType, iLoadStatusables){\r
+ var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.GET_RESULT_SERVICE, \r
+ fireReloadEventType, \r
+ iLoadStatusables\r
+ );\r
+ request.setParameter("uuid", resultId);\r
+ return request;\r
+ },\r
+\r
+ /**\r
+ * List currently registered SlcExecutions.\r
+ * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getListSlcExecutionsService:function(fireReloadEventType, iLoadStatusables){\r
+ return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.LIST_SLCEXEC_SERVICE,\r
+ fireReloadEventType,\r
+ iLoadStatusables\r
+ );\r
+ },\r
+ \r
+ \r
+ /**\r
+ * List currently available agents queues.\r
+ * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getListAgentsService:function(fireReloadEventType, iLoadStatusables){\r
+ return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.LIST_AGENTS_SERVICE,\r
+ fireReloadEventType,\r
+ iLoadStatusables\r
+ );\r
+ },\r
+\r
+ /**\r
+ * Load the module descriptors\r
+ * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getListModulesService : function(fireReloadEventType, iLoadStatusables){\r
+ return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.LIST_MODULES_SERVICE,\r
+ fireReloadEventType,\r
+ iLoadStatusables\r
+ );\r
+ },\r
+ \r
+ /**\r
+ * Get an execution module descriptor by its name and version\r
+ * @param moduleName {String} The name of the module to get\r
+ * @param moduleVersion {String} Its version, passed directly as a string\r
+ * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getLoadExecutionDescriptorService : function(moduleName, moduleVersion, fireReloadEventType, iLoadStatusables){\r
+ var req = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.GET_EXECUTION_DESC_SERVICE,\r
+ fireReloadEventType,\r
+ iLoadStatusables\r
+ ); \r
+ req.setParameter("moduleName", moduleName);\r
+ req.setParameter("version", moduleVersion);\r
+ return req;\r
+ },\r
+\r
+ /**\r
+ * Fire the reload of an OSGI bundle.\r
+ * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
+ * @return {qx.io.remote.Request}\r
+ */\r
+ getReloadBundleService : function(bundleName, bundleVersion, fireReloadEventType, iLoadStatusables){\r
+ var req = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
+ org.argeo.slc.ria.SlcApi.RELOAD_BUNDLE_SERVICE,\r
+ fireReloadEventType,\r
+ iLoadStatusables\r
+ );\r
+ req.setParameter("bundleName", bundleName);\r
+ req.setParameter("bundleVersion", bundleVersion);\r
+ return req;\r
+ },\r
+ \r
+ \r
+ \r
+ /**\r
+ * Send a JMS message to the AMQ_CONTEXT\r
+ * @param destination {String} The destination queue, in the form "topic://destination" \r
+ * @param message {org.argeo.slc.ria.SlcExecutionMessage} The message object\r
+ * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
+ */\r
+ getSendAmqMessageRequest : function(destination, message, iLoadStatusables){\r
+ var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();\r
+ var request = serviceManager.getRequest(\r
+ org.argeo.slc.ria.SlcApi.DEFAULT_CONTEXT+"/"+org.argeo.slc.ria.SlcApi.AMQ_SERVICE,\r
+ "POST",\r
+ "text/plain",\r
+ null,\r
+ iLoadStatusables\r
+ );\r
+ request.setParameter("destination", destination);\r
+ request.setParameter("message", message.toXml());\r
+ request.setParameter("type", "send");\r
+ return request;\r
+ }\r
+ \r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * A simple Hello World applet for documentation purpose. \r
+ * The only associated command is the "Close" command.\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.SlcExecLoggerApplet",\r
+{\r
+ extend : qx.ui.container.Composite,\r
+ implement : [org.argeo.ria.components.IView], \r
+\r
+ construct : function(){\r
+ this.base(arguments);\r
+ this.setLayout(new qx.ui.layout.Dock()); \r
+ },\r
+\r
+ properties : \r
+ {\r
+ /**\r
+ * The viewPane inside which this applet is added. \r
+ */\r
+ view : {\r
+ init : null\r
+ },\r
+ viewSelection : {\r
+ nullable:false, \r
+ check:"org.argeo.ria.components.ViewSelection"\r
+ }, \r
+ instanceId : {init:""},\r
+ instanceLabel : {init:""}, \r
+ /**\r
+ * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions} \r
+ */\r
+ commands : {\r
+ init : {\r
+ "reloadlogs" : {\r
+ label : "Reload Logs", \r
+ icon : "resource/slc/view-refresh.png",\r
+ shortcut : "Control+r",\r
+ enabled : true,\r
+ menu : null,\r
+ toolbar : null,\r
+ callback : function(e){\r
+ this._reloadLogger();\r
+ },\r
+ command : null\r
+ } \r
+ }\r
+ }\r
+ },\r
+\r
+ members :\r
+ {\r
+ /**\r
+ * Called at applet creation. Just registers viewPane.\r
+ * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.\r
+ */\r
+ init : function(viewPane){\r
+ this.setView(viewPane);\r
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId())); \r
+ this._createLayout();\r
+ },\r
+ \r
+ /**\r
+ * \r
+ */\r
+ load : function(){\r
+ this._reloadLogger(); \r
+ this.timer = new qx.event.Timer(15000);\r
+ this.timer.addListener("interval", this._reloadLogger, this);\r
+ this.timer.start(); \r
+ },\r
+ \r
+ addScroll : function(){\r
+ return false;\r
+ },\r
+ \r
+ close : function(){\r
+ this.timer.stop();\r
+ },\r
+ \r
+ /**\r
+ * Creates the applet layout\r
+ */\r
+ _createLayout : function(){\r
+ this.logModel = new qx.ui.table.model.Simple();\r
+ this.logModel.setColumns(["Date", "Host", "Id", "Status"]);\r
+ this.logPane = new qx.ui.table.Table(this.logModel, {\r
+ tableColumnModel: function(obj){\r
+ return new qx.ui.table.columnmodel.Resize(obj)\r
+ }\r
+ });\r
+ this.logPane.setDecorator(null);\r
+ this._initLogger();\r
+ this.add(this.logPane, {edge:'center'});\r
+ },\r
+ \r
+ /**\r
+ * Initialize the log table.\r
+ */\r
+ _initLogger : function(){\r
+ this.logPane.set({ \r
+ statusBarVisible: false,\r
+ showCellFocusIndicator:false\r
+ });\r
+ var columnModel = this.logPane.getTableColumnModel();\r
+ columnModel.getBehavior().setWidth(0, "30%");\r
+ columnModel.getBehavior().setWidth(1, "15%");\r
+ columnModel.getBehavior().setWidth(3, "12%"); \r
+ },\r
+ \r
+ /**\r
+ * Refresh the data model.\r
+ */\r
+ _reloadLogger : function(){\r
+ var request = org.argeo.slc.ria.SlcApi.getListSlcExecutionsService();\r
+ request.addListener("completed", function(response){ \r
+ var messages = org.argeo.ria.util.Element.selectNodes(response.getContent(), "//slc:slc-execution");\r
+ this.logModel.setData([]);\r
+ for(var i=0;i<messages.length;i++){\r
+ var message = messages[i];\r
+ var slcExec = new org.argeo.slc.ria.SlcExecutionMessage(message.getAttribute("uuid"));\r
+ slcExec.fromXml(message);\r
+ this.logModel.addRows([\r
+ [slcExec.getDate(), slcExec.getHost(), slcExec.getUuid(), slcExec.getStatus()]\r
+ ]); \r
+ }\r
+ }, this);\r
+ request.send(); \r
+ }\r
+ \r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * A generic JMS slcExecution message encapsulator.\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.SlcExecutionMessage", {\r
+ extend : qx.core.Object,\r
+ /**\r
+ * New instance\r
+ * @param uuid {String} The Uuid of the message. If none is passed, one is generated.\r
+ */\r
+ construct : function(uuid){\r
+ this.base(arguments);\r
+ if(uuid){\r
+ this.setUuid(uuid);\r
+ }else{\r
+ var s = [];\r
+ var itoh = '0123456789ABCDEF';\r
+ for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10);\r
+ s[14] = 4; // Set 4 high bits of time_high field to version\r
+ s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence\r
+ for (var i = 0; i <36; i++) s[i] = itoh[s[i]];\r
+ s[8] = s[13] = s[18] = s[23] = '-';\r
+ this.setUuid(s.join('').toLowerCase()); \r
+ }\r
+ this.setAttributes({});\r
+ },\r
+ properties : {\r
+ /**\r
+ * The unique id identifying the message\r
+ */\r
+ uuid : {\r
+ check : "String"\r
+ },\r
+ /**\r
+ * Execution status\r
+ */\r
+ status : {\r
+ check : "String",\r
+ init : "STARTED"\r
+ },\r
+ /**\r
+ * Execution type\r
+ */\r
+ type : {\r
+ check : "String",\r
+ init : "slcAnt"\r
+ },\r
+ /**\r
+ * Execution Host\r
+ */\r
+ host : {\r
+ check : "String",\r
+ init : "localhost"\r
+ },\r
+ /**\r
+ * Execution User\r
+ */\r
+ user : {\r
+ check : "String",\r
+ init : "user"\r
+ },\r
+ /**\r
+ * Date of the message. now() by default.\r
+ */\r
+ date : {\r
+ check : "String", \r
+ init : new Date().toString()\r
+ },\r
+ /**\r
+ * Additionnal attributes as map of key/values\r
+ */\r
+ attributes : {\r
+ check : "Map"\r
+ }\r
+ },\r
+ members : {\r
+ \r
+ /**\r
+ * Add a free attribute to the message\r
+ * @param attName {String} Name\r
+ * @param attValue {String} Value\r
+ */\r
+ addAttribute: function(attName, attValue){\r
+ var attr = this.getAttributes();\r
+ attr[attName] = attValue;\r
+ this.setAttributes(attr);\r
+ },\r
+ /**\r
+ * Build the xml formatted message body to send\r
+ * \r
+ * @return {String} The message content as Xml\r
+ */\r
+ toXml : function (){\r
+ var builder = new qx.util.StringBuilder();\r
+ builder.add('<slc:slc-execution xmlns:slc="http://argeo.org/projects/slc/schemas" uuid="'+this.getUuid()+'">');\r
+ builder.add('<slc:status>'+this.getStatus()+'</slc:status>');\r
+ builder.add('<slc:type>'+this.getType()+'</slc:type>');\r
+ builder.add('<slc:host>'+this.getHost()+'</slc:host>');\r
+ builder.add('<slc:user>'+this.getUser()+'</slc:user>');\r
+ var attr = this.getAttributes();\r
+ if(qx.lang.Object.getLength(attr)){\r
+ builder.add('<slc:attributes>');\r
+ for(var key in attr){\r
+ builder.add('<slc:attribute name="'+key+'">'+attr[key]+'</slc:attribute>');\r
+ }\r
+ builder.add('</slc:attributes>');\r
+ }\r
+ builder.add('</slc:slc-execution>');\r
+ return builder.get();\r
+ },\r
+ \r
+ /**\r
+ * Parse an XML answer and fill the object with it.\r
+ * @param slcExecXml {String} An slcExecMessage mapped in XML.\r
+ */\r
+ fromXml : function(slcExecXml){\r
+ var NSMap = {slc:"http://argeo.org/projects/slc/schemas"}; \r
+ this.setStatus(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:status", NSMap));\r
+ this.setType(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:type", NSMap));\r
+ this.setHost(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:host", NSMap));\r
+ this.setUser(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:user", NSMap));\r
+ var attributes = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:attribute", NSMap);\r
+ for(var i=0;i<attributes.length;i++){\r
+ this.addAttribute(attribute.getAttribute("name"), attribute.firstChild);\r
+ }\r
+ var stepsDates = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:steps/slc:slc-execution-step/slc:begin", NSMap);\r
+ if(stepsDates.length){\r
+ this.setDate(org.argeo.ria.util.Element.getSingleNodeText(stepsDates[stepsDates.length-1], ".", NSMap));\r
+ }\r
+ }\r
+ } \r
+});
\ No newline at end of file
--- /dev/null
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2007 OpenHex SPRL, http://www.openhex.org
+
+ License:
+ LGPL: http://www.gnu.org/licenses/lgpl.html
+ EPL: http://www.eclipse.org/org/documents/epl-v10.php
+ See the LICENSE file in the project's top-level directory for details.
+
+ Authors:
+ * Dirk Wellmann (dw(at)piponline.net)
+
+************************************************************************ */
+
+/**
+ * This Cellrender is for test status use. It create green or red background
+ * cells depending on the status value (PASSED or FAILED).
+ */
+qx.Class.define("org.argeo.slc.ria.StatusCellRenderer",
+{
+ extend : qx.ui.table.cellrenderer.Html,
+
+ construct : function(){
+ this.base(arguments);
+ var style =
+ [
+ ".slc-status-passed{background-color:#8fc98f;color:#008300;border-bottom:1px solid #cccccc;text-align:center;filter:alpha(opacity=80);opacity: 0.8;-moz-opacity:0.8;}",
+ ".slc-status-failed{background-color:#cb8f8f;color:#830000;border-bottom:1px solid #cccccc;text-align:center;filter:alpha(opacity=80);opacity: 0.8;-moz-opacity:0.8;}"
+ ];
+ // Include stylesheet
+ qx.bom.Stylesheet.createElement(style.join(""));
+ },
+
+ /*
+ *****************************************************************************
+ MEMBERS
+ *****************************************************************************
+ */
+
+ members :
+ {
+ // overridden
+ _getContentHtml : function(cellInfo) {
+ return (cellInfo.value || "");
+ },
+
+ // overridden
+ _getCellClass : function(cellInfo) {
+ if(cellInfo.value == "PASSED"){
+ return "qooxdoo-table-cell slc-status-passed";
+ }else if(cellInfo.value == "FAILED"){
+ return "qooxdoo-table-cell slc-status-failed";
+ }else{
+ return "qooxdoo-table-cell";
+ }
+ }
+ }
+});
--- /dev/null
+/**\r
+ * Package containing SLC generic components to be used by any RIA SLC applications\r
+ * as a library.\r
+ * Currently contains the SlcApi client and a canonical Applet for displaying test results.\r
+ */
\ No newline at end of file
--- /dev/null
+/**\r
+ * Data model for an entry of the Batch list : original Spec, flow and module, and currently computed value.\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.BatchEntrySpec", {\r
+ extend : org.argeo.slc.ria.execution.Spec,\r
+ \r
+ properties : {\r
+ /**\r
+ * Reference module\r
+ */\r
+ module :{},\r
+ /**\r
+ * Reference flow\r
+ */\r
+ flow : {},\r
+ /**\r
+ * Original Spec (values shall stay untouched).\r
+ */\r
+ originalSpec : {} \r
+ },\r
+ \r
+ /**\r
+ * Instance of BatchEntrySpec\r
+ * @param module {org.argeo.slc.ria.execution.Module} Reference module\r
+ * @param flow {org.argeo.slc.ria.execution.Flow} Reference flow\r
+ */\r
+ construct : function(module, flow){\r
+ this.base(arguments);\r
+ this.setModule(module);\r
+ this.setFlow(flow);\r
+ this.setOriginalSpec(flow.getExecutionSpec());\r
+ this.setName(flow.getExecutionSpec().getName());\r
+ this.fetchInstanceValues();\r
+ },\r
+ \r
+ members : {\r
+ /**\r
+ * Create a label to display in the batch list.\r
+ * @return {String} The label\r
+ */\r
+ getLabel : function(){\r
+ var label = this.getModule().getName();\r
+ label += "/" + this.getModule().getVersion();\r
+ label += "/" + this.getFlow().getName();\r
+ return label;\r
+ },\r
+ \r
+ toXml : function(){ \r
+ var valuesXml = '';\r
+ var values = this.getValues();\r
+ for(var key in values){\r
+ valuesXml += values[key].toValueXml();\r
+ }\r
+ var execFlowDescXML = '<slc:execution-flow-descriptor name="'+this.getFlow().getName()+'" executionSpec="'+this.getName()+'"><slc:values>'+valuesXml+'</slc:values></slc:execution-flow-descriptor>';\r
+ \r
+ var execSpecDescXML = this.getOriginalSpec().toXml();\r
+ \r
+ var moduleData = '<slc:module-name>'+this.getModule().getName()+'</slc:module-name><slc:module-version>'+this.getModule().getVersion()+'</slc:module-version>';\r
+ \r
+ return '<slc:realized-flow>'+moduleData + execFlowDescXML + execSpecDescXML +'</slc:realized-flow>';\r
+ \r
+ },\r
+ \r
+ /**\r
+ * Fetch the Spec Values with the Flow Values to make the current instance value\r
+ */\r
+ fetchInstanceValues : function(){\r
+ var specValues = this.getOriginalSpec().getValues();\r
+ var flow = this.getFlow();\r
+ var instanceValues = {};\r
+ for(var key in specValues){\r
+ var flowValue = flow.getValue(\r
+ key, \r
+ specValues[key].getSpecType(), \r
+ specValues[key].getSpecSubType()\r
+ );\r
+ var instValue = specValues[key].clone();\r
+ if(flowValue){\r
+ instValue.setValue(flowValue);\r
+ }\r
+ instanceValues[key] = instValue;\r
+ }\r
+ this.setValues(instanceValues);\r
+ //this.debug(instanceValues);\r
+ }\r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Wrapper for ExecutionFlow server object\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.Flow", {\r
+ \r
+ extend : qx.core.Object,\r
+ \r
+ properties : {\r
+ /**\r
+ * Name of this Execution Flow \r
+ */\r
+ name : {\r
+ check : "String",\r
+ init : ""\r
+ },\r
+ /**\r
+ * An optional path describing this flow\r
+ */\r
+ path : {\r
+ check : "String",\r
+ nullable : true\r
+ },\r
+ /**\r
+ * Name of the associated spec, to be found in the module \r
+ */\r
+ executionSpecName : {\r
+ check : "String"\r
+ },\r
+ /**\r
+ * Reference the actual ExecutionSpec object\r
+ */\r
+ executionSpec : {\r
+ check : "org.argeo.slc.ria.execution.Spec"\r
+ },\r
+ /**\r
+ * The values to init the ExecutionSpec\r
+ */\r
+ values : {\r
+ check : "Node"\r
+ },\r
+ /**\r
+ * Castor representation of the object \r
+ */\r
+ xmlNode : {\r
+ apply : "_applyXmlNode"\r
+ }\r
+ },\r
+ \r
+ statics : {\r
+ /**\r
+ * Xpath to the name \r
+ */\r
+ XPATH_NAME : "@name",\r
+ /**\r
+ * XPath to the ExecutionSpec name\r
+ */\r
+ XPATH_EXEC_SPEC_NAME : "@executionSpec",\r
+ /**\r
+ * XPath to the values\r
+ */\r
+ XPATH_VALUES : "slc:values",\r
+ /**\r
+ * An optional hierarchical path\r
+ */\r
+ XPATH_PATH : "@path"\r
+ },\r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ },\r
+ \r
+ members : { \r
+ /**\r
+ * Init the object from an XML representation\r
+ * @param xmlNode {Node} Castor representation of this object\r
+ */\r
+ _applyXmlNode : function(xmlNode){\r
+ this.set({\r
+ name : org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_NAME),\r
+ path : org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_PATH),\r
+ executionSpecName : org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_EXEC_SPEC_NAME)\r
+ });\r
+ var values = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_VALUES);\r
+ this.setValues(values[0]);\r
+ },\r
+ /**\r
+ * Get a given value inside the values map\r
+ * @param key {String} The key of the value \r
+ * @param specType {String} Expected type (currently "primitive" and "ref" are supported)\r
+ * @param specSubType {String} Expected subtype (depends on the type)\r
+ * @return {String} Value if it is set.\r
+ */\r
+ getValue: function(key, specType, specSubType){\r
+ var xpath;\r
+ if(specType == "primitive"){\r
+ xpath = 'slc:value[@key="'+key+'"]/slc:primitive-value[@type="'+specSubType+'"]';\r
+ }else if(specType == "ref"){\r
+ xpath = 'slc:value[@key="'+key+'"]/slc:ref-value/slc:label';\r
+ }\r
+ return org.argeo.ria.util.Element.getSingleNodeText(this.getValues(), xpath);\r
+ }\r
+ } \r
+ \r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * A generic JMS slcExecution message encapsulator.\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.Message", {\r
+ extend : qx.core.Object,\r
+ /**\r
+ * New instance\r
+ * @param uuid {String} The Uuid of the message. If none is passed, one is generated.\r
+ */\r
+ construct : function(uuid){\r
+ this.base(arguments);\r
+ if(uuid){\r
+ this.setUuid(uuid);\r
+ }else{\r
+ var s = [];\r
+ var itoh = '0123456789ABCDEF';\r
+ for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10);\r
+ s[14] = 4; // Set 4 high bits of time_high field to version\r
+ s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence\r
+ for (var i = 0; i <36; i++) s[i] = itoh[s[i]];\r
+ s[8] = s[13] = s[18] = s[23] = '-';\r
+ this.setUuid(s.join('').toLowerCase()); \r
+ }\r
+ this.setBatchEntrySpecs([]);\r
+ this.setAttributes({});\r
+ },\r
+ properties : {\r
+ /**\r
+ * The unique id identifying the message\r
+ */\r
+ uuid : {\r
+ check : "String"\r
+ },\r
+ /**\r
+ * Execution status\r
+ */\r
+ status : {\r
+ check : "String",\r
+ init : "STARTED"\r
+ },\r
+ /**\r
+ * Execution type\r
+ */\r
+ type : {\r
+ check : "String",\r
+ init : "slcAnt"\r
+ },\r
+ /**\r
+ * Execution Host\r
+ */\r
+ host : {\r
+ check : "String",\r
+ init : "localhost"\r
+ },\r
+ /**\r
+ * Execution User\r
+ */\r
+ user : {\r
+ check : "String",\r
+ init : "user"\r
+ },\r
+ /**\r
+ * Date of the message. now() by default.\r
+ */\r
+ date : {\r
+ check : "String", \r
+ init : new Date().toString()\r
+ },\r
+ /**\r
+ * Additionnal attributes as map of key/values\r
+ */\r
+ attributes : {\r
+ check : "Map"\r
+ },\r
+ batchEntrySpecs : {\r
+ check : "Array"\r
+ }\r
+ },\r
+ members : {\r
+ \r
+ /**\r
+ * Add a free attribute to the message\r
+ * @param attName {String} Name\r
+ * @param attValue {String} Value\r
+ */\r
+ addAttribute: function(attName, attValue){\r
+ var attr = this.getAttributes();\r
+ attr[attName] = attValue;\r
+ this.setAttributes(attr);\r
+ },\r
+ \r
+ addBatchEntrySpec : function(entrySpec){\r
+ this.getBatchEntrySpecs().push(entrySpec);\r
+ },\r
+ \r
+ /**\r
+ * Build the xml formatted message body to send\r
+ * \r
+ * @return {String} The message content as Xml\r
+ */\r
+ toXml : function (){\r
+ var builder = new qx.util.StringBuilder();\r
+ builder.add('<slc:slc-execution xmlns:slc="http://argeo.org/projects/slc/schemas" uuid="'+this.getUuid()+'">');\r
+ builder.add('<slc:status>'+this.getStatus()+'</slc:status>');\r
+ builder.add('<slc:type>'+this.getType()+'</slc:type>');\r
+ builder.add('<slc:host>'+this.getHost()+'</slc:host>');\r
+ builder.add('<slc:user>'+this.getUser()+'</slc:user>');\r
+ var flows = this.getBatchEntrySpecs();\r
+ if(flows.length){\r
+ builder.add('<realized-flows>');\r
+ for(var i=0;i<flows.length;i++){\r
+ builder.add(flows[i].toXml()); \r
+ }\r
+ builder.add('</realized-flows>');\r
+ } \r
+ var attr = this.getAttributes();\r
+ if(qx.lang.Object.getLength(attr)){\r
+ builder.add('<slc:attributes>');\r
+ for(var key in attr){\r
+ builder.add('<slc:attribute name="'+key+'">'+attr[key]+'</slc:attribute>');\r
+ }\r
+ builder.add('</slc:attributes>');\r
+ }\r
+ builder.add('</slc:slc-execution>');\r
+ return builder.get();\r
+ },\r
+ \r
+ /**\r
+ * Parse an XML answer and fill the object with it.\r
+ * @param slcExecXml {String} An slcExecMessage mapped in XML.\r
+ */\r
+ fromXml : function(slcExecXml){\r
+ var NSMap = {slc:"http://argeo.org/projects/slc/schemas"}; \r
+ this.setStatus(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:status", NSMap));\r
+ this.setType(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:type", NSMap));\r
+ this.setHost(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:host", NSMap));\r
+ this.setUser(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:user", NSMap));\r
+ var attributes = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:attribute", NSMap);\r
+ for(var i=0;i<attributes.length;i++){\r
+ this.addAttribute(attribute.getAttribute("name"), attribute.firstChild);\r
+ }\r
+ var stepsDates = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:steps/slc:slc-execution-step/slc:begin", NSMap);\r
+ if(stepsDates.length){\r
+ this.setDate(org.argeo.ria.util.Element.getSingleNodeText(stepsDates[stepsDates.length-1], ".", NSMap));\r
+ }\r
+ }\r
+ } \r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Wrapper for ExecutionModule server object\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.Module", {\r
+ \r
+ extend : qx.core.Object,\r
+ \r
+ properties : {\r
+ /**\r
+ * The name of the module\r
+ */\r
+ name : {\r
+ check : "String",\r
+ init : ""\r
+ },\r
+ /**\r
+ * The version of the module\r
+ */\r
+ version : {\r
+ check : "String",\r
+ init : ""\r
+ },\r
+ /**\r
+ * All execution flows registered by their name\r
+ */\r
+ executionFlows : {\r
+ check : "Map"\r
+ },\r
+ /**\r
+ * All execution specs registered by their name\r
+ */\r
+ executionSpecs : {\r
+ check : "Map"\r
+ },\r
+ /**\r
+ * XML description (castor)\r
+ */\r
+ xmlNode : {\r
+ apply : "_applyXmlNode"\r
+ }\r
+ },\r
+ \r
+ statics : {\r
+ XPATH_NAME : "slc:execution-module-descriptor/slc:name",\r
+ XPATH_VERSION : "slc:execution-module-descriptor/slc:version",\r
+ XPATH_EXECUTION_FLOWS : "slc:execution-module-descriptor/slc:execution-flows/slc:execution-flow-descriptor",\r
+ XPATH_EXECUTION_SPECS : "slc:execution-module-descriptor/slc:execution-specs/slc:default-execution-spec"\r
+ },\r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ this.setExecutionFlows({});\r
+ this.setExecutionSpecs({});\r
+ },\r
+ \r
+ members : {\r
+ /**\r
+ * Add an execution flow to this module\r
+ * @param executionFlow {org.argeo.slc.ria.execution.Flow} An instance of execution.Flow\r
+ */\r
+ addExecutionFlow : function(executionFlow){\r
+ var spec = this.getExecutionSpecByName(executionFlow.getExecutionSpecName());\r
+ if(spec){\r
+ executionFlow.setExecutionSpec(spec);\r
+ }else{\r
+ this.error("Warning, reference to an unknown ExecutionSpec : "+executionFlow.getExecutionSpecName());\r
+ }\r
+ this.getExecutionFlows()[executionFlow.getName()] = executionFlow;\r
+ },\r
+ \r
+ /**\r
+ * Add an execution Spec to this module\r
+ * @param executionSpec {org.argeo.slc.ria.execution.Spec} An instance of ExecutionSpec\r
+ */\r
+ addExecutionSpec : function(executionSpec){\r
+ this.getExecutionSpecs()[executionSpec.getName()] = executionSpec;\r
+ },\r
+ /**\r
+ * Find an execution spec by its name\r
+ * @param name {String} Name of the spec\r
+ * @return {org.argeo.slc.ria.execution.Spec} The spec\r
+ */\r
+ getExecutionSpecByName : function(name){\r
+ return this.getExecutionSpecs()[name];\r
+ },\r
+ \r
+ /**\r
+ * Find an execution flow by its name\r
+ * @param name {String} name of the flow\r
+ * @return {org.argeo.slc.ria.execution.Flow} The flow\r
+ */\r
+ getExecutionFlowByName : function(name){\r
+ return this.getExecutionFlows()[name];\r
+ },\r
+ \r
+ /**\r
+ * An xml node containing the castor mapped description of this object\r
+ * @param xmlNode {Node}\r
+ */\r
+ _applyXmlNode : function(xmlNode){\r
+ // Parse now\r
+ this.setName(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_NAME));\r
+ this.setVersion(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_VERSION));\r
+ // Parse Specs first\r
+ var specs = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_EXECUTION_SPECS);\r
+ for(i=0; i< specs.length;i++){\r
+ var execSpec = new org.argeo.slc.ria.execution.Spec();\r
+ execSpec.setXmlNode(specs[i]);\r
+ this.addExecutionSpec(execSpec);\r
+ }\r
+ // Now parse Flows : to do AFTER specs\r
+ var flows = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_EXECUTION_FLOWS);\r
+ for(var i=0;i<flows.length;i++){\r
+ var execFlow = new org.argeo.slc.ria.execution.Flow();\r
+ execFlow.setXmlNode(flows[i]);\r
+ this.addExecutionFlow(execFlow);\r
+ }\r
+ }\r
+ \r
+ } \r
+ \r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Wrapper for ExecutionSpec server object\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.Spec", {\r
+ \r
+ extend : qx.core.Object,\r
+ \r
+ properties : {\r
+ /**\r
+ * Unique name of this spec \r
+ */\r
+ name : {\r
+ check : "String",\r
+ init : ""\r
+ },\r
+ /**\r
+ * Defined parameters \r
+ */\r
+ values : {\r
+ check : "Map"\r
+ },\r
+ /**\r
+ * Castor representation of this object\r
+ */\r
+ xmlNode : {\r
+ apply : "_applyXmlNode" \r
+ }\r
+ },\r
+ \r
+ statics : {\r
+ XPATH_NAME : "@name",\r
+ XPATH_VALUES : "slc:values/slc:value"\r
+ },\r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ this.setValues({});\r
+ },\r
+ \r
+ members : {\r
+ /**\r
+ * Init the object from an XML representation\r
+ * @param xmlNode {Node} Castor representation of this object\r
+ */ \r
+ _applyXmlNode : function(xmlNode){\r
+ // Parse now\r
+ this.setName(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_NAME));\r
+ var values = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_VALUES);\r
+ var parsedValues = {};\r
+ for(var i=0;i<values.length;i++){\r
+ //var valueNode = values[i];\r
+ var value = new org.argeo.slc.ria.execution.Value();\r
+ value.setXmlSpecNode(values[i]);\r
+ parsedValues[value.getKey()] = value;\r
+ }\r
+ this.setValues(parsedValues);\r
+ },\r
+ /**\r
+ * XML Representation of this object.\r
+ * @return {String} An XML String\r
+ */\r
+ toXml : function(){\r
+ var valuesXml = '';\r
+ var values = this.getValues();\r
+ for(var key in values){\r
+ valuesXml += values[key].toAttributeXml();\r
+ }\r
+ return '<slc:default-execution-spec name="'+this.getName()+'"><slc:values>'+valuesXml+'</slc:values></slc:default-execution-spec>';\r
+ }\r
+ } \r
+ \r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Generic modal popup window.\r
+ * It is layed out with a dock layout. When adding components to it, they are added as "center".\r
+ * @author Charles du Jeu\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.SpecEditor",\r
+{\r
+ extend : qx.ui.window.Window,\r
+ \r
+ properties : {\r
+ /**\r
+ * The Spec to edit\r
+ */\r
+ batchEntrySpec : {\r
+ check : "org.argeo.slc.ria.execution.BatchEntrySpec"\r
+ }\r
+ },\r
+ \r
+ events : {\r
+ /**\r
+ * Triggered when the user clicks the "save" button. \r
+ */\r
+ "save" : "qx.event.type.Event",\r
+ /**\r
+ * Triggered when any data is modified\r
+ */\r
+ "modified" : "qx.event.type.Event"\r
+\r
+ },\r
+ /**\r
+ * Opens an editor with the given values. \r
+ * @param batchEntrySpec {org.argeo.slc.ria.execution.BatchEntrySpec} The initial spec to edit\r
+ */\r
+ construct : function(batchEntrySpec){\r
+ var editorLabel = "Edit Specs for "+batchEntrySpec.getLabel();\r
+ this.base(arguments, editorLabel);\r
+ this.set({\r
+ batchEntrySpec : batchEntrySpec,\r
+ showMaximize : false,\r
+ showMinimize : false,\r
+ width: Math.min(parseInt(qx.bom.Viewport.getWidth()*90/100), 400),\r
+ height: parseInt(qx.bom.Viewport.getHeight()*60/100)\r
+ });\r
+ this.setLayout(new qx.ui.layout.Dock());\r
+ this.setModal(true);\r
+ this.center();\r
+ this._initFormObject(this.getBatchEntrySpec().getLabel());\r
+ this._addFormHeader(this.formObject, editorLabel);\r
+ this.createFormFromSpec();\r
+ this.addContent(this.formObject.pane);\r
+ this.addOkCancel();\r
+ this.addListener("save", function(e){\r
+ this.saveFormToSpec();\r
+ }, this);\r
+ },\r
+ \r
+ members : {\r
+ /**\r
+ * Builds the form from the BatchEntrySpec\r
+ */\r
+ createFormFromSpec : function(){\r
+ var values = this.getBatchEntrySpec().getValues();\r
+ for(var key in values){\r
+ var valueObj = values[key];\r
+ var label = key;\r
+ var hidden = valueObj.getHidden();\r
+ var disabled = valueObj.getFrozen();\r
+ var value = valueObj.getValue();\r
+ var type = valueObj.getSpecType();\r
+ var subType = valueObj.getSpecSubType();\r
+ if(type == "primitive" && !hidden){\r
+ this._addFormInputText(this.formObject, key, key, value, disabled, subType);\r
+ }\r
+ }\r
+ },\r
+ /**\r
+ * Gather data from the form\r
+ */\r
+ saveFormToSpec : function(){\r
+ var values = this.getBatchEntrySpec().getValues();\r
+ for(var key in values){\r
+ var valueObj = values[key];\r
+ var hidden = valueObj.getHidden();\r
+ var disabled = valueObj.getFrozen();\r
+ if(valueObj.getSpecType() == "primitive"){\r
+ if(!hidden && !disabled){\r
+ valueObj.setValue(this.formObject.fields[key].getValue());\r
+ }\r
+ }\r
+ } \r
+ },\r
+ \r
+ /**\r
+ * Display a component (panel) in the center of the popup\r
+ * @param panel {qx.ui.core.Widget} A gui component (will be set at width 100%).\r
+ */\r
+ addContent: function(panel){\r
+ this.add(new qx.ui.container.Scroll(panel), {edge:'center', width:'100%'});\r
+ },\r
+ /**\r
+ * Automatically attach to the application root, then show.\r
+ */\r
+ attachAndShow:function(){\r
+ org.argeo.ria.components.ViewsManager.getInstance().getApplicationRoot().add(this); \r
+ this.show();\r
+ },\r
+ /**\r
+ * Init a form part : creates a pane, a set of fields, etc.\r
+ * @param label {String} A label\r
+ * @return {Map} The form part.\r
+ */\r
+ _initFormObject : function(label){\r
+ this.formObject = {};\r
+ this.formObject.hiddenFields = {};\r
+ this.formObject.freeFields = [];\r
+ this.formObject.fields = {};\r
+ this.formObject.label = label;\r
+ this.formObject.pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));\r
+ return this.formObject;\r
+ },\r
+ \r
+ /**\r
+ * Creates a simple label/input form entry.\r
+ * @param formObject {Map} The form part\r
+ * @param fieldName {String} Name\r
+ * @param fieldLabel {String} Label of the field\r
+ * @param defaultValue {String} The default value\r
+ * @param choiceValues {Map} An map of values\r
+ * @param disabled {Boolean} The field is not writable\r
+ * @param subType {String} The type expected (string, integer, etc).\r
+ */\r
+ _addFormInputText : function(formObject, fieldName, fieldLabel, defaultValue, disabled, subType, choiceValues){\r
+ var labelElement;\r
+ if(choiceValues){\r
+ var fieldElement = new qx.ui.form.SelectBox();\r
+ for(var key in choiceValues){\r
+ fieldElement.add(new qx.ui.form.ListItem(choiceValues[key], null, key));\r
+ }\r
+ fieldElement.addListener("changeSelected", function(e){this.fireEvent("modified")}, this);\r
+ }else{\r
+ var fieldElement = new qx.ui.form.TextField();\r
+ if(subType == "integer"){\r
+ fieldElement.addListener("changeValue", function(e){\r
+ var isNum = !isNaN(e.getData() * 1);\r
+ if(!isNum){\r
+ alert("Warning, this field only accepts Integers!");\r
+ }\r
+ }, this); \r
+ }\r
+ fieldElement.addListener("input", function(e){this.fireEvent("modified")}, this); \r
+ }\r
+ if(defaultValue){\r
+ fieldElement.setValue(defaultValue);\r
+ }\r
+ if(fieldName && fieldLabel){\r
+ labelElement = new qx.ui.basic.Label(fieldLabel);\r
+ formObject.fields[fieldName] = fieldElement;\r
+ }else{\r
+ labelElement = new qx.ui.form.TextField();\r
+ formObject.freeFields.push({\r
+ labelEl:labelElement, \r
+ valueEl:fieldElement\r
+ });\r
+ }\r
+ if(disabled) fieldElement.setEnabled(false);\r
+ this._addFormEntry(formObject, labelElement, fieldElement);\r
+ },\r
+ \r
+ /**\r
+ * Add an header\r
+ * @param formObject {Map} The form part\r
+ * @param content {Mixed} Content to add.\r
+ * @param additionnalButton {Mixed} Any widget to add on the east.\r
+ */\r
+ _addFormHeader : function(formObject, content, additionnalButton){\r
+ var header = new qx.ui.basic.Label('<big><b>'+content+'</b></big>');\r
+ header.setRich(true); \r
+ if(!additionnalButton){\r
+ header.setPaddingBottom(10);\r
+ formObject.pane.add(header);\r
+ }else{\r
+ var pane = new qx.ui.container.Composite(new qx.ui.layout.Dock());\r
+ pane.setPaddingBottom(10);\r
+ pane.setPaddingRight(10);\r
+ pane.add(header, {edge:'center'});\r
+ pane.add(additionnalButton, {edge:'east'});\r
+ formObject.pane.add(pane);\r
+ }\r
+ },\r
+ \r
+ /**\r
+ * Adds a label/input like entry in the form.\r
+ * @param formObject {Map} The form part\r
+ * @param labelElement {Object} Either a label or an input \r
+ * @param fieldElement {Object} Any form input.\r
+ */\r
+ _addFormEntry : function(formObject, labelElement, fieldElement){\r
+ var entryPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));\r
+ labelElement.setWidth(150);\r
+ labelElement.setTextAlign("right"); \r
+ entryPane.add(labelElement);\r
+ entryPane.add(new qx.ui.basic.Label(':'));\r
+ fieldElement.setWidth(150);\r
+ entryPane.add(fieldElement);\r
+ formObject.pane.add(entryPane);\r
+ },\r
+ \r
+ /**\r
+ * Adds a close button bottom-center aligned to the popup\r
+ */\r
+ addCloseButton : function(){\r
+ this.closeButton = new qx.ui.form.Button("Close");\r
+ this.closeButton.addListener("execute", this._closeAndDestroy, this);\r
+ this.add(this.closeButton, {edge:'south'}); \r
+ },\r
+ /**\r
+ * Adds two buttons bottom-center aligned (Ok and Cancel). \r
+ * Ok button has no listener by default, Cancel will close and destroy the popup.\r
+ */\r
+ addOkCancel : function(){\r
+ var buttonPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5, 'right'));\r
+ buttonPane.setAlignX("center");\r
+ this.add(buttonPane, {edge:"south"});\r
+ this.okButton = new qx.ui.form.Button("Save");\r
+ this.okButton.setEnabled(false);\r
+ this.addListener("modified", function(e){\r
+ this.okButton.setEnabled(true);\r
+ }, this);\r
+ this.okButton.addListener("execute", function(e){\r
+ this.fireEvent("save");\r
+ this.okButton.setEnabled(false);\r
+ }, this);\r
+ this.cancelButton = new qx.ui.form.Button("Close");\r
+ this.cancelButton.addListener("execute", this._closeAndDestroy, this);\r
+\r
+ this.saveCloseButton = new qx.ui.form.Button("Save & Close");\r
+ this.saveCloseButton.addListener("execute", function(e){\r
+ this.fireEvent("save");\r
+ this._closeAndDestroy();\r
+ }, this);\r
+ \r
+ buttonPane.add(this.okButton);\r
+ buttonPane.add(this.cancelButton);\r
+ buttonPane.add(this.saveCloseButton);\r
+ },\r
+ /**\r
+ * Close this modal window and destroy it.\r
+ */\r
+ _closeAndDestroy : function(){\r
+ this.hide();\r
+ this.destroy(); \r
+ }\r
+ }\r
+});
\ No newline at end of file
--- /dev/null
+/**\r
+ * Wrapper for SlcValue object\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.Value", {\r
+ \r
+ extend : qx.core.Object,\r
+ \r
+ properties : {\r
+ /**\r
+ * Name of this Execution Flow \r
+ */\r
+ key : {\r
+ check : "String",\r
+ init : ""\r
+ },\r
+ /**\r
+ * The type of this value, for the moment "primitive" and "ref" are supported \r
+ */\r
+ specType : {\r
+ check : "String",\r
+ init : "" \r
+ },\r
+ /**\r
+ * Subtype, depending on the "type". \r
+ */\r
+ specSubType : {\r
+ check : "String"\r
+ },\r
+ /**\r
+ * Whether it is a parameter or not \r
+ */\r
+ parameter : {\r
+ check : "Boolean"\r
+ },\r
+ /**\r
+ * Whether it is frozen on the server, i.e. disabled in the form \r
+ */\r
+ frozen : {\r
+ check : "Boolean"\r
+ },\r
+ /**\r
+ * Should not be editable nor seeable, thus hidden \r
+ */\r
+ hidden : {\r
+ check : "Boolean"\r
+ },\r
+ /**\r
+ * The real value \r
+ */\r
+ value : {\r
+ nullable : true\r
+ },\r
+ /**\r
+ * Castor representation of the object \r
+ */\r
+ xmlSpecNode : {\r
+ apply : "_applyXmlSpecNode"\r
+ }\r
+ },\r
+ \r
+ statics : {\r
+ XPATH_KEY : "@key"\r
+ },\r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ },\r
+ \r
+ members : { \r
+ /**\r
+ * Init the object from an XML representation\r
+ * @param xmlNode {Node} Castor representation of this object\r
+ */\r
+ _applyXmlSpecNode : function(xmlNode){\r
+ this.setKey(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, "@key"));\r
+ var childs = xmlNode.childNodes;\r
+ for(var i=0;i<childs.length;i++){\r
+ var child = childs[i];\r
+ if(child.nodeType != 1) continue;\r
+ if(child.nodeName == "slc:primitive-spec-attribute"){\r
+ this.setSpecType("primitive");\r
+ this.setSpecSubType(org.argeo.ria.util.Element.getSingleNodeText(child, "@type"));\r
+ if(org.argeo.ria.util.Element.getSingleNodeText(child, ".")){\r
+ this.setValue(org.argeo.ria.util.Element.getSingleNodeText(child, "."));\r
+ }\r
+ }else if(child.nodeName == "slc:ref-spec-attribute"){\r
+ this.setSpecType("ref");\r
+ this.setSpecSubType(org.argeo.ria.util.Element.getSingleNodeText(child, "@targetClassName"));\r
+ }\r
+ this.set({\r
+ parameter : (org.argeo.ria.util.Element.getSingleNodeText(child, "@isParameter")=="true"?true:false),\r
+ frozen : (org.argeo.ria.util.Element.getSingleNodeText(child, "@isFrozen")=="true"?true:false),\r
+ hidden : (org.argeo.ria.util.Element.getSingleNodeText(child, "@isHidden")=="true"?true:false)\r
+ }); \r
+ }\r
+ },\r
+ \r
+ /**\r
+ * Create an XML Representation of this value\r
+ * @return {String} The XML String\r
+ */\r
+ toAttributeXml : function(){\r
+ var valueTag = '';\r
+ var specAttribute = '';\r
+ if(this.getSpecType() == "primitive"){\r
+ valueTag = (this.getValue()?this.getValue():'');\r
+ specAttribute = '<slc:primitive-spec-attribute isParameter="'+(this.getParameter()?"true":"false")+'" isFrozen="'+(this.getFrozen()?"true":"false")+'" isHidden="'+(this.getHidden()?"true":"false")+'" type="'+this.getSpecSubType()+'">'+valueTag+'</slc:primitive-spec-attribute>';\r
+ }else if(this.getSpecType() == "ref"){\r
+ valueTag = (this.getValue()?'<slc:label>'+this.getValue()+'</slc:label>':'');\r
+ specAttribute = '<slc:ref-spec-attribute isParameter="'+(this.getParameter()?"true":"false")+'" isFrozen="'+(this.getFrozen()?"true":"false")+'" isHidden="'+(this.getHidden()?"true":"false")+'" targetClassName="'+this.getSpecSubType()+'">'+valueTag+'</slc:ref-spec-attribute>';\r
+ }\r
+ return '<slc:value key="'+this.getKey()+'">'+specAttribute+'</slc:value>';\r
+ },\r
+ \r
+ toValueXml : function(){\r
+ var valueTag = '';\r
+ var specAttribute = '';\r
+ if(this.getSpecType() == "primitive"){\r
+ valueTag = this.getValue();\r
+ specAttribute = '<slc:primitive-value type="'+this.getSpecSubType()+'">'+valueTag+'</slc:primitive-value>';\r
+ }else if(this.getSpecType() == "ref"){\r
+ valueTag = '<slc:label>'+this.getValue()+'</slc:label>';\r
+ specAttribute = '<slc:ref-value >'+valueTag+'</slc:ref-value>';\r
+ }\r
+ return '<slc:value key="'+this.getKey()+'">'+specAttribute+'</slc:value>'; \r
+ }\r
+ } \r
+ \r
+});
\ No newline at end of file
+++ /dev/null
-{\r
- "info" : \r
- {\r
- "name" : "org.argeo.ria.sample",\r
-\r
- "summary" : "Sample RIA Application",\r
- "description" : "Basic RIA Implementation for documentation purposes",\r
- \r
- "homepage" : "http://www.argeo.org/",\r
-\r
- "license" : "LGPL",\r
- "authors" : \r
- [\r
- {\r
- "name" : "Charles du Jeu",\r
- "email" : "charles.dujeu@gmail.com"\r
- }\r
- ],\r
-\r
- "version" : "trunk",\r
- "qooxdoo-versions": ["0.8"]\r
- },\r
- \r
- "provides" : \r
- {\r
- "namespace" : "org.argeo.ria.sample",\r
- "encoding" : "utf-8",\r
- "class" : "class",\r
- "resource" : "resource",\r
- "translation" : "translation",\r
- "type" : "library"\r
- }\r
-}\r
-\r
+++ /dev/null
-/**
- * A simple Hello World applet for documentation purpose.
- * The only associated command is the "Close" command.
- */
-qx.Class.define("org.argeo.ria.sample.Applet",
-{
- extend : qx.ui.container.Composite,
- implement : [org.argeo.ria.components.IView],
-
- construct : function(){
- this.base(arguments);
- this.setLayout(new qx.ui.layout.VBox());
- this.passedStatus = "PASSED";
- this.failedStatus = "FAILED";
- },
-
- properties :
- {
- /**
- * The viewPane inside which this applet is added.
- */
- view : {
- init : null
- },
- /**
- * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
- */
- commands : {
- init : {
- "close" : {
- label : "Close Result",
- icon : "resource/slc/window-close.png",
- shortcut : "Control+w",
- enabled : true,
- menu : "Applet",
- toolbar : "result",
- callback : function(e){
- // Call service to delete
- this.getView().empty();
- },
- command : null
- }
- }
- },
- viewSelection : {
- nullable:false,
- check:"org.argeo.ria.components.ViewSelection"
- },
- instanceId : {init:"Hello Applet"},
- instanceLabel : {init:"Hello"}
-
- },
-
- members :
- {
- /**
- * Called at applet creation. Just registers viewPane.
- * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
- */
- init : function(viewPane, data){
- this.setView(viewPane);
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
- this.data = data;
- this.setInstanceId(data[0]);
- this.setInstanceLabel("Hello applet #"+data[0]);
- },
-
- /**
- * Load a given row : the data passed must be a simple data array.
- * @param data {Element} The text xml description.
- */
- load : function(){
- this.createHtmlGui("<b>Hello World ! Data ID is : "+this.getInstanceId()+"</b>");
- },
-
- addScroll : function(){
- return false;
- },
-
- close : function(){
- return false;
- },
-
- /**
- * Create a simple HtmlElement and and insert the html string..
- * Not used but sample.
- * @param htmlText {String} Html code to display.
- */
- createHtmlGui : function(htmlText){
- var htmlElement = new qx.ui.embed.Html(htmlText);
- htmlElement.setOverflowX("auto");
- htmlElement.setOverflowY("auto");
- this.add(htmlElement, {flex:1});
- }
-
- }
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * A Basic IView implementation displaying a fake list of result and opening \r
- * an org.argeo.ria.sample.Applet\r
- */\r
-qx.Class.define("org.argeo.ria.sample.List",\r
-{\r
- extend : qx.ui.container.Composite,\r
- implement : [org.argeo.ria.components.IView], \r
-\r
- construct : function(){\r
- this.base(arguments, new qx.ui.layout.VBox()); \r
- var model = new qx.ui.table.model.Simple();\r
- model.setColumns(["Test Case", "Date"]);\r
- this.table = new qx.ui.table.Table(model, {\r
- tableColumnModel: function(obj){\r
- return new qx.ui.table.columnmodel.Resize(obj)\r
- }\r
- });\r
- },\r
-\r
- properties : \r
- {\r
- /**\r
- * The viewPane containing this applet.\r
- */\r
- view : {\r
- init : null\r
- },\r
- /**\r
- * The applet commands.\r
- */\r
- commands : {\r
- init : {\r
- "opentest" : {\r
- label : "Open", \r
- icon : "resource/slc/media-playback-start.png",\r
- shortcut : "Control+o",\r
- enabled : false,\r
- menu : "Selection",\r
- toolbar : "selection",\r
- callback : function(e){\r
- var viewsManager = org.argeo.ria.components.ViewsManager.getInstance();\r
- var classObj = org.argeo.ria.sample.Applet;\r
- var rowData = viewsManager.getViewPaneSelection("list").getNodes();\r
- var iView = viewsManager.initIViewClass(classObj, "applet", rowData[0]);\r
- iView.load();\r
- },\r
- selectionChange : function(viewId, rowData){\r
- if(viewId != "list") return;\r
- this.setEnabled(false);\r
- if(rowData == null || !rowData.length) return;\r
- this.setEnabled(true);\r
- },\r
- command : null\r
- }\r
- }\r
- },\r
- viewSelection : {\r
- nullable:false, \r
- check:"org.argeo.ria.components.ViewSelection"\r
- },\r
- instanceId : {init:"0"},\r
- instanceLabel : {init:"Sample List"} \r
- },\r
- \r
- members : {\r
- init : function(viewPane, data){\r
- this.setView(viewPane);\r
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));\r
- \r
- },\r
- load : function(){\r
- //\r
- // Customize table appearance\r
- //\r
- this.table.set({ \r
- statusBarVisible: false,\r
- showCellFocusIndicator:false,\r
- columnVisibilityButtonVisible:false,\r
- contextMenu : org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["opentest", "download", "copytocollection", "deletetest"]),\r
- decorator : new qx.ui.decoration.Background("#fff")\r
- });\r
- \r
- // \r
- // Link table selection changes to the standard viewSelection mechanism\r
- //\r
- var selectionModel = this.table.getSelectionManager().getSelectionModel();\r
- selectionModel.addListener("changeSelection", function(e){\r
- var viewSelection = this.getViewSelection();\r
- viewSelection.clear();\r
- if(!selectionModel.getSelectedCount()){\r
- return;\r
- }\r
- var ranges = selectionModel.getSelectedRanges();\r
- var rowData = this.table.getTableModel().getRowData(ranges[0].minIndex);\r
- viewSelection.addNode(rowData);\r
- }, this); \r
- \r
- //\r
- // Add table to the GUI component\r
- // \r
- this.add(this.table, {flex:1});\r
-\r
- //\r
- // Now create fake rows\r
- // \r
- var model = this.table.getTableModel();\r
- model.addRows([\r
- ["Id 1","Sample 1"], \r
- ["Id 2","Sample 2"],\r
- ["Id 3","Sample 3"]\r
- ]);\r
- },\r
- \r
- addScroll : function(){\r
- return false;\r
- },\r
- \r
- close : function(){\r
- \r
- }\r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
- */\r
-qx.Class.define("org.argeo.ria.sample.Perspective",\r
-{\r
- extend : qx.core.Object,\r
- implement : [org.argeo.ria.components.IPerspective], \r
- \r
- construct : function(){\r
- this.base(arguments);\r
- },\r
- \r
- members : {\r
- \r
- initViewPanes : function(viewsManager){\r
- \r
- this.splitPane = new qx.ui.splitpane.Pane("horizontal");\r
- var topLeft = new org.argeo.ria.components.ViewPane("list", "Sample List", {\r
- orientation : "horizontal",\r
- min : 36\r
- });\r
- topLeft.set({width:300});\r
- viewsManager.registerViewPane(topLeft);\r
- \r
- this.splitPane.add(topLeft, 0);\r
- var rightPane = new org.argeo.ria.components.ViewPane("applet", "Sample Applet"); \r
- viewsManager.registerViewPane(rightPane);\r
- this.splitPane.add(rightPane, 1);\r
- \r
- viewsManager.getViewPanesContainer().add(this.splitPane, {flex:1});\r
- \r
- },\r
- \r
- initViews : function(viewsManager){\r
- var view = viewsManager.initIViewClass(org.argeo.ria.sample.List, "list");\r
- view.load();\r
- },\r
- \r
- remove : function(viewsManager){\r
- viewsManager.getViewPaneById("list").empty();\r
- viewsManager.getViewPaneById("applet").empty();\r
- viewsManager.getViewPanesContainer().remove(this.splitPane);\r
- }\r
- \r
- }\r
-\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Specific classes used for training by the Argeo RIA documentation\r
- */
\ No newline at end of file
+++ /dev/null
-{\r
- "info" : \r
- {\r
- "name" : "org.argeo.slc.web",\r
-\r
- "summary" : "Slc Web Application",\r
- "description" : "RIA Implementation for SLC Web",\r
- \r
- "homepage" : "http://www.argeo.org/",\r
-\r
- "license" : "LGPL",\r
- "authors" : \r
- [\r
- {\r
- "name" : "Charles du Jeu",\r
- "email" : "charles.dujeu@gmail.com"\r
- }\r
- ],\r
-\r
- "version" : "trunk",\r
- "qooxdoo-versions": ["0.8"]\r
- },\r
- \r
- "provides" : \r
- {\r
- "namespace" : "org.argeo.slc.web",\r
- "encoding" : "utf-8",\r
- "class" : "class",\r
- "resource" : "resource",\r
- "translation" : "translation",\r
- "type" : "library"\r
- }\r
-}\r
-\r
+++ /dev/null
-/**\r
- * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
- */\r
-qx.Class.define("org.argeo.slc.web.LauncherPerspective",\r
-{\r
- extend : qx.core.Object,\r
- implement : [org.argeo.ria.components.IPerspective], \r
- \r
- construct : function(){\r
- this.base(arguments);\r
- org.argeo.ria.util.Element.DEFAULT_NAMESPACE_MAP = {slc:"http://argeo.org/projects/slc/schemas"};\r
- },\r
-\r
- statics : {\r
- LABEL : "Slc Execution",\r
- ICON : "resource/slc/utilities-terminal.png"\r
- },\r
- \r
- members : {\r
- \r
- _rightPane : null,\r
- \r
- initViewPanes : function(viewsManager){\r
-\r
- this._splitPane = new qx.ui.splitpane.Pane("horizontal");\r
- var topLeft = new org.argeo.ria.components.ViewPane("form", "Execution Launcher", {\r
- orientation : "horizontal",\r
- min : 36\r
- });\r
- topLeft.set({width:290});\r
- viewsManager.registerViewPane(topLeft);\r
- \r
- this._splitPane.add(topLeft, 0);\r
- var rightPane = new org.argeo.ria.components.ViewPane("main", "Executions Log"); \r
- viewsManager.registerViewPane(rightPane);\r
- this._splitPane.add(rightPane, 1);\r
- \r
- viewsManager.getViewPanesContainer().add(this._splitPane, {flex:1});\r
- \r
- },\r
- \r
- initViews : function(viewsManager){\r
- var formApplet = viewsManager.initIViewClass(org.argeo.slc.ria.NewLauncherApplet, "form");\r
- formApplet.load();\r
- \r
- var logger = viewsManager.initIViewClass(org.argeo.slc.ria.SlcExecLoggerApplet, "main");\r
- logger.load();\r
- },\r
- \r
- remove : function(viewsManager){\r
- viewsManager.getViewPaneById("main").empty();\r
- viewsManager.getViewPaneById("form").empty();\r
- viewsManager.getViewPanesContainer().remove(this._splitPane); \r
- } \r
- \r
- }\r
-\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * IPerspective Implementation : Horizontal split pane defining two panes, "list" and "applet".\r
- */\r
-qx.Class.define("org.argeo.slc.web.Perspective",\r
-{\r
- extend : qx.core.Object,\r
- implement : [org.argeo.ria.components.IPerspective], \r
- \r
- construct : function(){\r
- this.base(arguments);\r
- org.argeo.ria.util.Element.DEFAULT_NAMESPACE_MAP = {slc:"http://argeo.org/projects/slc/schemas"};\r
- },\r
- \r
- statics : {\r
- LABEL : "Test Results",\r
- ICON : "resource/slc/office-chart.png"\r
- },\r
- \r
- members : {\r
- _splitPane : null, \r
- \r
- initViewPanes : function(viewsManager){\r
- \r
- this._splitPane = new qx.ui.splitpane.Pane("horizontal");\r
- var topLeft = new org.argeo.ria.components.ViewPane("list", "Collection", {\r
- orientation : "horizontal",\r
- min : 36\r
- });\r
- topLeft.set({width:300});\r
- viewsManager.registerViewPane(topLeft);\r
- \r
- this._splitPane.add(topLeft, 0);\r
- var rightPane = new org.argeo.ria.components.TabbedViewPane("applet", "Test Detail"); \r
- viewsManager.registerViewPane(rightPane);\r
- this._splitPane.add(rightPane, 1);\r
- \r
- viewsManager.getViewPanesContainer().add(this._splitPane, {flex:1});\r
- \r
- },\r
- \r
- initViews : function(viewsManager){\r
- var view = viewsManager.initIViewClass(org.argeo.slc.web.TestList, "list");\r
- view.load();\r
- view.loadCollections();\r
- view.loadList();\r
- },\r
- \r
- remove : function(viewsManager){\r
- viewsManager.getViewPaneById("list").empty();\r
- viewsManager.getViewPaneById("applet").empty();\r
- viewsManager.getViewPanesContainer().remove(this._splitPane); \r
- }\r
- \r
- }\r
-\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Basic IView implementation for displaying the test results list, by collection.\r
- * \r
- * This component creates a Table object and feed it with the results. It adds a collection chooser to its viewPane header.\r
- * \r
- * It creates the following commands : "loadtestlist", "polllistloading", "opentest", "download", "copytocollection", "deletetest".\r
- */\r
-qx.Class.define("org.argeo.slc.web.TestList",\r
-{\r
- extend : qx.ui.container.Composite,\r
- implement : [org.argeo.ria.components.IView], \r
-\r
- construct : function(){\r
- this.base(arguments, new qx.ui.layout.VBox()); \r
- var model = new qx.ui.table.model.Simple();\r
- model.setColumns(["Test Case", "Date"]);\r
- this.table = new qx.ui.table.Table(model, {\r
- tableColumnModel: function(obj){\r
- return new qx.ui.table.columnmodel.Resize(obj)\r
- }\r
- });\r
- },\r
-\r
- properties : \r
- {\r
- /**\r
- * The viewPane containing this applet.\r
- */\r
- view : {\r
- init : null\r
- },\r
- viewSelection : {\r
- nullable:false, \r
- check:"org.argeo.ria.components.ViewSelection"\r
- }, \r
- instanceId : {init:""},\r
- instanceLabel : {init:""},\r
- /**\r
- * The load list of available collection (Map of ids => labels)\r
- */\r
- collectionList : {\r
- init : {},\r
- check : "Map"\r
- },\r
- /**\r
- * The current collection id selected.\r
- */\r
- collectionId:{\r
- init : 'My Collection',\r
- check : "String"\r
- },\r
- /**\r
- * The applet commands.\r
- */\r
- commands : {\r
- init : {\r
- "loadtestlist" : {\r
- label : "Load Collection", \r
- icon : "resource/slc/view-refresh.png",\r
- shortcut : "Control+l",\r
- enabled : true,\r
- menu : "Collection",\r
- toolbar : "collection",\r
- callback : function(e){\r
- this.loadList();\r
- }, \r
- command : null\r
- },\r
- "polllistloading" : {\r
- label : "Auto load", \r
- icon : "resource/slc/document-open-recent.png",\r
- shortcut : "Control+l",\r
- enabled : true,\r
- toggle : true,\r
- menu : "Collection",\r
- toolbar : "collection",\r
- callback : function(event){\r
- this.pollListLoading(event.getTarget().getUserData("slc.command.toggleState"));\r
- }, \r
- command : null\r
- },\r
- /*\r
- "copyfullcollection" : {\r
- label : "Copy to...", \r
- icon : "resource/slc/edit-copy.png",\r
- shortcut : null,\r
- enabled : false,\r
- menu : "Collection",\r
- toolbar : "collection",\r
- callback : function(e){\r
- // Call service to copy\r
- },\r
- submenu : {},\r
- submenuCallback : function(commandId){\r
- this.copySelectionToCollection(commandId, "current_collection");\r
- },\r
- init : function(){\r
- // Call at command creation\r
- org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(event){\r
- if(event.getDataType() == "collection" || event.getDataType() == "test_cases"){\r
- var testList = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("list").getContent();\r
- testList.collectionListToMenu(this);\r
- }\r
- }, this);\r
- },\r
- command : null\r
- },\r
- */\r
- "opentest" : {\r
- label : "Open", \r
- icon : "resource/slc/media-playback-start.png",\r
- shortcut : "Control+o",\r
- enabled : false,\r
- menu : "Selection",\r
- toolbar : "selection",\r
- callback : function(e){\r
- var viewsManager = org.argeo.ria.components.ViewsManager.getInstance();\r
- var classObj = org.argeo.slc.ria.Applet;\r
- var xmlNodes = viewsManager.getViewPaneSelection("list").getNodes();\r
- var iView = viewsManager.initIViewClass(classObj, "applet", xmlNodes[0]);\r
- iView.load(xmlNodes[0]);\r
- },\r
- selectionChange : function(viewId, xmlNodes){\r
- if(viewId != "list") return;\r
- this.setEnabled(false);\r
- if(xmlNodes == null || !xmlNodes.length) return;\r
- this.setEnabled(true);\r
- },\r
- command : null\r
- },\r
- "download" : {\r
- label : "Download as...", \r
- icon : "resource/slc/go-down.png",\r
- shortcut : null,\r
- enabled : false,\r
- menu : "Selection",\r
- toolbar : "selection",\r
- callback : function(e){ },\r
- command : null,\r
- submenu : [\r
- {'label':"Xsl", 'icon':'resource/slc/mime-xsl.png', 'commandId':'xsl'},\r
- {'label':"Xml", 'icon':'resource/slc/mime-xml.png', 'commandId':'xml'},\r
- {'label':"Excel", 'icon':'resource/slc/mime-xls.png', 'commandId':'xls'},\r
- {'label':"Pdf", 'icon':'resource/slc/mime-pdf.png', 'commandId':'pdf'}\r
- ],\r
- submenuCallback : function(commandId){\r
- var uuid = this.extractTestUuid();\r
- var urls = {\r
- xsl : "resultView.xslt",\r
- xml : "resultViewXml.xslt",\r
- xls : "resultView.xls",\r
- pdf : "resultView.pdf"\r
- };\r
- var url = "../"+urls[commandId]+"?uuid="+uuid;\r
- if(commandId == "xls" || commandId == "pdf"){\r
- document.location.href = url;\r
- }else{\r
- var win = window.open(url);\r
- }\r
- },\r
- selectionChange : function(viewId, xmlNodes){\r
- if(viewId!="list")return;\r
- //this.clearMenus();\r
- this.setEnabled(false);\r
- if(xmlNodes == null || !xmlNodes.length) return;\r
- this.setEnabled(true);\r
- }\r
- },\r
- "copytocollection" : {\r
- label : "Copy to...", \r
- icon : "resource/slc/edit-copy.png",\r
- shortcut : "Control+c",\r
- enabled : false,\r
- menu : "Selection",\r
- toolbar : "selection",\r
- callback : function(e){\r
- // Call service to copy\r
- },\r
- submenu : {},\r
- submenuCallback : function(commandId){\r
- this.copySelectionToCollection(commandId, "current_selection"); \r
- },\r
- init : function(){\r
- // Call at command creation\r
- org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(event){\r
- if(event.getDataType() == "collection" || event.getDataType() == "test_cases"){\r
- var testList = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("list").getContent();\r
- testList.collectionListToMenu(this, true);\r
- }\r
- }, this);\r
- },\r
- selectionChange : function(viewId, xmlNodes){\r
- if(viewId != "list") return;\r
- this.setEnabled(false);\r
- if(xmlNodes == null || !xmlNodes.length) return;\r
- this.setEnabled(true); \r
- },\r
- command : null\r
- },\r
- "deletetest" : {\r
- label : "Delete", \r
- icon : "resource/slc/edit-delete.png",\r
- shortcut : "Control+d",\r
- enabled : false,\r
- menu : "Selection",\r
- toolbar : "selection",\r
- callback : function(e){\r
- var modal = new org.argeo.ria.components.Modal("Confirm", null);\r
- modal.addConfirm("Are you sure you want to delete<br> test " + this.extractTestUuid() + "?");\r
- modal.addListener("ok", function(){\r
- var request = org.argeo.slc.ria.SlcApi.getRemoveResultService(this.getCollectionId(), this.extractTestUuid());\r
- request.addListener("completed", function(response){\r
- this.loadCollections();\r
- this.loadList();\r
- this.info("Test was successfully deleted");\r
- }, this);\r
- request.send(); \r
- }, this);\r
- modal.attachAndShow();\r
- },\r
- selectionChange : function(viewId, xmlNodes){\r
- if(viewId != "list") return;\r
- this.setEnabled(false);\r
- if(xmlNodes == null || !xmlNodes.length) return;\r
- this.setEnabled(true); \r
- },\r
- command : null\r
- }\r
- }\r
- }\r
- },\r
- \r
- members : {\r
- init : function(viewPane, data){\r
- this.setView(viewPane);\r
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId())); \r
- },\r
- load : function(){\r
- this.table.set({ \r
- statusBarVisible: false,\r
- showCellFocusIndicator:false,\r
- columnVisibilityButtonVisible:false,\r
- contextMenu : org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["opentest", "download", "copytocollection", "deletetest"]),\r
- decorator : new qx.ui.decoration.Background("#fff")\r
- });\r
- var viewPane = this.getView();\r
- this.table.addListener("dblclick", function(e){\r
- org.argeo.ria.event.CommandsManager.getInstance().executeCommand("opentest");\r
- }, this);\r
- var columnModel = this.table.getTableColumnModel(); \r
- columnModel.getBehavior().setWidth(0, "60%");\r
- var renderer = new org.argeo.slc.web.XmlRenderer();\r
- columnModel.setDataCellRenderer(0, renderer);\r
- columnModel.setDataCellRenderer(1, renderer);\r
- \r
- this.table.getSelectionManager().getSelectionModel().addListener("changeSelection", function(e){\r
- var viewSelection = this.getViewSelection();\r
- viewSelection.clear();\r
- var selectionModel = this.table.getSelectionManager().getSelectionModel();\r
- if(!selectionModel.getSelectedCount()){\r
- return;\r
- }\r
- var ranges = this.table.getSelectionManager().getSelectionModel().getSelectedRanges();\r
- var xmlNode = this.table.getTableModel().getRowData(ranges[0].minIndex);\r
- viewSelection.addNode(xmlNode);\r
- //viewPane.setViewSelection(viewSelection);\r
- }, this); \r
- \r
- var select = new qx.ui.form.SelectBox();\r
- this.getView().addHeaderComponent(select);\r
- this.getView().setViewTitle("");\r
- this.add(this.table, {flex:1});\r
-\r
- select.addListener("changeValue", this.collectionSelectorListener, this);\r
-\r
- org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(event){\r
- if(event.getDataType()!="collection") return;\r
- select.removeListener("changeValue", this.collectionSelectorListener, this);\r
- var collectionList = event.getContent();\r
- select.removeAll();\r
- for(key in collectionList){\r
- var item = new qx.ui.form.ListItem(collectionList[key], "resource/slc/folder.png", key);\r
- select.add(item);\r
- if(key == this.getCollectionId()){\r
- select.setSelected(item);\r
- }\r
- }\r
- if(qx.lang.Object.getLength(collectionList)){\r
- this.setCollectionId(select.getSelected().getValue());\r
- }\r
- select.addListener("changeValue", this.collectionSelectorListener, this);\r
- }, this);\r
- \r
- },\r
- \r
- /**\r
- * Use SlcApi to load the available collections.\r
- */\r
- loadCollections : function(){\r
- var request = org.argeo.slc.ria.SlcApi.getListCollectionsService();\r
- var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
- request.addListener("completed", function(response){\r
- var xml = response.getContent();\r
- var collections = {};\r
- var nodes = org.argeo.ria.util.Element.selectNodes(xml, "//slc:ref", NSMap);\r
- for(var i=0;i<nodes.length;i++){\r
- var collId = qx.xml.Element.getSingleNodeText(nodes[i], ".");\r
- collections[collId] = collId;\r
- }\r
- this.setCollectionList(collections);\r
- org.argeo.ria.remote.RequestManager.getInstance().fireReloadEvent("collection", this.getCollectionList());\r
- }, this);\r
- request.setAsynchronous(false);\r
- request.send();\r
- },\r
- \r
- /**\r
- * Load the results of the currently selected collection.\r
- */\r
- loadList : function(){\r
- var model = this.table.getTableModel();\r
- model.removeRows(0, model.getRowCount());\r
- var commandManager = org.argeo.ria.event.CommandsManager.getInstance();\r
- var request = org.argeo.slc.ria.SlcApi.getListResultsService(this.getCollectionId(), null, [commandManager.getCommandById("loadtestlist"), this.getView()]);\r
- var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
- request.addListener("completed", function(response){\r
- var xml = response.getContent();\r
- this.debug("Successfully loaded XML");\r
- var nodes = org.argeo.ria.util.Element.selectNodes(xml, "//slc:result-attributes", NSMap);\r
- //model.addRows(nodes);\r
- \r
- for(var i=0; i<nodes.length;i++){ \r
- model.addRows([nodes[i]]);\r
- } \r
- }, request);\r
- request.send(); \r
- },\r
- \r
- /**\r
- * Enable/disable the automatic reloading of the list.\r
- * @param state {Boolean} Whether the automatic reloading must be started or stopped.\r
- */\r
- pollListLoading : function(state){\r
- if(!this.timer){\r
- this.timer = new qx.event.Timer(5000);\r
- this.timer.addListener("interval", this.loadList, this);\r
- }\r
- if(state){\r
- this.loadList();\r
- this.timer.start();\r
- }else{\r
- this.timer.stop();\r
- }\r
- },\r
- \r
- /**\r
- * Creates a menu gui component from the currently loaded collectionList.\r
- * @param command {qx.event.Command} The command on which to attach the created menu. \r
- * @param checkSelection {Boolean} Whether at the end, we must check the current viewSelection to enable/disable the command accordingly. \r
- */\r
- collectionListToMenu : function(command, checkSelection){\r
- command.setEnabled(false);\r
- command.clearMenus();\r
- var collectionList = this.getCollectionList();\r
- if(!collectionList) return;\r
- var submenus = [];\r
- for(var key in collectionList){\r
- if(this.getCollectionId() && key == this.getCollectionId()) continue;\r
- submenus.push({\r
- "label":collectionList[key], \r
- "icon":"resource/slc/folder.png", \r
- "commandId":key\r
- });\r
- } \r
- submenus.push({'separator':true});\r
- submenus.push({"label":"New...", "icon":"resource/slc/folder-new.png", "commandId":"slc.client.create"});\r
- command.setMenu(submenus);\r
- if(checkSelection){\r
- var viewSelection = this.getView().getViewSelection();\r
- if(viewSelection.getCount()) command.setEnabled(true);\r
- }else{\r
- command.setEnabled(true);\r
- }\r
- },\r
- /**\r
- * Use SlcApi "addResult" service to add selected results to a given collection.\r
- * If collectionId is "slc.client.create", first triggers a modal dialog to enter a new collection name, then retrigger itself with the new id.\r
- * @param collectionId {String} The id of the destination collection, or "slc.client.create".\r
- * @param selectionType {String} "current_collection"|"current_selection". The first adds the whole collection content to the destination, the second only selected results.\r
- */\r
- copySelectionToCollection:function(collectionId, selectionType){\r
- if(collectionId == "slc.client.create"){\r
- var modal = new org.argeo.ria.components.Modal("Create collection", "resource/slc/folder-new.png");\r
- modal.makePromptForm("Enter the new collection name", function(value){\r
- if(value == ""){\r
- alert("Please enter a name for the new collection!");\r
- return false;\r
- }\r
- else {\r
- // Create the collection now, then recall the callback with the new name. \r
- this.copySelectionToCollection(value, selectionType);\r
- return true;\r
- }\r
- }, this);\r
- modal.attachAndShow();\r
- return;\r
- }\r
-\r
- var currentFocus = org.argeo.ria.components.ViewsManager.getInstance().getCurrentFocus();\r
- if(currentFocus.getViewId() == "applet"){\r
- alert("Should copy data from the applet - command was " + collectionId);\r
- return;\r
- }\r
- \r
- if(selectionType == "current_collection"){\r
- this.error("Not implemented yet!"); \r
- }else if(selectionType == "current_selection"){\r
- // get selection ID\r
- var request = org.argeo.slc.ria.SlcApi.getAddResultService(collectionId,this.extractTestUuid());\r
- request.addListener("completed", function(response){\r
- this.info("Result successfully copied to collection!");\r
- this.loadCollections();\r
- }, this);\r
- request.send(); \r
- }\r
- },\r
- \r
- /**\r
- * Utilitary function to extract test unique id from the currently selected node.\r
- * @return {String} The test unique id.\r
- */\r
- extractTestUuid: function(){\r
- var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
- var xmlNodes = this.getView().getViewSelection().getNodes();\r
- var uuid = qx.dom.Node.getText(org.argeo.ria.util.Element.selectSingleNode(xmlNodes[0], "slc:uuid"));\r
- return uuid;\r
- },\r
- \r
- /**\r
- * Listener of the collection selector (select box added to the viewpane header). \r
- * @param event {qx.event.type.Event} The event.\r
- */\r
- collectionSelectorListener : function(event){\r
- this.setCollectionId(event.getData());\r
- this.loadList(); \r
- },\r
- \r
- addScroll : function(){\r
- return false;\r
- },\r
- \r
- close : function(){\r
- if(this.timer){\r
- this.pollListLoading(false);\r
- }\r
- }\r
- \r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Basic helper for SLC XML results to be displayed in a qx.ui.table.\r
- * Overrides the html of the standard qx.ui.table.cellrenderer.String\r
- * \r
- * TODO : put in org.argeo.slc.ria package\r
- * \r
- */\r
-qx.Class.define("org.argeo.slc.web.XmlRenderer",\r
-{\r
- extend : qx.ui.table.cellrenderer.String,\r
-\r
- /*\r
- *****************************************************************************\r
- MEMBERS\r
- *****************************************************************************\r
- */\r
-\r
- members :\r
- {\r
- /**\r
- * Overrides the parent method.\r
- * @param cellInfo {Map} The current cell data \r
- * @return {String}\r
- */\r
- _getContentHtml : function(cellInfo) {\r
- var xmlNode = cellInfo.rowData;\r
- if(!xmlNode) return "";\r
- var xPath;\r
- var NSMap = {slc:"http://argeo.org/projects/slc/schemas"};\r
- switch(cellInfo.col){\r
- case 0 :\r
- xPath = "slc:uuid";\r
- var nameParam = org.argeo.ria.util.Element.selectSingleNode(xmlNode, xPath, NSMap);\r
- var value = qx.bom.String.escape(qx.dom.Node.getText(nameParam) || "Not Found");\r
- break;\r
- case 1 : \r
- xPath = "slc:close-date";\r
- var nameParam = org.argeo.ria.util.Element.selectSingleNode(xmlNode, xPath, NSMap);\r
- var value = qx.bom.String.escape(qx.dom.Node.getText(nameParam) || "NOT CLOSED");\r
- if(value == "NOT CLOSED") return value;\r
- var splits = value.split(".");\r
- value = splits[0].replace("T", " "); \r
- var dateFormat = new qx.util.format.DateFormat("yyyy-MM-dd HH:mm:ss");\r
- try {\r
- var date = dateFormat.parse(value);\r
- var dateFormat2 = new qx.util.format.DateFormat("MMM d, yy HH:mm:ss");\r
- return dateFormat2.format(date);\r
- }catch(e){}\r
- break;\r
- default :\r
- return "";\r
- break;\r
- }\r
- \r
- return value;\r
- },\r
- \r
- // overridden\r
- /**\r
- * Overrides parent method\r
- * @param cellInfo {Map} Current cell data\r
- * @return {String}\r
- */\r
- _getCellClass : function(cellInfo) {\r
- return this.base(arguments, cellInfo);\r
- }\r
- \r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Specific classes used by the SLC-WEB RIA application.\r
- */
\ No newline at end of file
+++ /dev/null
-{\r
- "info" : \r
- {\r
- "name" : "org.argeo.slc.ria",\r
-\r
- "summary" : "Slc Ria library",\r
- "description" : "Utilities for SLC RIA",\r
- \r
- "homepage" : "http://www.argeo.org/",\r
-\r
- "license" : "LGPL",\r
- "authors" : \r
- [\r
- {\r
- "name" : "Charles du Jeu",\r
- "email" : "charles.dujeu@gmail.com"\r
- }\r
- ],\r
-\r
- "version" : "trunk",\r
- "qooxdoo-versions": ["0.8"]\r
- },\r
- \r
- "provides" : \r
- {\r
- "namespace" : "org.argeo.slc.ria",\r
- "encoding" : "utf-8",\r
- "class" : "class",\r
- "resource" : "resource",\r
- "translation" : "translation",\r
- "type" : "library"\r
- }\r
-}\r
-\r
+++ /dev/null
-/**
- * The canonical SLC applet for test result viewing. It will display a TreeTestResult in a TreeVirtual component
- * composed of four columns : test name, state (passed/failed/error), message and date.
- *
- * It makes use of the StatusCellRenderer class for the "state" cell being a background-colored cell, the color depending on the FAILED or PASSED state message.
- * The only associated command is the "Close" command.
- */
-qx.Class.define("org.argeo.slc.ria.Applet",
-{
- extend : qx.ui.container.Composite,
- implement : [org.argeo.ria.components.IView],
-
- construct : function(){
- this.base(arguments);
- this.setLayout(new qx.ui.layout.VBox());
- this.passedStatus = "PASSED";
- this.failedStatus = "FAILED";
- this.loaded = false;
- },
-
- properties :
- {
- /**
- * The viewPane inside which this applet is added.
- */
- view : {
- init : null
- },
- viewSelection : {
- nullable:false,
- check:"org.argeo.ria.components.ViewSelection"
- },
- instanceId : {
- init : ""
- },
- instanceLabel : {
- init : ""
- },
- /**
- * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
- */
- commands : {
- init : {
- "close" : {
- label : "Close Current",
- icon : "resource/slc/window-close.png",
- shortcut : "Control+w",
- enabled : true,
- menu : "Test",
- toolbar : "result",
- callback : function(e){
- this.getView().closeCurrent();
- //this.getView().empty();
-
- },
- command : null
- }
- /*,
- "copytocollection" : {
- shared : true,
- selectionChange : function(viewId, xmlNode){
- if(viewId != "applet") return;
- if(!xmlNode){
- this.setEnabled(false);
- }else{
- this.setEnabled(true);
- }
- }
- },
- "deletetest" : {
- shared : true,
- callback : function(e){
- //this.debug(this);
- alert("Should delete applet selection in " + this.getInstanceId());
- },
- selectionChange : function(viewId, xmlNode){
- if(viewId != "applet") return;
- if(!xmlNode){
- this.setEnabled(false);
- }else{
- this.setEnabled(true);
- }
- }
- }
- */
- }
- }
- },
-
- members :
- {
- init : function(viewPane, xmlNode){
- this.setView(viewPane);
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
- this.data = xmlNode;
- if(this.data){
- this.testId = org.argeo.ria.util.Element.getSingleNodeText(this.data, "slc:uuid");
- this.setInstanceId("test:"+this.testId);
- this.setInstanceLabel("Test " + this.testId.substring(0,4)+"...");
- }
- },
-
- load : function(){
- if(!this.data) return;
- if(this.loaded) return;
- // Load XML or Whatever
- var service;
- //this.testId = qx.dom.Node.getText(org.argeo.ria.util.Element.selectSingleNode(this.data, "slc:uuid"));
- this.getView().setViewTitle("Test "+this.testId);
- var request = org.argeo.slc.ria.SlcApi.getLoadResultService(this.testId);
- request.addListener("completed", function(response){
- this.createXmlGui(response.getContent());
- this.getView().setOnLoad(false);
- this.loaded = true;
- }, this);
- this.getView().setOnLoad(true);
- request.send();
-
- },
-
- addScroll : function(){
- return false;
- },
-
- close : function(){
-
- },
-
- /**
- * Creates the GUI.
- * @param responseXml {Document} The xml response of the "load" query.
- */
- createXmlGui : function(responseXml){
- var NSMap = {
- "slc" : "http://argeo.org/projects/slc/schemas"
- }
- if(!qx.Class.hasMixin(qx.ui.treevirtual.TreeVirtual, qx.ui.treevirtual.MNode)){
- qx.Class.include(qx.ui.treevirtual.TreeVirtual,qx.ui.treevirtual.MNode);
- }
- this.tree = new qx.ui.treevirtual.TreeVirtual(["Test", "State", "Message", "Id"]);
- this.tree.getTableColumnModel().setDataCellRenderer(0, new org.argeo.ria.util.TreeDataCellRenderer());
- this.tree.getDataRowRenderer().setHighlightFocusRow(false); // Default row renderer
- this.tree.setRowHeight(18);
- this.tree.setStatusBarVisible(false);
- this.tree.setDecorator(new qx.ui.decoration.Background("#fff"));
- var model = this.tree.getDataModel();
- var resNodes = org.argeo.ria.util.Element.selectNodes(responseXml, "//slc:result-part", NSMap);
- var resultParts = {};
- var addedPaths = {};
- for(var i=0;i<resNodes.length;i++){
- var currentParentId = null;
- var node = resNodes[i];
- var pathAttr = qx.xml.Element.getSingleNodeText(node, "@path");
- var pathParts = pathAttr.split("/");
- if(pathParts[0] == ""){
- pathParts.shift();
- }
- var crtPath = "";
- for(var j=0;j<pathParts.length;j++){
- //if(pathParts[j] == "") continue;
- crtPath = crtPath.concat("/", pathParts[j]);
- if(addedPaths[crtPath]) {
- currentParentId = addedPaths[crtPath];
- continue; // Node already exists, set as parent and go to next!
- }
- var element = org.argeo.ria.util.Element.selectSingleNode(responseXml, '//slc:element[@path="'+crtPath+'"]', NSMap);
- var label;
- if(element != null){
- label = org.argeo.ria.util.Element.getSingleNodeText(element, "*/slc:label", NSMap);
- }else{
- label = crtPath;
- }
- var simpleResults = org.argeo.ria.util.Element.selectNodes(node, "slc:part-sub-list/slc:parts/slc:simple-result-part", NSMap);
-
- var newId;
- //newId = model.addBranch(currentParentId, label, false);
-
- // Test Leaf Node
- if(!simpleResults || !simpleResults.length){
- newId = model.addBranch(currentParentId, label, false);
- addedPaths[crtPath] = newId;
- currentParentId = newId;
- continue;
- }
- if(simpleResults.length == 1){
- //newId = model.addBranch(currentParentId, label, false);
- var sResNode = simpleResults[0];
- newId = model.addBranch(currentParentId, label);
- model.setColumnData(newId, 3, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:test-run-uuid", NSMap));
- model.setColumnData(newId, 2, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:message", NSMap));
- var status = org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:status", NSMap);
- if(status != "PASSED"){
- status = this.failedStatus ;
- this._setParentBranchAsFailed(newId);
- }else{
- status = this.passedStatus;
- }
- model.setColumnData(newId, 1, status);
- addedPaths[crtPath] = newId;
- currentParentId = newId;
- continue;
- }
- newId = model.addBranch(currentParentId, label, false);
- for(var k=0;k<simpleResults.length;k++){
- var sResNode = simpleResults[k];
- resId = model.addLeaf(currentParentId, label);
- model.setColumnData(resId, 3, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:test-run-uuid", NSMap));
- model.setColumnData(resId, 2, org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:message", NSMap));
- var status = org.argeo.ria.util.Element.getSingleNodeText(sResNode, "slc:status", NSMap);
- if(status != "PASSED"){
- status = this.failedStatus ;
- this._setParentBranchAsFailed(resId);
- }else{
- status = this.passedStatus;
- }
- model.setColumnData(resId, 1, status);
- }
-
- addedPaths[crtPath] = newId;
- currentParentId = newId;
- }
- }
- this._refineLeaves(this.tree, 0);
- this.add(this.tree, {flex:1});
- model.setData();
- var columnModel = this.tree.getTableColumnModel();
- var resize = columnModel.getBehavior();
- resize.set(0, {width:250, minWidth:250});
- resize.set(1, {width:55});
- resize.set(2, {width:"1*"});
- resize.set(3, {width:150});
- columnModel.setDataCellRenderer(1, new org.argeo.slc.ria.StatusCellRenderer());
-
- this.tree.getSelectionManager().getSelectionModel().addListener("changeSelection", function(e){
- var viewSelection = this.getViewSelection();
- viewSelection.clear();
- var nodes = this.tree.getDataModel().getSelectedNodes();
- if(nodes.length){
- viewSelection.addNode(nodes[0]);
- }
- this.getView().focus();
- }, this);
-
- var contextMenu = org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["close"]);
- this.tree.setContextMenu(contextMenu);
-
- },
-
- /**
- * Goes up the parents recursively to set a whole tree branch in "failed" mode.
- * @param id {Integer} The id of the child node.
- */
- _setParentBranchAsFailed : function(id){
- var model = this.tree.getDataModel();
- while(id != null && id!=0){
- var node = this.tree.nodeGet(id);
- id = node.parentNodeId;
- if(id != null && id!=0){
- model.setColumnData(id, 1, this.failedStatus);
- this.tree.nodeSetOpened(id, true);
- }
- }
- },
-
- /**
- * Recursively make sur the last children are of qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF type.
- *
- * @param tree {qx.ui.treevirtual.TreeVirtual} The main tree of the applet.
- * @param nodeId {Integer} Current node id.
- */
- _refineLeaves : function(tree, nodeId){
- var node = tree.nodeGet(nodeId);
- if(node.children && node.children.length){
- for(var i=0;i<node.children.length;i++){
- this._refineLeaves(tree, node.children[i]);
- }
- }else{
- node.type = qx.ui.treevirtual.SimpleTreeDataModel.Type.LEAF;
- }
- },
-
- /**
- * Alternatively to the createXmlGui, create a simple HtmlElement and append the query responseText.
- * Not used but sample.
- * @param responseText {String} Html code to display.
- */
- createHtmlGui : function(responseText){
- var htmlElement = new qx.ui.embed.Html(responseText);
- htmlElement.setOverflowX("auto");
- htmlElement.setOverflowY("auto");
- this.add(htmlElement, {flex:1});
- }
-
- }
-});
\ No newline at end of file
+++ /dev/null
-/**
- * A simple Hello World applet for documentation purpose.
- * The only associated command is the "Close" command.
- */
-qx.Class.define("org.argeo.slc.ria.LauncherApplet",
-{
- extend : qx.ui.container.Composite,
- implement : [org.argeo.ria.components.IView],
-
- construct : function(){
- this.base(arguments);
- this.setLayout(new qx.ui.layout.Dock());
-
- this.COMMON_FORM_HEADER_LABEL = "Choose Agent";
- this.CHOOSE_AGENT_LABEL = "Agent Uuid";
- this.CHOOSE_FORM_PART_LABEL = "Test Type";
- },
-
- properties :
- {
- /**
- * The viewPane inside which this applet is added.
- */
- view : {
- init : null
- },
- viewSelection : {
- nullable:false,
- check:"org.argeo.ria.components.ViewSelection"
- },
- instanceId : {init:""},
- instanceLabel : {init:""},
- /**
- * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
- */
- commands : {
- init : {
- "submitform" : {
- label : "Execute",
- icon : "resource/slc/media-playback-start.png",
- shortcut : "Control+e",
- enabled : true,
- menu : "Launcher",
- toolbar : "launcher",
- callback : function(e){
- this.submitForm();
- },
- command : null
- },
- "reloadagents" : {
- label : "Reload Agents",
- icon : "resource/slc/view-refresh.png",
- shortcut : "Control+r",
- enabled : true,
- menu : "Launcher",
- toolbar : "launcher",
- callback : function(e){
- var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
- req.send();
- },
- command : null
- }
- }
- },
- /**
- * A map containing all currently registered agents.
- */
- registeredTopics : {
- init : {},
- check : "Map",
- event : "changeRegisteredTopics"
- }
- },
-
- members :
- {
- /**
- * Called at applet creation. Just registers viewPane.
- * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
- */
- init : function(viewPane){
- this.setView(viewPane);
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
- this._createLayout();
- this._createForm();
- this._amqClient = org.argeo.ria.remote.JmsClient.getInstance();
- this._amqClient.startPolling();
- },
-
- /**
- *
- */
- load : function(){
- this.getView().setViewTitle("Execution Launcher");
- this.addListener("changeRegisteredTopics", function(event){
- //this._refreshTopicsSubscriptions(event);
- this._feedSelector(event);
- }, this);
- var reloadHandler = function(message){
- // Delay reload to be sure the jms was first integrated by the db, then ask the db.
- qx.event.Timer.once(function(){
- org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadagents").execute();
- }, this, 1000);
- }
- this._amqClient.addListener("agentregister", "topic://agent.register", reloadHandler, this);
- this._amqClient.addListener("agentunregister", "topic://agent.unregister", reloadHandler, this);
- reloadHandler();
- },
-
- addScroll : function(){
- return false;
- },
-
- close : function(){
- this._amqClient.removeListener("agentregister", "topic://agent.register");
- this._amqClient.removeListener("agentunregister", "topic://agent.unregister");
-
- this.setRegisteredTopics({});
- this._amqClient.stopPolling();
- },
-
- /**
- * Creates the main applet layout.
- */
- _createLayout : function(){
- this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
- this.scroll = new qx.ui.container.Scroll(this.formPane);
- this.formPane.setPadding(10);
- this.add(this.scroll, {edge:'center'});
-
- },
-
- /**
- * Creates the form.
- */
- _createForm : function(){
- this.fields = {};
- this.hiddenFields = {};
- this.freeFields = [];
-
- var execButtonPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
- var execButton = new qx.ui.form.Button(
- "Execute",
- "resource/slc/media-playback-start-32.png"
- )
- execButton.addListener("click", function(){
- this.submitForm();
- }, this);
- execButtonPane.setPadding(10, 80);
- execButtonPane.add(execButton, {edge:"center"});
- this.formPane.add(execButtonPane);
-
- this.agentSelector = new qx.ui.form.SelectBox();
- var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();
- serviceManager.addListener("reload", function(reloadEvent){
- if(reloadEvent.getDataType()!= "agents") return ;
- var xmlDoc = reloadEvent.getContent();
- var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
- var newTopics = {};
- for(var i=0;i<nodes.length;i++){
- var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
- var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
- newTopics[uuid] = host+" ("+uuid+")";
- }
- this.setRegisteredTopics(newTopics);
- }, this);
-
- var commonForm = {pane:this.formPane};
- this._addFormHeader(commonForm, this.COMMON_FORM_HEADER_LABEL);
- this._addFormEntry(commonForm, new qx.ui.basic.Label(this.CHOOSE_AGENT_LABEL), this.agentSelector);
- this._createFormVariableParts();
- if(!this.parts) return;
- if(qx.lang.Object.getLength(this.parts) > 1){
- // Add chooser
- this.partChooser = new qx.ui.form.SelectBox();
- for(var key in this.parts){
- this.partChooser.add(new qx.ui.form.ListItem(this.parts[key].label, null, key));
- }
- this._addFormEntry(commonForm, new qx.ui.basic.Label(this.CHOOSE_FORM_PART_LABEL), this.partChooser);
- this.partChooser.addListener("changeValue", function(ev){
- this._showSelectedPart(ev.getData());
- }, this);
- }
- this._showSelectedPart(qx.lang.Object.getKeys(this.parts)[0]);
- },
-
- /**
- * Show a form part given its id.
- * @param partId {String} The part id
- */
- _showSelectedPart : function(partId){
- if(!this.parts) return;
- if(!this.partsContainer){
- this.partsContainer = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
- this.formPane.add(this.partsContainer);
- }
- for(var i in this.parts){
- var formObject = this.parts[i];
- if(!formObject.added){
- this.partsContainer.add(formObject.pane, {top:0, left:0});
- formObject.added = true;
- }
- formObject.pane.hide();
- }
- if(this.parts[partId]){
- this.parts[partId].pane.show();
- }
- },
-
- /**
- * Init a form part : creates a pane, a set of fields, etc.
- * @param formId {String} A unique ID
- * @param label {String} A label
- * @return {Map} The form part.
- */
- _initFormPart : function(formId, label){
- if(!this.parts) this.parts = {};
- var formObject = {};
- formObject.hiddenFields = {};
- formObject.freeFields = [];
- formObject.fields = {};
- formObject.id = formId;
- formObject.label = label;
- this.parts[formId] = formObject;
- formObject.pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
- return formObject;
- },
-
- /**
- * To be overriden by this class children.
- */
- _createFormVariableParts : function(){
- var standard = this._initFormPart("standard", "Canonical");
- this._createStandardForm(standard);
- var simple = this._initFormPart("simple", "SLC Sample");
- this._createSimpleForm(simple);
- },
-
- /**
- * Creates a form for SLC demo
- * @param formObject {Map} The form part
- */
- _createSimpleForm : function(formObject){
-
- this._addFormInputText(formObject, "ant.file", "File", "Category1/SubCategory2/build.xml");
- var moreButton = new qx.ui.basic.Image("resource/slc/list-add.png");
- moreButton.setToolTip(new qx.ui.tooltip.ToolTip("Add a parameter"));
- moreButton.setCursor("pointer");
- moreButton.addListener("click", function(){
- this._addFormInputText(formObject);
- }, this);
- this._addFormHeader(formObject, "Add optionnal parameters", moreButton);
- this._addFormInputText(formObject);
- this._addFormInputText(formObject);
-
- },
-
- /**
- * Create a canonical form.
- * @param formObject {Map} The form part
- */
- _createStandardForm : function(formObject){
-
- this._addFormHeader(formObject, "Set Execution Parameters");
- this._addFormInputText(formObject, "status", "Status", "STARTED");
- this._addFormInputText(formObject, "host", "Host", "localhost");
- this._addFormInputText(formObject, "user", "User", "user");
-
- var moreButton = new qx.ui.basic.Image("resource/slc/list-add.png");
- moreButton.setToolTip(new qx.ui.tooltip.ToolTip("Add a parameter"));
- moreButton.setCursor("pointer");
- moreButton.addListener("click", function(){
- this._addFormInputText(formObject);
- }, this);
- this._addFormHeader(formObject, "Add optionnal parameters", moreButton);
- this._addFormInputText(formObject);
- this._addFormInputText(formObject);
- },
-
- /**
- * Add an hidden field to the form
- * @param formObject {Map} The form part
- * @param fieldName {String} Name
- * @param fieldValue {String} Value
- */
- _addFormHiddenField : function(formObject, fieldName, fieldValue){
- formObject.hiddenFields[fieldName] = fieldValue;
- },
-
- /**
- * Creates a simple label/input form entry.
- * @param formObject {Map} The form part
- * @param fieldName {String} Name
- * @param fieldLabel {String} Label of the field
- * @param defaultValue {String} The default value
- * @param choiceValues {Map} An map of values
- */
- _addFormInputText : function(formObject, fieldName, fieldLabel, defaultValue, choiceValues){
- var labelElement;
- if(choiceValues){
- var fieldElement = new qx.ui.form.SelectBox();
- for(var key in choiceValues){
- fieldElement.add(new qx.ui.form.ListItem(choiceValues[key], null, key));
- }
- }else{
- var fieldElement = new qx.ui.form.TextField();
- }
- if(defaultValue){
- fieldElement.setValue(defaultValue);
- }
- if(fieldName && fieldLabel){
- labelElement = new qx.ui.basic.Label(fieldLabel);
- formObject.fields[fieldName] = fieldElement;
- }else{
- labelElement = new qx.ui.form.TextField();
- formObject.freeFields.push({
- labelEl:labelElement,
- valueEl:fieldElement
- });
- }
- this._addFormEntry(formObject, labelElement, fieldElement);
- },
-
- /**
- * Add an header
- * @param formObject {Map} The form part
- * @param content {Mixed} Content to add.
- * @param additionnalButton {Mixed} Any widget to add on the east.
- */
- _addFormHeader : function(formObject, content, additionnalButton){
- var header = new qx.ui.basic.Label('<b>'+content+'</b>');
- header.setRich(true);
- if(!additionnalButton){
- header.setPaddingTop(10);
- formObject.pane.add(header);
- }else{
- var pane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
- pane.setPaddingTop(10);
- pane.setPaddingRight(10);
- pane.add(header, {edge:'center'});
- pane.add(additionnalButton, {edge:'east'});
- formObject.pane.add(pane);
- }
- },
-
- /**
- * Adds a label/input like entry in the form.
- * @param formObject {Map} The form part
- * @param labelElement {Object} Either a label or an input
- * @param fieldElement {Object} Any form input.
- */
- _addFormEntry : function(formObject, labelElement, fieldElement){
- var entryPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));
- labelElement.setWidth(100);
- labelElement.setTextAlign("right");
- entryPane.add(labelElement);
- entryPane.add(new qx.ui.basic.Label(':'));
- fieldElement.setWidth(150);
- entryPane.add(fieldElement);
- formObject.pane.add(entryPane);
- },
-
- /*
- _refreshTopicsSubscriptions : function(changeTopicsEvent){
- var oldTopics = changeTopicsEvent.getOldData() || {};
- var newTopics = changeTopicsEvent.getData();
- var removed = [];
- var added = [];
- for(var key in oldTopics){
- if(!newTopics[key]) {
- //this._removeAmqListener(key);
- }
- }
- for(var key in newTopics){
- if(!oldTopics[key]) {
- //this._addAmqListener(key);
- }
- }
- },
- */
-
- /**
- * Refresh the selector when the topics are updated.
- * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
- */
- _feedSelector : function(changeTopicsEvent){
- var topics = changeTopicsEvent.getData();
- this.agentSelector.removeAll();
- var emptyItem = new qx.ui.form.ListItem("", null, "");
- this.agentSelector.add(emptyItem);
- this.agentSelector.setSelected(emptyItem);
- for(var key in topics){
- var listItem = new qx.ui.form.ListItem(topics[key], null, key);
- this.agentSelector.add(listItem);
- }
- },
-
- /*
- _addAmqListener: function(uuid){
- this._amqClient.addListener("slcExec", "topic://agent."+uuid+".newExecution", function(response){
- var message = org.argeo.ria.util.Element.selectSingleNode(response, "slc:slc-execution");
- var slcExec = new org.argeo.slc.ria.SlcExecutionMessage(message.getAttribute("uuid"));
- slcExec.fromXml(message);
- this.logModel.addRows([
- [new Date().toString(), slcExec.getHost()+' ('+slcExec.getUuid()+')', slcExec.getStatus()]
- ]);
- }, this);
- },
-
- _removeAmqListener : function(uuid){
- this._amqClient.removeListener("slcExec", "topic://agent."+uuid+".newExecution");
- },
- */
-
- /**
- * Make an SlcExecutionMessage from the currently displayed form.
- * @param crtPartId {String} The form part currently displayed
- * @param slcExec {org.argeo.slc.ria.SlcExecutionMessage} The message to fill.
- * @param fields {Map} The fields of the form
- * @param hiddenFields {Map} The hidden ones
- * @param freeFields {Array} The free fields.
- */
- _prepareSlcExecutionMessage : function(crtPartId, slcExec, fields, hiddenFields, freeFields){
- if(crtPartId == "standard"){
- slcExec.setStatus(fields.status.getValue());
- slcExec.setHost(fields.host.getValue());
- slcExec.setUser(fields.user.getValue());
- }else{
- slcExec.addAttribute("ant.file", fields["ant.file"].getValue());
- }
- for(var i=0;i<freeFields.length;i++){
- var fF = freeFields[i];
- if(fF.labelEl.getValue() != "" && fF.valueEl.getValue() != ""){
- slcExec.addAttribute(fF.labelEl.getValue(), fF.valueEl.getValue());
- }
- }
- },
-
- /**
- * Called when the user clicks the "Execute" button.
- */
- submitForm : function(){
- var currentUuid = this.agentSelector.getValue();
- if(!currentUuid) return;
- var slcExec = new org.argeo.slc.ria.SlcExecutionMessage();
-
- var fields = {};
- var hiddenFields = {};
- var freeFields = {};
- var crtPartId = "";
- if(this.parts){
- if(this.partChooser){
- crtPartId = this.partChooser.getValue();
- }else{
- crtPartId = qx.lang.Object.getKeys(this.parts)[0];
- }
- var crtPart = this.parts[crtPartId];
- fields = crtPart.fields;
- hiddenFields = crtPart.hiddenFields;
- freeFields = crtPart.freeFields;
- }
-
- this._prepareSlcExecutionMessage(crtPartId, slcExec, fields, hiddenFields, freeFields);
-
- this._amqClient.sendMessage(
- "topic://agent.newExecution",
- slcExec.toXml(),
- {"slc-agentId":currentUuid}
- );
- // Force logs refresh right now!
- qx.event.Timer.once(function(){
- var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
- if(command){
- command.execute();
- }
- }, this, 2000);
- }
-
- }
-});
\ No newline at end of file
+++ /dev/null
-/**
- * A simple Hello World applet for documentation purpose.
- * The only associated command is the "Close" command.
- */
-qx.Class.define("org.argeo.slc.ria.NewLauncherApplet",
-{
- extend : qx.ui.container.Composite,
- implement : [org.argeo.ria.components.IView],
-
- construct : function(){
- this.base(arguments);
- this.setLayout(new qx.ui.layout.Dock());
- },
-
- properties :
- {
- /**
- * The viewPane inside which this applet is added.
- */
- view : {
- init : null
- },
- viewSelection : {
- nullable:false,
- check:"org.argeo.ria.components.ViewSelection"
- },
- instanceId : {init:""},
- instanceLabel : {init:""},
- /**
- * A boolean registering whether the SpecEditor must autoOpen or not when a spec is added to the Batch.
- */
- autoOpen : {
- init : true,
- check : "Boolean"
- },
- /**
- * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
- */
- commands : {
- init : {
- "submitform" : {
- label : "Execute Batch On...",
- icon : "resource/slc/media-playback-start.png",
- shortcut : null,
- enabled : true,
- menu : "Launcher",
- toolbar : null,
- callback : function(e){},
- submenu : [],
- submenuCallback : function(commandId){
- //alert("Execute Batch on Agent "+commandId);
- this.executeBatchOnAgent(commandId);
- },
- command : null
- },
- "addtobatch" : {
- label : "Add to batch",
- icon : "resource/slc/list-add.png",
- shortcut : null,
- enabled : true,
- menu : null,
- toolbar : null,
- callback : function(e){
- this._addFlowToBatch();
- },
- selectionChange : function(viewId, selection){
- if(viewId != "form:tree") return;
- if(!selection || selection.length != 1) return;
- var item = selection[0];
- this.setEnabled(false);
- if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.TreeFile)){
- this.setEnabled(true);
- }
-
- },
- command : null
- },
- "toggleopenonadd" : {
- label : "Auto Open",
- icon : "resource/slc/document-open.png",
- shortcut : null,
- enabled : true,
- toggle : true,
- toggleInitialState : true,
- menu : "Launcher",
- toolbar : "launcher",
- callback : function(event){
- var state = event.getTarget().getUserData("slc.command.toggleState");
- this.setAutoOpen(state);
- },
- command : null
- },
- "editexecutionspecs" : {
- label : "Edit Execution Specs",
- icon : "resource/slc/document-open.png",
- shortcut : null,
- enabled : false,
- menu : "Launcher",
- toolbar : null,
- callback : function(e){
- var sel = this.list.getSortedSelection();
- var item = sel[0];
- var specEditor = new org.argeo.slc.ria.execution.SpecEditor(item.getUserData("batchEntrySpec"));
- specEditor.attachAndShow();
- },
- selectionChange : function(viewId, selection){
- if(viewId != "form:list") return;
- this.setEnabled(false);
- if((selection && selection.length == 1)) this.setEnabled(true);
- },
- command : null
- },
- "removefrombatch" : {
- label : "Remove from batch",
- icon : "resource/slc/edit-delete.png",
- shortcut : null,
- enabled : false,
- menu : "Launcher",
- toolbar : null,
- callback : function(e){
- var sel = this.list.getSortedSelection();
- var modal = new org.argeo.ria.components.Modal("Confirm", null);
- modal.addConfirm("Are you sure you want to remove<br> the selected test" + (sel.length>1?"s":"") + " from the Batch?");
- modal.addListener("ok", function(){
- for(var i=0;i<sel.length;i++){
- this.list.remove(sel[i]);
- }
- }, this);
- modal.attachAndShow();
- },
- selectionChange : function(viewId, selection){
- if(viewId != "form:list") return;
- this.setEnabled(false);
- if((selection && selection.length > 0)) this.setEnabled(true);
- },
- command : null
- },
- "reloadagents" : {
- label : "Reload Agents",
- icon : "resource/slc/view-refresh.png",
- shortcut : "Control+r",
- enabled : true,
- menu : "Launcher",
- toolbar : "launcher",
- callback : function(e){
- var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
- req.send();
- },
- command : null
- },
- "reloadtree" : {
- label : "Reload",
- icon : "resource/slc/view-refresh.png",
- shortcut : "Control+m",
- enabled : false,
- menu : "Launcher",
- toolbar : "launcher",
- callback : function(e){
- var selected = this.tree.getSelectedItem();
- if(selected.classname == "org.argeo.ria.components.DynamicTreeFolder"){
- if(selected.getUserData("moduleData")){
- // It's a "module" node, first trigger the reloadBundle.service
- selected.setUserData("dataModel", {});
- selected.setEnabled(false);
- selected.setOpen(false);
- var moduleData = selected.getUserData("moduleData");
- var bundleService = org.argeo.slc.ria.SlcApi.getReloadBundleService(moduleData.name, moduleData.version);
- bundleService.addListener("completed", function(response){
- selected.setEnabled(true);
- selected.setOpen(true);
- selected.reload();
- }, this);
- //bundleService.send();
- //Do not send, not implemented yet, false timer instead.
- qx.event.Timer.once(function(response){
- selected.setEnabled(true);
- selected.setOpen(true);
- selected.reload();
- }, this, 2000);
- }else{
- selected.reload();
- }
- }
- },
- selectionChange : function(viewId, selection){
- if(viewId != "form:tree") return;
- if(!selection || selection.length != 1) return;
- var item = selection[0];
- if(!qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.AbstractTreeItem)) return;
- this.setEnabled(false);
- if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), org.argeo.ria.components.DynamicTreeFolder)){
- this.setEnabled(true);
- }
- },
- command : null
- }
- }
- },
- /**
- * A map containing all currently registered agents.
- */
- registeredTopics : {
- init : {},
- check : "Map",
- event : "changeRegisteredTopics"
- }
- },
-
- statics : {
- /**
- * Loader for the "flow" level : takes a folder containing "moduleData" and create its children.
- * @param folder {qx.ui.tree.TreeFolder} A Tree folder containing in the key "moduleData" of its user data a map containing the keys {name,version}
- */
- flowLoader : function(folder){
- var moduleData = folder.getUserData("moduleData");
- //var pathStub = ["", "/test/toto/zobi", "loop"];
- //var indexStub = 0;
-
- var req = org.argeo.slc.ria.SlcApi.getLoadExecutionDescriptorService(moduleData.name, moduleData.version);
- req.addListener("completed", function(response){
- var executionModule = new org.argeo.slc.ria.execution.Module();
- executionModule.setXmlNode(response.getContent());
- var execFlows = executionModule.getExecutionFlows();
- for(var key in execFlows){
- var file = new qx.ui.tree.TreeFile(key);
- var path = execFlows[key].getPath();
- //path = pathStub[indexStub];
- //indexStub ++;
- file.setUserData("executionModule", executionModule);
- file.setUserData("executionFlow", execFlows[key]);
- org.argeo.slc.ria.NewLauncherApplet.attachNodeByPath(folder, path, file);
- folder.appendDragData(file);
- }
- folder.setLoaded(true);
- });
- req.send();
- },
-
- /**
- * Loader for the "modules" level : takes any tree folder, currently the root folder.
- * @param folder {qx.ui.tree.TreeFolder} The root folder
- */
- modulesLoader : function(folder){
- var req = org.argeo.slc.ria.SlcApi.getListModulesService();
- req.addListener("completed", function(response){
- var descriptors = org.argeo.ria.util.Element.selectNodes(response.getContent(), "slc:object-list/slc:execution-module-descriptor");
- var mods = {};
- for(var i=0;i<descriptors.length; i++){
- var name = org.argeo.ria.util.Element.getSingleNodeText(descriptors[i], "slc:name");
- var version = org.argeo.ria.util.Element.getSingleNodeText(descriptors[i], "slc:version");
- if(!mods[name]) mods[name] = [];
- mods[name].push(version);
- }
- var flowLoader = org.argeo.slc.ria.NewLauncherApplet.flowLoader;
- for(var key in mods){
- for(var i=0;i<mods[key].length;i++){
- var versionFolder = new org.argeo.ria.components.DynamicTreeFolder(
- key + ' ('+mods[key][i]+')',
- flowLoader,
- "Loading Flows",
- folder.getDragData()
- );
- folder.add(versionFolder);
- versionFolder.setUserData("moduleData", {name:key, version:mods[key][i]});
- }
- folder.setLoaded(true);
- }
- });
- req.send();
- },
-
- /**
- * Parse a string path and search if there is a root node.
- * @param rootNode {qx.ui.tree.AbstractTreeItem} The parent node (containing data model)
- * @param path {String} The path of the node to attach.
- */
- attachNodeByPath : function(rootNode, path, childNode){
- if(!path || path=="" || path == "/" ){
- rootNode.add(childNode);
- return;
- }
- var model = rootNode.getUserData("dataModel");
- if(!model){
- model = {};
- rootNode.setUserData("dataModel", model);
- }
- var parts = path.split("/");
- var keys = qx.lang.Object.getKeys(model);
- var crtPath = "/";
- var crtFolder = rootNode;
- for(var i=0;i<parts.length;i++){
- if(parts[i] == "") continue;
- crtPath += parts[i];
- if(!model[parts[i]]) {
- var virtualFolder = new qx.ui.tree.TreeFolder(parts[i]);
- model[parts[i]] = virtualFolder;
- crtFolder.add(virtualFolder);
- crtFolder = virtualFolder;
- }else{
- crtFolder = model[parts[i]];
- }
- }
- crtFolder.add(childNode);
- }
- },
-
- members :
- {
- /**
- * Called at applet creation. Just registers viewPane.
- * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
- */
- init : function(viewPane){
- this.setView(viewPane);
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
- this._amqClient = org.argeo.ria.remote.JmsClient.getInstance();
- this._amqClient.uri = "/org.argeo.slc.webapp/amq";
- this._amqClient.startPolling();
- },
-
- /**
- *
- */
- load : function(){
- this._createLayout();
- this.getView().setViewTitle("Execution Launcher");
- org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(reloadEvent){
- if(reloadEvent.getDataType()!= "agents") return ;
- var xmlDoc = reloadEvent.getContent();
- var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
- var newTopics = {};
- for(var i=0;i<nodes.length;i++){
- var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
- var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
- newTopics[uuid] = host+" ("+uuid+")";
- }
- this.setRegisteredTopics(newTopics);
- }, this);
- this.addListener("changeRegisteredTopics", function(event){
- //this._refreshTopicsSubscriptions(event);
- this._feedSelector(event);
- }, this);
- var reloadHandler = function(message){
- // Delay reload to be sure the jms was first integrated by the db, then ask the db.
- qx.event.Timer.once(function(){
- org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadagents").execute();
- }, this, 1000);
- }
- this._amqClient.addListener("agentregister", "topic://agent.register", reloadHandler, this);
- this._amqClient.addListener("agentunregister", "topic://agent.unregister", reloadHandler, this);
- reloadHandler();
- },
-
- addScroll : function(){
- return false;
- },
-
- close : function(){
- this._amqClient.removeListener("agentregister", "topic://agent.register");
- this._amqClient.removeListener("agentunregister", "topic://agent.unregister");
- this._amqClient.removeListener("modulesResponse", "topic://modulesManager.response");
- this.setRegisteredTopics({});
- this._amqClient.stopPolling();
- },
-
- /**
- * Creates the main applet layout.
- */
- _createLayout : function(){
-
- var splitPane = new qx.ui.splitpane.Pane("vertical");
- splitPane.setDecorator(null);
- this.add(splitPane);
-
- this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
- this.scroll = new qx.ui.container.Scroll(this.formPane);
- this.formPane.setPadding(10);
-
- this.tree = new qx.ui.tree.Tree();
- this.tree.setDecorator(null);
- var dragData = {
- "file" : {
- "type" : ["items"],
- "action":["move"]
- }
- };
-
- var root = new org.argeo.ria.components.DynamicTreeFolder(
- "All Tests",
- this.self(arguments).modulesLoader,
- "Loading Modules",
- dragData
- );
- this.tree.setRoot(root);
- root.setOpen(true);
- this.tree.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["addtobatch", "reloadtree"]));
-
- this.tree.addListener("changeSelection", function(e){
- var viewSelection = this.getViewSelection();
- viewSelection.setViewId("form:tree");
- viewSelection.clear();
- var sel = this.tree.getSortedSelection();
- for(var i=0;i<sel.length;i++){
- viewSelection.addNode(sel[i]);
- }
- }, this);
-
- this.listPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
- var listToolBar = new qx.ui.toolbar.ToolBar();
- var toolGroup = new qx.ui.toolbar.Part();
- listToolBar.add(toolGroup);
-
- var execButton = this.getCommands()["submitform"].command.getToolbarButton();
- toolGroup.add(execButton);
-
- listToolBar.addSpacer();
- listToolBar.setPaddingRight(4);
- var delButton = this.getCommands()["removefrombatch"].command.getToolbarButton();
- var formButton = this.getCommands()["editexecutionspecs"].command.getToolbarButton();
- delButton.setShow("icon");
- formButton.setShow("icon");
- listToolBar.add(formButton);
- listToolBar.add(delButton);
-
- this.listPane.add(listToolBar, {edge:"north"});
-
- var indicator = new qx.ui.core.Widget();
- indicator.setDecorator(new qx.ui.decoration.Single().set({top:[1,"solid","#33508D"]}));
- indicator.setHeight(0);
- indicator.setOpacity(0.5);
- indicator.setZIndex(100);
- indicator.setLayoutProperties({left:-1000,top:-1000});
- org.argeo.ria.Application.INSTANCE.getRoot().add(indicator);
-
-
- this.list = new qx.ui.form.List();
- this.list.setDecorator(null);
- this.list.setSelectionMode("multi");
- this.list.setDroppable(true);
- this.list.setDraggable(true);
- this.list.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["editexecutionspecs", "removefrombatch"]));
-
-
- this.list.addListener("dragstart", function(e){
- e.addType(["items"]);
- e.addAction(["move"]);
- },this);
- this.list.addListener("dragend", function(e){
- indicator.setDomPosition(-1000,-1000);
- });
- this.list.addListener("dragover", function(e){
- var orig = e.getOriginalTarget();
- var origCoords = orig.getContainerLocation();
- indicator.setWidth(orig.getBounds().width);
- indicator.setDomPosition(origCoords.left, origCoords.bottom);
- });
- this.list.addListener("drag", function(e){
- var orig = e.getOriginalTarget();
- var origCoords = orig.getContainerLocation();
- indicator.setWidth(orig.getBounds().width);
- indicator.setDomPosition(origCoords.left, origCoords.bottom);
- });
-
- this.list.addListener("drop", function(e){
- var target = e.getRelatedTarget();
- var afterItem = e.getOriginalTarget();
- indicator.setDomPosition(-1000,-1000);
- if(afterItem.classname != "qx.ui.form.ListItem") afterItem = null;
- if(!target){
- target = this.list.getSortedSelection()[0];
- }
- this._addFlowToBatch(target, afterItem);
- }, this);
- this.listPane.add(this.list, {edge:"center"});
-
- this.list.addListener("changeSelection", function(e){
- var viewSelection = this.getViewSelection();
- viewSelection.setViewId("form:list");
- viewSelection.clear();
- var listSel = this.list.getSortedSelection();
- for(var i=0;i<listSel.length;i++){
- viewSelection.addNode(listSel[i]);
- }
- }, this);
-
- splitPane.add(this.tree, 0);
- splitPane.add(this.listPane, 1);
- },
-
- /**
- * Adds a given ExecutionFlow to the batch
- * @param target {mixed} The dropped target, can be a TreeFile (add) or a ListItem (reorder).
- * @param after {qx.ui.form.ListItem} Optional list item : if set, the flow will be added as a new list item positionned after this one.
- */
- _addFlowToBatch : function(target, after){
- //this.debug(target);
- if(!target){
- target = this.tree.getSelectedItem();
- if(!target) return;
- }else if(target.classname == "qx.ui.form.ListItem"){
- if(!after) return;
- if(after == "first") this.list.addAt(target, 0);
- else this.list.addAfter(target, after);
- return;
- }
- var executionModule = target.getUserData("executionModule");
- var executionFlow = target.getUserData("executionFlow");
- var batchEntry = new org.argeo.slc.ria.execution.BatchEntrySpec(executionModule, executionFlow);
- var label = batchEntry.getLabel();
- var icon = target.getIcon();
- var item = new qx.ui.form.ListItem(label, icon);
- item.addListener("dblclick", function(e){
- this.getCommands()["editexecutionspecs"].command.execute();
- }, this);
- item.setUserData("batchEntrySpec", batchEntry);
- item.setPaddingTop(1);
- item.setPaddingBottom(2);
- if(after){
- if(after == "first") this.list.addAt(item, 0);
- else this.list.addAfter(item, after);
- }else{
- this.list.add(item);
- }
- this.list.select(item);
- if(this.getAutoOpen()){
- this.getCommands()["editexecutionspecs"].command.execute();
- }
- },
-
- /**
- * Refresh the selector when the topics are updated.
- * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
- */
- _feedSelector : function(changeTopicsEvent){
- var topics = changeTopicsEvent.getData();
- var command = this.getCommands()["submitform"].command;
- command.setEnabled(false);
- var menu = [];
- for(var key in topics){
- var submenu = {"label":topics[key],"icon":"resource/slc/mime-xsl.png", "commandId":key};
- menu.push(submenu);
- }
- // FAKE!!
- if(!menu.length){
- menu.push({"label":"Fake Agent", "icon":"resource/slc/mime-xsl.png", "commandId":"fake_agent_uuid"});
- }
- command.clearMenus();
- command.setMenu(menu);
- if(menu.length) command.setEnabled(true);
- },
-
-
- /**
- * Called at execution
- * @param agentUuid {String} The id of the target agent
- */
- executeBatchOnAgent : function(agentUuid){
- var selection = this.list.getChildren();
- if(!selection.length) return;
- var slcExecMessage = new org.argeo.slc.ria.execution.Message();
- for(var i=0;i<selection.length;i++){
- var batchEntrySpec = selection[i].getUserData("batchEntrySpec");
- slcExecMessage.addBatchEntrySpec(batchEntrySpec);
- }
- this._amqClient.sendMessage(
- "topic://agent.newExecution",
- slcExecMessage.toXml(),
- {"slc-agentId":agentUuid}
- );
- // Force logs refresh right now!
- qx.event.Timer.once(function(){
- var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
- if(command){
- command.execute();
- }
- }, this, 2000);
- }
-
- }
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * SLC API Client implementation :\r
- * This class encapsulate the various SLC services available. It just creates the Request object\r
- * and return them, it does not execute them. \r
- * Available services are : \r
- * + loadResult / removeResult / addResult\r
- * + listCollection / listResults\r
- * When using it, be sure the static constant DEFAULT_CONTEXT is pointing to the right URL.\r
- */\r
-qx.Class.define("org.argeo.slc.ria.SlcApi",\r
-{\r
- extend : qx.core.Object,\r
- \r
- statics : {\r
- DEFAULT_CONTEXT : "/org.argeo.slc.webapp",\r
- \r
- REMOVE_RESULT_FROM_COLL_SERVICE : "removeResultFromCollection.service",\r
- ADD_RESULT_TO_COLL_SERVICE : "addResultToCollection.service",\r
- LIST_COLLECTIONS_SERVICE : "listCollectionRefs.service",\r
- COPY_COLLECTION_TO_COLL_SERVICE : "copyCollectionToCollection.service",\r
- LIST_RESULTS_SERVICE : "listResultAttributes.service",\r
- GET_RESULT_SERVICE : "getResult.service",\r
- LIST_SLCEXEC_SERVICE : "listSlcExecutions.service",\r
- \r
- LIST_AGENTS_SERVICE : "listAgents.service",\r
- LIST_MODULES_SERVICE : "listModulesDescriptors.service",\r
- GET_EXECUTION_DESC_SERVICE : "getExecutionDescriptor.service",\r
- RELOAD_BUNDLE_SERVICE : "reloadBundle.service",\r
- AMQ_SERVICE : "amq",\r
- \r
- /**\r
- * Standard Request getter\r
- * @param serviceName {String} The name of the service to call (without base context)\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request}\r
- */\r
- getServiceRequest:function(serviceName, fireReloadEventType, iLoadStatusables){\r
- var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();\r
- return serviceManager.getRequest(\r
- org.argeo.slc.ria.SlcApi.DEFAULT_CONTEXT+"/"+serviceName,\r
- "GET",\r
- "application/xml",\r
- fireReloadEventType,\r
- iLoadStatusables\r
- );\r
- },\r
- \r
- /**\r
- * Remove a result from a collection\r
- * @param collectionId {String} Id of the destination collection\r
- * @param resultId {String} Id of the test result to remove\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request}\r
- */\r
- getRemoveResultService : function(collectionId, resultId, fireReloadEventType, iLoadStatusables){\r
- var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.REMOVE_RESULT_FROM_COLL_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables\r
- );\r
- request.setParameter("collectionId", collectionId);\r
- request.setParameter("resultUuid", resultId);\r
- return request;\r
- },\r
- \r
- /**\r
- * Remove a set of results from a collection. Either filtered by a given pattern, or the whole collection.\r
- * @param collectionId {String} The id of the collection\r
- * @param patternAttribute {String} An optional attribute name on which to filter\r
- * @param patternValue {String} The pattern to use for filtering a subset of result\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request} The Request object\r
- */\r
- getRemoveFromCollectionService : function(collectionId, patternAttribute, patternValue, fireReloadEventType, iLoadStatusables){\r
- var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.REMOVE_RESULT_FROM_COLL_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables\r
- );\r
- request.setParameter("collectionId", collectionId);\r
- if(patternAttribute && patternValue){\r
- request.setParameter("attrName", patternAttribute);\r
- request.setParameter("attrPattern", patternValue);\r
- }\r
- return request;\r
- },\r
- \r
- /**\r
- * Add a result to a given collection\r
- * @param collectionId {String} Id of the destination collection\r
- * @param resultId {String} Id of the test result to add\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request}\r
- */\r
- getAddResultService : function(collectionId, resultId, fireReloadEventType, iLoadStatusables){\r
- var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.ADD_RESULT_TO_COLL_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables\r
- );\r
- request.setParameter("collectionId", collectionId);\r
- request.setParameter("resultUuid", resultId);\r
- return request;\r
- },\r
- \r
- /**\r
- * List current collections\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request}\r
- */\r
- getListCollectionsService : function(fireReloadEventType, iLoadStatusables){\r
- return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.LIST_COLLECTIONS_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables\r
- );\r
- },\r
- \r
- /**\r
- * Copy a whole collection or a subset of it to another collection. If a new id is provided for the target, it will be created.\r
- * @param sourceCollectionId {String} The current collection from which to copy\r
- * @param targetCollectionId {String} The target collection. If unknown, it will be created.\r
- * @param patternAttribute {String} An optional attribute on which a filter can be applied to create a subset.\r
- * @param patternValue {String} The associated pattern to filter on the atttribute's value.\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request} The request object\r
- */\r
- getCopyCollectionService : function(sourceCollectionId, targetCollectionId, patternAttribute, patternValue, fireReloadEventType, iLoadStatusables){\r
- var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.COPY_COLLECTION_TO_COLL_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables \r
- );\r
- request.setParameter("sourceCollectionId", sourceCollectionId);\r
- request.setParameter("targetCollectionId", targetCollectionId);\r
- if(patternAttribute && patternValue){\r
- request.setParameter("attrName", patternAttribute);\r
- request.setParameter("attrPattern", patternValue);\r
- }\r
- return request;\r
- },\r
- \r
- /**\r
- * List all results or results of a given collection \r
- * @param collectionId {String} Id of the collection to load\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request}\r
- */\r
- getListResultsService : function(collectionId, fireReloadEventType, iLoadStatusables){\r
- var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.LIST_RESULTS_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables\r
- );\r
- if(collectionId){\r
- request.setParameter("id", collectionId);\r
- }\r
- return request;\r
- },\r
- \r
- /**\r
- * Load a result test\r
- * @param resultId {String} Id of the test result to load\r
- * @param fireReloadEventType {String} Whether query should trigger a ReloadEvent\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- * @return {qx.io.remote.Request}\r
- */\r
- getLoadResultService : function(resultId, fireReloadEventType, iLoadStatusables){\r
- var request = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.GET_RESULT_SERVICE, \r
- fireReloadEventType, \r
- iLoadStatusables\r
- );\r
- request.setParameter("uuid", resultId);\r
- return request;\r
- },\r
-\r
- /**\r
- * List currently registered SlcExecutions.\r
- * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
- * @return {qx.io.remote.Request}\r
- */\r
- getListSlcExecutionsService:function(fireReloadEventType, iLoadStatusables){\r
- return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.LIST_SLCEXEC_SERVICE,\r
- fireReloadEventType,\r
- iLoadStatusables\r
- );\r
- },\r
- \r
- \r
- /**\r
- * List currently available agents queues.\r
- * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
- * @return {qx.io.remote.Request}\r
- */\r
- getListAgentsService:function(fireReloadEventType, iLoadStatusables){\r
- return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.LIST_AGENTS_SERVICE,\r
- fireReloadEventType,\r
- iLoadStatusables\r
- );\r
- },\r
-\r
- /**\r
- * Load the module descriptors\r
- * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
- * @return {qx.io.remote.Request}\r
- */\r
- getListModulesService : function(fireReloadEventType, iLoadStatusables){\r
- return org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.LIST_MODULES_SERVICE,\r
- fireReloadEventType,\r
- iLoadStatusables\r
- );\r
- },\r
- \r
- /**\r
- * Get an execution module descriptor by its name and version\r
- * @param moduleName {String} The name of the module to get\r
- * @param moduleVersion {String} Its version, passed directly as a string\r
- * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
- * @return {qx.io.remote.Request}\r
- */\r
- getLoadExecutionDescriptorService : function(moduleName, moduleVersion, fireReloadEventType, iLoadStatusables){\r
- var req = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.GET_EXECUTION_DESC_SERVICE,\r
- fireReloadEventType,\r
- iLoadStatusables\r
- ); \r
- req.setParameter("moduleName", moduleName);\r
- req.setParameter("version", moduleVersion);\r
- return req;\r
- },\r
-\r
- /**\r
- * Fire the reload of an OSGI bundle.\r
- * @param fireReloadEventType {String} Event type to trigger (optionnal)\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update \r
- * @return {qx.io.remote.Request}\r
- */\r
- getReloadBundleService : function(bundleName, bundleVersion, fireReloadEventType, iLoadStatusables){\r
- var req = org.argeo.slc.ria.SlcApi.getServiceRequest(\r
- org.argeo.slc.ria.SlcApi.RELOAD_BUNDLE_SERVICE,\r
- fireReloadEventType,\r
- iLoadStatusables\r
- );\r
- req.setParameter("bundleName", bundleName);\r
- req.setParameter("bundleVersion", bundleVersion);\r
- return req;\r
- },\r
- \r
- \r
- \r
- /**\r
- * Send a JMS message to the AMQ_CONTEXT\r
- * @param destination {String} The destination queue, in the form "topic://destination" \r
- * @param message {org.argeo.slc.ria.SlcExecutionMessage} The message object\r
- * @param iLoadStatusables {org.argeo.ria.components.ILoadStatusables[]} Gui parts to update\r
- */\r
- getSendAmqMessageRequest : function(destination, message, iLoadStatusables){\r
- var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();\r
- var request = serviceManager.getRequest(\r
- org.argeo.slc.ria.SlcApi.DEFAULT_CONTEXT+"/"+org.argeo.slc.ria.SlcApi.AMQ_SERVICE,\r
- "POST",\r
- "text/plain",\r
- null,\r
- iLoadStatusables\r
- );\r
- request.setParameter("destination", destination);\r
- request.setParameter("message", message.toXml());\r
- request.setParameter("type", "send");\r
- return request;\r
- }\r
- \r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * A simple Hello World applet for documentation purpose. \r
- * The only associated command is the "Close" command.\r
- */\r
-qx.Class.define("org.argeo.slc.ria.SlcExecLoggerApplet",\r
-{\r
- extend : qx.ui.container.Composite,\r
- implement : [org.argeo.ria.components.IView], \r
-\r
- construct : function(){\r
- this.base(arguments);\r
- this.setLayout(new qx.ui.layout.Dock()); \r
- },\r
-\r
- properties : \r
- {\r
- /**\r
- * The viewPane inside which this applet is added. \r
- */\r
- view : {\r
- init : null\r
- },\r
- viewSelection : {\r
- nullable:false, \r
- check:"org.argeo.ria.components.ViewSelection"\r
- }, \r
- instanceId : {init:""},\r
- instanceLabel : {init:""}, \r
- /**\r
- * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions} \r
- */\r
- commands : {\r
- init : {\r
- "reloadlogs" : {\r
- label : "Reload Logs", \r
- icon : "resource/slc/view-refresh.png",\r
- shortcut : "Control+r",\r
- enabled : true,\r
- menu : null,\r
- toolbar : null,\r
- callback : function(e){\r
- this._reloadLogger();\r
- },\r
- command : null\r
- } \r
- }\r
- }\r
- },\r
-\r
- members :\r
- {\r
- /**\r
- * Called at applet creation. Just registers viewPane.\r
- * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.\r
- */\r
- init : function(viewPane){\r
- this.setView(viewPane);\r
- this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId())); \r
- this._createLayout();\r
- },\r
- \r
- /**\r
- * \r
- */\r
- load : function(){\r
- this._reloadLogger(); \r
- this.timer = new qx.event.Timer(15000);\r
- this.timer.addListener("interval", this._reloadLogger, this);\r
- this.timer.start(); \r
- },\r
- \r
- addScroll : function(){\r
- return false;\r
- },\r
- \r
- close : function(){\r
- this.timer.stop();\r
- },\r
- \r
- /**\r
- * Creates the applet layout\r
- */\r
- _createLayout : function(){\r
- this.logModel = new qx.ui.table.model.Simple();\r
- this.logModel.setColumns(["Date", "Host", "Id", "Status"]);\r
- this.logPane = new qx.ui.table.Table(this.logModel, {\r
- tableColumnModel: function(obj){\r
- return new qx.ui.table.columnmodel.Resize(obj)\r
- }\r
- });\r
- this.logPane.setDecorator(null);\r
- this._initLogger();\r
- this.add(this.logPane, {edge:'center'});\r
- },\r
- \r
- /**\r
- * Initialize the log table.\r
- */\r
- _initLogger : function(){\r
- this.logPane.set({ \r
- statusBarVisible: false,\r
- showCellFocusIndicator:false\r
- });\r
- var columnModel = this.logPane.getTableColumnModel();\r
- columnModel.getBehavior().setWidth(0, "30%");\r
- columnModel.getBehavior().setWidth(1, "15%");\r
- columnModel.getBehavior().setWidth(3, "12%"); \r
- },\r
- \r
- /**\r
- * Refresh the data model.\r
- */\r
- _reloadLogger : function(){\r
- var request = org.argeo.slc.ria.SlcApi.getListSlcExecutionsService();\r
- request.addListener("completed", function(response){ \r
- var messages = org.argeo.ria.util.Element.selectNodes(response.getContent(), "//slc:slc-execution");\r
- this.logModel.setData([]);\r
- for(var i=0;i<messages.length;i++){\r
- var message = messages[i];\r
- var slcExec = new org.argeo.slc.ria.SlcExecutionMessage(message.getAttribute("uuid"));\r
- slcExec.fromXml(message);\r
- this.logModel.addRows([\r
- [slcExec.getDate(), slcExec.getHost(), slcExec.getUuid(), slcExec.getStatus()]\r
- ]); \r
- }\r
- }, this);\r
- request.send(); \r
- }\r
- \r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * A generic JMS slcExecution message encapsulator.\r
- */\r
-qx.Class.define("org.argeo.slc.ria.SlcExecutionMessage", {\r
- extend : qx.core.Object,\r
- /**\r
- * New instance\r
- * @param uuid {String} The Uuid of the message. If none is passed, one is generated.\r
- */\r
- construct : function(uuid){\r
- this.base(arguments);\r
- if(uuid){\r
- this.setUuid(uuid);\r
- }else{\r
- var s = [];\r
- var itoh = '0123456789ABCDEF';\r
- for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10);\r
- s[14] = 4; // Set 4 high bits of time_high field to version\r
- s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence\r
- for (var i = 0; i <36; i++) s[i] = itoh[s[i]];\r
- s[8] = s[13] = s[18] = s[23] = '-';\r
- this.setUuid(s.join('').toLowerCase()); \r
- }\r
- this.setAttributes({});\r
- },\r
- properties : {\r
- /**\r
- * The unique id identifying the message\r
- */\r
- uuid : {\r
- check : "String"\r
- },\r
- /**\r
- * Execution status\r
- */\r
- status : {\r
- check : "String",\r
- init : "STARTED"\r
- },\r
- /**\r
- * Execution type\r
- */\r
- type : {\r
- check : "String",\r
- init : "slcAnt"\r
- },\r
- /**\r
- * Execution Host\r
- */\r
- host : {\r
- check : "String",\r
- init : "localhost"\r
- },\r
- /**\r
- * Execution User\r
- */\r
- user : {\r
- check : "String",\r
- init : "user"\r
- },\r
- /**\r
- * Date of the message. now() by default.\r
- */\r
- date : {\r
- check : "String", \r
- init : new Date().toString()\r
- },\r
- /**\r
- * Additionnal attributes as map of key/values\r
- */\r
- attributes : {\r
- check : "Map"\r
- }\r
- },\r
- members : {\r
- \r
- /**\r
- * Add a free attribute to the message\r
- * @param attName {String} Name\r
- * @param attValue {String} Value\r
- */\r
- addAttribute: function(attName, attValue){\r
- var attr = this.getAttributes();\r
- attr[attName] = attValue;\r
- this.setAttributes(attr);\r
- },\r
- /**\r
- * Build the xml formatted message body to send\r
- * \r
- * @return {String} The message content as Xml\r
- */\r
- toXml : function (){\r
- var builder = new qx.util.StringBuilder();\r
- builder.add('<slc:slc-execution xmlns:slc="http://argeo.org/projects/slc/schemas" uuid="'+this.getUuid()+'">');\r
- builder.add('<slc:status>'+this.getStatus()+'</slc:status>');\r
- builder.add('<slc:type>'+this.getType()+'</slc:type>');\r
- builder.add('<slc:host>'+this.getHost()+'</slc:host>');\r
- builder.add('<slc:user>'+this.getUser()+'</slc:user>');\r
- var attr = this.getAttributes();\r
- if(qx.lang.Object.getLength(attr)){\r
- builder.add('<slc:attributes>');\r
- for(var key in attr){\r
- builder.add('<slc:attribute name="'+key+'">'+attr[key]+'</slc:attribute>');\r
- }\r
- builder.add('</slc:attributes>');\r
- }\r
- builder.add('</slc:slc-execution>');\r
- return builder.get();\r
- },\r
- \r
- /**\r
- * Parse an XML answer and fill the object with it.\r
- * @param slcExecXml {String} An slcExecMessage mapped in XML.\r
- */\r
- fromXml : function(slcExecXml){\r
- var NSMap = {slc:"http://argeo.org/projects/slc/schemas"}; \r
- this.setStatus(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:status", NSMap));\r
- this.setType(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:type", NSMap));\r
- this.setHost(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:host", NSMap));\r
- this.setUser(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:user", NSMap));\r
- var attributes = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:attribute", NSMap);\r
- for(var i=0;i<attributes.length;i++){\r
- this.addAttribute(attribute.getAttribute("name"), attribute.firstChild);\r
- }\r
- var stepsDates = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:steps/slc:slc-execution-step/slc:begin", NSMap);\r
- if(stepsDates.length){\r
- this.setDate(org.argeo.ria.util.Element.getSingleNodeText(stepsDates[stepsDates.length-1], ".", NSMap));\r
- }\r
- }\r
- } \r
-});
\ No newline at end of file
+++ /dev/null
-/* ************************************************************************
-
- qooxdoo - the new era of web development
-
- http://qooxdoo.org
-
- Copyright:
- 2007 OpenHex SPRL, http://www.openhex.org
-
- License:
- LGPL: http://www.gnu.org/licenses/lgpl.html
- EPL: http://www.eclipse.org/org/documents/epl-v10.php
- See the LICENSE file in the project's top-level directory for details.
-
- Authors:
- * Dirk Wellmann (dw(at)piponline.net)
-
-************************************************************************ */
-
-/**
- * This Cellrender is for test status use. It create green or red background
- * cells depending on the status value (PASSED or FAILED).
- */
-qx.Class.define("org.argeo.slc.ria.StatusCellRenderer",
-{
- extend : qx.ui.table.cellrenderer.Html,
-
- construct : function(){
- this.base(arguments);
- var style =
- [
- ".slc-status-passed{background-color:#8fc98f;color:#008300;border-bottom:1px solid #cccccc;text-align:center;filter:alpha(opacity=80);opacity: 0.8;-moz-opacity:0.8;}",
- ".slc-status-failed{background-color:#cb8f8f;color:#830000;border-bottom:1px solid #cccccc;text-align:center;filter:alpha(opacity=80);opacity: 0.8;-moz-opacity:0.8;}"
- ];
- // Include stylesheet
- qx.bom.Stylesheet.createElement(style.join(""));
- },
-
- /*
- *****************************************************************************
- MEMBERS
- *****************************************************************************
- */
-
- members :
- {
- // overridden
- _getContentHtml : function(cellInfo) {
- return (cellInfo.value || "");
- },
-
- // overridden
- _getCellClass : function(cellInfo) {
- if(cellInfo.value == "PASSED"){
- return "qooxdoo-table-cell slc-status-passed";
- }else if(cellInfo.value == "FAILED"){
- return "qooxdoo-table-cell slc-status-failed";
- }else{
- return "qooxdoo-table-cell";
- }
- }
- }
-});
+++ /dev/null
-/**\r
- * Package containing SLC generic components to be used by any RIA SLC applications\r
- * as a library.\r
- * Currently contains the SlcApi client and a canonical Applet for displaying test results.\r
- */
\ No newline at end of file
+++ /dev/null
-/**\r
- * Data model for an entry of the Batch list : original Spec, flow and module, and currently computed value.\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.BatchEntrySpec", {\r
- extend : org.argeo.slc.ria.execution.Spec,\r
- \r
- properties : {\r
- /**\r
- * Reference module\r
- */\r
- module :{},\r
- /**\r
- * Reference flow\r
- */\r
- flow : {},\r
- /**\r
- * Original Spec (values shall stay untouched).\r
- */\r
- originalSpec : {} \r
- },\r
- \r
- /**\r
- * Instance of BatchEntrySpec\r
- * @param module {org.argeo.slc.ria.execution.Module} Reference module\r
- * @param flow {org.argeo.slc.ria.execution.Flow} Reference flow\r
- */\r
- construct : function(module, flow){\r
- this.base(arguments);\r
- this.setModule(module);\r
- this.setFlow(flow);\r
- this.setOriginalSpec(flow.getExecutionSpec());\r
- this.setName(flow.getExecutionSpec().getName());\r
- this.fetchInstanceValues();\r
- },\r
- \r
- members : {\r
- /**\r
- * Create a label to display in the batch list.\r
- * @return {String} The label\r
- */\r
- getLabel : function(){\r
- var label = this.getModule().getName();\r
- label += "/" + this.getModule().getVersion();\r
- label += "/" + this.getFlow().getName();\r
- return label;\r
- },\r
- \r
- toXml : function(){ \r
- var valuesXml = '';\r
- var values = this.getValues();\r
- for(var key in values){\r
- valuesXml += values[key].toValueXml();\r
- }\r
- var execFlowDescXML = '<slc:execution-flow-descriptor name="'+this.getFlow().getName()+'" executionSpec="'+this.getName()+'"><slc:values>'+valuesXml+'</slc:values></slc:execution-flow-descriptor>';\r
- \r
- var execSpecDescXML = this.getOriginalSpec().toXml();\r
- \r
- var moduleData = '<slc:module-name>'+this.getModule().getName()+'</slc:module-name><slc:module-version>'+this.getModule().getVersion()+'</slc:module-version>';\r
- \r
- return '<slc:realized-flow>'+moduleData + execFlowDescXML + execSpecDescXML +'</slc:realized-flow>';\r
- \r
- },\r
- \r
- /**\r
- * Fetch the Spec Values with the Flow Values to make the current instance value\r
- */\r
- fetchInstanceValues : function(){\r
- var specValues = this.getOriginalSpec().getValues();\r
- var flow = this.getFlow();\r
- var instanceValues = {};\r
- for(var key in specValues){\r
- var flowValue = flow.getValue(\r
- key, \r
- specValues[key].getSpecType(), \r
- specValues[key].getSpecSubType()\r
- );\r
- var instValue = specValues[key].clone();\r
- if(flowValue){\r
- instValue.setValue(flowValue);\r
- }\r
- instanceValues[key] = instValue;\r
- }\r
- this.setValues(instanceValues);\r
- //this.debug(instanceValues);\r
- }\r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Wrapper for ExecutionFlow server object\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.Flow", {\r
- \r
- extend : qx.core.Object,\r
- \r
- properties : {\r
- /**\r
- * Name of this Execution Flow \r
- */\r
- name : {\r
- check : "String",\r
- init : ""\r
- },\r
- /**\r
- * An optional path describing this flow\r
- */\r
- path : {\r
- check : "String",\r
- nullable : true\r
- },\r
- /**\r
- * Name of the associated spec, to be found in the module \r
- */\r
- executionSpecName : {\r
- check : "String"\r
- },\r
- /**\r
- * Reference the actual ExecutionSpec object\r
- */\r
- executionSpec : {\r
- check : "org.argeo.slc.ria.execution.Spec"\r
- },\r
- /**\r
- * The values to init the ExecutionSpec\r
- */\r
- values : {\r
- check : "Node"\r
- },\r
- /**\r
- * Castor representation of the object \r
- */\r
- xmlNode : {\r
- apply : "_applyXmlNode"\r
- }\r
- },\r
- \r
- statics : {\r
- /**\r
- * Xpath to the name \r
- */\r
- XPATH_NAME : "@name",\r
- /**\r
- * XPath to the ExecutionSpec name\r
- */\r
- XPATH_EXEC_SPEC_NAME : "@executionSpec",\r
- /**\r
- * XPath to the values\r
- */\r
- XPATH_VALUES : "slc:values",\r
- /**\r
- * An optional hierarchical path\r
- */\r
- XPATH_PATH : "@path"\r
- },\r
- \r
- construct : function(){\r
- this.base(arguments);\r
- },\r
- \r
- members : { \r
- /**\r
- * Init the object from an XML representation\r
- * @param xmlNode {Node} Castor representation of this object\r
- */\r
- _applyXmlNode : function(xmlNode){\r
- this.set({\r
- name : org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_NAME),\r
- path : org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_PATH),\r
- executionSpecName : org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_EXEC_SPEC_NAME)\r
- });\r
- var values = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_VALUES);\r
- this.setValues(values[0]);\r
- },\r
- /**\r
- * Get a given value inside the values map\r
- * @param key {String} The key of the value \r
- * @param specType {String} Expected type (currently "primitive" and "ref" are supported)\r
- * @param specSubType {String} Expected subtype (depends on the type)\r
- * @return {String} Value if it is set.\r
- */\r
- getValue: function(key, specType, specSubType){\r
- var xpath;\r
- if(specType == "primitive"){\r
- xpath = 'slc:value[@key="'+key+'"]/slc:primitive-value[@type="'+specSubType+'"]';\r
- }else if(specType == "ref"){\r
- xpath = 'slc:value[@key="'+key+'"]/slc:ref-value/slc:label';\r
- }\r
- return org.argeo.ria.util.Element.getSingleNodeText(this.getValues(), xpath);\r
- }\r
- } \r
- \r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * A generic JMS slcExecution message encapsulator.\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.Message", {\r
- extend : qx.core.Object,\r
- /**\r
- * New instance\r
- * @param uuid {String} The Uuid of the message. If none is passed, one is generated.\r
- */\r
- construct : function(uuid){\r
- this.base(arguments);\r
- if(uuid){\r
- this.setUuid(uuid);\r
- }else{\r
- var s = [];\r
- var itoh = '0123456789ABCDEF';\r
- for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10);\r
- s[14] = 4; // Set 4 high bits of time_high field to version\r
- s[19] = (s[19] & 0x3) | 0x8; // Specify 2 high bits of clock sequence\r
- for (var i = 0; i <36; i++) s[i] = itoh[s[i]];\r
- s[8] = s[13] = s[18] = s[23] = '-';\r
- this.setUuid(s.join('').toLowerCase()); \r
- }\r
- this.setBatchEntrySpecs([]);\r
- this.setAttributes({});\r
- },\r
- properties : {\r
- /**\r
- * The unique id identifying the message\r
- */\r
- uuid : {\r
- check : "String"\r
- },\r
- /**\r
- * Execution status\r
- */\r
- status : {\r
- check : "String",\r
- init : "STARTED"\r
- },\r
- /**\r
- * Execution type\r
- */\r
- type : {\r
- check : "String",\r
- init : "slcAnt"\r
- },\r
- /**\r
- * Execution Host\r
- */\r
- host : {\r
- check : "String",\r
- init : "localhost"\r
- },\r
- /**\r
- * Execution User\r
- */\r
- user : {\r
- check : "String",\r
- init : "user"\r
- },\r
- /**\r
- * Date of the message. now() by default.\r
- */\r
- date : {\r
- check : "String", \r
- init : new Date().toString()\r
- },\r
- /**\r
- * Additionnal attributes as map of key/values\r
- */\r
- attributes : {\r
- check : "Map"\r
- },\r
- batchEntrySpecs : {\r
- check : "Array"\r
- }\r
- },\r
- members : {\r
- \r
- /**\r
- * Add a free attribute to the message\r
- * @param attName {String} Name\r
- * @param attValue {String} Value\r
- */\r
- addAttribute: function(attName, attValue){\r
- var attr = this.getAttributes();\r
- attr[attName] = attValue;\r
- this.setAttributes(attr);\r
- },\r
- \r
- addBatchEntrySpec : function(entrySpec){\r
- this.getBatchEntrySpecs().push(entrySpec);\r
- },\r
- \r
- /**\r
- * Build the xml formatted message body to send\r
- * \r
- * @return {String} The message content as Xml\r
- */\r
- toXml : function (){\r
- var builder = new qx.util.StringBuilder();\r
- builder.add('<slc:slc-execution xmlns:slc="http://argeo.org/projects/slc/schemas" uuid="'+this.getUuid()+'">');\r
- builder.add('<slc:status>'+this.getStatus()+'</slc:status>');\r
- builder.add('<slc:type>'+this.getType()+'</slc:type>');\r
- builder.add('<slc:host>'+this.getHost()+'</slc:host>');\r
- builder.add('<slc:user>'+this.getUser()+'</slc:user>');\r
- var flows = this.getBatchEntrySpecs();\r
- if(flows.length){\r
- builder.add('<realized-flows>');\r
- for(var i=0;i<flows.length;i++){\r
- builder.add(flows[i].toXml()); \r
- }\r
- builder.add('</realized-flows>');\r
- } \r
- var attr = this.getAttributes();\r
- if(qx.lang.Object.getLength(attr)){\r
- builder.add('<slc:attributes>');\r
- for(var key in attr){\r
- builder.add('<slc:attribute name="'+key+'">'+attr[key]+'</slc:attribute>');\r
- }\r
- builder.add('</slc:attributes>');\r
- }\r
- builder.add('</slc:slc-execution>');\r
- return builder.get();\r
- },\r
- \r
- /**\r
- * Parse an XML answer and fill the object with it.\r
- * @param slcExecXml {String} An slcExecMessage mapped in XML.\r
- */\r
- fromXml : function(slcExecXml){\r
- var NSMap = {slc:"http://argeo.org/projects/slc/schemas"}; \r
- this.setStatus(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:status", NSMap));\r
- this.setType(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:type", NSMap));\r
- this.setHost(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:host", NSMap));\r
- this.setUser(org.argeo.ria.util.Element.getSingleNodeText(slcExecXml, "slc:user", NSMap));\r
- var attributes = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:attribute", NSMap);\r
- for(var i=0;i<attributes.length;i++){\r
- this.addAttribute(attribute.getAttribute("name"), attribute.firstChild);\r
- }\r
- var stepsDates = org.argeo.ria.util.Element.selectNodes(slcExecXml, "slc:steps/slc:slc-execution-step/slc:begin", NSMap);\r
- if(stepsDates.length){\r
- this.setDate(org.argeo.ria.util.Element.getSingleNodeText(stepsDates[stepsDates.length-1], ".", NSMap));\r
- }\r
- }\r
- } \r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Wrapper for ExecutionModule server object\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.Module", {\r
- \r
- extend : qx.core.Object,\r
- \r
- properties : {\r
- /**\r
- * The name of the module\r
- */\r
- name : {\r
- check : "String",\r
- init : ""\r
- },\r
- /**\r
- * The version of the module\r
- */\r
- version : {\r
- check : "String",\r
- init : ""\r
- },\r
- /**\r
- * All execution flows registered by their name\r
- */\r
- executionFlows : {\r
- check : "Map"\r
- },\r
- /**\r
- * All execution specs registered by their name\r
- */\r
- executionSpecs : {\r
- check : "Map"\r
- },\r
- /**\r
- * XML description (castor)\r
- */\r
- xmlNode : {\r
- apply : "_applyXmlNode"\r
- }\r
- },\r
- \r
- statics : {\r
- XPATH_NAME : "slc:execution-module-descriptor/slc:name",\r
- XPATH_VERSION : "slc:execution-module-descriptor/slc:version",\r
- XPATH_EXECUTION_FLOWS : "slc:execution-module-descriptor/slc:execution-flows/slc:execution-flow-descriptor",\r
- XPATH_EXECUTION_SPECS : "slc:execution-module-descriptor/slc:execution-specs/slc:default-execution-spec"\r
- },\r
- \r
- construct : function(){\r
- this.base(arguments);\r
- this.setExecutionFlows({});\r
- this.setExecutionSpecs({});\r
- },\r
- \r
- members : {\r
- /**\r
- * Add an execution flow to this module\r
- * @param executionFlow {org.argeo.slc.ria.execution.Flow} An instance of execution.Flow\r
- */\r
- addExecutionFlow : function(executionFlow){\r
- var spec = this.getExecutionSpecByName(executionFlow.getExecutionSpecName());\r
- if(spec){\r
- executionFlow.setExecutionSpec(spec);\r
- }else{\r
- this.error("Warning, reference to an unknown ExecutionSpec : "+executionFlow.getExecutionSpecName());\r
- }\r
- this.getExecutionFlows()[executionFlow.getName()] = executionFlow;\r
- },\r
- \r
- /**\r
- * Add an execution Spec to this module\r
- * @param executionSpec {org.argeo.slc.ria.execution.Spec} An instance of ExecutionSpec\r
- */\r
- addExecutionSpec : function(executionSpec){\r
- this.getExecutionSpecs()[executionSpec.getName()] = executionSpec;\r
- },\r
- /**\r
- * Find an execution spec by its name\r
- * @param name {String} Name of the spec\r
- * @return {org.argeo.slc.ria.execution.Spec} The spec\r
- */\r
- getExecutionSpecByName : function(name){\r
- return this.getExecutionSpecs()[name];\r
- },\r
- \r
- /**\r
- * Find an execution flow by its name\r
- * @param name {String} name of the flow\r
- * @return {org.argeo.slc.ria.execution.Flow} The flow\r
- */\r
- getExecutionFlowByName : function(name){\r
- return this.getExecutionFlows()[name];\r
- },\r
- \r
- /**\r
- * An xml node containing the castor mapped description of this object\r
- * @param xmlNode {Node}\r
- */\r
- _applyXmlNode : function(xmlNode){\r
- // Parse now\r
- this.setName(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_NAME));\r
- this.setVersion(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_VERSION));\r
- // Parse Specs first\r
- var specs = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_EXECUTION_SPECS);\r
- for(i=0; i< specs.length;i++){\r
- var execSpec = new org.argeo.slc.ria.execution.Spec();\r
- execSpec.setXmlNode(specs[i]);\r
- this.addExecutionSpec(execSpec);\r
- }\r
- // Now parse Flows : to do AFTER specs\r
- var flows = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_EXECUTION_FLOWS);\r
- for(var i=0;i<flows.length;i++){\r
- var execFlow = new org.argeo.slc.ria.execution.Flow();\r
- execFlow.setXmlNode(flows[i]);\r
- this.addExecutionFlow(execFlow);\r
- }\r
- }\r
- \r
- } \r
- \r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Wrapper for ExecutionSpec server object\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.Spec", {\r
- \r
- extend : qx.core.Object,\r
- \r
- properties : {\r
- /**\r
- * Unique name of this spec \r
- */\r
- name : {\r
- check : "String",\r
- init : ""\r
- },\r
- /**\r
- * Defined parameters \r
- */\r
- values : {\r
- check : "Map"\r
- },\r
- /**\r
- * Castor representation of this object\r
- */\r
- xmlNode : {\r
- apply : "_applyXmlNode" \r
- }\r
- },\r
- \r
- statics : {\r
- XPATH_NAME : "@name",\r
- XPATH_VALUES : "slc:values/slc:value"\r
- },\r
- \r
- construct : function(){\r
- this.base(arguments);\r
- this.setValues({});\r
- },\r
- \r
- members : {\r
- /**\r
- * Init the object from an XML representation\r
- * @param xmlNode {Node} Castor representation of this object\r
- */ \r
- _applyXmlNode : function(xmlNode){\r
- // Parse now\r
- this.setName(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, this.self(arguments).XPATH_NAME));\r
- var values = org.argeo.ria.util.Element.selectNodes(xmlNode, this.self(arguments).XPATH_VALUES);\r
- var parsedValues = {};\r
- for(var i=0;i<values.length;i++){\r
- //var valueNode = values[i];\r
- var value = new org.argeo.slc.ria.execution.Value();\r
- value.setXmlSpecNode(values[i]);\r
- parsedValues[value.getKey()] = value;\r
- }\r
- this.setValues(parsedValues);\r
- },\r
- /**\r
- * XML Representation of this object.\r
- * @return {String} An XML String\r
- */\r
- toXml : function(){\r
- var valuesXml = '';\r
- var values = this.getValues();\r
- for(var key in values){\r
- valuesXml += values[key].toAttributeXml();\r
- }\r
- return '<slc:default-execution-spec name="'+this.getName()+'"><slc:values>'+valuesXml+'</slc:values></slc:default-execution-spec>';\r
- }\r
- } \r
- \r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Generic modal popup window.\r
- * It is layed out with a dock layout. When adding components to it, they are added as "center".\r
- * @author Charles du Jeu\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.SpecEditor",\r
-{\r
- extend : qx.ui.window.Window,\r
- \r
- properties : {\r
- /**\r
- * The Spec to edit\r
- */\r
- batchEntrySpec : {\r
- check : "org.argeo.slc.ria.execution.BatchEntrySpec"\r
- }\r
- },\r
- \r
- events : {\r
- /**\r
- * Triggered when the user clicks the "save" button. \r
- */\r
- "save" : "qx.event.type.Event",\r
- /**\r
- * Triggered when any data is modified\r
- */\r
- "modified" : "qx.event.type.Event"\r
-\r
- },\r
- /**\r
- * Opens an editor with the given values. \r
- * @param batchEntrySpec {org.argeo.slc.ria.execution.BatchEntrySpec} The initial spec to edit\r
- */\r
- construct : function(batchEntrySpec){\r
- var editorLabel = "Edit Specs for "+batchEntrySpec.getLabel();\r
- this.base(arguments, editorLabel);\r
- this.set({\r
- batchEntrySpec : batchEntrySpec,\r
- showMaximize : false,\r
- showMinimize : false,\r
- width: Math.min(parseInt(qx.bom.Viewport.getWidth()*90/100), 400),\r
- height: parseInt(qx.bom.Viewport.getHeight()*60/100)\r
- });\r
- this.setLayout(new qx.ui.layout.Dock());\r
- this.setModal(true);\r
- this.center();\r
- this._initFormObject(this.getBatchEntrySpec().getLabel());\r
- this._addFormHeader(this.formObject, editorLabel);\r
- this.createFormFromSpec();\r
- this.addContent(this.formObject.pane);\r
- this.addOkCancel();\r
- this.addListener("save", function(e){\r
- this.saveFormToSpec();\r
- }, this);\r
- },\r
- \r
- members : {\r
- /**\r
- * Builds the form from the BatchEntrySpec\r
- */\r
- createFormFromSpec : function(){\r
- var values = this.getBatchEntrySpec().getValues();\r
- for(var key in values){\r
- var valueObj = values[key];\r
- var label = key;\r
- var hidden = valueObj.getHidden();\r
- var disabled = valueObj.getFrozen();\r
- var value = valueObj.getValue();\r
- var type = valueObj.getSpecType();\r
- var subType = valueObj.getSpecSubType();\r
- if(type == "primitive" && !hidden){\r
- this._addFormInputText(this.formObject, key, key, value, disabled, subType);\r
- }\r
- }\r
- },\r
- /**\r
- * Gather data from the form\r
- */\r
- saveFormToSpec : function(){\r
- var values = this.getBatchEntrySpec().getValues();\r
- for(var key in values){\r
- var valueObj = values[key];\r
- var hidden = valueObj.getHidden();\r
- var disabled = valueObj.getFrozen();\r
- if(valueObj.getSpecType() == "primitive"){\r
- if(!hidden && !disabled){\r
- valueObj.setValue(this.formObject.fields[key].getValue());\r
- }\r
- }\r
- } \r
- },\r
- \r
- /**\r
- * Display a component (panel) in the center of the popup\r
- * @param panel {qx.ui.core.Widget} A gui component (will be set at width 100%).\r
- */\r
- addContent: function(panel){\r
- this.add(new qx.ui.container.Scroll(panel), {edge:'center', width:'100%'});\r
- },\r
- /**\r
- * Automatically attach to the application root, then show.\r
- */\r
- attachAndShow:function(){\r
- org.argeo.ria.components.ViewsManager.getInstance().getApplicationRoot().add(this); \r
- this.show();\r
- },\r
- /**\r
- * Init a form part : creates a pane, a set of fields, etc.\r
- * @param label {String} A label\r
- * @return {Map} The form part.\r
- */\r
- _initFormObject : function(label){\r
- this.formObject = {};\r
- this.formObject.hiddenFields = {};\r
- this.formObject.freeFields = [];\r
- this.formObject.fields = {};\r
- this.formObject.label = label;\r
- this.formObject.pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));\r
- return this.formObject;\r
- },\r
- \r
- /**\r
- * Creates a simple label/input form entry.\r
- * @param formObject {Map} The form part\r
- * @param fieldName {String} Name\r
- * @param fieldLabel {String} Label of the field\r
- * @param defaultValue {String} The default value\r
- * @param choiceValues {Map} An map of values\r
- * @param disabled {Boolean} The field is not writable\r
- * @param subType {String} The type expected (string, integer, etc).\r
- */\r
- _addFormInputText : function(formObject, fieldName, fieldLabel, defaultValue, disabled, subType, choiceValues){\r
- var labelElement;\r
- if(choiceValues){\r
- var fieldElement = new qx.ui.form.SelectBox();\r
- for(var key in choiceValues){\r
- fieldElement.add(new qx.ui.form.ListItem(choiceValues[key], null, key));\r
- }\r
- fieldElement.addListener("changeSelected", function(e){this.fireEvent("modified")}, this);\r
- }else{\r
- var fieldElement = new qx.ui.form.TextField();\r
- if(subType == "integer"){\r
- fieldElement.addListener("changeValue", function(e){\r
- var isNum = !isNaN(e.getData() * 1);\r
- if(!isNum){\r
- alert("Warning, this field only accepts Integers!");\r
- }\r
- }, this); \r
- }\r
- fieldElement.addListener("input", function(e){this.fireEvent("modified")}, this); \r
- }\r
- if(defaultValue){\r
- fieldElement.setValue(defaultValue);\r
- }\r
- if(fieldName && fieldLabel){\r
- labelElement = new qx.ui.basic.Label(fieldLabel);\r
- formObject.fields[fieldName] = fieldElement;\r
- }else{\r
- labelElement = new qx.ui.form.TextField();\r
- formObject.freeFields.push({\r
- labelEl:labelElement, \r
- valueEl:fieldElement\r
- });\r
- }\r
- if(disabled) fieldElement.setEnabled(false);\r
- this._addFormEntry(formObject, labelElement, fieldElement);\r
- },\r
- \r
- /**\r
- * Add an header\r
- * @param formObject {Map} The form part\r
- * @param content {Mixed} Content to add.\r
- * @param additionnalButton {Mixed} Any widget to add on the east.\r
- */\r
- _addFormHeader : function(formObject, content, additionnalButton){\r
- var header = new qx.ui.basic.Label('<big><b>'+content+'</b></big>');\r
- header.setRich(true); \r
- if(!additionnalButton){\r
- header.setPaddingBottom(10);\r
- formObject.pane.add(header);\r
- }else{\r
- var pane = new qx.ui.container.Composite(new qx.ui.layout.Dock());\r
- pane.setPaddingBottom(10);\r
- pane.setPaddingRight(10);\r
- pane.add(header, {edge:'center'});\r
- pane.add(additionnalButton, {edge:'east'});\r
- formObject.pane.add(pane);\r
- }\r
- },\r
- \r
- /**\r
- * Adds a label/input like entry in the form.\r
- * @param formObject {Map} The form part\r
- * @param labelElement {Object} Either a label or an input \r
- * @param fieldElement {Object} Any form input.\r
- */\r
- _addFormEntry : function(formObject, labelElement, fieldElement){\r
- var entryPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));\r
- labelElement.setWidth(150);\r
- labelElement.setTextAlign("right"); \r
- entryPane.add(labelElement);\r
- entryPane.add(new qx.ui.basic.Label(':'));\r
- fieldElement.setWidth(150);\r
- entryPane.add(fieldElement);\r
- formObject.pane.add(entryPane);\r
- },\r
- \r
- /**\r
- * Adds a close button bottom-center aligned to the popup\r
- */\r
- addCloseButton : function(){\r
- this.closeButton = new qx.ui.form.Button("Close");\r
- this.closeButton.addListener("execute", this._closeAndDestroy, this);\r
- this.add(this.closeButton, {edge:'south'}); \r
- },\r
- /**\r
- * Adds two buttons bottom-center aligned (Ok and Cancel). \r
- * Ok button has no listener by default, Cancel will close and destroy the popup.\r
- */\r
- addOkCancel : function(){\r
- var buttonPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5, 'right'));\r
- buttonPane.setAlignX("center");\r
- this.add(buttonPane, {edge:"south"});\r
- this.okButton = new qx.ui.form.Button("Save");\r
- this.okButton.setEnabled(false);\r
- this.addListener("modified", function(e){\r
- this.okButton.setEnabled(true);\r
- }, this);\r
- this.okButton.addListener("execute", function(e){\r
- this.fireEvent("save");\r
- this.okButton.setEnabled(false);\r
- }, this);\r
- this.cancelButton = new qx.ui.form.Button("Close");\r
- this.cancelButton.addListener("execute", this._closeAndDestroy, this);\r
-\r
- this.saveCloseButton = new qx.ui.form.Button("Save & Close");\r
- this.saveCloseButton.addListener("execute", function(e){\r
- this.fireEvent("save");\r
- this._closeAndDestroy();\r
- }, this);\r
- \r
- buttonPane.add(this.okButton);\r
- buttonPane.add(this.cancelButton);\r
- buttonPane.add(this.saveCloseButton);\r
- },\r
- /**\r
- * Close this modal window and destroy it.\r
- */\r
- _closeAndDestroy : function(){\r
- this.hide();\r
- this.destroy(); \r
- }\r
- }\r
-});
\ No newline at end of file
+++ /dev/null
-/**\r
- * Wrapper for SlcValue object\r
- */\r
-qx.Class.define("org.argeo.slc.ria.execution.Value", {\r
- \r
- extend : qx.core.Object,\r
- \r
- properties : {\r
- /**\r
- * Name of this Execution Flow \r
- */\r
- key : {\r
- check : "String",\r
- init : ""\r
- },\r
- /**\r
- * The type of this value, for the moment "primitive" and "ref" are supported \r
- */\r
- specType : {\r
- check : "String",\r
- init : "" \r
- },\r
- /**\r
- * Subtype, depending on the "type". \r
- */\r
- specSubType : {\r
- check : "String"\r
- },\r
- /**\r
- * Whether it is a parameter or not \r
- */\r
- parameter : {\r
- check : "Boolean"\r
- },\r
- /**\r
- * Whether it is frozen on the server, i.e. disabled in the form \r
- */\r
- frozen : {\r
- check : "Boolean"\r
- },\r
- /**\r
- * Should not be editable nor seeable, thus hidden \r
- */\r
- hidden : {\r
- check : "Boolean"\r
- },\r
- /**\r
- * The real value \r
- */\r
- value : {\r
- nullable : true\r
- },\r
- /**\r
- * Castor representation of the object \r
- */\r
- xmlSpecNode : {\r
- apply : "_applyXmlSpecNode"\r
- }\r
- },\r
- \r
- statics : {\r
- XPATH_KEY : "@key"\r
- },\r
- \r
- construct : function(){\r
- this.base(arguments);\r
- },\r
- \r
- members : { \r
- /**\r
- * Init the object from an XML representation\r
- * @param xmlNode {Node} Castor representation of this object\r
- */\r
- _applyXmlSpecNode : function(xmlNode){\r
- this.setKey(org.argeo.ria.util.Element.getSingleNodeText(xmlNode, "@key"));\r
- var childs = xmlNode.childNodes;\r
- for(var i=0;i<childs.length;i++){\r
- var child = childs[i];\r
- if(child.nodeType != 1) continue;\r
- if(child.nodeName == "slc:primitive-spec-attribute"){\r
- this.setSpecType("primitive");\r
- this.setSpecSubType(org.argeo.ria.util.Element.getSingleNodeText(child, "@type"));\r
- if(org.argeo.ria.util.Element.getSingleNodeText(child, ".")){\r
- this.setValue(org.argeo.ria.util.Element.getSingleNodeText(child, "."));\r
- }\r
- }else if(child.nodeName == "slc:ref-spec-attribute"){\r
- this.setSpecType("ref");\r
- this.setSpecSubType(org.argeo.ria.util.Element.getSingleNodeText(child, "@targetClassName"));\r
- }\r
- this.set({\r
- parameter : (org.argeo.ria.util.Element.getSingleNodeText(child, "@isParameter")=="true"?true:false),\r
- frozen : (org.argeo.ria.util.Element.getSingleNodeText(child, "@isFrozen")=="true"?true:false),\r
- hidden : (org.argeo.ria.util.Element.getSingleNodeText(child, "@isHidden")=="true"?true:false)\r
- }); \r
- }\r
- },\r
- \r
- /**\r
- * Create an XML Representation of this value\r
- * @return {String} The XML String\r
- */\r
- toAttributeXml : function(){\r
- var valueTag = '';\r
- var specAttribute = '';\r
- if(this.getSpecType() == "primitive"){\r
- valueTag = (this.getValue()?this.getValue():'');\r
- specAttribute = '<slc:primitive-spec-attribute isParameter="'+(this.getParameter()?"true":"false")+'" isFrozen="'+(this.getFrozen()?"true":"false")+'" isHidden="'+(this.getHidden()?"true":"false")+'" type="'+this.getSpecSubType()+'">'+valueTag+'</slc:primitive-spec-attribute>';\r
- }else if(this.getSpecType() == "ref"){\r
- valueTag = (this.getValue()?'<slc:label>'+this.getValue()+'</slc:label>':'');\r
- specAttribute = '<slc:ref-spec-attribute isParameter="'+(this.getParameter()?"true":"false")+'" isFrozen="'+(this.getFrozen()?"true":"false")+'" isHidden="'+(this.getHidden()?"true":"false")+'" targetClassName="'+this.getSpecSubType()+'">'+valueTag+'</slc:ref-spec-attribute>';\r
- }\r
- return '<slc:value key="'+this.getKey()+'">'+specAttribute+'</slc:value>';\r
- },\r
- \r
- toValueXml : function(){\r
- var valueTag = '';\r
- var specAttribute = '';\r
- if(this.getSpecType() == "primitive"){\r
- valueTag = this.getValue();\r
- specAttribute = '<slc:primitive-value type="'+this.getSpecSubType()+'">'+valueTag+'</slc:primitive-value>';\r
- }else if(this.getSpecType() == "ref"){\r
- valueTag = '<slc:label>'+this.getValue()+'</slc:label>';\r
- specAttribute = '<slc:ref-value >'+valueTag+'</slc:ref-value>';\r
- }\r
- return '<slc:value key="'+this.getKey()+'">'+specAttribute+'</slc:value>'; \r
- }\r
- } \r
- \r
-});
\ No newline at end of file