+ refactor to separate runtime and module project under eclipse plugin.
authorBruno Sinou <bsinou@argeo.org>
Mon, 8 Nov 2010 16:11:08 +0000 (16:11 +0000)
committerBruno Sinou <bsinou@argeo.org>
Mon, 8 Nov 2010 16:11:08 +0000 (16:11 +0000)
+ 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

70 files changed:
eclipse/plugins/runtime/org.argeo.slc.client.ui/.classpath [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/.project [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/MANIFEST.MF [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/commands.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/controllers.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/listeners.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/osgi.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/META-INF/spring/views.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/build.properties [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/archive.png [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/batch.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/clear_batch.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/computer.png [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/edit_parameters.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/error.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/execution_module.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/folder.png [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/launch.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/passed.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/process_details.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/processes.png [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/refresh.png [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/remove_one.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/result_details.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/results.gif [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/icons/system.png [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/plugin.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/pom.xml [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ClearBatchHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/controllers/ProcessController.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/perspectives/SlcExecution.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ExecutionModulesView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessBuilderView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessDetailView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessListView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ProcessParametersView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultDetailView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/ResultListView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/ClientUiPlugin.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ClearBatchHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/LaunchBatchHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessDetailsDisplayHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ProcessListViewRefreshHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/RemoveSelectedProcessFromBatchHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultDetailsDisplayHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/commands/ResultListViewRefreshHandler.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/controllers/ProcessController.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/listeners/TestManagerServiceAdapter.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/perspectives/SlcExecution.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ExecutionModulesContentProvider.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/providers/ProcessParametersEditingSupport.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ExecutionModulesView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessBuilderView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessDetailView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessListView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ProcessParametersView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultDetailView.java [new file with mode: 0644]
eclipse/plugins/runtime/org.argeo.slc.client.ui/src/org/argeo/slc/client/ui/views/ResultListView.java [new file with mode: 0644]

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 (file)
index 0000000..8b978d9
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
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 (file)
index 0000000..ed71a2e
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.slc.client.ui</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
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 (file)
index 0000000..95d6b05
--- /dev/null
@@ -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 (file)
index 0000000..31cbfae
--- /dev/null
@@ -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 (file)
index 0000000..5969e74
--- /dev/null
@@ -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 (file)
index 0000000..5312a33
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <bean id="org.argeo.slc.client.ui.refreshResultList"
+               class="org.argeo.slc.client.ui.commands.ResultListViewRefreshHandler"
+               scope="prototype">
+       </bean>
+       <bean id="org.argeo.slc.client.ui.refreshProcessList"
+               class="org.argeo.slc.client.ui.commands.ProcessListViewRefreshHandler"
+               scope="prototype">
+       </bean>
+       <bean id="org.argeo.slc.client.ui.displayProcessDetails"
+               class="org.argeo.slc.client.ui.commands.ProcessDetailsDisplayHandler"
+               scope="prototype">
+       </bean>
+       <bean id="org.argeo.slc.client.ui.displayResultDetails"
+               class="org.argeo.slc.client.ui.commands.ResultDetailsDisplayHandler"
+               scope="prototype">
+       </bean>
+       <bean id="org.argeo.slc.client.ui.launchBatch" class="org.argeo.slc.client.ui.commands.LaunchBatchHandler"
+               scope="prototype">
+       </bean>
+       <bean id="org.argeo.slc.client.ui.removeSelectedFromBatch"
+               class="org.argeo.slc.client.ui.commands.RemoveSelectedProcessFromBatchHandler"
+               scope="prototype">
+       </bean>
+       <bean id="org.argeo.slc.client.ui.clearBatch" class="org.argeo.slc.client.ui.commands.ClearBatchHandler"
+               scope="prototype">
+       </bean>
+</beans>
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 (file)
index 0000000..6215437
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <bean id="processController" class="org.argeo.slc.client.ui.controllers.ProcessController">
+               <property name="slcExecutionService" ref="slcExecutionService" />
+       </bean>
+</beans>
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 (file)
index 0000000..509fe81
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <bean id="testManagerServiceAdapter"
+               class="org.argeo.slc.client.ui.listeners.TestManagerServiceAdapter">
+               <property name="testManagerService" ref="testManagerService" />
+       </bean>
+
+       <bean id="slcExecutionServiceAdapter" class="org.argeo.slc.services.impl.SlcExecutionServiceAdapter">
+               <property name="slcExecutionService" ref="slcExecutionService" />
+       </bean>
+
+</beans>
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 (file)
index 0000000..e05a865
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/osgi  \r
+       http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+       http://www.springframework.org/schema/beans   \r
+       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+       <beans:description> Implements SLC specific RCP UIs.\r
+       </beans:description>\r
+\r
+       <!-- Services exposed by the current bundle -->\r
+\r
+       <!-- Listeners used by the execution modules -->\r
+       <service ref="testManagerServiceAdapter"\r
+               interface="org.argeo.slc.core.test.tree.TreeTestResultListener" />\r
+       <service ref="slcExecutionServiceAdapter" interface="org.argeo.slc.process.SlcExecutionNotifier" />\r
+\r
+       <!-- References needed by the current bundle -->\r
+       <reference id="slcExecutionService" interface="org.argeo.slc.services.SlcExecutionService" />\r
+       <reference id="testManagerService" interface="org.argeo.slc.services.TestManagerService" />\r
+       <reference id="oxmBean" interface="org.argeo.slc.client.oxm.OxmInterface" />\r
+\r
+       <!-- References Needed -->\r
+       <!-- <reference id="marshaller" interface="org.springframework.oxm.Marshaller" \r
+               /> <reference id="unmarshaller" interface="org.springframework.oxm.Unmarshaller" \r
+               /> -->\r
+\r
+       <!-- DAO -->\r
+       <reference id="testResultCollectionDao"\r
+               interface="org.argeo.slc.dao.test.tree.TreeTestResultCollectionDao"\r
+               context-class-loader="service-provider" />\r
+\r
+       <reference id="treeTestResultDao" interface="org.argeo.slc.dao.test.tree.TreeTestResultDao"\r
+               context-class-loader="service-provider" />\r
+\r
+\r
+       <reference id="slcExecutionDao" interface="org.argeo.slc.dao.process.SlcExecutionDao"\r
+               context-class-loader="service-provider" />\r
+\r
+       <!-- Content providers are deported in an other bundle for UI not to depend \r
+               on DB used implementation. We use bean-name reference because interface is \r
+               not enough to choose between various been with same interface -->\r
+       <reference id="processListTableLabelProvider" interface="org.eclipse.jface.viewers.ITableLabelProvider"\r
+               bean-name="processListTableLabelProvider" />\r
+       <reference id="processListStructuredContentProvider"\r
+               interface="org.eclipse.jface.viewers.IStructuredContentProvider"\r
+               bean-name="processListStructuredContentProvider" />\r
+       <reference id="processDetailContentProvider"\r
+               interface="org.eclipse.jface.viewers.ITreeContentProvider" bean-name="processDetailContentProvider" />\r
+       <reference id="resultDetailContentProvider"\r
+               interface="org.eclipse.jface.viewers.ITreeContentProvider" bean-name="resultDetailContentProvider" />\r
+       <reference id="resultDetailLabelProvider" interface="org.eclipse.jface.viewers.ITableLabelProvider"\r
+               bean-name="resultDetailLabelProvider" />\r
+\r
+\r
+       <!-- TODO : what is it for ? -->\r
+       <list id="slcAgents" interface="org.argeo.slc.runtime.SlcAgent" />\r
+</beans:beans>
\ 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 (file)
index 0000000..74b7d92
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <!-- Views -->
+       <bean id="org.argeo.slc.client.ui.executionModulesView" class="org.argeo.slc.client.ui.views.ExecutionModulesView"
+               scope="prototype">
+               <property name="contentProvider" ref="executionModulesContentProvider" />
+               <property name="processController" ref="processController" />
+               <property name="oxmBean" ref="oxmBean" />
+       </bean>
+
+       <bean id="org.argeo.slc.client.ui.resultListView" class="org.argeo.slc.client.ui.views.ResultListView"
+               scope="prototype">
+               <property name="testResultCollectionDao" ref="testResultCollectionDao" />
+       </bean>
+
+       <bean id="org.argeo.slc.client.ui.resultDetailView" class="org.argeo.slc.client.ui.views.ResultDetailView"
+               scope="prototype">
+               <property name="treeTestResultDao" ref="treeTestResultDao" />
+               <property name="contentProvider" ref="resultDetailContentProvider" />
+               <property name="labelProvider" ref="resultDetailLabelProvider" />
+       </bean>
+
+
+       <bean id="org.argeo.slc.client.ui.processListView" class="org.argeo.slc.client.ui.views.ProcessListView"
+               scope="prototype">
+               <property name="slcExecutionDao" ref="slcExecutionDao" />
+               <property name="structuredContentProvider" ref="processListStructuredContentProvider" />
+               <property name="tableLabelProvider" ref="processListTableLabelProvider" />
+       </bean>
+
+       <bean id="org.argeo.slc.client.ui.processDetailView" class="org.argeo.slc.client.ui.views.ProcessDetailView"
+               scope="prototype">
+               <property name="slcExecutionDao" ref="slcExecutionDao" />
+               <property name="contentProvider" ref="processDetailContentProvider" />
+               <property name="labelProvider" ref="processDetailLabelProvider" />
+       </bean>
+
+       <bean id="org.argeo.slc.client.ui.processBuilderView" class="org.argeo.slc.client.ui.views.ProcessBuilderView"
+               scope="prototype">
+               <property name="processController" ref="processController" />
+               <property name="oxmBean" ref="oxmBean" />
+               <property name="slcAgents" ref="slcAgents" />
+       </bean>
+
+       <bean id="org.argeo.slc.client.ui.processParametersView" class="org.argeo.slc.client.ui.views.ProcessParametersView"
+               scope="prototype">
+       </bean>
+
+       <!-- Providers. -->
+       <bean id="executionModulesContentProvider"
+               class="org.argeo.slc.client.ui.providers.ExecutionModulesContentProvider">
+               <property name="slcAgents" ref="slcAgents" />
+       </bean>
+</beans>
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 (file)
index 0000000..a1c313d
--- /dev/null
@@ -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 (file)
index 0000000..fb36f36
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 (file)
index 0000000..b8ca14a
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 (file)
index 0000000..28a3785
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 (file)
index 0000000..ff64b84
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 (file)
index 0000000..94eedf6
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 (file)
index 0000000..64b4384
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 (file)
index 0000000..983932f
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 (file)
index 0000000..6937ed4
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 (file)
index 0000000..ec477ea
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 (file)
index 0000000..23c97f0
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 (file)
index 0000000..c81630a
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 (file)
index 0000000..364c0e7
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 (file)
index 0000000..364c0e7
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 (file)
index 0000000..bb3803b
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 (file)
index 0000000..2cd9c54
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 (file)
index 0000000..4017f6d
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 (file)
index 0000000..0dc862c
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 (file)
index 0000000..71f44d0
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 (file)
index 0000000..b6f4dd1
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+       
+   <extension
+         point="org.eclipse.ui.views">
+   <view
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         icon="icons/execution_module.gif"
+         id="org.argeo.slc.client.ui.executionModulesView"
+         name="Execution Modules"
+         restorable="true">
+   </view>
+   <view
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         icon="icons/results.gif"
+         id="org.argeo.slc.client.ui.resultListView"
+         name="Results"
+         restorable="true">
+   </view>
+   <view
+         allowMultiple="true"
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         icon="icons/result_details.gif"
+         id="org.argeo.slc.client.ui.resultDetailView"
+         name="Result details"
+         restorable="true">
+   </view>
+   <view
+         id="org.argeo.slc.client.ui.processListView"
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         name="Processes"
+         icon="icons/processes.gif"
+         restorable="true">
+   </view>
+   <view
+         allowMultiple="true"
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         icon="icons/process_details.gif"
+         id="org.argeo.slc.client.ui.processDetailView"
+         name="Process details"
+         restorable="true">
+   </view>
+   <view
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         icon="icons/edit_parameters.gif"
+         id="org.argeo.slc.client.ui.processParametersView"
+         name="Process Parameters"
+         restorable="true">
+   </view>
+   <view
+         class="org.argeo.eclipse.spring.SpringExtensionFactory"
+         icon="icons/batch.gif"
+         id="org.argeo.slc.client.ui.processBuilderView"
+         name="Batch"
+         restorable="true">
+   </view>
+    </extension>
+
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            id="org.argeo.slc.client.ui.refreshResultList"
+            name="RefreshResultList">
+      </command>
+      <command
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            id="org.argeo.slc.client.ui.launchBatch"
+            name="LaunchBatch">
+      </command>
+      <command
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            id="org.argeo.slc.client.ui.removeSelectedFromBatch"
+            name="RemoveSelectedFromBatch">
+      </command>
+      <command
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            id="org.argeo.slc.client.ui.clearBatch"
+            name="ClearBatch">
+      </command>
+      <command
+            defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+            id="org.argeo.slc.client.ui.refreshProcessList"
+            name="RefreshProcessList ">
+      </command>
+        <command 
+               defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+               id="org.argeo.slc.client.ui.displayProcessDetails"
+               name="DisplayProcessDetails">
+                       <commandParameter
+                       id="org.argeo.slc.client.commands.processUuid"
+                       name="Process UUID">
+                       </commandParameter>
+       </command>
+   <command 
+               defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+               id="org.argeo.slc.client.ui.displayResultDetails"
+               name="DisplayResultDetails">
+                       <commandParameter
+                       id="org.argeo.slc.client.commands.resultUuid"
+                       name="Result UUID">
+                       </commandParameter>
+       </command>
+   </extension>
+   <extension
+        point="org.eclipse.ui.bindings">
+     <key
+           commandId="org.argeo.slc.client.ui.refreshResultList"
+           schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+           sequence="CTRL+R">
+     </key>
+  </extension>
+   
+   <extension
+         id="menu:org.eclipse.ui.main.menu"
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="menu:org.eclipse.ui.main.menu?after=fileMenu">
+         <menu
+               id="slcMenu"
+               label="SLC">
+            <command
+                  commandId="org.argeo.slc.client.ui.refreshResultList"
+                  label="Refresh"
+                  style="push"
+                  tooltip="Refresh  the result list">
+            </command>
+         </menu>
+      </menuContribution>
+      <menuContribution
+            locationURI="toolbar:org.eclipse.ui.main.toolbar">
+         <toolbar
+               id="org.argeo.slc.client.ui.ResultViewToolbar">
+            <command
+                  commandId="org.argeo.slc.client.ui.refreshResultList"
+                  icon="icons/refresh.png"
+                  label="Refresh"
+                  style="toggle"
+                  tooltip="Refresh the result list">
+            </command>
+            <separator
+                  name="resultListViewGroup">
+            </separator>
+         </toolbar>
+      </menuContribution>
+      <menuContribution
+            locationURI="toolbar:org.argeo.slc.client.ui.processBuilderView">
+         <command
+               commandId="org.argeo.slc.client.ui.launchBatch"
+               icon="icons/launch.gif"
+               label="Launch Batch"
+               tooltip="Launch the batch built in the process builder view.">
+         </command>
+         <command
+               commandId="org.argeo.slc.client.ui.clearBatch"
+               label="Clear Batch"
+               icon="icons/clear_batch.gif"
+               tooltip="Clear the batch built in the process builder view.">
+         </command>
+         <command
+               commandId="org.argeo.slc.client.ui.removeSelectedFromBatch"
+               icon="icons/remove_one.gif"
+               label="Remove Selected From Batch"
+               tooltip="Remove selected process from process builder view.">
+         </command>
+      </menuContribution>
+   </extension>
+</plugin>
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 (file)
index 0000000..895938d
--- /dev/null
@@ -0,0 +1,73 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.argeo.slc.eclipse</groupId>
+               <artifactId>plugins</artifactId>
+               <version>0.13.0-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.slc.client.ui</artifactId>
+       <name>SLC Client UI</name>
+       <packaging>jar</packaging>
+       <dependencies>
+               <!-- SLC Client UI -->
+               <dependency>
+                       <groupId>org.argeo.slc.eclipse</groupId>
+                       <artifactId>org.argeo.slc.client.commons</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.slc.eclipse</groupId>
+                       <artifactId>org.argeo.slc.client.oxm</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.slc.eclipse</groupId>
+                       <artifactId>org.argeo.slc.client.hibernate</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.slc.eclipse</groupId>
+                       <artifactId>org.argeo.slc.client.core</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+
+               <!-- SLC -->
+               <dependency>
+                       <groupId>org.argeo.slc.runtime</groupId>
+                       <artifactId>org.argeo.slc.core</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.argeo.slc.runtime</groupId>
+                       <artifactId>org.argeo.slc.server</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+               <!-- Commons -->
+               <dependency>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.ui</artifactId>
+                       <version>${version.argeo-commons}</version>
+               </dependency>
+               <!-- Spring -->
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.context</artifactId>
+               </dependency>
+               <!-- Eclipse -->
+               <dependency>
+                       <groupId>org.eclipse.ui</groupId>
+                       <artifactId>org.eclipse.ui</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.core</groupId>
+                       <artifactId>org.eclipse.core.runtime</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.swt</groupId>
+                       <artifactId>org.eclipse.swt.gtk.linux.x86_64</artifactId>
+               </dependency>
+       </dependencies>
+</project>
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 (file)
index 0000000..eb6809c
--- /dev/null
@@ -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 (file)
index 0000000..e770c34
--- /dev/null
@@ -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 (file)
index 0000000..cdc2881
--- /dev/null
@@ -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 (file)
index 0000000..47f9d00
--- /dev/null
@@ -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 (file)
index 0000000..12e8de0
--- /dev/null
@@ -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 (file)
index 0000000..98c502f
--- /dev/null
@@ -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 (file)
index 0000000..23fa879
--- /dev/null
@@ -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 (file)
index 0000000..5785305
--- /dev/null
@@ -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 (file)
index 0000000..4995598
--- /dev/null
@@ -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 (file)
index 0000000..f50ea18
--- /dev/null
@@ -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 (file)
index 0000000..1278609
--- /dev/null
@@ -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<SlcAgent> 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<AgentNode> agentNodes = new ArrayList<AgentNode>();
+                       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<String, ExecutionFlowDescriptor> 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<String, FolderNode> folderNodes = new TreeMap<String, FolderNode>();
+                       flowDescriptors = new HashMap<String, ExecutionFlowDescriptor>();
+
+                       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<String, FolderNode> 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<String, ExecutionFlowDescriptor> 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<SlcAgent> 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 (file)
index 0000000..7ca534e
--- /dev/null
@@ -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 (file)
index 0000000..07df89a
--- /dev/null
@@ -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<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+                               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 (file)
index 0000000..5d62983
--- /dev/null
@@ -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<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+       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<SlcAgent> 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<List>
+       public void clearBatch() {
+               // we clear the list
+               realizedFlows = new ArrayList<RealizedFlow>();
+               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<SlcAgent> 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 (file)
index 0000000..944207e
--- /dev/null
@@ -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 (file)
index 0000000..83194d6
--- /dev/null
@@ -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<Parameterization> parameters = new ArrayList<Parameterization>();
+
+                                       // 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 (file)
index 0000000..b45fb99
--- /dev/null
@@ -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 <code> ProcessBuilderView </code>
+ *         enables the display and editing the parameters of a given process.
+ * 
+ *         Note that for now we use <code>ExecutionFlowDescriptor.values</code>
+ *         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<String, Object> values;
+       // This map stores the spec of the attributes used to offer the end user
+       // some choices.
+       private Map<String, ExecutionSpecAttribute> 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<String, Object> to List<Object>
+               public Object[] getElements(Object obj) {
+
+                       if (obj instanceof Map && ((Map) obj).size() != 0) {
+                               List<ObjectWithName> list = new ArrayList<ObjectWithName>();
+                               Map<String, Object> map = (Map<String, Object>) 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 (file)
index 0000000..6d9f901
--- /dev/null
@@ -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 (file)
index 0000000..c61f8de
--- /dev/null
@@ -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<ResultAttributes>) 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<ResultAttributes> 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<Parameterization> parameters = new ArrayList<Parameterization>();
+
+                                       // 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 (file)
index 0000000..7148f0f
--- /dev/null
@@ -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 (file)
index 0000000..eb6809c
--- /dev/null
@@ -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 (file)
index 0000000..e770c34
--- /dev/null
@@ -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 (file)
index 0000000..cdc2881
--- /dev/null
@@ -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 (file)
index 0000000..47f9d00
--- /dev/null
@@ -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 (file)
index 0000000..12e8de0
--- /dev/null
@@ -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 (file)
index 0000000..98c502f
--- /dev/null
@@ -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 (file)
index 0000000..23fa879
--- /dev/null
@@ -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 (file)
index 0000000..5785305
--- /dev/null
@@ -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 (file)
index 0000000..4995598
--- /dev/null
@@ -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 (file)
index 0000000..f50ea18
--- /dev/null
@@ -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 (file)
index 0000000..1278609
--- /dev/null
@@ -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<SlcAgent> 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<AgentNode> agentNodes = new ArrayList<AgentNode>();
+                       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<String, ExecutionFlowDescriptor> 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<String, FolderNode> folderNodes = new TreeMap<String, FolderNode>();
+                       flowDescriptors = new HashMap<String, ExecutionFlowDescriptor>();
+
+                       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<String, FolderNode> 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<String, ExecutionFlowDescriptor> 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<SlcAgent> 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 (file)
index 0000000..7ca534e
--- /dev/null
@@ -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 (file)
index 0000000..07df89a
--- /dev/null
@@ -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<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+                               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 (file)
index 0000000..5d62983
--- /dev/null
@@ -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<RealizedFlow> realizedFlows = new ArrayList<RealizedFlow>();
+       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<SlcAgent> 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<List>
+       public void clearBatch() {
+               // we clear the list
+               realizedFlows = new ArrayList<RealizedFlow>();
+               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<SlcAgent> 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 (file)
index 0000000..944207e
--- /dev/null
@@ -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 (file)
index 0000000..83194d6
--- /dev/null
@@ -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<Parameterization> parameters = new ArrayList<Parameterization>();
+
+                                       // 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 (file)
index 0000000..b45fb99
--- /dev/null
@@ -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 <code> ProcessBuilderView </code>
+ *         enables the display and editing the parameters of a given process.
+ * 
+ *         Note that for now we use <code>ExecutionFlowDescriptor.values</code>
+ *         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<String, Object> values;
+       // This map stores the spec of the attributes used to offer the end user
+       // some choices.
+       private Map<String, ExecutionSpecAttribute> 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<String, Object> to List<Object>
+               public Object[] getElements(Object obj) {
+
+                       if (obj instanceof Map && ((Map) obj).size() != 0) {
+                               List<ObjectWithName> list = new ArrayList<ObjectWithName>();
+                               Map<String, Object> map = (Map<String, Object>) 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 (file)
index 0000000..6d9f901
--- /dev/null
@@ -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 (file)
index 0000000..c61f8de
--- /dev/null
@@ -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<ResultAttributes>) 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<ResultAttributes> 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<Parameterization> parameters = new ArrayList<Parameterization>();
+
+                                       // 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;
+       }
+
+}