From c9564ba61dc570c7b069acd262bfa9b9e670f671 Mon Sep 17 00:00:00 2001 From: Lum Date: Thu, 25 Jan 2024 17:12:03 -0800 Subject: [PATCH 1/3] plate bean naming consistency, new DB bean for plates --- .../org/labkey/api/assay/plate/Plate.java | 4 +- .../plate/AssayPlateMetadataServiceImpl.java | 8 +- .../org/labkey/assay/plate/PlateCache.java | 8 +- .../assay/plate/PlateDocumentProvider.java | 2 +- .../src/org/labkey/assay/plate/PlateImpl.java | 108 ++++++++------ .../org/labkey/assay/plate/PlateManager.java | 47 +++--- .../labkey/assay/plate/model/PlateBean.java | 140 ++++++++++++++++++ ...{PlateTypeImpl.java => PlateTypeBean.java} | 8 +- .../plate/model/{Well.java => WellBean.java} | 2 +- 9 files changed, 242 insertions(+), 85 deletions(-) create mode 100644 assay/src/org/labkey/assay/plate/model/PlateBean.java rename assay/src/org/labkey/assay/plate/model/{PlateTypeImpl.java => PlateTypeBean.java} (88%) rename assay/src/org/labkey/assay/plate/model/{Well.java => WellBean.java} (98%) diff --git a/assay/api-src/org/labkey/api/assay/plate/Plate.java b/assay/api-src/org/labkey/api/assay/plate/Plate.java index dd44b2bab97..4fccd60579b 100644 --- a/assay/api-src/org/labkey/api/assay/plate/Plate.java +++ b/assay/api-src/org/labkey/api/assay/plate/Plate.java @@ -40,9 +40,9 @@ public interface Plate extends PropertySet, Identifiable boolean isTemplate(); - @NotNull PlateType getPlateTypeObject(); + @NotNull PlateType getPlateType(); - @Nullable PlateSet getPlateSetObject(); + @Nullable PlateSet getPlateSet(); /** * Returns an existing well, or creates a new well if one diff --git a/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java b/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java index 7b118ec8156..ca561698c8f 100644 --- a/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/AssayPlateMetadataServiceImpl.java @@ -45,7 +45,7 @@ import org.labkey.api.query.ValidationException; import org.labkey.api.security.User; import org.labkey.assay.TSVProtocolSchema; -import org.labkey.assay.plate.model.Well; +import org.labkey.assay.plate.model.WellBean; import org.labkey.assay.query.AssayDbSchema; import java.io.File; @@ -296,11 +296,11 @@ public List> mergePlateMetadata( if (!plate.getCustomFields().isEmpty()) { // create the map of well locations to the well - Map positionToWell = new HashMap<>(); + Map positionToWell = new HashMap<>(); SimpleFilter filter = SimpleFilter.createContainerFilter(plate.getContainer()); filter.addCondition(FieldKey.fromParts("PlateId"), plate.getRowId()); - for (Well well : new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), filter, null).getArrayList(Well.class)) + for (WellBean well : new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), filter, null).getArrayList(WellBean.class)) positionToWell.put(new PositionImpl(plate.getContainer(), well.getRow(), well.getCol()), well); for (Map row : mergedRows) @@ -503,7 +503,7 @@ public OntologyManager.UpdateableTableImportHelper getImportHelper( SimpleFilter filter = SimpleFilter.createContainerFilter(plate.getContainer()); filter.addCondition(FieldKey.fromParts("PlateId"), plate.getRowId()); - for (Well well : new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), filter, null).getArrayList(Well.class)) + for (WellBean well : new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), filter, null).getArrayList(WellBean.class)) positionToWellLsid.put(new PositionImpl(plate.getContainer(), well.getRow(), well.getCol()), Lsid.parse(well.getLsid())); return new PlateMetadataImportHelper(plate.getContainer(), data, Collections.unmodifiableMap(positionToWellLsid)); diff --git a/assay/src/org/labkey/assay/plate/PlateCache.java b/assay/src/org/labkey/assay/plate/PlateCache.java index 85bb5308956..b21ccad4a30 100644 --- a/assay/src/org/labkey/assay/plate/PlateCache.java +++ b/assay/src/org/labkey/assay/plate/PlateCache.java @@ -16,6 +16,7 @@ import org.labkey.api.data.TableSelector; import org.labkey.api.exp.Lsid; import org.labkey.api.query.FieldKey; +import org.labkey.assay.plate.model.PlateBean; import org.labkey.assay.query.AssayDbSchema; import java.util.ArrayList; @@ -46,13 +47,14 @@ public Plate load(@NotNull String key, @Nullable Object argument) SimpleFilter filter = SimpleFilter.createContainerFilter(cacheKey._container); filter.addCondition(FieldKey.fromParts(cacheKey._type.name()), cacheKey._identifier); - List plates = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlate(), filter, null).getArrayList(PlateImpl.class); + List plates = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlate(), filter, null).getArrayList(PlateBean.class); assert plates.size() <= 1; if (plates.size() == 1) { - PlateImpl plate = plates.get(0); - PlateManager.get().populatePlate(plate); + PlateBean bean = plates.get(0); + + Plate plate = PlateManager.get().populatePlate(bean); LOG.info(String.format("Caching plate \"%s\" for folder %s", plate.getName(), cacheKey._container.getPath())); // add all cache keys for this plate diff --git a/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java b/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java index 165d68896a6..78717bd01bb 100644 --- a/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java +++ b/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java @@ -73,7 +73,7 @@ public static WebdavResource createDocument(@NotNull Plate plate) StringBuilder body = new StringBuilder(); - PlateType plateType = plate.getPlateTypeObject(); + PlateType plateType = plate.getPlateType(); if (plateType != null) append(body, plateType.getDescription()); diff --git a/assay/src/org/labkey/assay/plate/PlateImpl.java b/assay/src/org/labkey/assay/plate/PlateImpl.java index 5e31ad401e2..7b826014303 100644 --- a/assay/src/org/labkey/assay/plate/PlateImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateImpl.java @@ -31,12 +31,14 @@ import org.labkey.api.assay.plate.Well; import org.labkey.api.assay.plate.WellGroup; import org.labkey.api.data.Container; +import org.labkey.api.data.ContainerManager; import org.labkey.api.data.Transient; import org.labkey.api.query.QueryRowReference; import org.labkey.api.util.GUID; import org.labkey.api.util.UnexpectedException; import org.labkey.api.view.ActionURL; import org.labkey.assay.PlateController; +import org.labkey.assay.plate.model.PlateBean; import java.util.ArrayList; import java.util.Arrays; @@ -59,12 +61,10 @@ public class PlateImpl extends PropertySetImpl implements Plate, Cloneable private String _dataFileId; private String _assayType; private boolean _isTemplate; - private Integer _plateSetId; - private Integer _plateType; private String _description; private String _plateId; - private PlateType _plateTypeObject; - private PlateSet _plateSetObject; + private PlateType _plateType; + private PlateSet _plateSet; private Map> _groups; private List _deletedGroups; @@ -94,13 +94,12 @@ public PlateImpl(Container container, String name, String assayType, @NotNull Pl _assayType = assayType; _container = container; _dataFileId = GUID.makeGUID(); - _plateType = plateType.getRowId(); - _plateTypeObject = plateType; + _plateType = plateType; } public PlateImpl(PlateImpl plate, double[][] wellValues, boolean[][] excluded, int runId, int plateNumber) { - this(plate.getContainer(), plate.getName(), plate.getAssayType(), plate.getPlateTypeObject()); + this(plate.getContainer(), plate.getName(), plate.getAssayType(), plate.getPlateType()); if (wellValues == null) wellValues = new double[plate.getRows()][plate.getColumns()]; @@ -127,6 +126,42 @@ else if (wellValues.length != plate.getRows() && wellValues[0].length != plate.g setContainer(plate.getContainer()); } + public static PlateImpl from(PlateBean bean) + { + PlateImpl plate = new PlateImpl(); + + // plate fields + plate.setRowId(bean.getRowId()); + plate.setLsid(bean.getLsid()); + plate.setName(bean.getName()); + plate.setTemplate(bean.getTemplate()); + plate.setDataFileId(bean.getDataFileId()); + plate.setAssayType(bean.getAssayType()); + plate.setPlateId(bean.getPlateId()); + plate.setDescription(bean.getDescription()); + + // entity fields + Container container = ContainerManager.getForId(bean.getContainerId()); + plate.setContainer(container); + plate.setCreated(bean.getCreated()); + plate.setCreatedBy(bean.getCreatedBy()); + plate.setModified(bean.getModified()); + plate.setModifiedBy(bean.getModifiedBy()); + + // plate type and plate set objects + PlateType plateType = PlateManager.get().getPlateType(bean.getPlateType()); + if (plateType == null) + throw new IllegalStateException("Unable to get Plate Type with id : " + bean.getPlateType()); + plate.setPlateType(plateType); + + PlateSet plateSet = PlateManager.get().getPlateSet(container, bean.getPlateSet()); + if (plateSet == null) + throw new IllegalStateException("Unable to get Plate Set with id : " + bean.getPlateSet()); + plate.setPlateSet(plateSet); + + return plate; + } + @JsonIgnore @Override public @Nullable ActionURL detailsURL() @@ -291,9 +326,9 @@ public Map> getWellGroupMap() @JsonIgnore public int getColumns() { - if (_plateTypeObject == null) + if (_plateType == null) return 0; - return _plateTypeObject.getColumns(); + return _plateType.getColumns(); } @Override @@ -306,9 +341,9 @@ public String getName() @JsonIgnore public int getRows() { - if (_plateTypeObject == null) + if (_plateType == null) return 0; - return _plateTypeObject.getRows(); + return _plateType.getRows(); } @JsonIgnore @@ -534,27 +569,36 @@ public void setTemplate(boolean template) _isTemplate = template; } - public void setPlateSet(Integer plateSetId) + @Override + @JsonIgnore + public @Nullable PlateSet getPlateSet() { - _plateSetId = plateSetId; + return _plateSet; } - public Integer getPlateSet() + public void setPlateSet(PlateSet plateSet) { - return _plateSetId; + _plateSet = plateSet; } - public void setPlateType(Integer plateType) + @JsonProperty("plateSet") + public Integer getPlateSetId() { - _plateType = plateType; + return _plateSet.getRowId(); } - @JsonIgnore // Ignored for client serialization due to full serialization of "plateType" - public Integer getPlateType() + @Override + //@JsonProperty("plateType") + public @NotNull PlateType getPlateType() { return _plateType; } + public void setPlateType(PlateType plateType) + { + _plateType = plateType; + } + public String getDescription() { return _description; @@ -565,32 +609,6 @@ public void setDescription(String description) _description = description; } - @Override - @JsonProperty("plateType") - public @NotNull PlateType getPlateTypeObject() - { - if (_plateTypeObject == null) - _plateTypeObject = PlateManager.get().getPlateType(_plateType); - return _plateTypeObject; - } - - public void setPlateTypeObject(PlateType plateTypeObject) - { - _plateTypeObject = plateTypeObject; - } - - @Override - @JsonIgnore - public @Nullable PlateSet getPlateSetObject() - { - return _plateSetObject; - } - - public void setPlateSetObject(PlateSet plateSetObject) - { - _plateSetObject = plateSetObject; - } - @JsonIgnore public int getRunId() { diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index fda35bad65f..499bf1b5962 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -98,7 +98,9 @@ import org.labkey.api.view.UnauthorizedException; import org.labkey.api.webdav.WebdavResource; import org.labkey.assay.TsvAssayProvider; -import org.labkey.assay.plate.model.PlateTypeImpl; +import org.labkey.assay.plate.model.PlateBean; +import org.labkey.assay.plate.model.PlateTypeBean; +import org.labkey.assay.plate.model.WellBean; import org.labkey.assay.plate.model.WellGroupBean; import org.labkey.assay.plate.query.PlateSchema; import org.labkey.assay.plate.query.PlateSetTable; @@ -238,7 +240,7 @@ public List getWellGroupTypes() PlateSet plateSet = getPlateSet(container, plateSetId); if (plateSet == null) throw new IllegalArgumentException("Failed to create plate. Plate set with rowId (" + plateSetId + ") is not available in " + container.getPath()); - ((PlateImpl) plate).setPlateSet(plateSetId); + ((PlateImpl) plate).setPlateSet(plateSet); } if (StringUtils.trimToNull(plateName) != null) @@ -547,18 +549,12 @@ public int save(Container container, User user, Plate plate) throws Exception throw new IllegalArgumentException("Only plate instances created by the plate service can be saved."); } - protected void populatePlate(PlateImpl plate) + /** + * Creates a plate instance from a database row. + */ + protected Plate populatePlate(PlateBean bean) { - // plate type and plate set objects - PlateType plateType = getPlateType(plate.getPlateType()); - if (plateType == null) - throw new IllegalStateException("Unable to get Plate Type with id : " + plate.getPlateType()); - plate.setPlateTypeObject(plateType); - - PlateSet plateSet = getPlateSet(plate.getContainer(), plate.getPlateSet()); - if (plateSet == null) - throw new IllegalStateException("Unable to get Plate Set with id : " + plate.getPlateSet()); - plate.setPlateSetObject(plateSet); + PlateImpl plate = PlateImpl.from(bean); // set plate properties: setProperties(plate.getContainer(), plate); @@ -648,6 +644,7 @@ protected void populatePlate(PlateImpl plate) .map(PlateCustomField::new).toList()); } } + return plate; } private WellImpl[] getWells(Plate plate) @@ -694,10 +691,9 @@ private int savePlateImpl(Container container, User user, PlateImpl plate) throw if (!updateExisting && plate.getPlateSet() == null) { // ensure a plate set for each new plate - Integer plateSetId = ensureDefaultPlateSet(container, user); - plate.setPlateSet(plateSetId); + plate.setPlateSet(ensureDefaultPlateSet(container, user)); } - Map plateRow = ObjectFactory.Registry.getFactory(PlateImpl.class).toMap(plate, new ArrayListMap<>()); + Map plateRow = ObjectFactory.Registry.getFactory(PlateBean.class).toMap(PlateBean.from(plate), new ArrayListMap<>()); QueryUpdateService qus = getPlateUpdateService(container, user); BatchValidationException errors = new BatchValidationException(); @@ -840,7 +836,7 @@ private int savePlateImpl(Container container, User user, PlateImpl plate) throw } // creates a default plate set in the specified container and returns its ID - private Integer ensureDefaultPlateSet(Container container, User user) throws Exception + private PlateSet ensureDefaultPlateSet(Container container, User user) throws Exception { BatchValidationException errors = new BatchValidationException(); QueryUpdateService qus = getPlateSetUpdateService(container, user); @@ -852,7 +848,8 @@ private Integer ensureDefaultPlateSet(Container container, User user) throws Exc if (errors.hasErrors()) throw errors; - return (Integer)insertedRows.get(0).get("RowId"); + Integer rowId = (Integer)insertedRows.get(0).get("RowId"); + return getPlateSet(container, rowId); } // return a list of wellId and wellGroupId pairs @@ -1230,7 +1227,7 @@ public Plate copyPlate(Plate source, User user, Container destContainer) { if (plateExists(destContainer, source.getName())) throw new PlateService.NameConflictException(source.getName()); - Plate newPlate = createPlateTemplate(destContainer, source.getAssayType(), source.getPlateTypeObject()); + Plate newPlate = createPlateTemplate(destContainer, source.getAssayType(), source.getPlateType()); newPlate.setName(source.getName()); for (String property : source.getPropertyNames()) newPlate.setProperty(property, source.getProperty(property)); @@ -1276,7 +1273,7 @@ public DilutionCurve getDilutionCurve(List wellGroups, boolean assume @Override public List getPlateTypes() { - return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getArrayList(PlateTypeImpl.class); + return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getArrayList(PlateTypeBean.class); } @Override @@ -1286,7 +1283,7 @@ public PlateType getPlateType(int rows, int columns) SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("Rows"), rows); filter.addCondition(FieldKey.fromParts("Columns"), columns); - return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType(), filter, null).getObject(PlateTypeImpl.class); + return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType(), filter, null).getObject(PlateTypeBean.class); } public record PlateLayout(String name, PlateType type, String assayType, String description){} @@ -1324,7 +1321,7 @@ public List getPlateLayouts() public PlateType getPlateType(Integer plateTypeId) { if (plateTypeId == null) return null; - return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getObject(plateTypeId, PlateTypeImpl.class); + return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getObject(plateTypeId, PlateTypeBean.class); } public @NotNull Map>> getPlateOperationConfirmationData( @@ -1903,7 +1900,7 @@ public void createPlateTemplate() throws Exception assertEquals(plateId, savedTemplate.getRowId().intValue()); assertEquals("bob", savedTemplate.getName()); assertEquals("yes", savedTemplate.getProperty("friendly")); assertNotNull(savedTemplate.getLSID()); - assertEquals(plateType.getRowId(), savedTemplate.getPlateTypeObject().getRowId()); + assertEquals(plateType.getRowId(), savedTemplate.getPlateType().getRowId()); List wellGroups = savedTemplate.getWellGroups(); assertEquals(3, wellGroups.size()); @@ -2083,7 +2080,7 @@ public void testCreatePlateMetadata() throws Exception SimpleFilter filter = SimpleFilter.createContainerFilter(container); filter.addCondition(FieldKey.fromParts("PlateId"), plateId); filter.addCondition(FieldKey.fromParts("Row"), 0); - List< org.labkey.assay.plate.model.Well> wells = new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), filter, new Sort("Col")).getArrayList(org.labkey.assay.plate.model.Well.class); + List wells = new TableSelector(AssayDbSchema.getInstance().getTableInfoWell(), filter, new Sort("Col")).getArrayList(WellBean.class); assertEquals("Expected 24 wells to be returned", 24, wells.size()); @@ -2094,7 +2091,7 @@ public void testCreatePlateMetadata() throws Exception BatchValidationException errors = new BatchValidationException(); // verify metadata update works for Property URI as well as field key - org.labkey.assay.plate.model.Well well = wells.get(0); + WellBean well = wells.get(0); List> rows = List.of(CaseInsensitiveHashMap.of( "rowid", well.getRowId(), fields.get(0).getPropertyURI(), 1.25, // concentration diff --git a/assay/src/org/labkey/assay/plate/model/PlateBean.java b/assay/src/org/labkey/assay/plate/model/PlateBean.java new file mode 100644 index 00000000000..4e3ed67e135 --- /dev/null +++ b/assay/src/org/labkey/assay/plate/model/PlateBean.java @@ -0,0 +1,140 @@ +package org.labkey.assay.plate.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import org.labkey.api.data.Entity; +import org.labkey.assay.plate.PlateImpl; + +/** + * Serializes a row in the assay.plate table. + */ +public class PlateBean extends Entity +{ + private Integer _rowId; + private String _lsid; + private String _name; + private Boolean _template; + private String _dataFileId; + private String _assayType; + private Integer _plateSet; + private Integer _plateType; + private String _plateId; + private String _description; + + public static PlateBean from(PlateImpl plate) + { + PlateBean bean = new PlateBean(); + + bean.setRowId(plate.getRowId()); + bean.setLsid(plate.getLSID()); + bean.setName(plate.getName()); + bean.setTemplate(plate.isTemplate()); + bean.setDataFileId(plate.getDataFileId()); + bean.setAssayType(plate.getAssayType()); + bean.setPlateSet(plate.getPlateSet() != null ? plate.getPlateSet().getRowId() : null); + bean.setPlateType(plate.getPlateType().getRowId()); + bean.setPlateId(plate.getPlateId()); + bean.setDescription(plate.getDescription()); + + return bean; + } + + public Integer getRowId() + { + return _rowId; + } + + public void setRowId(Integer rowId) + { + _rowId = rowId; + } + + public String getLsid() + { + return _lsid; + } + + public void setLsid(String lsid) + { + _lsid = lsid; + } + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _name = name; + } + + public Boolean getTemplate() + { + return _template; + } + + public void setTemplate(Boolean template) + { + _template = template; + } + + public String getDataFileId() + { + return _dataFileId; + } + + public void setDataFileId(String dataFileId) + { + _dataFileId = dataFileId; + } + + public String getAssayType() + { + return _assayType; + } + + public void setAssayType(String assayType) + { + _assayType = assayType; + } + + public Integer getPlateSet() + { + return _plateSet; + } + + public void setPlateSet(Integer plateSet) + { + _plateSet = plateSet; + } + + public Integer getPlateType() + { + return _plateType; + } + + public void setPlateType(Integer plateType) + { + _plateType = plateType; + } + + public String getPlateId() + { + return _plateId; + } + + public void setPlateId(String plateId) + { + _plateId = plateId; + } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + _description = description; + } +} diff --git a/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java b/assay/src/org/labkey/assay/plate/model/PlateTypeBean.java similarity index 88% rename from assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java rename to assay/src/org/labkey/assay/plate/model/PlateTypeBean.java index c9ee38c54fe..8e7ff2d9901 100644 --- a/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java +++ b/assay/src/org/labkey/assay/plate/model/PlateTypeBean.java @@ -6,7 +6,7 @@ import java.util.Objects; @JsonInclude(JsonInclude.Include.NON_NULL) -public class PlateTypeImpl implements PlateType +public class PlateTypeBean implements PlateType { private Integer _rowId; private Integer _rows; @@ -14,7 +14,7 @@ public class PlateTypeImpl implements PlateType private String _description; private boolean _archived; - public PlateTypeImpl() + public PlateTypeBean() { } @@ -92,7 +92,7 @@ public boolean equals(Object obj) if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; - if (!Objects.equals(_rows, ((PlateTypeImpl) obj)._rows)) return false; - return Objects.equals(_cols, ((PlateTypeImpl) obj)._cols); + if (!Objects.equals(_rows, ((PlateTypeBean) obj)._rows)) return false; + return Objects.equals(_cols, ((PlateTypeBean) obj)._cols); } } diff --git a/assay/src/org/labkey/assay/plate/model/Well.java b/assay/src/org/labkey/assay/plate/model/WellBean.java similarity index 98% rename from assay/src/org/labkey/assay/plate/model/Well.java rename to assay/src/org/labkey/assay/plate/model/WellBean.java index 59639d2bac9..07811823521 100644 --- a/assay/src/org/labkey/assay/plate/model/Well.java +++ b/assay/src/org/labkey/assay/plate/model/WellBean.java @@ -6,7 +6,7 @@ * Represents a row in the plate.well table */ @JsonInclude(JsonInclude.Include.NON_NULL) -public class Well +public class WellBean { private Integer _rowId; private String _lsid; From 7c37c9b606c424a557253c4e470eb10d4890d872 Mon Sep 17 00:00:00 2001 From: lum Date: Fri, 26 Jan 2024 13:56:53 -0800 Subject: [PATCH 2/3] support plateId and remove plate name from the plate cache --- .../org/labkey/api/assay/plate/Plate.java | 2 ++ .../labkey/api/assay/plate/PlateService.java | 16 +++++++++ .../labkey/assay/AssayDomainServiceImpl.java | 5 +-- .../org/labkey/assay/AssayUpgradeCode.java | 2 +- .../src/org/labkey/assay/PlateController.java | 3 ++ .../org/labkey/assay/plate/PlateCache.java | 36 +++++++++++-------- .../assay/plate/PlateDataServiceImpl.java | 2 +- .../src/org/labkey/assay/plate/PlateImpl.java | 3 +- .../org/labkey/assay/plate/PlateManager.java | 35 +++++++++++++++--- 9 files changed, 78 insertions(+), 26 deletions(-) diff --git a/assay/api-src/org/labkey/api/assay/plate/Plate.java b/assay/api-src/org/labkey/api/assay/plate/Plate.java index 4fccd60579b..85d68edd733 100644 --- a/assay/api-src/org/labkey/api/assay/plate/Plate.java +++ b/assay/api-src/org/labkey/api/assay/plate/Plate.java @@ -44,6 +44,8 @@ public interface Plate extends PropertySet, Identifiable @Nullable PlateSet getPlateSet(); + @NotNull String getPlateId(); + /** * Returns an existing well, or creates a new well if one * had not previously existed. diff --git a/assay/api-src/org/labkey/api/assay/plate/PlateService.java b/assay/api-src/org/labkey/api/assay/plate/PlateService.java index 24b9664c09e..1339ad2fa59 100644 --- a/assay/api-src/org/labkey/api/assay/plate/PlateService.java +++ b/assay/api-src/org/labkey/api/assay/plate/PlateService.java @@ -130,6 +130,14 @@ static PlateService get() */ @Nullable Plate getPlate(Container container, int rowId); + /** + * Gets a plate instance object by plate id. + * @param container The plate's container. + * @param plateId The plate id of the plate. + * @return The requested plate, or null if no plate exists with the specified plate id. + */ + @Nullable Plate getPlate(Container container, String plateId); + /** * Gets a plate instance object by row id. * @param cf The container filter to find the plate @@ -146,6 +154,14 @@ static PlateService get() */ @Nullable Plate getPlate(ContainerFilter cf, Lsid lsid); + /** + * Gets a plate instance object by plate id. + * @param cf The container filter to find the plate + * @param plateId The plate id of the plate. + * @return The requested plate, or null if no plate exists with the specified plate id. + */ + @Nullable Plate getPlate(ContainerFilter cf, String plateId); + /** * Gets all plate templates for the specified container. Plate templates are Plate instances * which have their template field set to TRUE. diff --git a/assay/src/org/labkey/assay/AssayDomainServiceImpl.java b/assay/src/org/labkey/assay/AssayDomainServiceImpl.java index 2815c60915b..e5d4f936123 100644 --- a/assay/src/org/labkey/assay/AssayDomainServiceImpl.java +++ b/assay/src/org/labkey/assay/AssayDomainServiceImpl.java @@ -26,7 +26,6 @@ import org.labkey.api.assay.AssayDomainService; import org.labkey.api.assay.AssayProvider; import org.labkey.api.assay.AssayQCService; -import org.labkey.api.assay.AssaySchema; import org.labkey.api.assay.AssayService; import org.labkey.api.assay.DetectionMethodAssayProvider; import org.labkey.api.assay.plate.Plate; @@ -58,9 +57,7 @@ import org.labkey.api.gwt.client.model.GWTContainer; import org.labkey.api.gwt.client.model.GWTDomain; import org.labkey.api.gwt.client.model.GWTPropertyDescriptor; -import org.labkey.api.query.QueryChangeListener; import org.labkey.api.query.QueryService; -import org.labkey.api.query.SchemaKey; import org.labkey.api.query.ValidationException; import org.labkey.api.security.SecurityPolicy; import org.labkey.api.security.User; @@ -484,7 +481,7 @@ public GWTProtocol saveChanges(GWTProtocol assay, boolean replaceIfExisting) thr if (provider instanceof PlateBasedAssayProvider && assay.getSelectedPlateTemplate() != null) { PlateBasedAssayProvider plateProvider = (PlateBasedAssayProvider)provider; - Plate plate = PlateManager.get().getPlate(getContainer(), assay.getSelectedPlateTemplate()); + Plate plate = PlateManager.get().getPlateByName(getContainer(), assay.getSelectedPlateTemplate()); if (plate != null) plateProvider.setPlate(getContainer(), protocol, plate); else diff --git a/assay/src/org/labkey/assay/AssayUpgradeCode.java b/assay/src/org/labkey/assay/AssayUpgradeCode.java index 1341dc0b954..107708cb1cc 100644 --- a/assay/src/org/labkey/assay/AssayUpgradeCode.java +++ b/assay/src/org/labkey/assay/AssayUpgradeCode.java @@ -205,7 +205,7 @@ private static Plate getPlate(ExpProtocol protocol) { // resolve plate by the legacy deprecated plate name method ObjectProperty prop = protocol.getObjectProperties().get(protocol.getLSID() + AbstractPlateBasedAssayProvider.PLATE_TEMPLATE_SUFFIX); - return prop != null ? PlateManager.get().getPlate(protocol.getContainer(), prop.getStringValue()) : null; + return prop != null ? PlateManager.get().getPlateByName(protocol.getContainer(), prop.getStringValue()) : null; } /** diff --git a/assay/src/org/labkey/assay/PlateController.java b/assay/src/org/labkey/assay/PlateController.java index 06f828cc2a7..93bb7903447 100644 --- a/assay/src/org/labkey/assay/PlateController.java +++ b/assay/src/org/labkey/assay/PlateController.java @@ -282,6 +282,9 @@ public static class CopyTemplateBean public CopyTemplateBean(final Container container, final User user, final Integer plateId, final String selectedDestination) { + if (plateId == null) + throw new IllegalArgumentException("Plate ID cannot be null"); + _plate = PlateService.get().getPlate(container, plateId); if (_plate == null) throw new IllegalStateException("Could not resolve the plate with ID : " + plateId); diff --git a/assay/src/org/labkey/assay/plate/PlateCache.java b/assay/src/org/labkey/assay/plate/PlateCache.java index b21ccad4a30..06526b55d65 100644 --- a/assay/src/org/labkey/assay/plate/PlateCache.java +++ b/assay/src/org/labkey/assay/plate/PlateCache.java @@ -68,8 +68,8 @@ private void addCacheKeys(PlateCacheKey cacheKey, Plate plate) { if (plate != null) { - if (plate.getName() == null) - throw new IllegalArgumentException("Plate cannot be cached, name is null"); + if (plate.getPlateId() == null) + throw new IllegalArgumentException("Plate cannot be cached, plateId is null"); if (plate.getRowId() == null) throw new IllegalArgumentException("Plate cannot be cached, rowId is null"); if (plate.getLSID() == null) @@ -80,8 +80,8 @@ private void addCacheKeys(PlateCacheKey cacheKey, Plate plate) PLATE_CACHE.put(PlateCacheKey.getCacheKey(plate.getContainer(), plate.getRowId()), plate); if (cacheKey._type != PlateCacheKey.Type.lsid) PLATE_CACHE.put(PlateCacheKey.getCacheKey(plate.getContainer(), Lsid.parse(plate.getLSID())), plate); - if (cacheKey._type != PlateCacheKey.Type.name) - PLATE_CACHE.put(PlateCacheKey.getCacheKey(plate.getContainer(), plate.getName()), plate); + if (cacheKey._type != PlateCacheKey.Type.plateId) + PLATE_CACHE.put(PlateCacheKey.getCacheKey(plate.getContainer(), plate.getPlateId()), plate); _containerPlateMap.computeIfAbsent(cacheKey._container, k -> new ArrayList<>()).add(plate); } @@ -112,6 +112,14 @@ private void addCacheKeys(PlateCacheKey cacheKey, Plate plate) return c != null ? PLATE_CACHE.get(PlateCacheKey.getCacheKey(c, lsid)) : null; } + public static @Nullable Plate getPlate(ContainerFilter cf, String plateId) + { + SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("plateId"), plateId); + Container c = getContainerWithIdentifier(cf, filter); + + return c != null ? PLATE_CACHE.get(PlateCacheKey.getCacheKey(c, plateId)) : null; + } + private static @Nullable Container getContainerWithIdentifier(ContainerFilter cf, SimpleFilter filter) { filter.addClause(cf.createFilterClause(AssayDbSchema.getInstance().getSchema(), FieldKey.fromParts("Container"))); @@ -129,9 +137,9 @@ private void addCacheKeys(PlateCacheKey cacheKey, Plate plate) return null; } - public static @Nullable Plate getPlate(Container c, String name) + public static @Nullable Plate getPlate(Container c, String plateId) { - Plate plate = PLATE_CACHE.get(PlateCacheKey.getCacheKey(c, name)); + Plate plate = PLATE_CACHE.get(PlateCacheKey.getCacheKey(c, plateId)); return plate != null ? plate.copy() : null; } @@ -187,14 +195,14 @@ public static void uncache(Container c, Plate plate) { LOG.info(String.format("Un-caching plate \"%s\" for folder %s", plate.getName(), c.getPath())); - if (plate.getName() == null) - throw new IllegalArgumentException("Plate cannot be uncached, name is null"); + if (plate.getPlateId() == null) + throw new IllegalArgumentException("Plate cannot be uncached, plateId is null"); if (plate.getRowId() == null) throw new IllegalArgumentException("Plate cannot be uncached, rowId is null"); if (plate.getLSID() == null) throw new IllegalArgumentException("Plate cannot be uncached, LSID is null"); - PLATE_CACHE.remove(PlateCacheKey.getCacheKey(c, plate.getName())); + PLATE_CACHE.remove(PlateCacheKey.getCacheKey(c, plate.getPlateId())); PLATE_CACHE.remove(PlateCacheKey.getCacheKey(c, plate.getRowId())); PLATE_CACHE.remove(PlateCacheKey.getCacheKey(c, Lsid.parse(plate.getLSID()))); @@ -212,7 +220,7 @@ private static class PlateCacheKey enum Type { rowId, - name, + plateId, lsid, } private Type _type; @@ -228,14 +236,14 @@ enum Type _identifier = json.get("identifier"); } - public static String getCacheKey(Container c, String name) + public static String getCacheKey(Container c, String plateId) { - return _getCacheKey(c, Type.name, name); + return _getCacheKey(c, Type.plateId, plateId); } - public static String getCacheKey(Container c, Integer plateId) + public static String getCacheKey(Container c, Integer rowId) { - return _getCacheKey(c, Type.rowId, plateId); + return _getCacheKey(c, Type.rowId, rowId); } public static String getCacheKey(Container c, Lsid lsid) diff --git a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java index 93013be7761..210757f5bcc 100644 --- a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java @@ -177,7 +177,7 @@ public int saveChanges(GWTPlate gwtPlate, boolean replaceIfExisting) throws Exce else { // check another plate of the same name doesn't already exist - Plate other = PlateManager.get().getPlate(getContainer(), gwtPlate.getName()); + Plate other = PlateManager.get().getPlateByName(getContainer(), gwtPlate.getName()); if (other != null) { if (!replaceIfExisting) diff --git a/assay/src/org/labkey/assay/plate/PlateImpl.java b/assay/src/org/labkey/assay/plate/PlateImpl.java index 7b826014303..7ade098ad6e 100644 --- a/assay/src/org/labkey/assay/plate/PlateImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateImpl.java @@ -588,7 +588,6 @@ public Integer getPlateSetId() } @Override - //@JsonProperty("plateType") public @NotNull PlateType getPlateType() { return _plateType; @@ -674,6 +673,8 @@ public void setRunCount(Integer runCount) _runCount = runCount; } + @NotNull + @Override public String getPlateId() { return _plateId; diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 499bf1b5962..f0c12616b95 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -331,9 +331,16 @@ public Position createPosition(Container container, int row, int column) * Use the rowId or lsid variants instead. */ @Deprecated - public @Nullable Plate getPlate(Container container, String plateName) + public @Nullable Plate getPlateByName(Container container, String plateName) { - return PlateCache.getPlate(container, plateName); + SimpleFilter filter = SimpleFilter.createContainerFilter(container); + filter.addCondition(FieldKey.fromParts("name"), plateName); + + PlateBean bean = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlate(), filter, null).getObject(PlateBean.class); + if (bean != null) + return populatePlate(bean); + + return null; } @Override @@ -445,6 +452,18 @@ public Plate createPlateTemplate(Container container, String templateType, @NotN return PlateCache.getPlate(cf, lsid); } + @Override + public @Nullable Plate getPlate(Container container, String plateId) + { + return PlateCache.getPlate(container, plateId); + } + + @Override + public @Nullable Plate getPlate(ContainerFilter cf, String plateId) + { + return PlateCache.getPlate(cf, plateId); + } + /** * Helper to create container filters to support assay import using cross folder * plates @@ -717,7 +736,7 @@ private int savePlateImpl(Container container, User user, PlateImpl plate) throw plateId = (Integer) row.get("RowId"); plate.setRowId(plateId); plate.setLsid((String) row.get("Lsid")); - plate.setName((String) row.get("Name")); + plate.setPlateId((String) row.get("PlateId")); } savePropertyBag(container, plate.getLSID(), plate.getProperties(), updateExisting); @@ -1896,7 +1915,7 @@ public void createPlateTemplate() throws Exception assertEquals(1, PlateManager.get().getPlateTemplates(container).size()); - Plate savedTemplate = PlateManager.get().getPlate(container, "bob"); + Plate savedTemplate = PlateManager.get().getPlateByName(container, "bob"); assertEquals(plateId, savedTemplate.getRowId().intValue()); assertEquals("bob", savedTemplate.getName()); assertEquals("yes", savedTemplate.getProperty("friendly")); assertNotNull(savedTemplate.getLSID()); @@ -1996,9 +2015,15 @@ public void testCreateAndSavePlate() throws Exception // Assert assertTrue("Expected plate to have been persisted and provided with a rowId", plate.getRowId() > 0); + assertTrue("Expected plate to have been persisted and provided with a plateId", plate.getPlateId() != null); + + // verify access via plate ID + Plate savedPlate = PlateService.get().getPlate(container, plate.getPlateId()); + assertTrue("Expected plate to be accessible via it's plate ID", savedPlate != null); + assertTrue("Plate retrieved by plate ID doesn't match the original plate.", savedPlate.getRowId().equals(plate.getRowId())); // verify container filter access - Plate savedPlate = PlateService.get().getPlate(ContainerManager.getSharedContainer(), plate.getRowId()); + savedPlate = PlateService.get().getPlate(ContainerManager.getSharedContainer(), plate.getRowId()); assertTrue("Saved plate should not exist in the shared container", savedPlate == null); savedPlate = PlateService.get().getPlate(ContainerFilter.Type.CurrentAndSubfolders.create(ContainerManager.getSharedContainer(), user), plate.getRowId()); From e2c2f7289be25e3f94688aad40ac61fec37ee7df Mon Sep 17 00:00:00 2001 From: Lum Date: Mon, 29 Jan 2024 10:22:07 -0800 Subject: [PATCH 3/3] code review feedback --- assay/src/org/labkey/assay/plate/PlateManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index f0c12616b95..90437793834 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -1290,6 +1290,7 @@ public DilutionCurve getDilutionCurve(List wellGroups, boolean assume } @Override + @NotNull public List getPlateTypes() { return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getArrayList(PlateTypeBean.class);