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 2d9ff59947f39926c4c6b5c6a8d810841cda99a1..a14a8487b30f35bf0f8c8d5447d41be59fe403e5 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 @@ -278,14 +278,14 @@ public final class CommonClientService extends AbstractClientService implements final String lineSeparator) { // Not directly needed but this refreshes the session. - getSessionToken(); + String session = getSessionToken(); final TableExportCriteria<T> exportCriteria = getAndRemoveExportCriteria(exportDataKey); final GridRowModels<T> entities = fetchCachedEntities(exportCriteria); EntityKind entityKindForUpdate = exportCriteria.getEntityKindForUpdateOrNull(); if (entityKindForUpdate != null) { return TableForUpdateExporter.getExportTableForUpdate(entities, entityKindForUpdate, - lineSeparator); + lineSeparator, commonServer, session); } ITableDataProvider dataProvider = TableDataProviderFactory.createDataProvider(entities, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporter.java index 623a6853c83ed05ef0c79e387780583fcb8a09d8..49ee880728c8e1552ea5e7ab89582dcc3bae120c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporter.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporter.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -30,15 +31,19 @@ import java.util.TreeMap; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridRowModels; import ch.systemsx.cisd.openbis.generic.client.web.server.IBasicTableDataProvider; import ch.systemsx.cisd.openbis.generic.client.web.server.util.TSVRenderer; +import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject; @@ -53,31 +58,87 @@ public class TableForUpdateExporter @SuppressWarnings("unchecked") public static String getExportTableForUpdate(GridRowModels<?> rows, EntityKind entityKind, - String lineSeparator) + String lineSeparator, ICommonServer commonServer, String sessionToken) { switch (entityKind) { case EXPERIMENT: return getExperimentTableForUpdate( - (GridRowModels<TableModelRowWithObject<Experiment>>) rows, lineSeparator); + (GridRowModels<TableModelRowWithObject<Experiment>>) rows, lineSeparator, + commonServer, sessionToken); case SAMPLE: return getSampleTableForUpdate( - (GridRowModels<TableModelRowWithObject<Sample>>) rows, lineSeparator); + (GridRowModels<TableModelRowWithObject<Sample>>) rows, lineSeparator, + commonServer, sessionToken); case DATA_SET: return getDataSetTableForUpdate( - (GridRowModels<TableModelRowWithObject<ExternalData>>) rows, lineSeparator); + (GridRowModels<TableModelRowWithObject<ExternalData>>) rows, lineSeparator, + commonServer, sessionToken); case MATERIAL: return "Export of materials for update is currently not supported."; } throw new IllegalArgumentException("Unspecified entity kind."); } + private static <T extends Serializable> List<PropertyType> getAllPropertyTypes( + GridRowModels<TableModelRowWithObject<T>> rows, List<? extends EntityType> types) + { + + Set<PropertyType> propertyTypes = new HashSet<PropertyType>(); + + for (GridRowModel<TableModelRowWithObject<T>> row : rows) + { + T t = row.getOriginalObject().getObjectOrNull(); + if (t == null) + { + continue; + } + + for (EntityType type : types) + { + if (type.getCode().equals(getType(t).getCode())) + { + for (EntityTypePropertyType<?> et : type.getAssignedPropertyTypes()) + { + if (et.isDynamic() == false && et.isManaged() == false) + { + propertyTypes.add(et.getPropertyType()); + } + } + } + } + } + + return new ArrayList<PropertyType>(propertyTypes); + } + + private static <T> EntityType getType(T t) + { + if (t instanceof Experiment) + { + return ((Experiment) t).getExperimentType(); + } else if (t instanceof ExternalData) + { + return ((ExternalData) t).getDataSetType(); + } else if (t instanceof Sample) + { + return ((Sample) t).getSampleType(); + } + + throw new IllegalArgumentException("Unknown data type " + t); + } + public static String getExperimentTableForUpdate( - GridRowModels<TableModelRowWithObject<Experiment>> rows, String lineSeparator) + GridRowModels<TableModelRowWithObject<Experiment>> rows, String lineSeparator, + ICommonServer commonServer, String sessionToken) { TypedTableModelBuilder<Experiment> builder = new TypedTableModelBuilder<Experiment>(); builder.addColumn(NewExperiment.IDENTIFIER_COLUMN); builder.addColumn("project"); + + builder.columnGroup("").addColumnsForPropertyTypesForUpdate( + getAllPropertyTypes(rows, commonServer.listExperimentTypes(sessionToken))); + for (GridRowModel<TableModelRowWithObject<Experiment>> row : rows) { Experiment experiment = row.getOriginalObject().getObjectOrNull(); @@ -89,7 +150,8 @@ public class TableForUpdateExporter } public static String getSampleTableForUpdate( - GridRowModels<TableModelRowWithObject<Sample>> rows, String lineSeparator) + GridRowModels<TableModelRowWithObject<Sample>> rows, String lineSeparator, + ICommonServer commonServer, String sessionToken) { Map<String, List<Sample>> samples = new TreeMap<String, List<Sample>>(); for (GridRowModel<TableModelRowWithObject<Sample>> row : rows) @@ -105,6 +167,9 @@ public class TableForUpdateExporter sampleList.add(sample); } + List<PropertyType> allPropertyTypes = + getAllPropertyTypes(rows, commonServer.listSampleTypes(sessionToken)); + StringBuilder builder = new StringBuilder(); Set<Entry<String, List<Sample>>> entrySet = samples.entrySet(); for (Entry<String, List<Sample>> entry : entrySet) @@ -113,19 +178,22 @@ public class TableForUpdateExporter { builder.append("[").append(entry.getKey()).append("]").append(lineSeparator); } - builder.append(getTableForSamples(entry, lineSeparator)); + builder.append(getTableForSamples(entry, lineSeparator, allPropertyTypes)); } return builder.toString(); } private static String getTableForSamples(Map.Entry<String, List<Sample>> entry, - String lineSeparator) + String lineSeparator, List<PropertyType> allPropertyTypes) { TypedTableModelBuilder<Sample> builder = new TypedTableModelBuilder<Sample>(); builder.addColumn(NewSample.IDENTIFIER_COLUMN); builder.addColumn(NewSample.CONTAINER); builder.addColumn(NewSample.PARENTS); builder.addColumn(NewSample.EXPERIMENT); + + builder.columnGroup("").addColumnsForPropertyTypesForUpdate(allPropertyTypes); + List<Sample> samples = entry.getValue(); Collections.sort(samples, new Comparator<Sample>() { @@ -169,7 +237,8 @@ public class TableForUpdateExporter } public static String getDataSetTableForUpdate( - GridRowModels<TableModelRowWithObject<ExternalData>> rows, String lineSeparator) + GridRowModels<TableModelRowWithObject<ExternalData>> rows, String lineSeparator, + ICommonServer commonServer, String sessionToken) { TypedTableModelBuilder<ExternalData> builder = new TypedTableModelBuilder<ExternalData>(); builder.addColumn(NewDataSet.CODE); @@ -177,6 +246,10 @@ public class TableForUpdateExporter builder.addColumn(NewDataSet.PARENTS); builder.addColumn(NewDataSet.EXPERIMENT); builder.addColumn(NewDataSet.SAMPLE); + + builder.columnGroup("").addColumnsForPropertyTypesForUpdate( + getAllPropertyTypes(rows, commonServer.listDataSetTypes(sessionToken))); + for (GridRowModel<TableModelRowWithObject<ExternalData>> row : rows) { ExternalData dataSet = row.getOriginalObject().getObjectOrNull(); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumnGroup.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumnGroup.java index 11cfb08d6fa0969eb2471696c7131f410fd4cbc6..ed70a747de584599e8234c2334ab5d7d7a14d0cd 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumnGroup.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/IColumnGroup.java @@ -61,12 +61,18 @@ public interface IColumnGroup */ public void addColumnsForPropertyTypes(List<PropertyType> propertyTypes); + /** + * Adds a column for all given property types using the group identifier as prefix. + */ + public void addColumnsForPropertyTypesForUpdate(List<PropertyType> propertyTypes); + /** * Adds a column for all given property types. The specified identifier prefix is used as a * prefix which combined with the property type code to determine the column id. The property * type label is used as column title. */ - public void addColumnsForPropertyTypes(String idPrefix, List<PropertyType> propertyTypes); + public void addColumnsForPropertyTypes(String idPrefix, List<PropertyType> propertyTypes, + boolean forUpdate); /** * Adds all specified properties. The group name is used as a prefix which is combined with the diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java index 9aa34fd06c3ec42215d68cd7a8de6901a90f2d8b..111d2391d8d4075f0e5886de83bb75191d07ab3f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/TypedTableModelBuilder.java @@ -188,15 +188,22 @@ public class TypedTableModelBuilder<T extends Serializable> @Override public void addColumnsForPropertyTypes(List<PropertyType> propertyTypes) { - addColumnsForPropertyTypes(groupKey, propertyTypes); + addColumnsForPropertyTypes(groupKey, propertyTypes, false); } @Override - public void addColumnsForPropertyTypes(String idPrefix, List<PropertyType> propertyTypes) + public void addColumnsForPropertyTypesForUpdate(List<PropertyType> propertyTypes) + { + addColumnsForPropertyTypes(groupKey, propertyTypes, true); + } + + @Override + public void addColumnsForPropertyTypes(String idPrefix, List<PropertyType> propertyTypes, + boolean forUpdate) { for (PropertyType propertyType : propertyTypes) { - addColumn(idPrefix, propertyType, false); + addColumn(idPrefix, propertyType, forUpdate); } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporterTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporterTest.java index a861d4bb33484338270e6b36b0b07fbcb023d581..0707a3af1ca74b5ad3a5832aef0f5355d4ff097d 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporterTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/TableForUpdateExporterTest.java @@ -22,18 +22,24 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import org.jmock.Expectations; +import org.jmock.Mockery; import org.testng.AssertJUnit; import org.testng.annotations.Test; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ColumnDistinctValues; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridCustomColumnInfo; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridRowModels; +import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ContainerDataSetBuilder; @@ -51,6 +57,7 @@ public class TableForUpdateExporterTest extends AssertJUnit @Test public void testExperimentExport() { + Experiment e1 = new ExperimentBuilder().identifier("/S/P/E1").getExperiment(); Experiment e2 = new ExperimentBuilder().identifier("/S/P/E2").property("P1", "hello") @@ -63,8 +70,19 @@ public class TableForUpdateExporterTest extends AssertJUnit GridRowModels<TableModelRowWithObject<Experiment>> rows = createGridRowModels(e1, e2, e3.getExperiment()); + Mockery context = new Mockery(); + final ICommonServer commonServer = context.mock(ICommonServer.class); + context.checking(new Expectations() + { + { + allowing(commonServer).listExperimentTypes(with(any(String.class))); + will(returnValue(new ArrayList<ExperimentType>())); + } + }); + String fileContent = - TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.EXPERIMENT, "\n"); + TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.EXPERIMENT, "\n", + commonServer, ""); assertEquals("identifier\tproject\tP1\t$P2\n" + "/S/P/E1\t\t\t\n" + "/S/P/E2\t\thello\t\n" + "/S/P/E3\t\t\tALPHA (GENE)\n", fileContent); @@ -85,8 +103,20 @@ public class TableForUpdateExporterTest extends AssertJUnit GridRowModels<TableModelRowWithObject<Sample>> rows = createGridRowModels(s1, s2.getSample()); + Mockery context = new Mockery(); + final ICommonServer commonServer = context.mock(ICommonServer.class); + context.checking(new Expectations() + { + { + allowing(commonServer).listSampleTypes(with(any(String.class))); + will(returnValue(new ArrayList<SampleType>())); + } + }); + String fileContent = - TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.SAMPLE, "\n"); + TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.SAMPLE, "\n", + commonServer, + ""); assertEquals("identifier\tcontainer\tparents\texperiment\tP1\n" + "/S/S1\t/S/C1\t\t/S/P/E1\t\n" + "/S/S2\t\t/S/S1,/S/S3\t\tA\n", fileContent); @@ -103,8 +133,20 @@ public class TableForUpdateExporterTest extends AssertJUnit GridRowModels<TableModelRowWithObject<Sample>> rows = createGridRowModels(s1, s2, s3.getSample()); + Mockery context = new Mockery(); + final ICommonServer commonServer = context.mock(ICommonServer.class); + context.checking(new Expectations() + { + { + allowing(commonServer).listSampleTypes(with(any(String.class))); + will(returnValue(new ArrayList<SampleType>())); + } + }); + String fileContent = - TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.SAMPLE, "\n"); + TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.SAMPLE, "\n", + commonServer, + ""); assertEquals("[T1]\n" + "identifier\tcontainer\tparents\texperiment\tP1\n" + "/A/S2\t\t\t\t\n" + "/S/S1\t\t\t\thello\n" + "[T2]\n" @@ -125,8 +167,20 @@ public class TableForUpdateExporterTest extends AssertJUnit .container(new ContainerDataSetBuilder().code("ds1").getContainerDataSet()) .sample(new SampleBuilder("/S/S1").getSample()).getDataSet(); GridRowModels<TableModelRowWithObject<DataSet>> rows = createGridRowModels(ds1, ds2); + + Mockery context = new Mockery(); + final ICommonServer commonServer = context.mock(ICommonServer.class); + context.checking(new Expectations() + { + { + allowing(commonServer).listDataSetTypes(with(any(String.class))); + will(returnValue(new ArrayList<DataSetType>())); + } + }); + String fileContent = - TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.DATA_SET, "\n"); + TableForUpdateExporter.getExportTableForUpdate(rows, EntityKind.DATA_SET, "\n", + commonServer, ""); assertEquals("code\tcontainer\tparents\texperiment\tsample\tP1\n" + "ds1\t\tds3,ds4\t/S/P/E\t\thello\n" + "ds2\tds1\t\t/S/P/E\t/S/S1\t\n",