From 84136d3e740bc3aa3fbc2f81894e597834a66a5e Mon Sep 17 00:00:00 2001
From: buczekp <buczekp>
Date: Thu, 21 Jan 2010 22:27:48 +0000
Subject: [PATCH] [LMS-1349] added process menu to dataset view

SVN: 14399
---
 .../client/web/client/application/Dict.java   |   6 +
 .../dto/DatastoreServiceDescription.java      |  12 +-
 .../application/dataset/DataViewSection.java  |  19 +-
 .../dataset/GenericDataSetViewer.java         | 180 +++++++++++++++++-
 .../cisd/openbis/public/common-dictionary.js  |   6 +
 5 files changed, 203 insertions(+), 20 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
index f4e939c7744..be2cc9f3e9d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
@@ -446,6 +446,12 @@ public abstract class Dict
 
     public static final String BUTTON_UPLOAD_DATASETS = "button_upload_datasets";
 
+    public static final String BUTTON_PROCESS = "button_process";
+
+    public static final String PROCESSING_INFO_TITLE = "processing_info_title";
+
+    public static final String PROCESSING_INFO_MSG = "processing_info_msg";
+
     public static final String CONFIRM_DATASET_UPLOAD_TITLE = "confirm_dataset_upload_title";
 
     public static final String CONFIRM_DATASET_UPLOAD_MSG = "confirm_dataset_upload_msg";
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatastoreServiceDescription.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatastoreServiceDescription.java
index c3bf61d8a0f..a5c42356844 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatastoreServiceDescription.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatastoreServiceDescription.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
 import java.io.Serializable;
+import java.util.Arrays;
 
 import com.google.gwt.user.client.rpc.IsSerializable;
 
@@ -27,7 +28,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
  */
 public class DatastoreServiceDescription implements IsSerializable, Serializable
 {
-     private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
 
     private String key;
 
@@ -86,7 +87,7 @@ public class DatastoreServiceDescription implements IsSerializable, Serializable
     {
         this.downloadURL = downloadURL;
     }
-    
+
     @Override
     public String toString()
     {
@@ -106,4 +107,11 @@ public class DatastoreServiceDescription implements IsSerializable, Serializable
         sb.append("]");
         return sb.toString();
     }
+
+    public static boolean isMatching(DatastoreServiceDescription service, ExternalData dataset)
+    {
+        return service.getDatastoreCode().equals(dataset.getDataStore().getCode())
+                && (Arrays.asList(service.getDatasetTypeCodes())).contains(dataset.getDataSetType()
+                        .getCode());
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataViewSection.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataViewSection.java
index 640ae9d29a7..3f9c2b91008 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataViewSection.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataViewSection.java
@@ -61,8 +61,8 @@ public class DataViewSection extends SingleSectionPanel
     {
         super(viewContext.getMessage(Dict.DATA_VIEW));
 
-        final DatastoreServiceViewerSelectionWidget serviceSelectionWidget =
-                new DatastoreServiceViewerSelectionWidget(viewContext, dataset);
+        final DatastoreServiceSelectionWidget serviceSelectionWidget =
+                new DatastoreServiceSelectionWidget(viewContext, dataset);
         getHeader().addTool(new LabelToolItem(serviceSelectionWidget.getFieldLabel() + ":&nbsp;"));
         getHeader().addTool(serviceSelectionWidget);
         serviceSelectionWidget.addSelectionChangedListener(createServiceSelectionChangedListener(
@@ -162,7 +162,12 @@ public class DataViewSection extends SingleSectionPanel
             };
     }
 
-    private static class DatastoreServiceViewerSelectionWidget extends
+    /**
+     * {@link DropDownList} for selection of reporting plugin or datastore 'Files' viewer.
+     * 
+     * @author Piotr Buczek
+     */
+    private static class DatastoreServiceSelectionWidget extends
             DropDownList<DatastoreServiceDescriptionModel, DatastoreServiceDescription>
     {
 
@@ -170,7 +175,7 @@ public class DataViewSection extends SingleSectionPanel
 
         private final ExternalData dataset;
 
-        public DatastoreServiceViewerSelectionWidget(final IViewContext<?> viewContext,
+        public DatastoreServiceSelectionWidget(final IViewContext<?> viewContext,
                 final ExternalData dataset)
         {
             super(viewContext, ("data-set_" + dataset.getCode() + "_viewer"), Dict.BUTTON_SHOW,
@@ -217,7 +222,7 @@ public class DataViewSection extends SingleSectionPanel
      * 
      * @author Piotr Buczek
      */
-    public static class DatastoreServiceDescriptionModel extends NonHierarchicalBaseModelData
+    private static class DatastoreServiceDescriptionModel extends NonHierarchicalBaseModelData
     {
 
         private static final long serialVersionUID = 1L;
@@ -235,9 +240,7 @@ public class DataViewSection extends SingleSectionPanel
                     new ArrayList<DatastoreServiceDescriptionModel>();
             for (final DatastoreServiceDescription service : services)
             {
-                if (service.getDatastoreCode().equals(dataset.getDataStore().getCode())
-                        && (Arrays.asList(service.getDatasetTypeCodes())).contains(dataset
-                                .getDataSetType().getCode()))
+                if (DatastoreServiceDescription.isMatching(service, dataset))
                 {
                     result.add(new DatastoreServiceDescriptionModel(service));
                 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
index 3d1337ad866..1e0a59791bf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/GenericDataSetViewer.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.dataset;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 
@@ -25,8 +26,10 @@ import com.extjs.gxt.ui.client.event.ButtonEvent;
 import com.extjs.gxt.ui.client.event.SelectionListener;
 import com.extjs.gxt.ui.client.widget.Component;
 import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.MessageBox;
 import com.extjs.gxt.ui.client.widget.button.Button;
 import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
+import com.extjs.gxt.ui.client.widget.menu.Menu;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
@@ -37,14 +40,20 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.SingleSect
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplayTypeIDGenerator;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.menu.ActionMenu;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.menu.IActionMenuItem;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractViewer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.DataSetListDeletionConfirmationDialog;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.SectionsPanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.DataSetUtils;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedAction;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DisplayedOrSelectedDatasetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifiable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync;
@@ -65,6 +74,8 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
 
     private final BrowseButtonHolder browseButtonHolder;
 
+    private final ProcessButtonHolder processButtonHolder;
+
     protected final TechId datasetId;
 
     private final IViewContext<?> viewContext;
@@ -94,6 +105,7 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
         this.viewContext = viewContext;
         this.datasetId = TechId.create(identifiable);
         this.browseButtonHolder = new BrowseButtonHolder();
+        this.processButtonHolder = new ProcessButtonHolder();
         extendToolBar();
     }
 
@@ -122,6 +134,8 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
                 }
 
             }));
+
+        addToolBarButton(processButtonHolder.getButton());
     }
 
     public static final String createId(final IIdentifiable identifiable)
@@ -245,6 +259,23 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
     {
         super.updateOriginalData(result);
         browseButtonHolder.setupData(result);
+        processButtonHolder.setupData(result);
+    }
+
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        return new DatabaseModificationKind[]
+            { DatabaseModificationKind.edit(ObjectKind.DATA_SET),
+                    DatabaseModificationKind.createOrDelete(ObjectKind.DATA_SET),
+                    DatabaseModificationKind.createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT),
+                    DatabaseModificationKind.edit(ObjectKind.PROPERTY_TYPE_ASSIGNMENT),
+                    DatabaseModificationKind.createOrDelete(ObjectKind.VOCABULARY_TERM),
+                    DatabaseModificationKind.edit(ObjectKind.VOCABULARY_TERM), };
+    }
+
+    public void update(Set<DatabaseModificationKind> observedModifications)
+    {
+        reloadData(); // reloads everything
     }
 
     /**
@@ -288,20 +319,149 @@ abstract public class GenericDataSetViewer extends AbstractViewer<ExternalData>
         }
     }
 
-    public DatabaseModificationKind[] getRelevantModifications()
+    /**
+     * Holder of a {@link Button} that has a menu with items that schedule dataset plugin
+     * processing. The button is hidden at the beginning. When data set is successfully loaded by
+     * the viewer and there is a nonempty list of plugins assigned to its data type data then the
+     * menu is filled and button is shown.
+     */
+    private class ProcessButtonHolder
     {
-        return new DatabaseModificationKind[]
-            { DatabaseModificationKind.edit(ObjectKind.DATA_SET),
-                    DatabaseModificationKind.createOrDelete(ObjectKind.DATA_SET),
-                    DatabaseModificationKind.createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT),
-                    DatabaseModificationKind.edit(ObjectKind.PROPERTY_TYPE_ASSIGNMENT),
-                    DatabaseModificationKind.createOrDelete(ObjectKind.VOCABULARY_TERM),
-                    DatabaseModificationKind.edit(ObjectKind.VOCABULARY_TERM), };
+        private final Button button;
+
+        public ProcessButtonHolder()
+        {
+            this.button = createProcessButton();
+        }
+
+        private Button createProcessButton()
+        {
+            final Button result = new Button(viewContext.getMessage(Dict.BUTTON_PROCESS));
+            // need to set menu here, otherwise menu button will not be displayed
+            result.setMenu(new Menu());
+            result.hide();
+            return result;
+        }
+
+        public Button getButton()
+        {
+            return this.button;
+        }
+
+        /** @param data external data that will be processed */
+        public void setupData(final ExternalData data)
+        {
+            viewContext.getCommonService().listDataStoreServices(DataStoreServiceKind.PROCESSING,
+                    new ProcessingServicesCallback(viewContext, getOriginalData(), button));
+        }
     }
 
-    public void update(Set<DatabaseModificationKind> observedModifications)
+    private static final class ProcessingServicesCallback extends
+            AbstractAsyncCallback<List<DatastoreServiceDescription>>
     {
-        reloadData(); // reloads everything
+
+        private final ExternalData dataset;
+
+        private final Button processButton;
+
+        public ProcessingServicesCallback(IViewContext<?> viewContext, ExternalData dataset,
+                Button processButton)
+        {
+            super(viewContext);
+            this.dataset = dataset;
+            this.processButton = processButton;
+        }
+
+        @Override
+        protected void process(List<DatastoreServiceDescription> result)
+        {
+            List<DatastoreServiceDescription> matchingServices = filterNotMatching(result);
+            if (matchingServices.size() > 0)
+            {
+                processButton.setMenu(createPerformProcessingMenu(matchingServices));
+                processButton.show();
+            }
+        }
+
+        private List<DatastoreServiceDescription> filterNotMatching(
+                List<DatastoreServiceDescription> services)
+        {
+            List<DatastoreServiceDescription> matchingServices =
+                    new ArrayList<DatastoreServiceDescription>();
+            for (DatastoreServiceDescription service : services)
+            {
+                if (DatastoreServiceDescription.isMatching(service, dataset))
+                {
+                    matchingServices.add(service);
+                }
+            }
+            return matchingServices;
+        }
+
+        private Menu createPerformProcessingMenu(List<DatastoreServiceDescription> services)
+        {
+            Menu result = new Menu();
+            final DisplayedOrSelectedDatasetCriteria criteria =
+                    DisplayedOrSelectedDatasetCriteria.createSelectedItems(Arrays.asList(dataset
+                            .getCode()));
+            for (DatastoreServiceDescription service : services)
+            {
+                result.add(new ActionMenu(createActionMenuItem(service), viewContext,
+                        createProcessDatasetAction(service, criteria)));
+            }
+            return result;
+        }
+
+        private IActionMenuItem createActionMenuItem(final DatastoreServiceDescription service)
+        {
+            return new IActionMenuItem()
+                {
+                    public String getMenuId()
+                    {
+                        return service.getKey();
+                    }
+
+                    public String getMenuText(IMessageProvider messageProvider)
+                    {
+                        return service.getLabel();
+                    }
+                };
+        }
+
+        private IDelegatedAction createProcessDatasetAction(
+                final DatastoreServiceDescription service,
+                final DisplayedOrSelectedDatasetCriteria criteria)
+        {
+            return new IDelegatedAction()
+                {
+                    public void execute()
+                    {
+                        viewContext.getCommonService().processDatasets(service, criteria,
+                                new ProcessingDisplayCallback(viewContext, service));
+                    }
+                };
+        }
+
+    }
+
+    private static final class ProcessingDisplayCallback extends AbstractAsyncCallback<Void>
+    {
+        private final DatastoreServiceDescription service;
+
+        private ProcessingDisplayCallback(IViewContext<?> viewContext,
+                DatastoreServiceDescription service)
+        {
+            super(viewContext);
+            this.service = service;
+        }
+
+        @Override
+        public final void process(final Void result)
+        {
+            final String title = viewContext.getMessage(Dict.PROCESSING_INFO_TITLE);
+            final String msg = viewContext.getMessage(Dict.PROCESSING_INFO_MSG, service.getLabel());
+            MessageBox.info(title, msg, null);
+        }
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
index 513fb4b9c08..ce543e541c3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
@@ -83,6 +83,7 @@ var common = {
   button_delete: "Delete",
   button_configure: "Settings",  
   button_upload_data_via_cifex: "Upload Data",
+  button_process: "Process",
   button_top: "Files",
   
   tooltip_refresh_disabled: "To activate select appropriate criteria first.",
@@ -513,7 +514,12 @@ var common = {
  confirm_dataset_upload_user_field: "CIFEX user",
  confirm_dataset_upload_password_field: "CIFEX password",
  
+ //
+ // Data Set Viewer
+ //
  
+ processing_info_title: "Processing",
+ processing_info_msg: "'{0}' has been scheduled successfully. Email will be send to you when it is finished.",
  
  //
  // Material Browser
-- 
GitLab