From 23c9a3fefc1c881611a73be9a5bfc07c4be30817 Mon Sep 17 00:00:00 2001
From: pkupczyk <pkupczyk>
Date: Tue, 4 Jun 2013 11:57:18 +0000
Subject: [PATCH] SP-652 / BIS-402: KNIME UI problems with 2 data store servers
 - allow merging an empty column with any type of column

SVN: 29283
---
 .../server/business/bo/DataSetTable.java      |  6 ++--
 .../shared/basic/TableModelAppender.java      | 26 ++++++++++----
 .../shared/util/SimpleTableModelBuilder.java  | 14 +++-----
 .../shared/basic/TableModelAppenderTest.java  | 36 ++++++++++++++++---
 4 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java
index 2138fa7ef7d..b9c01820e33 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java
@@ -60,7 +60,7 @@ import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnCountException;
-import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnTypesException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithIncompatibleColumnTypesException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
@@ -675,10 +675,10 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements
                 throw new UserFailureException("Could not merge reports from multiple data stores because '" + batchResults.getBatchId()
                         + "' data store returned a table with an incorrect number of columns (expected: " + e.getExpectedColumnCount()
                         + ", got: " + e.getAppendedColumnCount() + ")");
-            } catch (TableModelWithDifferentColumnTypesException e)
+            } catch (TableModelWithIncompatibleColumnTypesException e)
             {
                 throw new UserFailureException("Could not merge reports from multiple data stores because '" + batchResults.getBatchId()
-                        + "' data store returned a table with incorrect types of columns (expected: " + e.getExpectedColumnTypes()
+                        + "' data store returned a table with incompatible types of columns (expected: " + e.getExpectedColumnTypes()
                         + ", got: " + e.getAppendedColumnTypes() + ")");
             }
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppender.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppender.java
index 1b8bb0ba570..691eccf82c8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppender.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppender.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.shared.basic;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
@@ -83,14 +84,27 @@ public class TableModelAppender
             expectedTypes.add(expectedHeader.getDataType());
         }
 
-        for (TableModelColumnHeader appendedHeader : tableModel.getHeader())
+        if (tableModel.getHeader() != null)
         {
-            appendedTypes.add(appendedHeader.getDataType());
+            for (TableModelColumnHeader appendedHeader : tableModel.getHeader())
+            {
+                appendedTypes.add(appendedHeader.getDataType());
+            }
         }
 
-        if (expectedTypes.equals(appendedTypes) == false)
+        Iterator<DataTypeCode> expectedTypeIter = expectedTypes.iterator();
+        Iterator<DataTypeCode> appendedTypeIter = appendedTypes.iterator();
+
+        while (expectedTypeIter.hasNext() && appendedTypeIter.hasNext())
         {
-            throw new TableModelWithDifferentColumnTypesException(expectedTypes, appendedTypes);
+            DataTypeCode expectedType = expectedTypeIter.next();
+            DataTypeCode appendedType = appendedTypeIter.next();
+
+            if (expectedType != null && appendedType != null
+                    && expectedType.equals(appendedType) == false)
+            {
+                throw new TableModelWithIncompatibleColumnTypesException(expectedTypes, appendedTypes);
+            }
         }
     }
 
@@ -133,7 +147,7 @@ public class TableModelAppender
 
     }
 
-    public static class TableModelWithDifferentColumnTypesException extends IllegalTableModelException
+    public static class TableModelWithIncompatibleColumnTypesException extends IllegalTableModelException
     {
 
         private static final long serialVersionUID = 1L;
@@ -142,7 +156,7 @@ public class TableModelAppender
 
         private List<DataTypeCode> appendedColumnTypes;
 
-        public TableModelWithDifferentColumnTypesException(List<DataTypeCode> expectedColumnTypes, List<DataTypeCode> appendedColumnTypes)
+        public TableModelWithIncompatibleColumnTypesException(List<DataTypeCode> expectedColumnTypes, List<DataTypeCode> appendedColumnTypes)
         {
             this.expectedColumnTypes = expectedColumnTypes;
             this.appendedColumnTypes = appendedColumnTypes;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimpleTableModelBuilder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimpleTableModelBuilder.java
index 899113bd1bc..077b008c0f7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimpleTableModelBuilder.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimpleTableModelBuilder.java
@@ -81,8 +81,7 @@ public class SimpleTableModelBuilder
     /**
      * Adds header with specified title and default column width 150.
      * 
-     * @throws UserFailureException if non-unique header titles are not allowed and a header with
-     *             same title has already been added.
+     * @throws UserFailureException if non-unique header titles are not allowed and a header with same title has already been added.
      */
     public void addHeader(String title)
     {
@@ -92,8 +91,7 @@ public class SimpleTableModelBuilder
     /**
      * Adds header with specified title, specified code and default column width 150.
      * 
-     * @throws UserFailureException if non-unique header titles are not allowed and a header with
-     *             same title has already been added.
+     * @throws UserFailureException if non-unique header titles are not allowed and a header with same title has already been added.
      */
     public void addHeader(String title, String code)
     {
@@ -103,8 +101,7 @@ public class SimpleTableModelBuilder
     /**
      * Adds header with specified title and specified default column width.
      * 
-     * @throws UserFailureException if non-unique header titles are not allowed and a header with
-     *             same title has already been added.
+     * @throws UserFailureException if non-unique header titles are not allowed and a header with same title has already been added.
      */
     public void addHeader(String title, int defaultColumnWidth)
     {
@@ -114,8 +111,7 @@ public class SimpleTableModelBuilder
     /**
      * Adds header with specified title, specified code and specified default column width.
      * 
-     * @throws UserFailureException if non-unique header titles are not allowed and a header with
-     *             same title has already been added.
+     * @throws UserFailureException if non-unique header titles are not allowed and a header with same title has already been added.
      */
     private void addHeader(String title, String code, int defaultColumnWidth)
     {
@@ -223,7 +219,7 @@ public class SimpleTableModelBuilder
         TableModelColumnHeader header = headers.get(index);
         DataTypeCode headerDataType = header.getDataType();
         DataTypeCode dataType = getDataTypeCodeFor(value);
-        if (StringUtils.isBlank(value.toString()) == false)
+        if (value != null && StringUtils.isBlank(value.toString()) == false)
         {
             DataTypeCode compatibleDataType =
                     DataTypeUtils.getCompatibleDataType(headerDataType, dataType);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppenderTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppenderTest.java
index 6de28fc31f4..04a21ee063c 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppenderTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/basic/TableModelAppenderTest.java
@@ -24,7 +24,7 @@ import junit.framework.Assert;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnCountException;
-import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnTypesException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithIncompatibleColumnTypesException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.StringTableCell;
@@ -112,7 +112,35 @@ public class TableModelAppenderTest
     }
 
     @Test
-    public void testAppendWithDifferentTypesOfColumns()
+    public void testAppendWithCompatibleTypesOfColumns()
+    {
+        SimpleTableModelBuilder builder1 = new SimpleTableModelBuilder();
+        builder1.addHeader("column1");
+        builder1.addHeader("column2");
+        builder1.addRow(Arrays.asList(SimpleTableModelBuilder.asText("row1_column1"), SimpleTableModelBuilder.asText("row1_column2")));
+        builder1.addRow(Arrays.asList(SimpleTableModelBuilder.asText("row2_column1"), SimpleTableModelBuilder.asText("row2_column2")));
+
+        SimpleTableModelBuilder builder2 = new SimpleTableModelBuilder();
+        builder2.addHeader("column1");
+        builder2.addHeader("column2");
+        builder2.addRow(Arrays.asList(null, SimpleTableModelBuilder.asText("row3_column2")));
+
+        TableModelAppender appender = new TableModelAppender();
+        appender.append(builder1.getTableModel());
+        appender.append(builder2.getTableModel());
+        TableModel result = appender.toTableModel();
+
+        Assert.assertEquals(2, result.getHeader().size());
+        Assert.assertEquals(3, result.getRows().size());
+
+        assertHeaders(result, "column1", "column2");
+        assertRow(result, 0, "row1_column1", "row1_column2");
+        assertRow(result, 1, "row2_column1", "row2_column2");
+        assertRow(result, 2, null, "row3_column2");
+    }
+
+    @Test
+    public void testAppendWithIncompatibleTypesOfColumns()
     {
         SimpleTableModelBuilder builder1 = new SimpleTableModelBuilder();
         builder1.addHeader("column1");
@@ -131,7 +159,7 @@ public class TableModelAppenderTest
             appender.append(builder1.getTableModel());
             appender.append(builder2.getTableModel());
             Assert.fail();
-        } catch (TableModelWithDifferentColumnTypesException e)
+        } catch (TableModelWithIncompatibleColumnTypesException e)
         {
             Assert.assertEquals(Arrays.asList(DataTypeCode.VARCHAR, DataTypeCode.VARCHAR), e.getExpectedColumnTypes());
             Assert.assertEquals(Arrays.asList(DataTypeCode.VARCHAR, DataTypeCode.INTEGER), e.getAppendedColumnTypes());
@@ -155,7 +183,7 @@ public class TableModelAppenderTest
         for (ISerializableComparable value : row.getValues())
         {
             StringTableCell cell = (StringTableCell) value;
-            Assert.assertEquals(rowValues[columnIndex++], cell.toString());
+            Assert.assertEquals(rowValues[columnIndex++], cell != null ? cell.toString() : null);
         }
     }
 }
-- 
GitLab