From: Bruno Sinou Date: Mon, 8 Nov 2010 16:11:08 +0000 (+0000) Subject: + refactor to separate runtime and module project under eclipse plugin. X-Git-Tag: argeo-slc-2.1.7~1109 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=5e5b06fe0c831e66bc048d8bf8da40b32f79a5c9;p=gpl%2Fargeo-slc.git + refactor to separate runtime and module project under eclipse plugin. + add some pom to prepare the deployment + clean client rcp & ui project (change src & target folder) git-svn-id: https://svn.argeo.org/slc/trunk@3871 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/.classpath b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.classpath new file mode 100644 index 000000000..8b978d9ed --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/.project b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.project new file mode 100644 index 000000000..ed71a2e72 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.project @@ -0,0 +1,28 @@ + + + org.argeo.slc.client.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.jdt.core.prefs b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..95d6b05d7 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Wed Aug 04 16:31:36 CEST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.pde.core.prefs b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 000000000..31cbfaeee --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +#Tue Jul 27 14:24:51 CEST 2010 +eclipse.preferences.version=1 +resolve.requirebundle=false diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/MANIFEST.MF b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5969e74d3 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/MANIFEST.MF @@ -0,0 +1,40 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Ui +Bundle-SymbolicName: org.argeo.slc.client.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.argeo.slc.client.ui.ClientUiPlugin +Require-Bundle: org.eclipse.ui;resolution:=optional, + org.eclipse.core.runtime;resolution:=optional +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Export-Package: org.argeo.slc.client.ui.listeners, + org.argeo.slc.client.ui.perspectives, + org.argeo.slc.client.ui.views +Import-Package: org.argeo.slc.client.ui, + org.apache.commons.io;version="1.4.0", + org.apache.commons.logging;version="1.1.1", + org.argeo.eclipse.spring, + org.argeo.eclipse.ui, + org.argeo.slc, + org.argeo.slc.build, + org.argeo.slc.client.oxm, + org.argeo.slc.core.attachment, + org.argeo.slc.core.execution, + org.argeo.slc.core.runtime, + org.argeo.slc.core.structure.tree, + org.argeo.slc.core.test.tree, + org.argeo.slc.dao.process, + org.argeo.slc.dao.test, + org.argeo.slc.dao.test.tree, + org.argeo.slc.deploy, + org.argeo.slc.execution, + org.argeo.slc.msg.test.tree, + org.argeo.slc.process, + org.argeo.slc.runtime, + org.argeo.slc.services, + org.argeo.slc.services.impl, + org.argeo.slc.test, + org.springframework.beans.factory, + org.springframework.context, + org.springframework.core.io.support diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/commands.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/commands.xml new file mode 100644 index 000000000..5312a33a4 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/commands.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/controllers.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/controllers.xml new file mode 100644 index 000000000..62154375e --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/controllers.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/listeners.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/listeners.xml new file mode 100644 index 000000000..509fe8127 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/listeners.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/osgi.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/osgi.xml new file mode 100644 index 000000000..e05a86585 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/osgi.xml @@ -0,0 +1,59 @@ + + + + Implements SLC specific RCP UIs. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/views.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/views.xml new file mode 100644 index 000000000..74b7d9262 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/views.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/build.properties b/eclipse/plugins/runtime/org.argeo.slc.client.ui/build.properties new file mode 100644 index 000000000..a1c313d1c --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/build.properties @@ -0,0 +1,6 @@ +source.. = src/main/java +output.. = target/classes +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/archive.png b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/archive.png new file mode 100644 index 000000000..fb36f360b Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/archive.png differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/batch.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/batch.gif new file mode 100644 index 000000000..b8ca14a8b Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/batch.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/clear_batch.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/clear_batch.gif new file mode 100644 index 000000000..28a3785aa Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/clear_batch.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/computer.png b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/computer.png new file mode 100644 index 000000000..ff64b8426 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/computer.png differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/edit_parameters.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/edit_parameters.gif new file mode 100644 index 000000000..94eedf6f9 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/edit_parameters.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/error.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/error.gif new file mode 100644 index 000000000..64b438488 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/error.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/execution_module.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/execution_module.gif new file mode 100644 index 000000000..983932fcc Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/execution_module.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/folder.png b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/folder.png new file mode 100644 index 000000000..6937ed4a3 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/folder.png differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/launch.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/launch.gif new file mode 100644 index 000000000..ec477ea43 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/launch.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/passed.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/passed.gif new file mode 100644 index 000000000..23c97f09e Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/passed.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/process_details.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/process_details.gif new file mode 100644 index 000000000..c81630a08 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/process_details.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.gif new file mode 100644 index 000000000..364c0e70b Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.png b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.png new file mode 100644 index 000000000..364c0e70b Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.png differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/refresh.png b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/refresh.png new file mode 100644 index 000000000..bb3803b07 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/refresh.png differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/remove_one.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/remove_one.gif new file mode 100644 index 000000000..2cd9c5444 Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/remove_one.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/result_details.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/result_details.gif new file mode 100644 index 000000000..4017f6dbd Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/result_details.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/results.gif b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/results.gif new file mode 100644 index 000000000..0dc862cbd Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/results.gif differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/system.png b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/system.png new file mode 100644 index 000000000..71f44d0ce Binary files /dev/null and b/eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/system.png differ diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/plugin.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/plugin.xml new file mode 100644 index 000000000..b6f4dd1e0 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/plugin.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/pom.xml b/eclipse/plugins/runtime/org.argeo.slc.client.ui/pom.xml new file mode 100644 index 000000000..895938dc8 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/pom.xml @@ -0,0 +1,73 @@ + + 4.0.0 + + org.argeo.slc.eclipse + plugins + 0.13.0-SNAPSHOT + .. + + org.argeo.slc.client.ui + SLC Client UI + jar + + + + org.argeo.slc.eclipse + org.argeo.slc.client.commons + ${project.version} + + + org.argeo.slc.eclipse + org.argeo.slc.client.oxm + ${project.version} + + + org.argeo.slc.eclipse + org.argeo.slc.client.hibernate + ${project.version} + + + org.argeo.slc.eclipse + org.argeo.slc.client.core + ${project.version} + + + + + org.argeo.slc.runtime + org.argeo.slc.core + ${project.version} + + + + org.argeo.slc.runtime + org.argeo.slc.server + ${project.version} + + + + org.argeo.commons.eclipse + org.argeo.eclipse.ui + ${version.argeo-commons} + + + + org.springframework + org.springframework.context + + + + org.eclipse.ui + org.eclipse.ui + + + org.eclipse.core + org.eclipse.core.runtime + + + org.eclipse.swt + org.eclipse.swt.gtk.linux.x86_64 + + + diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ClearBatchHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ClearBatchHandler.java new file mode 100644 index 000000000..eb6809c1f --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ClearBatchHandler.java @@ -0,0 +1,30 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author bsinou + * + * Remove all processes from the batch built in the ProcessBuilderView + * + * NOTE : only one batch is supported with this command, if more than + * one batch is planned, this class must be updated with parameter. + */ +public class ClearBatchHandler extends AbstractHandler { + // private final static Log log = + // LogFactory.getLog(ClearBatchHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessBuilderView pbView = (ProcessBuilderView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessBuilderView.ID); + pbView.clearBatch(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java new file mode 100644 index 000000000..e770c34b0 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java @@ -0,0 +1,30 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author bsinou + * + * Launch the batch built in the ProcessBuilderView + * + * NOTE : only one batch is supported with this command, if more than + * one batch is planned, this class must be updated with parameter. + */ +public class LaunchBatchHandler extends AbstractHandler { + // private final static Log log = + // LogFactory.getLog(LaunchBatchHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessBuilderView pbView = (ProcessBuilderView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessBuilderView.ID); + pbView.launchBatch(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java new file mode 100644 index 000000000..cdc28812b --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java @@ -0,0 +1,43 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessDetailView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Command handler to set visible or create a ProcessDetailView. UUID of the + * process is passed via command parameters. + * + * @author bsinou + * + */ + +public class ProcessDetailsDisplayHandler extends AbstractHandler { + // private static final Log log = LogFactory + // .getLog(ProcessDetailsDisplayHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + + // We pass the UUID of the process we want to display via command + // parameters. + String uuid = event + .getParameter("org.argeo.slc.client.commands.processUuid"); + + // mode = 1 : VIEW_ACTIVATE, Show view mode that indicates the view + // should be made visible and activated. Use of this mode has the same + // effect as calling showView. + try { + ProcessDetailView pView = (ProcessDetailView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .showView(ProcessDetailView.ID, "UUID-" + uuid, 1); + pView.setUuid(uuid); + pView.retrieveResults(); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java new file mode 100644 index 000000000..47f9d0041 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java @@ -0,0 +1,19 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessListView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ProcessListViewRefreshHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessListView pView = (ProcessListView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessListView.ID); + pView.retrieveResults(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java new file mode 100644 index 000000000..12e8de0ff --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java @@ -0,0 +1,31 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author bsinou + * + * Launch the batch built in the ProcessBuilderView + * + * NOTE : only one batch is supported with this command, if more than + * one batch is planned, this class must be updated with parameter. + */ + +public class RemoveSelectedProcessFromBatchHandler extends AbstractHandler { + // private final static Log log = + // LogFactory.getLog(RemoveSelectedProcessFromBatchHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessBuilderView pbView = (ProcessBuilderView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessBuilderView.ID); + pbView.removeSelected(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java new file mode 100644 index 000000000..98c502f3e --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java @@ -0,0 +1,44 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ResultDetailView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Command handler to set visible or create a ResultDetailView. UUID of the + * testResult is passed via command parameters. + * + * @author bsinou + * + */ + +public class ResultDetailsDisplayHandler extends AbstractHandler { + // private static final Log log = LogFactory + // .getLog(ResultDetailsDisplayHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + + // We pass the UUID of the test result we want to display via command + // parameters. + String uuid = event + .getParameter("org.argeo.slc.client.commands.resultUuid"); + + // mode = 2 : VIEW_VISIBLE, Show view mode that indicates the view + // should be created or made visible if already created . + // mode = 1 : VIEW_ACTIVATE, Show view mode that indicates the view + // should be made visible and activated. Use of this mode has the same + // effect as calling + try { + ResultDetailView rView = (ResultDetailView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .showView(ResultDetailView.ID, "UUID-" + uuid, 1); + rView.setUuid(uuid); + rView.retrieveResults(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java new file mode 100644 index 000000000..23fa87916 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java @@ -0,0 +1,19 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ResultListView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ResultListViewRefreshHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + ResultListView view = (ResultListView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ResultListView.ID); + view.retrieveResults(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/controllers/ProcessController.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/controllers/ProcessController.java new file mode 100644 index 000000000..5785305ab --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/controllers/ProcessController.java @@ -0,0 +1,19 @@ +package org.argeo.slc.client.ui.controllers; + +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcAgent; +import org.argeo.slc.services.SlcExecutionService; + +public class ProcessController { + private SlcExecutionService slcExecutionService; + + public void execute(SlcAgent agent, SlcExecution slcExecution) { + slcExecutionService.newExecution(slcExecution); + agent.runSlcExecution(slcExecution); + } + + public void setSlcExecutionService(SlcExecutionService slcExecutionService) { + this.slcExecutionService = slcExecutionService; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java new file mode 100644 index 000000000..499559833 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java @@ -0,0 +1,105 @@ +package org.argeo.slc.client.ui.listeners; + +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.SimpleAttachment; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.core.test.tree.TreeTestResultListener; +import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest; +import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.ResultPartRequest; +import org.argeo.slc.services.TestManagerService; +import org.argeo.slc.test.TestResultPart; +import org.eclipse.ui.handlers.IHandlerService; + +/** In memory access to a test manager service */ +public class TestManagerServiceAdapter implements TreeTestResultListener { + // private static final Log log = LogFactory + // .getLog(TestManagerServiceAdapter.class); + + private Boolean onlyOnClose = false; + + private TestManagerService testManagerService; + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + if (onlyOnClose) + return; + + if (testResult.getResultParts().size() == 1 + && testResult.getResultParts().values().iterator().next() + .getParts().size() == 1) { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + testResult); + testManagerService.createTreeTestResult(req); + } else { + ResultPartRequest req = new ResultPartRequest(testResult); + testManagerService.addResultPart(req); + } + } + + public void close(TreeTestResult testResult) { + + if (onlyOnClose) { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + testResult); + testManagerService.createTreeTestResult(req); + } else { + CloseTreeTestResultRequest req = new CloseTreeTestResultRequest( + testResult); + testManagerService.closeTreeTestResult(req); + } + + // TODO : clean this -> pb of thread && commandID hardCoded. + // We force the refresh of the list view. + ClientUiPlugin.getDefault().getWorkbench().getDisplay() + .syncExec(new Runnable() { + public void run() { + IHandlerService handlerService = (IHandlerService) ClientUiPlugin + .getDefault().getWorkbench() + .getService(IHandlerService.class); + try { + handlerService + .executeCommand( + "org.argeo.slc.client.ui.refreshResultList", + null); + handlerService + .executeCommand( + "org.argeo.slc.client.ui.refreshProcessList", + null); + + } catch (Exception e) { + e.printStackTrace(); + throw new SlcException( + "Problem while rendering result. " + + e.getMessage()); + } + } + } + + ); + + } + + public void addAttachment(TreeTestResult testResult, Attachment attachment) { + if (onlyOnClose) + return; + AddTreeTestResultAttachmentRequest req = new AddTreeTestResultAttachmentRequest(); + req.setResultUuid(testResult.getUuid()); + req.setAttachment((SimpleAttachment) attachment); + testManagerService.addAttachment(req); + + } + + /** Publishes the test result only when it gets closed. */ + public void setOnlyOnClose(Boolean onlyOnClose) { + this.onlyOnClose = onlyOnClose; + } + + public void setTestManagerService(TestManagerService testManagerService) { + this.testManagerService = testManagerService; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/perspectives/SlcExecution.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/perspectives/SlcExecution.java new file mode 100644 index 000000000..f50ea1814 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/perspectives/SlcExecution.java @@ -0,0 +1,44 @@ +package org.argeo.slc.client.ui.perspectives; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class SlcExecution implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + layout.setFixed(false); + + // Create the main ui layout + + // For a vertical split, the part on top gets the specified ratio of the + // current space and the part on bottom gets the rest. Likewise, for a + // horizontal split, the part at left gets the specified ratio of the + // current space. + IFolderLayout main = layout.createFolder("main", IPageLayout.RIGHT, + 0.3f, editorArea); + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.3f, editorArea); + + IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.65f, "main"); + + IFolderLayout topRight = layout.createFolder("topRight", + IPageLayout.RIGHT, 0.6f, "main"); + + // add the views to the corresponding place holder + left.addView("org.argeo.slc.client.ui.executionModulesView"); + left.addView("org.argeo.slc.client.ui.resultListView"); + + main.addView("org.argeo.slc.client.ui.processBuilderView"); + main.addPlaceholder("org.argeo.slc.client.ui.resultDetailView:UUID-*"); + main.addPlaceholder("org.argeo.slc.client.ui.processDetailView:UUID-*"); + + bottom.addView("org.argeo.slc.client.ui.processListView"); + + topRight.addView("org.argeo.slc.client.ui.processParametersView"); + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java new file mode 100644 index 000000000..1278609bd --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java @@ -0,0 +1,261 @@ +package org.argeo.slc.client.ui.providers; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.eclipse.ui.TreeObject; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.slc.execution.ExecutionFlowDescriptor; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.runtime.SlcAgent; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class ExecutionModulesContentProvider implements ITreeContentProvider { + private final static Log log = LogFactory + .getLog(ExecutionModulesContentProvider.class); + + // IoC + private List slcAgents; + + public Object[] getChildren(Object parent) { + if (parent instanceof ExecutionModuleNode) { + ExecutionModuleNode executionModuleNode = (ExecutionModuleNode) parent; + ExecutionModuleDescriptor emd = executionModuleNode.getDescriptor(); + + // Terminate the building of UI specific object emd + emd = executionModuleNode + .getAgentNode() + .getAgent() + .getExecutionModuleDescriptor(emd.getName(), + emd.getVersion()); + executionModuleNode.cacheDescriptor(emd); + + // This is not recursive, e.g. ExecutionModuleNode build a Tree of + // specific + // treeObject and cache it in the cacheDescriptor. + // Then we only have TreeObjects + return executionModuleNode.getChildren(); + } else if (parent instanceof AgentNode) { + AgentNode agentNode = (AgentNode) parent; + + if (log.isTraceEnabled()) + log.trace("Scan agent " + agentNode); + + agentNode.clearChildren(); + for (ExecutionModuleDescriptor desc : agentNode.getAgent() + .listExecutionModuleDescriptors()) { + agentNode.addChild(new ExecutionModuleNode(agentNode, desc)); + } + + return agentNode.getChildren(); + } else if (parent instanceof TreeParent) { + return ((TreeParent) parent).getChildren(); + } else if (parent instanceof FlowNode) { + return new Object[0]; + } else { + List agentNodes = new ArrayList(); + for (SlcAgent slcAgent : slcAgents) { + agentNodes.add(new AgentNode(slcAgent)); + } + return agentNodes.toArray(); + } + } + + public Object getParent(Object node) { + // if (node instanceof TreeObject) { + // return ((TreeObject) node).getParent(); + // } + return null; + } + + public boolean hasChildren(Object parent) { + if (parent instanceof TreeParent && ((TreeParent) parent).isLoaded()) { + return ((TreeParent) parent).hasChildren(); + } else if (parent instanceof AgentNode) { + return true; + } else if (parent instanceof ExecutionModuleNode) { + return true; + } + return false; + } + + public void inputChanged(Viewer v, Object oldInput, Object newInput) { + } + + public void dispose() { + } + + public Object[] getElements(Object parent) { + return getChildren(parent); + } + + + + public class AgentNode extends TreeParent { + private final SlcAgent agent; + + public AgentNode(SlcAgent agent) { + super(agent.toString()); + this.agent = agent; + } + + public SlcAgent getAgent() { + return agent; + } + } + + public class ExecutionModuleNode extends TreeParent { + private final AgentNode agentNode; + private ExecutionModuleDescriptor descriptor; + private Map flowDescriptors; + + public ExecutionModuleNode(AgentNode agentNode, + ExecutionModuleDescriptor descriptor) { + super(descriptor.toString()); + this.agentNode = agentNode; + this.descriptor = descriptor; + + } + + public AgentNode getAgentNode() { + return agentNode; + } + + public ExecutionModuleDescriptor getDescriptor() { + return descriptor; + } + + public void cacheDescriptor(ExecutionModuleDescriptor descriptor) { + this.descriptor = descriptor; + + SortedMap folderNodes = new TreeMap(); + flowDescriptors = new HashMap(); + + for (ExecutionFlowDescriptor fd : descriptor.getExecutionFlows()) { + // Find, format and store path and label values for each flow + // descritor: + + // we format name of type path="" & name="path/toTest/Test" to : + // path="path/toTest/" name="Test" + String path; + String label; + int lastSlash = fd.getName().lastIndexOf('/'); + if ((fd.getPath() == null || fd.getPath().trim().equals("")) + && lastSlash >= 0) { + path = fd.getName().substring(0, lastSlash); + label = fd.getName().substring(lastSlash + 1); + } else { + path = fd.getPath(); + label = fd.getName(); + } + + if (path == null || path.trim().equals("") + || path.trim().equals("/")) { + // directChildren.put(name, new FlowNode(name, this)); + addChild(new FlowNode(label, fd.getName(), fd, this)); + } else { + FolderNode folderNode = mkdirs(this, path, folderNodes); + folderNode.addChild(new FlowNode(label, fd.getName(), fd, + this)); + } + + flowDescriptors.put(fd.getName(), fd); + } + // TODO: make it readonly + } + + protected FolderNode mkdirs(TreeParent root, String path, + SortedMap folderNodes) { + // Normalize + if (path.charAt(0) != '/') + path = '/' + path; + if (path.charAt(path.length() - 1) == '/') + path = path.substring(0, path.length() - 1); + + if (folderNodes.containsKey(path)) + return folderNodes.get(path); + + int lastIndx = path.lastIndexOf('/'); + String folderName; + String parentPath; + if (lastIndx >= 0) { + folderName = path.substring(lastIndx + 1); + parentPath = path.substring(0, lastIndx); + } else { + folderName = path; + parentPath = ""; + } + + TreeParent parent; + if (parentPath.equals("")) + parent = root; + else + parent = mkdirs(root, parentPath, folderNodes); + FolderNode newFolder = new FolderNode(folderName); + parent.addChild(newFolder); + folderNodes.put(path, newFolder); + return newFolder; + } + + public Map getFlowDescriptors() { + return flowDescriptors; + } + + } + + /** + * + * @author bsinou + * + * The implementation of a vernice of a given slc process. Note that + * we store the parent node (execution module node) & the + * ExecutionFlowDescriptor. + */ + public class FlowNode extends TreeObject { + + private final String flowName; + private final ExecutionModuleNode executionModuleNode; + private final ExecutionFlowDescriptor executionFlowDescriptor; + + public FlowNode(String label, String flowName, + ExecutionFlowDescriptor executionFlowDescriptor, + ExecutionModuleNode parent) { + super(label); + this.flowName = flowName; + this.executionFlowDescriptor = executionFlowDescriptor; + this.executionModuleNode = parent; + } + + public String getFlowName() { + return flowName; + } + + public ExecutionModuleNode getExecutionModuleNode() { + return executionModuleNode; + } + + public ExecutionFlowDescriptor getExecutionFlowDescriptor() { + return executionFlowDescriptor; + } + + } + + public class FolderNode extends TreeParent { + public FolderNode(String name) { + super(name); + } + + } + + // IoC + public void setSlcAgents(List slcAgents) { + this.slcAgents = slcAgents; + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java new file mode 100644 index 000000000..7ca534e0f --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java @@ -0,0 +1,118 @@ +package org.argeo.slc.client.ui.providers; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.argeo.slc.client.ui.views.ProcessParametersView; +import org.argeo.slc.core.execution.PrimitiveAccessor; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; + +/** + * + * + * Implements the ability to edit and save various type of + * parameter of a given process. Parameter values are directly saved as + * soon as the focus on a given field is lost. + * + * + * Note that EditingSupport is tightly coupled with both + * ProcessParametersView and ProcessBuilderView; it cannot serve as a + * generic EditingSupport as is. Note also that it assumes that the + * processes in ProcessBuilderView as stored as an ordered list. + + @author bsinou + * + */ + +public class ProcessParametersEditingSupport extends EditingSupport { + + // private final static Log log = LogFactory + // .getLog(ProcessParametersEditingSupport.class); + + private CellEditor strEditor; + private CellEditor nbEditor; + // private int column; + + private final static String strType = "string", intType = "integer"; + + // different type of primitive + private static enum primitiveType { + strType, intType + }; + + // So that we can update corresponding process + private int curProcessIndex; + private ProcessBuilderView pbView; + + public ProcessParametersEditingSupport(ColumnViewer viewer, int column) { + super(viewer); + strEditor = new TextCellEditor(((TableViewer) viewer).getTable()); + // nbEditor = new NumberCellEditor(((TableViewer) viewer).getTable()); + // this.column = column; + } + + @Override + protected CellEditor getCellEditor(Object element) { + // TODO return specific editor depending on the parameter type. + return strEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + ProcessParametersView.ObjectWithName objectWithName = (ProcessParametersView.ObjectWithName) element; + + if (objectWithName.obj instanceof PrimitiveAccessor) { + PrimitiveAccessor pv = (PrimitiveAccessor) objectWithName.obj; + // we only handle string & integer parameter in a first time + if (strType.equals(pv.getType())) { + return pv.getValue(); + } + if (intType.equals(pv.getType())) { + return ((Integer) pv.getValue()).toString(); + } + } + return "unsupported param type"; + + } + + @Override + protected void setValue(Object element, Object value) { + ProcessParametersView.ObjectWithName objectWithName = (ProcessParametersView.ObjectWithName) element; + if (objectWithName.obj instanceof PrimitiveAccessor) { + PrimitiveAccessor pv = (PrimitiveAccessor) objectWithName.obj; + // we only handle string parameter in a first time + if (strType.equals(pv.getType())) { + pv.setValue(value); + pbView.updateParameter(curProcessIndex, objectWithName.name, + objectWithName.obj); + } else if (intType.equals(pv.getType())) { + + String stVal = (String) value; + Integer val = ("".equals(stVal)) ? new Integer(0) + : new Integer(stVal); + pv.setValue(val); + pbView.updateParameter(curProcessIndex, objectWithName.name, pv); + } + getViewer().update(element, null); + } + + } + + // Store the index of the process which parameters are being edited + public void setCurrentProcessIndex(int index) { + this.curProcessIndex = index; + } + + public void setCurrentProcessBuilderView( + ProcessBuilderView processbuilderView) { + this.pbView = processbuilderView; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ExecutionModulesView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ExecutionModulesView.java new file mode 100644 index 000000000..07df89af6 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ExecutionModulesView.java @@ -0,0 +1,218 @@ +package org.argeo.slc.client.ui.views; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.oxm.OxmInterface; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.controllers.ProcessController; +import org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider; +import org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider.FlowNode; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + +public class ExecutionModulesView extends ViewPart { + // private final static Log log = LogFactory + // .getLog(ExecutionModulesView.class); + + public static final String ID = "org.argeo.slc.client.ui.executionModulesView"; + + private TreeViewer viewer; + + // Ioc + private IContentProvider contentProvider; + private OxmInterface oxmBean; + private ProcessController processController; + + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(contentProvider); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + viewer.addDragSupport(operations, tt, new ViewDragListener()); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + if (obj instanceof ExecutionModulesContentProvider.ExecutionModuleNode) { + ExecutionModuleDescriptor emd = ((ExecutionModulesContentProvider.ExecutionModuleNode) obj) + .getDescriptor(); + if (emd.getLabel() != null) + return emd.getLabel(); + else + return getText(emd); + } else + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return getImage(obj); + } + + public Image getImage(Object obj) { + if (obj instanceof ExecutionModulesContentProvider.AgentNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("agent"); + else if (obj instanceof ExecutionModulesContentProvider.ExecutionModuleNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("executionModule"); + else if (obj instanceof ExecutionModulesContentProvider.FolderNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("folder"); + else if (obj instanceof ExecutionModulesContentProvider.FlowNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("flow"); + else + return PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_OBJ_ELEMENT); + } + } + + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + if (obj instanceof ExecutionModulesContentProvider.FlowNode) { + ExecutionModulesContentProvider.FlowNode fn = (ExecutionModulesContentProvider.FlowNode) obj; + + List realizedFlows = new ArrayList(); + RealizedFlow realizedFlow = new RealizedFlow(); + realizedFlow.setModuleName(fn.getExecutionModuleNode() + .getDescriptor().getName()); + realizedFlow.setModuleVersion(fn.getExecutionModuleNode() + .getDescriptor().getVersion()); + realizedFlow.setFlowDescriptor(fn.getExecutionModuleNode() + .getFlowDescriptors().get(fn.getFlowName())); + realizedFlows.add(realizedFlow); + + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + slcExecution.setRealizedFlows(realizedFlows); + slcExecution.setHost(fn.getExecutionModuleNode().getAgentNode() + .getAgent().toString()); + processController.execute(fn.getExecutionModuleNode() + .getAgentNode().getAgent(), slcExecution); + } + } + + } + + class ViewDragListener implements DragSourceListener { + + public void dragStart(DragSourceEvent event) { + System.out.println("Start Drag"); + } + + public void dragSetData(DragSourceEvent event) { + System.out.println("dragSetData: " + event); + // System.out.println("dataType: " + event.dataType); + + IStructuredSelection selection = (IStructuredSelection) viewer + .getSelection(); + if (selection.getFirstElement() instanceof ExecutionModulesContentProvider.FlowNode) { + + if (TextTransfer.getInstance().isSupportedType(event.dataType)) { + ExecutionModulesContentProvider.FlowNode flowNode = (ExecutionModulesContentProvider.FlowNode) selection + .getFirstElement(); + + Properties props = new Properties(); + flowNodeAsProperties(props, flowNode); + props.setProperty("agentId", flowNode + .getExecutionModuleNode().getAgentNode().getAgent() + .getAgentUuid()); + props.setProperty("host", flowNode.getExecutionModuleNode().getAgentNode() + .getAgent().toString()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + props.store(out, ""); + event.data = new String(out.toByteArray()); + } catch (IOException e) { + throw new SlcException( + "Cannot transform realized flow", e); + } finally { + IOUtils.closeQuietly(out); + } + } + } + } + + public void dragFinished(DragSourceEvent event) { + System.out.println("Finished Drag"); + } + + protected void flowNodeAsProperties(Properties props, FlowNode fn) { + + RealizedFlow realizedFlow = new RealizedFlow(); + realizedFlow.setModuleName(fn.getExecutionModuleNode() + .getDescriptor().getName()); + realizedFlow.setModuleVersion(fn.getExecutionModuleNode() + .getDescriptor().getVersion()); + realizedFlow.setFlowDescriptor(fn.getExecutionFlowDescriptor()); + + // As we want to have the effective ExecutionSpec and not a + // reference; we store it at the RealizeFlow level : thus the + // marshaller will store the object and not only a reference. + realizedFlow.setExecutionSpec(fn.getExecutionFlowDescriptor() + .getExecutionSpec()); + + props.setProperty("RealizedFlowAsXml", + oxmBean.marshal(realizedFlow)); + System.out + .println(oxmBean.marshal(fn.getExecutionFlowDescriptor())); + + } + + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setProcessController(ProcessController processController) { + this.processController = processController; + } + + public void setOxmBean(OxmInterface oxmBean) { + this.oxmBean = oxmBean; + } + +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessBuilderView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessBuilderView.java new file mode 100644 index 000000000..5d62983f9 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessBuilderView.java @@ -0,0 +1,316 @@ +package org.argeo.slc.client.ui.views; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.oxm.OxmInterface; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.controllers.ProcessController; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcAgent; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; + +/** + * Display a list of processes that are to be launched as batch. For the moment + * being, only one agent by batch is enabled. The batch is contructed by + * dropping process from the ExecutionModuleView. Wrong type of data dropped in + * this view might raise errors. + * + * @author bsinou + * + */ +public class ProcessBuilderView extends ViewPart { + private final static Log log = LogFactory.getLog(ProcessBuilderView.class); + + public static final String ID = "org.argeo.slc.client.ui.processBuilderView"; + private static final String EDIT_CMD = "org.argeo.slc.client.ui.editRealizedFlowDetails"; + private static final String FLOWASXML_PARAM = "org.argeo.slc.client.commands.realizedFlowAsXml"; + private static final String INDEX_PARAM = "org.argeo.slc.client.commands.realizedFlowIndex"; + + // private final static Log log = + // LogFactory.getLog(ProcessBuilderView.class); + + private TableViewer viewer; + private List realizedFlows = new ArrayList(); + private String currentAgentUuid = null; + private String host = null; + + // TODO find a better way to get index of the current selected row + // used in removeSelected + private int curSelectedRow = -1; + + // IoC + private OxmInterface oxmBean; + private ProcessController processController; + private List slcAgents; + + public void createPartControl(Composite parent) { + Table table = createTable(parent); + viewer = new TableViewer(table); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setContentProvider(new ViewContentProvider()); + viewer.addSelectionChangedListener(new SelectionChangedListener()); + + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + viewer.addDropSupport(operations, tt, new ViewDropListener(viewer)); + + viewer.setInput(getViewSite()); + } + + protected Table createTable(Composite parent) { + int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; + + Table table = new Table(parent, style); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 3; + table.setLayoutData(gridData); + + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumn column = new TableColumn(table, SWT.LEFT, 0); + column.setText("Module"); + column.setWidth(200); + + column = new TableColumn(table, SWT.LEFT, 1); + column.setText("Flow"); + column.setWidth(200); + + return table; + } + + protected void execute() { + // TODO: use agent proxy to retrieve it + SlcAgent agent = null; + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + slcExecution.setRealizedFlows(realizedFlows); + processController.execute(agent, slcExecution); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + // update one of the parameter of a given RealizedFlow + public void updateParameter(int realizedFlowIndex, String paramName, + Object value) { + RealizedFlow curRealizedFlow = realizedFlows.get(realizedFlowIndex); + curRealizedFlow.getFlowDescriptor().getValues().put(paramName, value); + } + + // clear the realizedFlow + public void clearBatch() { + // we clear the list + realizedFlows = new ArrayList(); + curSelectedRow = -1; + refreshParameterview(); + viewer.refresh(); + } + + // Remove the selected process from the batch + public void removeSelected() { + if (curSelectedRow == -1) + return; + else + realizedFlows.remove(curSelectedRow); + curSelectedRow = -1; + refreshParameterview(); + viewer.refresh(); + } + + // calling this method with index =-1 will cause the reset of the view. + private void refreshParameterview() { + // We choose to directly access the view rather than going through + // commands. + ProcessParametersView ppView; + try { + ppView = (ProcessParametersView) ClientUiPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow().getActivePage() + .showView(ProcessParametersView.ID); + + if (curSelectedRow == -1) + ppView.setRealizedFlow(-1, null); + else + ppView.setRealizedFlow(curSelectedRow, + realizedFlows.get(curSelectedRow)); + } catch (PartInitException e) { + throw new SlcException( + "Cannot Retrieve ProcessParameterView to edit parameters of selected process", + e); + } + } + + // Return the list of the processes to execute. + public void launchBatch() { + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + + slcExecution.setRealizedFlows(realizedFlows); + slcExecution.setHost(host); + + // TODO : insure that the concept has been well understood & the + // specification respected + SlcAgent curAgent; + for (int i = 0; i < slcAgents.size(); i++) { + if (currentAgentUuid == null) + throw new SlcException( + "Cannot launch a batch if no agent is specified"); + if (currentAgentUuid.equals(slcAgents.get(i).getAgentUuid())) { + curAgent = slcAgents.get(i); + processController.execute(curAgent, slcExecution); + break; + } + } + } + + // Specific Providers for the current view. + protected class ViewContentProvider implements IStructuredContentProvider { + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + + public Object[] getElements(Object obj) { + return realizedFlows.toArray(); + } + } + + protected class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + RealizedFlow rf = (RealizedFlow) obj; + switch (index) { + case 0: + return rf.getModuleName(); + case 1: + return rf.getFlowDescriptor().getName(); + } + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + // Handle Events + class SelectionChangedListener implements ISelectionChangedListener { + public void selectionChanged(SelectionChangedEvent evt) { + + IStructuredSelection curSelection = (IStructuredSelection) evt + .getSelection(); + Object obj = curSelection.getFirstElement(); + + if (obj instanceof RealizedFlow) { + RealizedFlow rf = (RealizedFlow) obj; + curSelectedRow = realizedFlows.indexOf(rf); + refreshParameterview(); + } + } + } + + // Implementation of the Drop Listener + protected class ViewDropListener extends ViewerDropAdapter { + + public ViewDropListener(Viewer viewer) { + super(viewer); + } + + @Override + public boolean performDrop(Object data) { + + Properties props = new Properties(); + + // TODO : Handle wrong type of dropped data + ByteArrayInputStream in = new ByteArrayInputStream(data.toString() + .getBytes()); + try { + props.load(in); + } catch (IOException e) { + throw new SlcException("Cannot create read flow node", e); + } finally { + IOUtils.closeQuietly(in); + } + + String agentId = props.getProperty("agentId"); + if (currentAgentUuid == null) { + currentAgentUuid = agentId; + host = props.getProperty("host"); + } else if (!currentAgentUuid.equals(agentId)) { + // TODO: as for now, we can only construct batch on a single + // Agent, must be upgraded to enable batch on various agent. + throw new SlcException( + "Cannot create batch on two (or more) distinct agents", + null); + // return false; + } + + String fdXml = props.getProperty("RealizedFlowAsXml"); + if (fdXml == null) + return false; + RealizedFlow rf = (RealizedFlow) oxmBean.unmarshal(fdXml); + realizedFlows.add(rf); + curSelectedRow = realizedFlows.indexOf(rf); + refreshParameterview(); + getViewer().refresh(); + return true; + } + + @Override + public boolean validateDrop(Object target, int operation, + TransferData transferType) { + return true; + } + } + + // IoC + public void setSlcAgents(List slcAgents) { + this.slcAgents = slcAgents; + } + + public void setOxmBean(OxmInterface oxmBean) { + this.oxmBean = oxmBean; + } + + public void setProcessController(ProcessController processController) { + this.processController = processController; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessDetailView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessDetailView.java new file mode 100644 index 000000000..944207eb1 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessDetailView.java @@ -0,0 +1,96 @@ +package org.argeo.slc.client.ui.views; + +import org.argeo.slc.dao.process.SlcExecutionDao; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +/** + * Multi-instance view that enables to browse the details of a given + * SlcExecution + * + * @author bsinou + * + */ + +public class ProcessDetailView extends ViewPart { + // private final static Log log = + // LogFactory.getLog(ProcessDetailView.class); + public static final String ID = "org.argeo.slc.client.ui.processDetailView"; + + private TreeViewer viewer; + + private String uuid; + private SlcExecution se; + + // IoC + private IContentProvider contentProvider; + private SlcExecutionDao slcExecutionDao; + + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(contentProvider); + // viewer.setLabelProvider(labelProvider); + viewer.setLabelProvider(new ProcessDetailLabelProvider()); + // viewer.setInput(getViewSite()); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + public void retrieveResults() { + se = slcExecutionDao.getSlcExecution(uuid); + viewer.setInput(se); + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + // Inner Class + public class ProcessDetailLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + // log.debug(sessionFactory.getClass().toString()); + + SlcExecution se = (SlcExecution) obj; + switch (index) { + + case 0: + return getText(se.getStartDate()); + case 1: + return se.getHost(); + case 2: + return se.getUuid(); + case 3: + return se.currentStep().getType(); + } + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setSlcExecutionDao(SlcExecutionDao slcExecutionDao) { + this.slcExecutionDao = slcExecutionDao; + } +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessListView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessListView.java new file mode 100644 index 000000000..83194d603 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessListView.java @@ -0,0 +1,163 @@ +package org.argeo.slc.client.ui.views; + +import java.util.ArrayList; + +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.dao.process.SlcExecutionDao; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.part.ViewPart; + +/** + * This class display the list of all processes that have run in the + * corresponding agent. Currently, the local agent. + * + * @author bsinou + * + */ +public class ProcessListView extends ViewPart { + // private final static Log log = LogFactory.getLog(ProcessListView.class); + + public static final String ID = "org.argeo.slc.client.ui.processListView"; + + private TableViewer viewer; + + // IoC + private SlcExecutionDao slcExecutionDao; + private ITableLabelProvider tableLabelProvider; + private IStructuredContentProvider structuredContentProvider; + + public void createPartControl(Composite parent) { + Table table = createTable(parent); + viewer = new TableViewer(table); + viewer.setLabelProvider(tableLabelProvider); + viewer.setContentProvider(structuredContentProvider); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + + } + + protected Table createTable(Composite parent) { + int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; + + Table table = new Table(parent, style); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 3; + table.setLayoutData(gridData); + + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumn column = new TableColumn(table, SWT.LEFT, 0); + column.setText("Date"); + column.setWidth(200); + + column = new TableColumn(table, SWT.LEFT, 1); + column.setText("Host"); + column.setWidth(100); + + column = new TableColumn(table, SWT.LEFT, 2); + column.setText("Id"); + column.setWidth(300); + + column = new TableColumn(table, SWT.LEFT, 3); + column.setText("Status"); + column.setWidth(100); + + return table; + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public void retrieveResults() { + viewer.setInput(slcExecutionDao.listSlcExecutions()); + } + + // Handle Events + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + + if (obj instanceof SlcExecution) { + SlcExecution se = (SlcExecution) obj; + + IWorkbench iw = ClientUiPlugin.getDefault().getWorkbench(); + IHandlerService handlerService = (IHandlerService) iw + .getService(IHandlerService.class); + try { + // get the command from plugin.xml + IWorkbenchWindow window = iw.getActiveWorkbenchWindow(); + ICommandService cmdService = (ICommandService) window + .getService(ICommandService.class); + Command cmd = cmdService + .getCommand("org.argeo.slc.client.ui.displayProcessDetails"); + + ArrayList parameters = new ArrayList(); + + // get the parameter + IParameter iparam = cmd + .getParameter("org.argeo.slc.client.commands.processUuid"); + Parameterization params = new Parameterization(iparam, se + .getUuid()); // "testUUID");// + parameters.add(params); + + // build the parameterized command + ParameterizedCommand pc = new ParameterizedCommand(cmd, + parameters.toArray(new Parameterization[parameters + .size()])); + + // execute the command + handlerService = (IHandlerService) window + .getService(IHandlerService.class); + handlerService.executeCommand(pc, null); + + } catch (Exception e) { + e.printStackTrace(); + throw new SlcException("Problem while rendering result. " + + e.getMessage()); + } + } + } + } + + // IoC + public void setSlcExecutionDao(SlcExecutionDao slcExecutionDao) { + this.slcExecutionDao = slcExecutionDao; + } + + public void setTableLabelProvider(ITableLabelProvider tableLabelProvider) { + this.tableLabelProvider = tableLabelProvider; + } + + public void setStructuredContentProvider( + IStructuredContentProvider structuredContentProvider) { + this.structuredContentProvider = structuredContentProvider; + } + +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessParametersView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessParametersView.java new file mode 100644 index 000000000..b45fb9981 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessParametersView.java @@ -0,0 +1,210 @@ +package org.argeo.slc.client.ui.views; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.providers.ProcessParametersEditingSupport; +import org.argeo.slc.core.execution.PrimitiveAccessor; +import org.argeo.slc.execution.ExecutionSpecAttribute; +import org.argeo.slc.process.RealizedFlow; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** + * + * @author bsinou + * + * This view, directly linked with the ProcessBuilderView + * enables the display and editing the parameters of a given process. + * + * Note that for now we use ExecutionFlowDescriptor.values + * attribute to recall (and update ??) the various parameters. + */ +public class ProcessParametersView extends ViewPart { + private static final Log log = LogFactory + .getLog(ProcessParametersView.class); + + public static final String ID = "org.argeo.slc.client.ui.processParametersView"; + + // This map stores actual values set to default if existing at the begining + // and then the ones computed by the end user + private Map values; + // This map stores the spec of the attributes used to offer the end user + // some choices. + private Map specAttributes; + + // We must keep a reference to the current EditingSupport so that we can + // update the index of the process being updated + ProcessParametersEditingSupport ppEditingSupport; + + // view attributes + private TableViewer viewer; + + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION); + createColumns(viewer); + + // WARNING + // for the moment being, we support only one process builder at a time + // we set the corresponding view in the editor here. + ProcessBuilderView pbView = (ProcessBuilderView) ClientUiPlugin + .getDefault().getWorkbench().getActiveWorkbenchWindow() + .getActivePage().findView(ProcessBuilderView.ID); + ppEditingSupport.setCurrentProcessBuilderView(pbView); + + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setContentProvider(new ViewContentProvider()); + viewer.setInput(getViewSite()); + + } + + // This will create the columns for the table + private void createColumns(TableViewer viewer) { + + String[] titles = { "Attribute name", "value" }; + int[] bounds = { 200, 200 }; + + for (int i = 0; i < titles.length; i++) { + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setText(titles[i]); + column.getColumn().setWidth(bounds[i]); + column.getColumn().setResizable(true); + column.getColumn().setMoveable(true); + if (i == 1) { + // we create the used EditingSupport and enable editing support + // for value Column + ppEditingSupport = new ProcessParametersEditingSupport(viewer, + i); + column.setEditingSupport(ppEditingSupport); + } + } + Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + // set class attributes, refresh the lists of process paramaters to edit. + public void setRealizedFlow(int index, RealizedFlow rf) { + // force the cleaning of the view + if (index == -1) { + viewer.setInput(null); + return; + } + // we store the index of the edited Process in the editor so that it can + // save computed values. + ppEditingSupport.setCurrentProcessIndex(index); + + // TODO : + // We should handle ExecutionSpec here. need to be improved. + // ExecutionSpec es = rf.getExecutionSpec(); + // if (es != null && es.getAttributes() != null) + // parameters = es.getAttributes(); + // if (parameters != null) + // viewer.setInput(parameters); + + values = rf.getFlowDescriptor().getValues(); + specAttributes = rf.getFlowDescriptor().getExecutionSpec() + .getAttributes(); + + if (values != null) + viewer.setInput(values); + else + // No parameters to edit, we reset the view. + viewer.setInput(null); + + } + + // Inner Classes we should use ExecutionSpecAttribute instead of values + // see below + protected class ViewContentProvider implements IStructuredContentProvider { + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + + @SuppressWarnings("unchecked") + // we cast the Map to List + public Object[] getElements(Object obj) { + + if (obj instanceof Map && ((Map) obj).size() != 0) { + List list = new ArrayList(); + Map map = (Map) obj; + for (String key : map.keySet()) { + list.add(new ObjectWithName(key, map.get(key))); + } + return list.toArray(); + } else { + return new Object[0]; + } + } + } + + protected class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + + public String getColumnText(Object obj, int index) { + // NOTE : the passed object is a line of the table !!! + + if (obj instanceof ObjectWithName) { + ObjectWithName own = (ObjectWithName) obj; + switch (index) { + case 0: + return own.name; + case 1: + if (own.obj instanceof PrimitiveAccessor) { + PrimitiveAccessor pa = (PrimitiveAccessor) own.obj; + if ("string".equals(pa.getType())) + return (String) pa.getValue(); + else if ("integer".equals(pa.getType())) + return ((Integer) pa.getValue()).toString(); + else + return "Type " + pa.getType() + + " not yet supported"; + } else + return own.obj.toString(); + default: + return getText(obj); + } + } else + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + // We add an inner class to enrich the ExecutionSpecAttribute with a name + // so that we can display it. + public class ObjectWithName { + public Object obj; + public String name; + + public ObjectWithName(String name, Object obj) { + this.name = name; + this.obj = obj; + } + + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultDetailView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultDetailView.java new file mode 100644 index 000000000..6d9f90162 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultDetailView.java @@ -0,0 +1,121 @@ +package org.argeo.slc.client.ui.views; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.dao.test.tree.TreeTestResultDao; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.part.ViewPart; + +/** + * Multi-instance view that enables to browse the details of a given + * TreeTestResult + * + * @author bsinou + * + */ + +public class ResultDetailView extends ViewPart { + private final static Log log = LogFactory.getLog(ResultDetailView.class); + public static final String ID = "org.argeo.slc.client.ui.resultDetailView"; + + protected String[] columnNames = new String[] { "Test", "State", "Message", + "Id" }; + + private TreeViewer viewer; + private Tree resultDetailTree; + + private String uuid; + private TreeTestResult ttr; + + // IoC + private IContentProvider contentProvider; + private ITableLabelProvider labelProvider; + private TreeTestResultDao treeTestResultDao; + + public void createPartControl(Composite parent) { + resultDetailTree = new Tree(parent, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + resultDetailTree.setLayoutData(gd); + resultDetailTree.setLinesVisible(true); + resultDetailTree.setHeaderVisible(true); + + for (int i = 0; i < columnNames.length; i++) { + TreeColumn column = new TreeColumn(resultDetailTree, SWT.LEFT, i); + column.setText(columnNames[i]); + + // TIP: Don't forget to set the width. If not set it is set to + // 0 and it will look as if the column didn't exist. + switch (i) { + case 0: + column.setWidth(130); + case 1: + column.setWidth(200); + default: + column.setWidth(70); + } + } + viewer = new TreeViewer(resultDetailTree); + viewer.setColumnProperties(columnNames); + + viewer.setContentProvider(contentProvider); + // viewer.setLabelProvider(new ResultDetailLabelProvider()); + log.debug("Injected LabelProvider :" + labelProvider.toString()); + + // TIP: It seems, that if the table has not defined any TreeColumns then + // a plain LabelProvider will be used. Since, we don't provide an + // instance of LabelProvider, a default one will be used and + // the TableLableProvider is ignored without notice. Took me quite + // a while to find that one out. + viewer.setLabelProvider(labelProvider); + log.debug("Persisted labelProvider :" + + viewer.getLabelProvider().toString()); + // viewer.setInput(getViewSite()); + + // viewer.expandAll(); + + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + public void retrieveResults() { + ttr = treeTestResultDao.getTestResult(uuid); + viewer.setInput(ttr); + // viewer.setInput(getViewSite()); + + // setFocus(); + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setLabelProvider(ITableLabelProvider labelProvider) { + this.labelProvider = labelProvider; + } + + public void setTreeTestResultDao(TreeTestResultDao treeTestResultDao) { + this.treeTestResultDao = treeTestResultDao; + } + +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultListView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultListView.java new file mode 100644 index 000000000..c61f8de34 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultListView.java @@ -0,0 +1,198 @@ +package org.argeo.slc.client.ui.views; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.core.test.tree.ResultAttributes; +import org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.part.ViewPart; + +public class ResultListView extends ViewPart { + private final static Log log = LogFactory.getLog(ResultListView.class); + + public static final String ID = "org.argeo.slc.client.ui.resultListView"; + + private TableViewer viewer; + + private TreeTestResultCollectionDao testResultCollectionDao; + + public void createPartControl(Composite parent) { + Table table = createTable(parent); + viewer = new TableViewer(table); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setContentProvider(new ViewContentProvider()); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + } + + protected Table createTable(Composite parent) { + int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; + + Table table = new Table(parent, style); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 3; + table.setLayoutData(gridData); + + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumn column = new TableColumn(table, SWT.LEFT, 0); + column.setText("Date"); + column.setWidth(200); + + column = new TableColumn(table, SWT.LEFT, 1); + column.setText("UUID"); + column.setWidth(300); + + return table; + } + + // View Specific inner class + protected static class ViewContentProvider implements + IStructuredContentProvider { + + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + + @SuppressWarnings("unchecked") + public Object[] getElements(Object obj) { + if (obj instanceof List) { + return ((List) obj).toArray(); + } else { + return new Object[0]; + } + } + } + + protected class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + ResultAttributes ra = (ResultAttributes) obj; + switch (index) { + case 0: + return getText(ra.getCloseDate()); + case 1: + return ra.getUuid(); + } + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public void retrieveResults() { + try { + List lst = testResultCollectionDao + .listResultAttributes(null); + if (log.isTraceEnabled()) + log.trace("Result attributes count: " + lst.size()); + viewer.setInput(lst); + // viewer.refresh(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + // Handle Events + /** + * The ResultAttributes expose a part of the information contained in the + * TreeTestResult, It has the same UUID as the corresponding treeTestResult. + */ + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + + if (obj instanceof ResultAttributes) { + ResultAttributes ra = (ResultAttributes) obj; + log.debug("Double-clic on result with UUID" + ra.getUuid()); + + IWorkbench iw = ClientUiPlugin.getDefault().getWorkbench(); + IHandlerService handlerService = (IHandlerService) iw + .getService(IHandlerService.class); + try { + // get the command from plugin.xml + IWorkbenchWindow window = iw.getActiveWorkbenchWindow(); + ICommandService cmdService = (ICommandService) window + .getService(ICommandService.class); + Command cmd = cmdService + .getCommand("org.argeo.slc.client.ui.displayResultDetails"); + + // log.debug("cmd : " + cmd); + ArrayList parameters = new ArrayList(); + + // get the parameter + IParameter iparam = cmd + .getParameter("org.argeo.slc.client.commands.resultUuid"); + + Parameterization params = new Parameterization(iparam, + ra.getUuid()); + parameters.add(params); + + // build the parameterized command + ParameterizedCommand pc = new ParameterizedCommand(cmd, + parameters.toArray(new Parameterization[parameters + .size()])); + + // execute the command + handlerService = (IHandlerService) window + .getService(IHandlerService.class); + handlerService.executeCommand(pc, null); + + } catch (Exception e) { + e.printStackTrace(); + throw new SlcException("Problem while rendering result. " + + e.getMessage()); + } + } + } + } + + // Ioc + public void setTestResultCollectionDao( + TreeTestResultCollectionDao testResultCollectionDao) { + this.testResultCollectionDao = testResultCollectionDao; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/ClientUiPlugin.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/ClientUiPlugin.java new file mode 100644 index 000000000..7148f0f54 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/ClientUiPlugin.java @@ -0,0 +1,88 @@ +package org.argeo.slc.client.ui; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class ClientUiPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.argeo.slc.client.ui"; + + // The shared instance + private static ClientUiPlugin plugin; + + private BundleContext bundleContext; + + /** + * The constructor + */ + public ClientUiPlugin() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + this.bundleContext = context; + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static ClientUiPlugin getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given plug-in + * relative path + * + * @param path + * the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } + + @Override + protected void initializeImageRegistry(ImageRegistry reg) { + reg.put("agent", getImageDescriptor("icons/computer.png")); + reg.put("executionModule", getImageDescriptor("icons/archive.png")); + reg.put("folder", getImageDescriptor("icons/folder.png")); + reg.put("flow", getImageDescriptor("icons/system.png")); + reg.put("processes", getImageDescriptor("icons/processes.gif")); + reg.put("passedTest", getImageDescriptor("icons/passed.gif")); + reg.put("failedTest", getImageDescriptor("icons/error.gif")); + } + + public BundleContext getBundleContext() { + return bundleContext; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ClearBatchHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ClearBatchHandler.java new file mode 100644 index 000000000..eb6809c1f --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ClearBatchHandler.java @@ -0,0 +1,30 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author bsinou + * + * Remove all processes from the batch built in the ProcessBuilderView + * + * NOTE : only one batch is supported with this command, if more than + * one batch is planned, this class must be updated with parameter. + */ +public class ClearBatchHandler extends AbstractHandler { + // private final static Log log = + // LogFactory.getLog(ClearBatchHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessBuilderView pbView = (ProcessBuilderView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessBuilderView.ID); + pbView.clearBatch(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java new file mode 100644 index 000000000..e770c34b0 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java @@ -0,0 +1,30 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author bsinou + * + * Launch the batch built in the ProcessBuilderView + * + * NOTE : only one batch is supported with this command, if more than + * one batch is planned, this class must be updated with parameter. + */ +public class LaunchBatchHandler extends AbstractHandler { + // private final static Log log = + // LogFactory.getLog(LaunchBatchHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessBuilderView pbView = (ProcessBuilderView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessBuilderView.ID); + pbView.launchBatch(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java new file mode 100644 index 000000000..cdc28812b --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java @@ -0,0 +1,43 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessDetailView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Command handler to set visible or create a ProcessDetailView. UUID of the + * process is passed via command parameters. + * + * @author bsinou + * + */ + +public class ProcessDetailsDisplayHandler extends AbstractHandler { + // private static final Log log = LogFactory + // .getLog(ProcessDetailsDisplayHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + + // We pass the UUID of the process we want to display via command + // parameters. + String uuid = event + .getParameter("org.argeo.slc.client.commands.processUuid"); + + // mode = 1 : VIEW_ACTIVATE, Show view mode that indicates the view + // should be made visible and activated. Use of this mode has the same + // effect as calling showView. + try { + ProcessDetailView pView = (ProcessDetailView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .showView(ProcessDetailView.ID, "UUID-" + uuid, 1); + pView.setUuid(uuid); + pView.retrieveResults(); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java new file mode 100644 index 000000000..47f9d0041 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java @@ -0,0 +1,19 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessListView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ProcessListViewRefreshHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessListView pView = (ProcessListView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessListView.ID); + pView.retrieveResults(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java new file mode 100644 index 000000000..12e8de0ff --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java @@ -0,0 +1,31 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * + * @author bsinou + * + * Launch the batch built in the ProcessBuilderView + * + * NOTE : only one batch is supported with this command, if more than + * one batch is planned, this class must be updated with parameter. + */ + +public class RemoveSelectedProcessFromBatchHandler extends AbstractHandler { + // private final static Log log = + // LogFactory.getLog(RemoveSelectedProcessFromBatchHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + ProcessBuilderView pbView = (ProcessBuilderView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ProcessBuilderView.ID); + pbView.removeSelected(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java new file mode 100644 index 000000000..98c502f3e --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java @@ -0,0 +1,44 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ResultDetailView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Command handler to set visible or create a ResultDetailView. UUID of the + * testResult is passed via command parameters. + * + * @author bsinou + * + */ + +public class ResultDetailsDisplayHandler extends AbstractHandler { + // private static final Log log = LogFactory + // .getLog(ResultDetailsDisplayHandler.class); + + public Object execute(ExecutionEvent event) throws ExecutionException { + + // We pass the UUID of the test result we want to display via command + // parameters. + String uuid = event + .getParameter("org.argeo.slc.client.commands.resultUuid"); + + // mode = 2 : VIEW_VISIBLE, Show view mode that indicates the view + // should be created or made visible if already created . + // mode = 1 : VIEW_ACTIVATE, Show view mode that indicates the view + // should be made visible and activated. Use of this mode has the same + // effect as calling + try { + ResultDetailView rView = (ResultDetailView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .showView(ResultDetailView.ID, "UUID-" + uuid, 1); + rView.setUuid(uuid); + rView.retrieveResults(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java new file mode 100644 index 000000000..23fa87916 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java @@ -0,0 +1,19 @@ +package org.argeo.slc.client.ui.commands; + +import org.argeo.slc.client.ui.views.ResultListView; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ResultListViewRefreshHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + ResultListView view = (ResultListView) HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage() + .findView(ResultListView.ID); + view.retrieveResults(); + return null; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/controllers/ProcessController.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/controllers/ProcessController.java new file mode 100644 index 000000000..5785305ab --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/controllers/ProcessController.java @@ -0,0 +1,19 @@ +package org.argeo.slc.client.ui.controllers; + +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcAgent; +import org.argeo.slc.services.SlcExecutionService; + +public class ProcessController { + private SlcExecutionService slcExecutionService; + + public void execute(SlcAgent agent, SlcExecution slcExecution) { + slcExecutionService.newExecution(slcExecution); + agent.runSlcExecution(slcExecution); + } + + public void setSlcExecutionService(SlcExecutionService slcExecutionService) { + this.slcExecutionService = slcExecutionService; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java new file mode 100644 index 000000000..499559833 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java @@ -0,0 +1,105 @@ +package org.argeo.slc.client.ui.listeners; + +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.core.attachment.Attachment; +import org.argeo.slc.core.attachment.SimpleAttachment; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.core.test.tree.TreeTestResultListener; +import org.argeo.slc.msg.test.tree.AddTreeTestResultAttachmentRequest; +import org.argeo.slc.msg.test.tree.CloseTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.CreateTreeTestResultRequest; +import org.argeo.slc.msg.test.tree.ResultPartRequest; +import org.argeo.slc.services.TestManagerService; +import org.argeo.slc.test.TestResultPart; +import org.eclipse.ui.handlers.IHandlerService; + +/** In memory access to a test manager service */ +public class TestManagerServiceAdapter implements TreeTestResultListener { + // private static final Log log = LogFactory + // .getLog(TestManagerServiceAdapter.class); + + private Boolean onlyOnClose = false; + + private TestManagerService testManagerService; + + public void resultPartAdded(TreeTestResult testResult, + TestResultPart testResultPart) { + if (onlyOnClose) + return; + + if (testResult.getResultParts().size() == 1 + && testResult.getResultParts().values().iterator().next() + .getParts().size() == 1) { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + testResult); + testManagerService.createTreeTestResult(req); + } else { + ResultPartRequest req = new ResultPartRequest(testResult); + testManagerService.addResultPart(req); + } + } + + public void close(TreeTestResult testResult) { + + if (onlyOnClose) { + CreateTreeTestResultRequest req = new CreateTreeTestResultRequest( + testResult); + testManagerService.createTreeTestResult(req); + } else { + CloseTreeTestResultRequest req = new CloseTreeTestResultRequest( + testResult); + testManagerService.closeTreeTestResult(req); + } + + // TODO : clean this -> pb of thread && commandID hardCoded. + // We force the refresh of the list view. + ClientUiPlugin.getDefault().getWorkbench().getDisplay() + .syncExec(new Runnable() { + public void run() { + IHandlerService handlerService = (IHandlerService) ClientUiPlugin + .getDefault().getWorkbench() + .getService(IHandlerService.class); + try { + handlerService + .executeCommand( + "org.argeo.slc.client.ui.refreshResultList", + null); + handlerService + .executeCommand( + "org.argeo.slc.client.ui.refreshProcessList", + null); + + } catch (Exception e) { + e.printStackTrace(); + throw new SlcException( + "Problem while rendering result. " + + e.getMessage()); + } + } + } + + ); + + } + + public void addAttachment(TreeTestResult testResult, Attachment attachment) { + if (onlyOnClose) + return; + AddTreeTestResultAttachmentRequest req = new AddTreeTestResultAttachmentRequest(); + req.setResultUuid(testResult.getUuid()); + req.setAttachment((SimpleAttachment) attachment); + testManagerService.addAttachment(req); + + } + + /** Publishes the test result only when it gets closed. */ + public void setOnlyOnClose(Boolean onlyOnClose) { + this.onlyOnClose = onlyOnClose; + } + + public void setTestManagerService(TestManagerService testManagerService) { + this.testManagerService = testManagerService; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/perspectives/SlcExecution.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/perspectives/SlcExecution.java new file mode 100644 index 000000000..f50ea1814 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/perspectives/SlcExecution.java @@ -0,0 +1,44 @@ +package org.argeo.slc.client.ui.perspectives; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class SlcExecution implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + layout.setFixed(false); + + // Create the main ui layout + + // For a vertical split, the part on top gets the specified ratio of the + // current space and the part on bottom gets the rest. Likewise, for a + // horizontal split, the part at left gets the specified ratio of the + // current space. + IFolderLayout main = layout.createFolder("main", IPageLayout.RIGHT, + 0.3f, editorArea); + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.3f, editorArea); + + IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.65f, "main"); + + IFolderLayout topRight = layout.createFolder("topRight", + IPageLayout.RIGHT, 0.6f, "main"); + + // add the views to the corresponding place holder + left.addView("org.argeo.slc.client.ui.executionModulesView"); + left.addView("org.argeo.slc.client.ui.resultListView"); + + main.addView("org.argeo.slc.client.ui.processBuilderView"); + main.addPlaceholder("org.argeo.slc.client.ui.resultDetailView:UUID-*"); + main.addPlaceholder("org.argeo.slc.client.ui.processDetailView:UUID-*"); + + bottom.addView("org.argeo.slc.client.ui.processListView"); + + topRight.addView("org.argeo.slc.client.ui.processParametersView"); + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java new file mode 100644 index 000000000..1278609bd --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java @@ -0,0 +1,261 @@ +package org.argeo.slc.client.ui.providers; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.eclipse.ui.TreeObject; +import org.argeo.eclipse.ui.TreeParent; +import org.argeo.slc.execution.ExecutionFlowDescriptor; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.runtime.SlcAgent; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class ExecutionModulesContentProvider implements ITreeContentProvider { + private final static Log log = LogFactory + .getLog(ExecutionModulesContentProvider.class); + + // IoC + private List slcAgents; + + public Object[] getChildren(Object parent) { + if (parent instanceof ExecutionModuleNode) { + ExecutionModuleNode executionModuleNode = (ExecutionModuleNode) parent; + ExecutionModuleDescriptor emd = executionModuleNode.getDescriptor(); + + // Terminate the building of UI specific object emd + emd = executionModuleNode + .getAgentNode() + .getAgent() + .getExecutionModuleDescriptor(emd.getName(), + emd.getVersion()); + executionModuleNode.cacheDescriptor(emd); + + // This is not recursive, e.g. ExecutionModuleNode build a Tree of + // specific + // treeObject and cache it in the cacheDescriptor. + // Then we only have TreeObjects + return executionModuleNode.getChildren(); + } else if (parent instanceof AgentNode) { + AgentNode agentNode = (AgentNode) parent; + + if (log.isTraceEnabled()) + log.trace("Scan agent " + agentNode); + + agentNode.clearChildren(); + for (ExecutionModuleDescriptor desc : agentNode.getAgent() + .listExecutionModuleDescriptors()) { + agentNode.addChild(new ExecutionModuleNode(agentNode, desc)); + } + + return agentNode.getChildren(); + } else if (parent instanceof TreeParent) { + return ((TreeParent) parent).getChildren(); + } else if (parent instanceof FlowNode) { + return new Object[0]; + } else { + List agentNodes = new ArrayList(); + for (SlcAgent slcAgent : slcAgents) { + agentNodes.add(new AgentNode(slcAgent)); + } + return agentNodes.toArray(); + } + } + + public Object getParent(Object node) { + // if (node instanceof TreeObject) { + // return ((TreeObject) node).getParent(); + // } + return null; + } + + public boolean hasChildren(Object parent) { + if (parent instanceof TreeParent && ((TreeParent) parent).isLoaded()) { + return ((TreeParent) parent).hasChildren(); + } else if (parent instanceof AgentNode) { + return true; + } else if (parent instanceof ExecutionModuleNode) { + return true; + } + return false; + } + + public void inputChanged(Viewer v, Object oldInput, Object newInput) { + } + + public void dispose() { + } + + public Object[] getElements(Object parent) { + return getChildren(parent); + } + + + + public class AgentNode extends TreeParent { + private final SlcAgent agent; + + public AgentNode(SlcAgent agent) { + super(agent.toString()); + this.agent = agent; + } + + public SlcAgent getAgent() { + return agent; + } + } + + public class ExecutionModuleNode extends TreeParent { + private final AgentNode agentNode; + private ExecutionModuleDescriptor descriptor; + private Map flowDescriptors; + + public ExecutionModuleNode(AgentNode agentNode, + ExecutionModuleDescriptor descriptor) { + super(descriptor.toString()); + this.agentNode = agentNode; + this.descriptor = descriptor; + + } + + public AgentNode getAgentNode() { + return agentNode; + } + + public ExecutionModuleDescriptor getDescriptor() { + return descriptor; + } + + public void cacheDescriptor(ExecutionModuleDescriptor descriptor) { + this.descriptor = descriptor; + + SortedMap folderNodes = new TreeMap(); + flowDescriptors = new HashMap(); + + for (ExecutionFlowDescriptor fd : descriptor.getExecutionFlows()) { + // Find, format and store path and label values for each flow + // descritor: + + // we format name of type path="" & name="path/toTest/Test" to : + // path="path/toTest/" name="Test" + String path; + String label; + int lastSlash = fd.getName().lastIndexOf('/'); + if ((fd.getPath() == null || fd.getPath().trim().equals("")) + && lastSlash >= 0) { + path = fd.getName().substring(0, lastSlash); + label = fd.getName().substring(lastSlash + 1); + } else { + path = fd.getPath(); + label = fd.getName(); + } + + if (path == null || path.trim().equals("") + || path.trim().equals("/")) { + // directChildren.put(name, new FlowNode(name, this)); + addChild(new FlowNode(label, fd.getName(), fd, this)); + } else { + FolderNode folderNode = mkdirs(this, path, folderNodes); + folderNode.addChild(new FlowNode(label, fd.getName(), fd, + this)); + } + + flowDescriptors.put(fd.getName(), fd); + } + // TODO: make it readonly + } + + protected FolderNode mkdirs(TreeParent root, String path, + SortedMap folderNodes) { + // Normalize + if (path.charAt(0) != '/') + path = '/' + path; + if (path.charAt(path.length() - 1) == '/') + path = path.substring(0, path.length() - 1); + + if (folderNodes.containsKey(path)) + return folderNodes.get(path); + + int lastIndx = path.lastIndexOf('/'); + String folderName; + String parentPath; + if (lastIndx >= 0) { + folderName = path.substring(lastIndx + 1); + parentPath = path.substring(0, lastIndx); + } else { + folderName = path; + parentPath = ""; + } + + TreeParent parent; + if (parentPath.equals("")) + parent = root; + else + parent = mkdirs(root, parentPath, folderNodes); + FolderNode newFolder = new FolderNode(folderName); + parent.addChild(newFolder); + folderNodes.put(path, newFolder); + return newFolder; + } + + public Map getFlowDescriptors() { + return flowDescriptors; + } + + } + + /** + * + * @author bsinou + * + * The implementation of a vernice of a given slc process. Note that + * we store the parent node (execution module node) & the + * ExecutionFlowDescriptor. + */ + public class FlowNode extends TreeObject { + + private final String flowName; + private final ExecutionModuleNode executionModuleNode; + private final ExecutionFlowDescriptor executionFlowDescriptor; + + public FlowNode(String label, String flowName, + ExecutionFlowDescriptor executionFlowDescriptor, + ExecutionModuleNode parent) { + super(label); + this.flowName = flowName; + this.executionFlowDescriptor = executionFlowDescriptor; + this.executionModuleNode = parent; + } + + public String getFlowName() { + return flowName; + } + + public ExecutionModuleNode getExecutionModuleNode() { + return executionModuleNode; + } + + public ExecutionFlowDescriptor getExecutionFlowDescriptor() { + return executionFlowDescriptor; + } + + } + + public class FolderNode extends TreeParent { + public FolderNode(String name) { + super(name); + } + + } + + // IoC + public void setSlcAgents(List slcAgents) { + this.slcAgents = slcAgents; + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java new file mode 100644 index 000000000..7ca534e0f --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java @@ -0,0 +1,118 @@ +package org.argeo.slc.client.ui.providers; + +import org.argeo.slc.client.ui.views.ProcessBuilderView; +import org.argeo.slc.client.ui.views.ProcessParametersView; +import org.argeo.slc.core.execution.PrimitiveAccessor; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; + +/** + * + * + * Implements the ability to edit and save various type of + * parameter of a given process. Parameter values are directly saved as + * soon as the focus on a given field is lost. + * + * + * Note that EditingSupport is tightly coupled with both + * ProcessParametersView and ProcessBuilderView; it cannot serve as a + * generic EditingSupport as is. Note also that it assumes that the + * processes in ProcessBuilderView as stored as an ordered list. + + @author bsinou + * + */ + +public class ProcessParametersEditingSupport extends EditingSupport { + + // private final static Log log = LogFactory + // .getLog(ProcessParametersEditingSupport.class); + + private CellEditor strEditor; + private CellEditor nbEditor; + // private int column; + + private final static String strType = "string", intType = "integer"; + + // different type of primitive + private static enum primitiveType { + strType, intType + }; + + // So that we can update corresponding process + private int curProcessIndex; + private ProcessBuilderView pbView; + + public ProcessParametersEditingSupport(ColumnViewer viewer, int column) { + super(viewer); + strEditor = new TextCellEditor(((TableViewer) viewer).getTable()); + // nbEditor = new NumberCellEditor(((TableViewer) viewer).getTable()); + // this.column = column; + } + + @Override + protected CellEditor getCellEditor(Object element) { + // TODO return specific editor depending on the parameter type. + return strEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + ProcessParametersView.ObjectWithName objectWithName = (ProcessParametersView.ObjectWithName) element; + + if (objectWithName.obj instanceof PrimitiveAccessor) { + PrimitiveAccessor pv = (PrimitiveAccessor) objectWithName.obj; + // we only handle string & integer parameter in a first time + if (strType.equals(pv.getType())) { + return pv.getValue(); + } + if (intType.equals(pv.getType())) { + return ((Integer) pv.getValue()).toString(); + } + } + return "unsupported param type"; + + } + + @Override + protected void setValue(Object element, Object value) { + ProcessParametersView.ObjectWithName objectWithName = (ProcessParametersView.ObjectWithName) element; + if (objectWithName.obj instanceof PrimitiveAccessor) { + PrimitiveAccessor pv = (PrimitiveAccessor) objectWithName.obj; + // we only handle string parameter in a first time + if (strType.equals(pv.getType())) { + pv.setValue(value); + pbView.updateParameter(curProcessIndex, objectWithName.name, + objectWithName.obj); + } else if (intType.equals(pv.getType())) { + + String stVal = (String) value; + Integer val = ("".equals(stVal)) ? new Integer(0) + : new Integer(stVal); + pv.setValue(val); + pbView.updateParameter(curProcessIndex, objectWithName.name, pv); + } + getViewer().update(element, null); + } + + } + + // Store the index of the process which parameters are being edited + public void setCurrentProcessIndex(int index) { + this.curProcessIndex = index; + } + + public void setCurrentProcessBuilderView( + ProcessBuilderView processbuilderView) { + this.pbView = processbuilderView; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ExecutionModulesView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ExecutionModulesView.java new file mode 100644 index 000000000..07df89af6 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ExecutionModulesView.java @@ -0,0 +1,218 @@ +package org.argeo.slc.client.ui.views; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.oxm.OxmInterface; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.controllers.ProcessController; +import org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider; +import org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider.FlowNode; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.ViewPart; + +public class ExecutionModulesView extends ViewPart { + // private final static Log log = LogFactory + // .getLog(ExecutionModulesView.class); + + public static final String ID = "org.argeo.slc.client.ui.executionModulesView"; + + private TreeViewer viewer; + + // Ioc + private IContentProvider contentProvider; + private OxmInterface oxmBean; + private ProcessController processController; + + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(contentProvider); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + viewer.addDragSupport(operations, tt, new ViewDragListener()); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + if (obj instanceof ExecutionModulesContentProvider.ExecutionModuleNode) { + ExecutionModuleDescriptor emd = ((ExecutionModulesContentProvider.ExecutionModuleNode) obj) + .getDescriptor(); + if (emd.getLabel() != null) + return emd.getLabel(); + else + return getText(emd); + } else + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return getImage(obj); + } + + public Image getImage(Object obj) { + if (obj instanceof ExecutionModulesContentProvider.AgentNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("agent"); + else if (obj instanceof ExecutionModulesContentProvider.ExecutionModuleNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("executionModule"); + else if (obj instanceof ExecutionModulesContentProvider.FolderNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("folder"); + else if (obj instanceof ExecutionModulesContentProvider.FlowNode) + return ClientUiPlugin.getDefault().getImageRegistry() + .get("flow"); + else + return PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_OBJ_ELEMENT); + } + } + + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + if (obj instanceof ExecutionModulesContentProvider.FlowNode) { + ExecutionModulesContentProvider.FlowNode fn = (ExecutionModulesContentProvider.FlowNode) obj; + + List realizedFlows = new ArrayList(); + RealizedFlow realizedFlow = new RealizedFlow(); + realizedFlow.setModuleName(fn.getExecutionModuleNode() + .getDescriptor().getName()); + realizedFlow.setModuleVersion(fn.getExecutionModuleNode() + .getDescriptor().getVersion()); + realizedFlow.setFlowDescriptor(fn.getExecutionModuleNode() + .getFlowDescriptors().get(fn.getFlowName())); + realizedFlows.add(realizedFlow); + + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + slcExecution.setRealizedFlows(realizedFlows); + slcExecution.setHost(fn.getExecutionModuleNode().getAgentNode() + .getAgent().toString()); + processController.execute(fn.getExecutionModuleNode() + .getAgentNode().getAgent(), slcExecution); + } + } + + } + + class ViewDragListener implements DragSourceListener { + + public void dragStart(DragSourceEvent event) { + System.out.println("Start Drag"); + } + + public void dragSetData(DragSourceEvent event) { + System.out.println("dragSetData: " + event); + // System.out.println("dataType: " + event.dataType); + + IStructuredSelection selection = (IStructuredSelection) viewer + .getSelection(); + if (selection.getFirstElement() instanceof ExecutionModulesContentProvider.FlowNode) { + + if (TextTransfer.getInstance().isSupportedType(event.dataType)) { + ExecutionModulesContentProvider.FlowNode flowNode = (ExecutionModulesContentProvider.FlowNode) selection + .getFirstElement(); + + Properties props = new Properties(); + flowNodeAsProperties(props, flowNode); + props.setProperty("agentId", flowNode + .getExecutionModuleNode().getAgentNode().getAgent() + .getAgentUuid()); + props.setProperty("host", flowNode.getExecutionModuleNode().getAgentNode() + .getAgent().toString()); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + props.store(out, ""); + event.data = new String(out.toByteArray()); + } catch (IOException e) { + throw new SlcException( + "Cannot transform realized flow", e); + } finally { + IOUtils.closeQuietly(out); + } + } + } + } + + public void dragFinished(DragSourceEvent event) { + System.out.println("Finished Drag"); + } + + protected void flowNodeAsProperties(Properties props, FlowNode fn) { + + RealizedFlow realizedFlow = new RealizedFlow(); + realizedFlow.setModuleName(fn.getExecutionModuleNode() + .getDescriptor().getName()); + realizedFlow.setModuleVersion(fn.getExecutionModuleNode() + .getDescriptor().getVersion()); + realizedFlow.setFlowDescriptor(fn.getExecutionFlowDescriptor()); + + // As we want to have the effective ExecutionSpec and not a + // reference; we store it at the RealizeFlow level : thus the + // marshaller will store the object and not only a reference. + realizedFlow.setExecutionSpec(fn.getExecutionFlowDescriptor() + .getExecutionSpec()); + + props.setProperty("RealizedFlowAsXml", + oxmBean.marshal(realizedFlow)); + System.out + .println(oxmBean.marshal(fn.getExecutionFlowDescriptor())); + + } + + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setProcessController(ProcessController processController) { + this.processController = processController; + } + + public void setOxmBean(OxmInterface oxmBean) { + this.oxmBean = oxmBean; + } + +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessBuilderView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessBuilderView.java new file mode 100644 index 000000000..5d62983f9 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessBuilderView.java @@ -0,0 +1,316 @@ +package org.argeo.slc.client.ui.views; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.oxm.OxmInterface; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.controllers.ProcessController; +import org.argeo.slc.process.RealizedFlow; +import org.argeo.slc.process.SlcExecution; +import org.argeo.slc.runtime.SlcAgent; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; + +/** + * Display a list of processes that are to be launched as batch. For the moment + * being, only one agent by batch is enabled. The batch is contructed by + * dropping process from the ExecutionModuleView. Wrong type of data dropped in + * this view might raise errors. + * + * @author bsinou + * + */ +public class ProcessBuilderView extends ViewPart { + private final static Log log = LogFactory.getLog(ProcessBuilderView.class); + + public static final String ID = "org.argeo.slc.client.ui.processBuilderView"; + private static final String EDIT_CMD = "org.argeo.slc.client.ui.editRealizedFlowDetails"; + private static final String FLOWASXML_PARAM = "org.argeo.slc.client.commands.realizedFlowAsXml"; + private static final String INDEX_PARAM = "org.argeo.slc.client.commands.realizedFlowIndex"; + + // private final static Log log = + // LogFactory.getLog(ProcessBuilderView.class); + + private TableViewer viewer; + private List realizedFlows = new ArrayList(); + private String currentAgentUuid = null; + private String host = null; + + // TODO find a better way to get index of the current selected row + // used in removeSelected + private int curSelectedRow = -1; + + // IoC + private OxmInterface oxmBean; + private ProcessController processController; + private List slcAgents; + + public void createPartControl(Composite parent) { + Table table = createTable(parent); + viewer = new TableViewer(table); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setContentProvider(new ViewContentProvider()); + viewer.addSelectionChangedListener(new SelectionChangedListener()); + + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] tt = new Transfer[] { TextTransfer.getInstance() }; + viewer.addDropSupport(operations, tt, new ViewDropListener(viewer)); + + viewer.setInput(getViewSite()); + } + + protected Table createTable(Composite parent) { + int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; + + Table table = new Table(parent, style); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 3; + table.setLayoutData(gridData); + + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumn column = new TableColumn(table, SWT.LEFT, 0); + column.setText("Module"); + column.setWidth(200); + + column = new TableColumn(table, SWT.LEFT, 1); + column.setText("Flow"); + column.setWidth(200); + + return table; + } + + protected void execute() { + // TODO: use agent proxy to retrieve it + SlcAgent agent = null; + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + slcExecution.setRealizedFlows(realizedFlows); + processController.execute(agent, slcExecution); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + // update one of the parameter of a given RealizedFlow + public void updateParameter(int realizedFlowIndex, String paramName, + Object value) { + RealizedFlow curRealizedFlow = realizedFlows.get(realizedFlowIndex); + curRealizedFlow.getFlowDescriptor().getValues().put(paramName, value); + } + + // clear the realizedFlow + public void clearBatch() { + // we clear the list + realizedFlows = new ArrayList(); + curSelectedRow = -1; + refreshParameterview(); + viewer.refresh(); + } + + // Remove the selected process from the batch + public void removeSelected() { + if (curSelectedRow == -1) + return; + else + realizedFlows.remove(curSelectedRow); + curSelectedRow = -1; + refreshParameterview(); + viewer.refresh(); + } + + // calling this method with index =-1 will cause the reset of the view. + private void refreshParameterview() { + // We choose to directly access the view rather than going through + // commands. + ProcessParametersView ppView; + try { + ppView = (ProcessParametersView) ClientUiPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow().getActivePage() + .showView(ProcessParametersView.ID); + + if (curSelectedRow == -1) + ppView.setRealizedFlow(-1, null); + else + ppView.setRealizedFlow(curSelectedRow, + realizedFlows.get(curSelectedRow)); + } catch (PartInitException e) { + throw new SlcException( + "Cannot Retrieve ProcessParameterView to edit parameters of selected process", + e); + } + } + + // Return the list of the processes to execute. + public void launchBatch() { + SlcExecution slcExecution = new SlcExecution(); + slcExecution.setUuid(UUID.randomUUID().toString()); + + slcExecution.setRealizedFlows(realizedFlows); + slcExecution.setHost(host); + + // TODO : insure that the concept has been well understood & the + // specification respected + SlcAgent curAgent; + for (int i = 0; i < slcAgents.size(); i++) { + if (currentAgentUuid == null) + throw new SlcException( + "Cannot launch a batch if no agent is specified"); + if (currentAgentUuid.equals(slcAgents.get(i).getAgentUuid())) { + curAgent = slcAgents.get(i); + processController.execute(curAgent, slcExecution); + break; + } + } + } + + // Specific Providers for the current view. + protected class ViewContentProvider implements IStructuredContentProvider { + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + + public Object[] getElements(Object obj) { + return realizedFlows.toArray(); + } + } + + protected class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + RealizedFlow rf = (RealizedFlow) obj; + switch (index) { + case 0: + return rf.getModuleName(); + case 1: + return rf.getFlowDescriptor().getName(); + } + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + // Handle Events + class SelectionChangedListener implements ISelectionChangedListener { + public void selectionChanged(SelectionChangedEvent evt) { + + IStructuredSelection curSelection = (IStructuredSelection) evt + .getSelection(); + Object obj = curSelection.getFirstElement(); + + if (obj instanceof RealizedFlow) { + RealizedFlow rf = (RealizedFlow) obj; + curSelectedRow = realizedFlows.indexOf(rf); + refreshParameterview(); + } + } + } + + // Implementation of the Drop Listener + protected class ViewDropListener extends ViewerDropAdapter { + + public ViewDropListener(Viewer viewer) { + super(viewer); + } + + @Override + public boolean performDrop(Object data) { + + Properties props = new Properties(); + + // TODO : Handle wrong type of dropped data + ByteArrayInputStream in = new ByteArrayInputStream(data.toString() + .getBytes()); + try { + props.load(in); + } catch (IOException e) { + throw new SlcException("Cannot create read flow node", e); + } finally { + IOUtils.closeQuietly(in); + } + + String agentId = props.getProperty("agentId"); + if (currentAgentUuid == null) { + currentAgentUuid = agentId; + host = props.getProperty("host"); + } else if (!currentAgentUuid.equals(agentId)) { + // TODO: as for now, we can only construct batch on a single + // Agent, must be upgraded to enable batch on various agent. + throw new SlcException( + "Cannot create batch on two (or more) distinct agents", + null); + // return false; + } + + String fdXml = props.getProperty("RealizedFlowAsXml"); + if (fdXml == null) + return false; + RealizedFlow rf = (RealizedFlow) oxmBean.unmarshal(fdXml); + realizedFlows.add(rf); + curSelectedRow = realizedFlows.indexOf(rf); + refreshParameterview(); + getViewer().refresh(); + return true; + } + + @Override + public boolean validateDrop(Object target, int operation, + TransferData transferType) { + return true; + } + } + + // IoC + public void setSlcAgents(List slcAgents) { + this.slcAgents = slcAgents; + } + + public void setOxmBean(OxmInterface oxmBean) { + this.oxmBean = oxmBean; + } + + public void setProcessController(ProcessController processController) { + this.processController = processController; + } + +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessDetailView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessDetailView.java new file mode 100644 index 000000000..944207eb1 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessDetailView.java @@ -0,0 +1,96 @@ +package org.argeo.slc.client.ui.views; + +import org.argeo.slc.dao.process.SlcExecutionDao; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +/** + * Multi-instance view that enables to browse the details of a given + * SlcExecution + * + * @author bsinou + * + */ + +public class ProcessDetailView extends ViewPart { + // private final static Log log = + // LogFactory.getLog(ProcessDetailView.class); + public static final String ID = "org.argeo.slc.client.ui.processDetailView"; + + private TreeViewer viewer; + + private String uuid; + private SlcExecution se; + + // IoC + private IContentProvider contentProvider; + private SlcExecutionDao slcExecutionDao; + + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + viewer.setContentProvider(contentProvider); + // viewer.setLabelProvider(labelProvider); + viewer.setLabelProvider(new ProcessDetailLabelProvider()); + // viewer.setInput(getViewSite()); + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + public void retrieveResults() { + se = slcExecutionDao.getSlcExecution(uuid); + viewer.setInput(se); + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + // Inner Class + public class ProcessDetailLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + // log.debug(sessionFactory.getClass().toString()); + + SlcExecution se = (SlcExecution) obj; + switch (index) { + + case 0: + return getText(se.getStartDate()); + case 1: + return se.getHost(); + case 2: + return se.getUuid(); + case 3: + return se.currentStep().getType(); + } + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setSlcExecutionDao(SlcExecutionDao slcExecutionDao) { + this.slcExecutionDao = slcExecutionDao; + } +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessListView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessListView.java new file mode 100644 index 000000000..83194d603 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessListView.java @@ -0,0 +1,163 @@ +package org.argeo.slc.client.ui.views; + +import java.util.ArrayList; + +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.dao.process.SlcExecutionDao; +import org.argeo.slc.process.SlcExecution; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.part.ViewPart; + +/** + * This class display the list of all processes that have run in the + * corresponding agent. Currently, the local agent. + * + * @author bsinou + * + */ +public class ProcessListView extends ViewPart { + // private final static Log log = LogFactory.getLog(ProcessListView.class); + + public static final String ID = "org.argeo.slc.client.ui.processListView"; + + private TableViewer viewer; + + // IoC + private SlcExecutionDao slcExecutionDao; + private ITableLabelProvider tableLabelProvider; + private IStructuredContentProvider structuredContentProvider; + + public void createPartControl(Composite parent) { + Table table = createTable(parent); + viewer = new TableViewer(table); + viewer.setLabelProvider(tableLabelProvider); + viewer.setContentProvider(structuredContentProvider); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + + } + + protected Table createTable(Composite parent) { + int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; + + Table table = new Table(parent, style); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 3; + table.setLayoutData(gridData); + + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumn column = new TableColumn(table, SWT.LEFT, 0); + column.setText("Date"); + column.setWidth(200); + + column = new TableColumn(table, SWT.LEFT, 1); + column.setText("Host"); + column.setWidth(100); + + column = new TableColumn(table, SWT.LEFT, 2); + column.setText("Id"); + column.setWidth(300); + + column = new TableColumn(table, SWT.LEFT, 3); + column.setText("Status"); + column.setWidth(100); + + return table; + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public void retrieveResults() { + viewer.setInput(slcExecutionDao.listSlcExecutions()); + } + + // Handle Events + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + + if (obj instanceof SlcExecution) { + SlcExecution se = (SlcExecution) obj; + + IWorkbench iw = ClientUiPlugin.getDefault().getWorkbench(); + IHandlerService handlerService = (IHandlerService) iw + .getService(IHandlerService.class); + try { + // get the command from plugin.xml + IWorkbenchWindow window = iw.getActiveWorkbenchWindow(); + ICommandService cmdService = (ICommandService) window + .getService(ICommandService.class); + Command cmd = cmdService + .getCommand("org.argeo.slc.client.ui.displayProcessDetails"); + + ArrayList parameters = new ArrayList(); + + // get the parameter + IParameter iparam = cmd + .getParameter("org.argeo.slc.client.commands.processUuid"); + Parameterization params = new Parameterization(iparam, se + .getUuid()); // "testUUID");// + parameters.add(params); + + // build the parameterized command + ParameterizedCommand pc = new ParameterizedCommand(cmd, + parameters.toArray(new Parameterization[parameters + .size()])); + + // execute the command + handlerService = (IHandlerService) window + .getService(IHandlerService.class); + handlerService.executeCommand(pc, null); + + } catch (Exception e) { + e.printStackTrace(); + throw new SlcException("Problem while rendering result. " + + e.getMessage()); + } + } + } + } + + // IoC + public void setSlcExecutionDao(SlcExecutionDao slcExecutionDao) { + this.slcExecutionDao = slcExecutionDao; + } + + public void setTableLabelProvider(ITableLabelProvider tableLabelProvider) { + this.tableLabelProvider = tableLabelProvider; + } + + public void setStructuredContentProvider( + IStructuredContentProvider structuredContentProvider) { + this.structuredContentProvider = structuredContentProvider; + } + +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessParametersView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessParametersView.java new file mode 100644 index 000000000..b45fb9981 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessParametersView.java @@ -0,0 +1,210 @@ +package org.argeo.slc.client.ui.views; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.client.ui.providers.ProcessParametersEditingSupport; +import org.argeo.slc.core.execution.PrimitiveAccessor; +import org.argeo.slc.execution.ExecutionSpecAttribute; +import org.argeo.slc.process.RealizedFlow; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +/** + * + * @author bsinou + * + * This view, directly linked with the ProcessBuilderView + * enables the display and editing the parameters of a given process. + * + * Note that for now we use ExecutionFlowDescriptor.values + * attribute to recall (and update ??) the various parameters. + */ +public class ProcessParametersView extends ViewPart { + private static final Log log = LogFactory + .getLog(ProcessParametersView.class); + + public static final String ID = "org.argeo.slc.client.ui.processParametersView"; + + // This map stores actual values set to default if existing at the begining + // and then the ones computed by the end user + private Map values; + // This map stores the spec of the attributes used to offer the end user + // some choices. + private Map specAttributes; + + // We must keep a reference to the current EditingSupport so that we can + // update the index of the process being updated + ProcessParametersEditingSupport ppEditingSupport; + + // view attributes + private TableViewer viewer; + + public void createPartControl(Composite parent) { + viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION); + createColumns(viewer); + + // WARNING + // for the moment being, we support only one process builder at a time + // we set the corresponding view in the editor here. + ProcessBuilderView pbView = (ProcessBuilderView) ClientUiPlugin + .getDefault().getWorkbench().getActiveWorkbenchWindow() + .getActivePage().findView(ProcessBuilderView.ID); + ppEditingSupport.setCurrentProcessBuilderView(pbView); + + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setContentProvider(new ViewContentProvider()); + viewer.setInput(getViewSite()); + + } + + // This will create the columns for the table + private void createColumns(TableViewer viewer) { + + String[] titles = { "Attribute name", "value" }; + int[] bounds = { 200, 200 }; + + for (int i = 0; i < titles.length; i++) { + TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE); + column.getColumn().setText(titles[i]); + column.getColumn().setWidth(bounds[i]); + column.getColumn().setResizable(true); + column.getColumn().setMoveable(true); + if (i == 1) { + // we create the used EditingSupport and enable editing support + // for value Column + ppEditingSupport = new ProcessParametersEditingSupport(viewer, + i); + column.setEditingSupport(ppEditingSupport); + } + } + Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + // set class attributes, refresh the lists of process paramaters to edit. + public void setRealizedFlow(int index, RealizedFlow rf) { + // force the cleaning of the view + if (index == -1) { + viewer.setInput(null); + return; + } + // we store the index of the edited Process in the editor so that it can + // save computed values. + ppEditingSupport.setCurrentProcessIndex(index); + + // TODO : + // We should handle ExecutionSpec here. need to be improved. + // ExecutionSpec es = rf.getExecutionSpec(); + // if (es != null && es.getAttributes() != null) + // parameters = es.getAttributes(); + // if (parameters != null) + // viewer.setInput(parameters); + + values = rf.getFlowDescriptor().getValues(); + specAttributes = rf.getFlowDescriptor().getExecutionSpec() + .getAttributes(); + + if (values != null) + viewer.setInput(values); + else + // No parameters to edit, we reset the view. + viewer.setInput(null); + + } + + // Inner Classes we should use ExecutionSpecAttribute instead of values + // see below + protected class ViewContentProvider implements IStructuredContentProvider { + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + + @SuppressWarnings("unchecked") + // we cast the Map to List + public Object[] getElements(Object obj) { + + if (obj instanceof Map && ((Map) obj).size() != 0) { + List list = new ArrayList(); + Map map = (Map) obj; + for (String key : map.keySet()) { + list.add(new ObjectWithName(key, map.get(key))); + } + return list.toArray(); + } else { + return new Object[0]; + } + } + } + + protected class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + + public String getColumnText(Object obj, int index) { + // NOTE : the passed object is a line of the table !!! + + if (obj instanceof ObjectWithName) { + ObjectWithName own = (ObjectWithName) obj; + switch (index) { + case 0: + return own.name; + case 1: + if (own.obj instanceof PrimitiveAccessor) { + PrimitiveAccessor pa = (PrimitiveAccessor) own.obj; + if ("string".equals(pa.getType())) + return (String) pa.getValue(); + else if ("integer".equals(pa.getType())) + return ((Integer) pa.getValue()).toString(); + else + return "Type " + pa.getType() + + " not yet supported"; + } else + return own.obj.toString(); + default: + return getText(obj); + } + } else + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + // We add an inner class to enrich the ExecutionSpecAttribute with a name + // so that we can display it. + public class ObjectWithName { + public Object obj; + public String name; + + public ObjectWithName(String name, Object obj) { + this.name = name; + this.obj = obj; + } + + } +} diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultDetailView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultDetailView.java new file mode 100644 index 000000000..6d9f90162 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultDetailView.java @@ -0,0 +1,121 @@ +package org.argeo.slc.client.ui.views; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.core.test.tree.TreeTestResult; +import org.argeo.slc.dao.test.tree.TreeTestResultDao; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.part.ViewPart; + +/** + * Multi-instance view that enables to browse the details of a given + * TreeTestResult + * + * @author bsinou + * + */ + +public class ResultDetailView extends ViewPart { + private final static Log log = LogFactory.getLog(ResultDetailView.class); + public static final String ID = "org.argeo.slc.client.ui.resultDetailView"; + + protected String[] columnNames = new String[] { "Test", "State", "Message", + "Id" }; + + private TreeViewer viewer; + private Tree resultDetailTree; + + private String uuid; + private TreeTestResult ttr; + + // IoC + private IContentProvider contentProvider; + private ITableLabelProvider labelProvider; + private TreeTestResultDao treeTestResultDao; + + public void createPartControl(Composite parent) { + resultDetailTree = new Tree(parent, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + resultDetailTree.setLayoutData(gd); + resultDetailTree.setLinesVisible(true); + resultDetailTree.setHeaderVisible(true); + + for (int i = 0; i < columnNames.length; i++) { + TreeColumn column = new TreeColumn(resultDetailTree, SWT.LEFT, i); + column.setText(columnNames[i]); + + // TIP: Don't forget to set the width. If not set it is set to + // 0 and it will look as if the column didn't exist. + switch (i) { + case 0: + column.setWidth(130); + case 1: + column.setWidth(200); + default: + column.setWidth(70); + } + } + viewer = new TreeViewer(resultDetailTree); + viewer.setColumnProperties(columnNames); + + viewer.setContentProvider(contentProvider); + // viewer.setLabelProvider(new ResultDetailLabelProvider()); + log.debug("Injected LabelProvider :" + labelProvider.toString()); + + // TIP: It seems, that if the table has not defined any TreeColumns then + // a plain LabelProvider will be used. Since, we don't provide an + // instance of LabelProvider, a default one will be used and + // the TableLableProvider is ignored without notice. Took me quite + // a while to find that one out. + viewer.setLabelProvider(labelProvider); + log.debug("Persisted labelProvider :" + + viewer.getLabelProvider().toString()); + // viewer.setInput(getViewSite()); + + // viewer.expandAll(); + + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public TreeViewer getViewer() { + return viewer; + } + + public void retrieveResults() { + ttr = treeTestResultDao.getTestResult(uuid); + viewer.setInput(ttr); + // viewer.setInput(getViewSite()); + + // setFocus(); + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + // IoC + public void setContentProvider(IContentProvider contentProvider) { + this.contentProvider = contentProvider; + } + + public void setLabelProvider(ITableLabelProvider labelProvider) { + this.labelProvider = labelProvider; + } + + public void setTreeTestResultDao(TreeTestResultDao treeTestResultDao) { + this.treeTestResultDao = treeTestResultDao; + } + +} \ No newline at end of file diff --git a/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultListView.java b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultListView.java new file mode 100644 index 000000000..c61f8de34 --- /dev/null +++ b/eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultListView.java @@ -0,0 +1,198 @@ +package org.argeo.slc.client.ui.views; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.ClientUiPlugin; +import org.argeo.slc.core.test.tree.ResultAttributes; +import org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.eclipse.ui.part.ViewPart; + +public class ResultListView extends ViewPart { + private final static Log log = LogFactory.getLog(ResultListView.class); + + public static final String ID = "org.argeo.slc.client.ui.resultListView"; + + private TableViewer viewer; + + private TreeTestResultCollectionDao testResultCollectionDao; + + public void createPartControl(Composite parent) { + Table table = createTable(parent); + viewer = new TableViewer(table); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setContentProvider(new ViewContentProvider()); + viewer.setInput(getViewSite()); + viewer.addDoubleClickListener(new ViewDoubleClickListener()); + } + + protected Table createTable(Composite parent) { + int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; + + Table table = new Table(parent, style); + + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessVerticalSpace = true; + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalSpan = 3; + table.setLayoutData(gridData); + + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumn column = new TableColumn(table, SWT.LEFT, 0); + column.setText("Date"); + column.setWidth(200); + + column = new TableColumn(table, SWT.LEFT, 1); + column.setText("UUID"); + column.setWidth(300); + + return table; + } + + // View Specific inner class + protected static class ViewContentProvider implements + IStructuredContentProvider { + + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + + public void dispose() { + } + + @SuppressWarnings("unchecked") + public Object[] getElements(Object obj) { + if (obj instanceof List) { + return ((List) obj).toArray(); + } else { + return new Object[0]; + } + } + } + + protected class ViewLabelProvider extends LabelProvider implements + ITableLabelProvider { + public String getColumnText(Object obj, int index) { + ResultAttributes ra = (ResultAttributes) obj; + switch (index) { + case 0: + return getText(ra.getCloseDate()); + case 1: + return ra.getUuid(); + } + return getText(obj); + } + + public Image getColumnImage(Object obj, int index) { + return null; + } + + } + + public void setFocus() { + viewer.getControl().setFocus(); + } + + public void retrieveResults() { + try { + List lst = testResultCollectionDao + .listResultAttributes(null); + if (log.isTraceEnabled()) + log.trace("Result attributes count: " + lst.size()); + viewer.setInput(lst); + // viewer.refresh(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + // Handle Events + /** + * The ResultAttributes expose a part of the information contained in the + * TreeTestResult, It has the same UUID as the corresponding treeTestResult. + */ + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + + if (obj instanceof ResultAttributes) { + ResultAttributes ra = (ResultAttributes) obj; + log.debug("Double-clic on result with UUID" + ra.getUuid()); + + IWorkbench iw = ClientUiPlugin.getDefault().getWorkbench(); + IHandlerService handlerService = (IHandlerService) iw + .getService(IHandlerService.class); + try { + // get the command from plugin.xml + IWorkbenchWindow window = iw.getActiveWorkbenchWindow(); + ICommandService cmdService = (ICommandService) window + .getService(ICommandService.class); + Command cmd = cmdService + .getCommand("org.argeo.slc.client.ui.displayResultDetails"); + + // log.debug("cmd : " + cmd); + ArrayList parameters = new ArrayList(); + + // get the parameter + IParameter iparam = cmd + .getParameter("org.argeo.slc.client.commands.resultUuid"); + + Parameterization params = new Parameterization(iparam, + ra.getUuid()); + parameters.add(params); + + // build the parameterized command + ParameterizedCommand pc = new ParameterizedCommand(cmd, + parameters.toArray(new Parameterization[parameters + .size()])); + + // execute the command + handlerService = (IHandlerService) window + .getService(IHandlerService.class); + handlerService.executeCommand(pc, null); + + } catch (Exception e) { + e.printStackTrace(); + throw new SlcException("Problem while rendering result. " + + e.getMessage()); + } + } + } + } + + // Ioc + public void setTestResultCollectionDao( + TreeTestResultCollectionDao testResultCollectionDao) { + this.testResultCollectionDao = testResultCollectionDao; + } + +}