From cfb2140145b61b848d731040be4c1d52a3dc153e Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Wed, 22 Jun 2011 08:17:19 +0000
Subject: [PATCH] GridCustomColumnGrid refactored into a TypedTableGrid

SVN: 21793
---
 .../web/client/ICommonClientService.java      |   6 +-
 .../web/client/ICommonClientServiceAsync.java |   6 +-
 .../specific/CustomGridColumnColDefKind.java  | 115 ------------------
 .../column/GridCustomColumnGrid.java          |  84 +++++++------
 .../dto/CustomGridColumnGridColumnIDs.java    |  33 +++++
 .../web/server/CommonClientService.java       |  21 ++--
 .../resultset/CustomGridColumnProvider.java   |  76 ++++++++++++
 7 files changed, 168 insertions(+), 173 deletions(-)
 delete mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomGridColumnGridColumnIDs.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/CustomGridColumnProvider.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index 9a8d82ed042..dfd4d53e22e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -988,14 +988,14 @@ public interface ICommonClientService extends IClientService
     /**
      * Returns {@link GridCustomColumn}s for given grid and display criteria.
      */
-    public ResultSet<GridCustomColumn> listGridCustomColumns(String gridId,
-            DefaultResultSetConfig<String, GridCustomColumn> resultSetConfig)
+    public TypedTableResultSet<GridCustomColumn> listGridCustomColumns(String gridId,
+            DefaultResultSetConfig<String, TableModelRowWithObject<GridCustomColumn>> resultSetConfig)
             throws UserFailureException;
 
     /**
      * Like {@link #prepareExportSamples(TableExportCriteria)}, but for custom grid filters.
      */
-    public String prepareExportColumns(final TableExportCriteria<GridCustomColumn> criteria)
+    public String prepareExportColumns(final TableExportCriteria<TableModelRowWithObject<GridCustomColumn>> criteria)
             throws UserFailureException;
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index e8a258c3ed8..e9304a98d6a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -891,13 +891,13 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
      * @see ICommonClientService#listGridCustomColumns(String, DefaultResultSetConfig)
      */
     public void listGridCustomColumns(String gridId,
-            DefaultResultSetConfig<String, GridCustomColumn> resultSetConfig,
-            AsyncCallback<ResultSet<GridCustomColumn>> callback);
+            DefaultResultSetConfig<String, TableModelRowWithObject<GridCustomColumn>> resultSetConfig,
+            AsyncCallback<TypedTableResultSet<GridCustomColumn>> callback);
 
     /**
      * @see ICommonClientService#prepareExportColumns(TableExportCriteria)
      */
-    public void prepareExportColumns(final TableExportCriteria<GridCustomColumn> criteria,
+    public void prepareExportColumns(final TableExportCriteria<TableModelRowWithObject<GridCustomColumn>> criteria,
             AsyncCallback<String> asyncCallback);
 
     /** @see ICommonClientService#registerColumn(NewColumnOrFilter) */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java
deleted file mode 100644
index 12eab1723fc..00000000000
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2009 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomColumn;
-
-/**
- * Column definitions for the grid custom columns.<br>
- * It's very similar to the column definition enum for filters, but the code cannot be common
- * because enums can inherit only from interfaces.
- * 
- * @author Tomasz Pylak
- */
-public enum CustomGridColumnColDefKind implements IColumnDefinitionKind<GridCustomColumn>
-{
-    CODE(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.CODE)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return entity.getCode();
-            }
-        }),
-
-    NAME(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.NAME)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return entity.getName();
-            }
-        }),
-
-    DESCRIPTION(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.DESCRIPTION)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return entity.getDescription();
-            }
-        }),
-
-    EXPRESSION(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.EXPRESSION, true)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return entity.getExpression();
-            }
-        }),
-
-    PUBLIC(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.IS_PUBLIC, true)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return SimpleYesNoRenderer.render(entity.isPublic());
-            }
-        }),
-
-    REGISTRATOR(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.REGISTRATOR, true)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return renderRegistrator(entity);
-            }
-        }),
-
-    REGISTRATION_DATE(new AbstractColumnDefinitionKind<GridCustomColumn>(Dict.REGISTRATION_DATE,
-            AbstractColumnDefinitionKind.DATE_COLUMN_WIDTH, true)
-        {
-            @Override
-            public String tryGetValue(GridCustomColumn entity)
-            {
-                return renderRegistrationDate(entity);
-            }
-        });
-
-    private final AbstractColumnDefinitionKind<GridCustomColumn> columnDefinitionKind;
-
-    private CustomGridColumnColDefKind(
-            AbstractColumnDefinitionKind<GridCustomColumn> columnDefinitionKind)
-    {
-        this.columnDefinitionKind = columnDefinitionKind;
-    }
-
-    public String id()
-    {
-        return name();
-    }
-
-    public AbstractColumnDefinitionKind<GridCustomColumn> getDescriptor()
-    {
-        return columnDefinitionKind;
-    }
-}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/expressions/column/GridCustomColumnGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/expressions/column/GridCustomColumnGrid.java
index e5fb71ed2f9..eb8732da68c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/expressions/column/GridCustomColumnGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/expressions/column/GridCustomColumnGrid.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.expressions.column;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import com.extjs.gxt.ui.client.event.ButtonEvent;
@@ -34,35 +35,34 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplayTypeIDGenerator;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.help.HelpPageIdentifier;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.BaseEntityModel;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.CustomGridColumnColDefKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.TypedTableGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractColumnSettingsDataModelProvider;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractSimpleBrowserGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IBrowserGridActionInvoker;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.expressions.common.AbstractGridCustomExpressionEditOrRegisterDialog;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.AbstractDataConfirmationDialog;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedAction;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridRowModels;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExpression;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomColumn;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
 
 /**
  * Allows to display, update, delete and create new custom grid columns.
  * 
  * @author Tomasz Pylak
  */
-public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomColumn>
+public class GridCustomColumnGrid extends TypedTableGrid<GridCustomColumn>
 {
     private static final String BROWSER_ID =
             GenericConstants.ID_PREFIX + "custom-grid-column-browser";
@@ -81,7 +81,7 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
 
     static final String createGridId(String gridDisplayId)
     {
-        return createBrowserId(gridDisplayId) + "_grid";
+        return createBrowserId(gridDisplayId) + TypedTableGrid.GRID_POSTFIX;
     }
 
     private static final String createBrowserId(String gridDisplayId)
@@ -111,12 +111,12 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
         addButton(addButton);
         final Button editButton =
                 createSelectedItemButton(viewContext.getMessage(Dict.BUTTON_EDIT),
-                        new ISelectedEntityInvoker<BaseEntityModel<GridCustomColumn>>()
+                        new ISelectedEntityInvoker<BaseEntityModel<TableModelRowWithObject<GridCustomColumn>>>()
                             {
-                                public void invoke(BaseEntityModel<GridCustomColumn> selectedItem,
+                                public void invoke(BaseEntityModel<TableModelRowWithObject<GridCustomColumn>> selectedItem,
                                         boolean keyPressed)
                                 {
-                                    final GridCustomColumn selected = selectedItem.getBaseObject();
+                                    final GridCustomColumn selected = selectedItem.getBaseObject().getObjectOrNull();
                                     createEditDialog(selected).show();
                                 }
 
@@ -127,7 +127,7 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
                         new AbstractCreateDialogListener()
                             {
                                 @Override
-                                protected Dialog createDialog(List<GridCustomColumn> selected,
+                                protected Dialog createDialog(List<TableModelRowWithObject<GridCustomColumn>> selected,
                                         IBrowserGridActionInvoker invoker)
                                 {
                                     return new DeletionConfirmationDialog(viewContext, selected,
@@ -214,7 +214,7 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
     }
 
     private static class DeletionConfirmationDialog extends
-            AbstractDataConfirmationDialog<List<GridCustomColumn>>
+            AbstractDataConfirmationDialog<List<TableModelRowWithObject<GridCustomColumn>>>
     {
         private static final int LABEL_WIDTH = 60;
 
@@ -225,7 +225,7 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
         private final AbstractAsyncCallback<Void> callback;
 
         public DeletionConfirmationDialog(IViewContext<ICommonClientServiceAsync> viewContext,
-                List<GridCustomColumn> data, AbstractAsyncCallback<Void> callback)
+                List<TableModelRowWithObject<GridCustomColumn>> data, AbstractAsyncCallback<Void> callback)
         {
             super(viewContext, data, viewContext.getMessage(Dict.DELETE_CONFIRMATION_TITLE));
             this.callback = callback;
@@ -256,7 +256,7 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
     private GridCustomColumnGrid(IViewContext<ICommonClientServiceAsync> viewContext,
             String gridDisplayId, AbstractColumnSettingsDataModelProvider columnDataModelProvider)
     {
-        super(viewContext, createBrowserId(gridDisplayId), createGridId(gridDisplayId),
+        super(viewContext, createBrowserId(gridDisplayId), true,
                 DisplayTypeIDGenerator.CUSTOM_GRID_COLUMN_GRID);
         this.gridDisplayId = gridDisplayId;
         this.columnDataModelProvider = columnDataModelProvider;
@@ -264,14 +264,15 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
     }
 
     @Override
-    protected IColumnDefinitionKind<GridCustomColumn>[] getStaticColumnsDefinition()
+    protected String translateColumnIdToDictionaryKey(String columnID)
     {
-        return CustomGridColumnColDefKind.values();
+        return columnID.toLowerCase();
     }
-
+    
     @Override
-    protected void listEntities(DefaultResultSetConfig<String, GridCustomColumn> resultSetConfig,
-            final AbstractAsyncCallback<ResultSet<GridCustomColumn>> callback)
+    protected void listTableRows(
+            DefaultResultSetConfig<String, TableModelRowWithObject<GridCustomColumn>> resultSetConfig,
+            final AsyncCallback<TypedTableResultSet<GridCustomColumn>> callback)
     {
         final int orgOffset = resultSetConfig.getOffset();
         final int orgLimit = resultSetConfig.getLimit();
@@ -279,29 +280,34 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
         // model with it. There should not be that many custom columns.
         resultSetConfig.setOffset(0);
         resultSetConfig.setLimit(DefaultResultSetConfig.NO_LIMIT);
-        AsyncCallback<ResultSet<GridCustomColumn>> wrappedCallback =
-                new AsyncCallback<ResultSet<GridCustomColumn>>()
+        AsyncCallback<TypedTableResultSet<GridCustomColumn>> wrappedCallback =
+                new AsyncCallback<TypedTableResultSet<GridCustomColumn>>()
                     {
-                        public void onSuccess(ResultSet<GridCustomColumn> result)
+                        public void onSuccess(TypedTableResultSet<GridCustomColumn> result)
                         {
-                            List<GridCustomColumn> allCustomColumns =
-                                    result.getList().extractOriginalObjects();
-                            columnDataModelProvider.refreshCustomColumns(allCustomColumns);
+                            List<TableModelRowWithObject<GridCustomColumn>> allCustomColumns =
+                                    result.getResultSet().getList().extractOriginalObjects();
+                            List<GridCustomColumn> columns = new ArrayList<GridCustomColumn>();
+                            for (TableModelRowWithObject<GridCustomColumn> row : allCustomColumns)
+                            {
+                                columns.add(row.getObjectOrNull());
+                            }
+                            columnDataModelProvider.refreshCustomColumns(columns);
                             setPageFromAllFetched(result, orgOffset, orgLimit);
                             callback.onSuccess(result);
                         }
 
-                        private void setPageFromAllFetched(ResultSet<GridCustomColumn> result,
+                        private void setPageFromAllFetched(TypedTableResultSet<GridCustomColumn> result,
                                 final int offset, final int limit)
                         {
-                            GridRowModels<GridCustomColumn> allModel = result.getList();
-                            List<GridRowModel<GridCustomColumn>> pageResult =
-                                    new ArrayList<GridRowModel<GridCustomColumn>>(limit);
+                            GridRowModels<TableModelRowWithObject<GridCustomColumn>> allModel = result.getResultSet().getList();
+                            List<GridRowModel<TableModelRowWithObject<GridCustomColumn>>> pageResult =
+                                    new ArrayList<GridRowModel<TableModelRowWithObject<GridCustomColumn>>>(limit);
                             for (int i = offset; i < Math.min(offset + limit, allModel.size()); i++)
                             {
                                 pageResult.add(allModel.get(i));
                             }
-                            result.setList(allModel.cloneWithData(pageResult));
+                            result.getResultSet().setList(allModel.cloneWithData(pageResult));
                         }
 
                         public void onFailure(Throwable caught)
@@ -314,30 +320,30 @@ public class GridCustomColumnGrid extends AbstractSimpleBrowserGrid<GridCustomCo
     }
 
     @Override
-    protected void prepareExportEntities(TableExportCriteria<GridCustomColumn> exportCriteria,
+    protected void prepareExportEntities(TableExportCriteria<TableModelRowWithObject<GridCustomColumn>> exportCriteria,
             AbstractAsyncCallback<String> callback)
     {
         viewContext.getService().prepareExportColumns(exportCriteria, callback);
     }
 
     @Override
-    protected List<IColumnDefinition<GridCustomColumn>> getInitialFilters()
+    protected List<String> getColumnIdsOfFilters()
     {
-        return asColumnFilters(new CustomGridColumnColDefKind[]
-            { CustomGridColumnColDefKind.NAME, CustomGridColumnColDefKind.PUBLIC });
+        return Arrays.asList(CustomGridColumnGridColumnIDs.NAME, CustomGridColumnGridColumnIDs.IS_PUBLIC);
     }
 
     @Override
-    protected ColumnDefsAndConfigs<GridCustomColumn> createColumnsDefinition()
+    protected ColumnDefsAndConfigs<TableModelRowWithObject<GridCustomColumn>> createColumnsDefinition()
     {
-        ColumnDefsAndConfigs<GridCustomColumn> schema = super.createColumnsDefinition();
-        schema.setGridCellRendererFor(CustomGridColumnColDefKind.DESCRIPTION.id(),
+        ColumnDefsAndConfigs<TableModelRowWithObject<GridCustomColumn>> schema = super.createColumnsDefinition();
+        schema.setGridCellRendererFor(CustomGridColumnGridColumnIDs.DESCRIPTION,
                 createMultilineStringCellRenderer());
-        schema.setGridCellRendererFor(CustomGridColumnColDefKind.EXPRESSION.id(),
+        schema.setGridCellRendererFor(CustomGridColumnGridColumnIDs.EXPRESSION,
                 createMultilineStringCellRenderer());
         return schema;
     }
 
+    @Override
     public DatabaseModificationKind[] getRelevantModifications()
     {
         return new DatabaseModificationKind[]
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomGridColumnGridColumnIDs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomGridColumnGridColumnIDs.java
new file mode 100644
index 00000000000..1f9515908a2
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomGridColumnGridColumnIDs.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class CustomGridColumnGridColumnIDs
+{
+    public static final String CODE = "CODE";
+    public static final String NAME = "NAME";
+    public static final String DESCRIPTION = "DESCRIPTION";
+    public static final String EXPRESSION = "EXPRESSION";
+    public static final String IS_PUBLIC = "IS_PUBLIC";
+    public static final String REGISTRATOR = "REGISTRATOR";
+    public static final String REGISTRATION_DATE = "REGISTRATION_DATE";
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index 645932a6974..41bcbca3e59 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -70,6 +70,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.calculator.ITableDataP
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.AttachmentVersionsProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.AuthorizationGroupProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.CacheManager;
+import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.CustomGridColumnProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.DataSetTypeProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.EntityTypeProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.ExperimentProvider;
@@ -2551,23 +2552,17 @@ public final class CommonClientService extends AbstractClientService implements
         }
     }
 
-    public ResultSet<GridCustomColumn> listGridCustomColumns(final String gridId,
-            DefaultResultSetConfig<String, GridCustomColumn> resultSetConfig)
+    public TypedTableResultSet<GridCustomColumn> listGridCustomColumns(
+            final String gridId,
+            DefaultResultSetConfig<String, TableModelRowWithObject<GridCustomColumn>> resultSetConfig)
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
-        return listEntities(resultSetConfig,
-                new AbstractOriginalDataProviderWithoutHeaders<GridCustomColumn>()
-                    {
-                        @Override
-                        public List<GridCustomColumn> getFullOriginalData()
-                                throws UserFailureException
-                        {
-                            return listGridCustomColumns(gridId);
-                        }
-                    });
+        return listEntities(new CustomGridColumnProvider(commonServer, getSessionToken(), gridId),
+                resultSetConfig);
     }
 
-    public String prepareExportColumns(TableExportCriteria<GridCustomColumn> criteria)
+    public String prepareExportColumns(
+            TableExportCriteria<TableModelRowWithObject<GridCustomColumn>> criteria)
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
         return prepareExportEntities(criteria);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/CustomGridColumnProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/CustomGridColumnProvider.java
new file mode 100644
index 00000000000..cb68287470a
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/CustomGridColumnProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.server.resultset;
+
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.CODE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.DESCRIPTION;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.EXPRESSION;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.IS_PUBLIC;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.NAME;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.REGISTRATION_DATE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomGridColumnGridColumnIDs.REGISTRATOR;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomColumn;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableModel;
+import ch.systemsx.cisd.openbis.generic.shared.util.TypedTableModelBuilder;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class CustomGridColumnProvider extends AbstractCommonTableModelProvider<GridCustomColumn>
+{
+    private final String gridId;
+
+    public CustomGridColumnProvider(ICommonServer commonServer, String sessionToken, String gridId)
+    {
+        super(commonServer, sessionToken);
+        this.gridId = gridId;
+    }
+
+    @Override
+    protected TypedTableModel<GridCustomColumn> createTableModel()
+    {
+        List<GridCustomColumn> customColumns = commonServer.listGridCustomColumns(sessionToken, gridId);
+        TypedTableModelBuilder<GridCustomColumn> builder = new TypedTableModelBuilder<GridCustomColumn>();
+        builder.addColumn(CODE);
+        builder.addColumn(NAME);
+        builder.addColumn(DESCRIPTION);
+        builder.addColumn(EXPRESSION).hideByDefault();
+        builder.addColumn(IS_PUBLIC).hideByDefault();
+        builder.addColumn(REGISTRATOR).hideByDefault();
+        builder.addColumn(REGISTRATION_DATE).hideByDefault();
+        for (GridCustomColumn gridCustomColumn : customColumns)
+        {
+            builder.addRow(gridCustomColumn);
+            builder.column(CODE).addString(gridCustomColumn.getCode());
+            builder.column(NAME).addString(gridCustomColumn.getName());
+            builder.column(DESCRIPTION).addString(gridCustomColumn.getDescription());
+            builder.column(EXPRESSION).addString(gridCustomColumn.getExpression());
+            builder.column(IS_PUBLIC).addString(SimpleYesNoRenderer.render(gridCustomColumn.isPublic()));
+            builder.column(REGISTRATOR).addPerson(gridCustomColumn.getRegistrator());
+            builder.column(REGISTRATION_DATE).addDate(gridCustomColumn.getRegistrationDate());
+        }
+        return builder.getModel();
+    }
+
+}
-- 
GitLab