Skip to content

Commit caeed04

Browse files
add List support to Converter.convert()
basic Converter junit test
1 parent 82652d5 commit caeed04

2 files changed

Lines changed: 81 additions & 3 deletions

File tree

api/src/org/labkey/api/data/MultiChoice.java

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
import org.apache.commons.beanutils.ConvertUtils;
44
import org.apache.commons.lang3.StringUtils;
55
import org.jetbrains.annotations.NotNull;
6+
import org.json.JSONArray;
7+
import org.junit.Assert;
8+
import org.junit.Test;
69
import org.labkey.api.collections.CaseInsensitiveHashSet;
710
import org.labkey.api.exp.property.IPropertyValidator;
811
import org.labkey.api.exp.property.PropertyService;
912
import org.labkey.api.gwt.client.model.PropertyValidatorType;
1013
import org.labkey.api.ontology.Unit;
14+
import org.labkey.api.reader.TabLoader;
1115
import org.labkey.api.util.DOM;
1216
import org.labkey.api.util.HtmlString;
1317
import org.labkey.api.util.PageFlowUtil;
1418
import org.labkey.api.writer.HtmlWriter;
1519

20+
import java.io.StringBufferInputStream;
1621
import java.sql.ResultSet;
1722
import java.sql.SQLException;
1823
import java.sql.Types;
@@ -186,6 +191,7 @@ protected Array(Stream<Object> str)
186191
array = str.filter(Objects::nonNull)
187192
.map(s -> StringUtils.trimToNull(s.toString()))
188193
.filter(Objects::nonNull)
194+
.filter(set::add)
189195
.toArray(String[]::new);
190196
}
191197

@@ -206,6 +212,20 @@ private List<String> getList()
206212
return list;
207213
}
208214

215+
@Override
216+
public boolean equals(Object obj)
217+
{
218+
if (!(obj instanceof Array arr))
219+
return false;
220+
return Arrays.equals(array, arr.array);
221+
}
222+
223+
@Override
224+
public int hashCode()
225+
{
226+
return Arrays.hashCode(array);
227+
}
228+
209229
@Override
210230
public String toString()
211231
{
@@ -491,13 +511,17 @@ public static Converter getInstance()
491511
public <T> T convert(Class<T> aClass, Object o)
492512
{
493513
if (null == o)
494-
return (T) List.of();
514+
return (T) Array.from(new String[]{});
515+
if (o instanceof MultiChoice.Array arr)
516+
return (T)arr;
495517
if (o instanceof String s)
496518
return (T) Array.from(s);
497-
if (o instanceof org.json.JSONArray json)
498-
return (T) Array.from(json);
499519
if (o.getClass().isArray())
500520
return (T) Array.from((Object[]) o);
521+
if (o instanceof org.json.JSONArray json)
522+
return (T) Array.from(json);
523+
if (o instanceof List list)
524+
return (T) new Array(list.stream());
501525
return (T) Array.from(o.toString());
502526
}
503527

@@ -507,4 +531,56 @@ final public Object apply(Object o)
507531
return convert(MultiChoice.Array.class, o);
508532
}
509533
}
534+
535+
536+
537+
public static class TestCase extends Assert
538+
{
539+
@Test
540+
public void testConvert() throws Exception
541+
{
542+
Array expected = Array.from(new String[]{"a,","b\"","c "});
543+
544+
assertEquals(expected, _converter.convert(Array.class, expected));
545+
assertEquals(expected, _converter.convert(Array.class, "\"a,\",\"b\"\"\",\"c \""));
546+
assertEquals(expected, _converter.convert(Array.class, new String[]{"a,","b\"","c "}));
547+
assertEquals(expected, _converter.convert(Array.class, List.of("a,","b\"","c ")));
548+
assertEquals(expected, _converter.convert(Array.class, new JSONArray(List.of("a,","b\"","c "))));
549+
}
550+
551+
@Test
552+
public void testCSV() throws Exception
553+
{
554+
Array expected = Array.from(new String[]{"a,", "b\\", "c,d", "e\"f"});
555+
// toString() == "a,", b\, "c,d", "e""f"
556+
assertEquals("\"a,\", b\\, \"c,d\", \"e\"\"f\"", expected.toString());
557+
558+
// csv/tsv with double double-quote escaping
559+
// add " around entire value, and double the "
560+
// (need to use some \" to avoid ending the """ """ block)
561+
String oneMultiValueColumn = """
562+
column
563+
""\"a,"", b\\, ""c,d"", ""e""\""f""\"
564+
""";
565+
566+
try (var csvLoader = new TabLoader.CsvFactory().createLoader(new StringBufferInputStream(oneMultiValueColumn), true))
567+
{
568+
var maps = csvLoader.load();
569+
assertEquals(1, maps.size());
570+
Map<String,Object> map = maps.get(0);
571+
assertTrue(map.get("column") instanceof String);
572+
String value = (String) map.get("column");
573+
assertEquals(expected, Array.from(value));
574+
}
575+
try (var tsvLoader = new TabLoader.TsvFactory().createLoader(new StringBufferInputStream(oneMultiValueColumn), true))
576+
{
577+
var maps = tsvLoader.load();
578+
assertEquals(1, maps.size());
579+
Map<String,Object> map = maps.get(0);
580+
assertTrue(map.get("column") instanceof String);
581+
String value = (String) map.get("column");
582+
assertEquals(expected, Array.from(value));
583+
}
584+
}
585+
}
510586
}

core/src/org/labkey/core/CoreModule.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.labkey.api.data.DbSchema;
6161
import org.labkey.api.data.DbScope;
6262
import org.labkey.api.data.FileSqlScriptProvider;
63+
import org.labkey.api.data.MultiChoice;
6364
import org.labkey.api.data.MvUtil;
6465
import org.labkey.api.data.NormalContainerType;
6566
import org.labkey.api.data.OutOfRangeDisplayColumn;
@@ -1454,6 +1455,7 @@ public TabDisplayMode getTabDisplayMode()
14541455
ApiJsonWriter.TestCase.class,
14551456
ClassLoaderTestCase.class,
14561457
CopyFileRootPipelineJob.TestCase.class,
1458+
MultiChoice.TestCase.class,
14571459
OutOfRangeDisplayColumn.TestCase.class,
14581460
PostgreSqlVersion.TestCase.class,
14591461
ScriptEngineManagerImpl.TestCase.class,

0 commit comments

Comments
 (0)