From ded56ba2055e46e9a0db92f6580d30daa4b64687 Mon Sep 17 00:00:00 2001 From: lum Date: Fri, 12 Jan 2024 16:46:45 -0800 Subject: [PATCH 01/21] plate type checkpoint --- ...r.java => AbstractPlateLayoutHandler.java} | 23 +++- .../org/labkey/api/assay/plate/Plate.java | 2 + ...peHandler.java => PlateLayoutHandler.java} | 12 +- .../labkey/api/assay/plate/PlateService.java | 9 +- .../org/labkey/api/assay/plate/PlateType.java | 8 ++ assay/resources/schemas/assay.xml | 20 +++ .../postgresql/assay-24.001-24.002.sql | 20 +++ assay/src/org/labkey/assay/AssayModule.java | 4 +- .../src/org/labkey/assay/PlateController.java | 16 ++- .../org/labkey/assay/TsvProviderSchema.java | 4 +- .../assay/plate/PlateDataServiceImpl.java | 12 +- .../assay/plate/PlateDocumentProvider.java | 4 +- .../src/org/labkey/assay/plate/PlateImpl.java | 19 +++ .../org/labkey/assay/plate/PlateLayout.java | 42 +++++++ .../org/labkey/assay/plate/PlateManager.java | 118 +++++++++--------- ...andler.java => TsvPlateLayoutHandler.java} | 27 ++-- .../{PlateType.java => PlateTypeImpl.java} | 29 ++++- .../labkey/assay/plate/query/PlateSchema.java | 5 +- .../labkey/assay/plate/query/PlateTable.java | 1 + .../assay/plate/query/PlateTypeTable.java | 37 ++++++ .../assay/plate/view/plateTemplateList.jsp | 19 ++- .../org/labkey/assay/query/AssayDbSchema.java | 5 + 22 files changed, 326 insertions(+), 110 deletions(-) rename assay/api-src/org/labkey/api/assay/plate/{AbstractPlateTypeHandler.java => AbstractPlateLayoutHandler.java} (61%) rename assay/api-src/org/labkey/api/assay/plate/{PlateTypeHandler.java => PlateLayoutHandler.java} (86%) create mode 100644 assay/api-src/org/labkey/api/assay/plate/PlateType.java create mode 100644 assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql create mode 100644 assay/src/org/labkey/assay/plate/PlateLayout.java rename assay/src/org/labkey/assay/plate/{TsvPlateTypeHandler.java => TsvPlateLayoutHandler.java} (67%) rename assay/src/org/labkey/assay/plate/model/{PlateType.java => PlateTypeImpl.java} (68%) create mode 100644 assay/src/org/labkey/assay/plate/query/PlateTypeTable.java diff --git a/assay/api-src/org/labkey/api/assay/plate/AbstractPlateTypeHandler.java b/assay/api-src/org/labkey/api/assay/plate/AbstractPlateLayoutHandler.java similarity index 61% rename from assay/api-src/org/labkey/api/assay/plate/AbstractPlateTypeHandler.java rename to assay/api-src/org/labkey/api/assay/plate/AbstractPlateLayoutHandler.java index abaa96bf715..2a1002fed4a 100644 --- a/assay/api-src/org/labkey/api/assay/plate/AbstractPlateTypeHandler.java +++ b/assay/api-src/org/labkey/api/assay/plate/AbstractPlateLayoutHandler.java @@ -18,17 +18,22 @@ import org.labkey.api.data.Container; import org.labkey.api.query.ValidationException; import org.labkey.api.security.User; +import org.labkey.api.util.Pair; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * User: klum * Date: Jun 13, 2012 */ -public abstract class AbstractPlateTypeHandler implements PlateTypeHandler +public abstract class AbstractPlateLayoutHandler implements PlateLayoutHandler { + Map, PlateType> _plateTypeMap; + @Override public void validateTemplate(Container container, User user, Plate template) throws ValidationException { @@ -40,6 +45,22 @@ public Map> getDefaultGroupsForTypes() return Collections.emptyMap(); } + abstract protected List> getSupportedPlateSizes(); + + @Override + public List getSupportedPlateTypes() + { + if (_plateTypeMap == null) + { + _plateTypeMap = new HashMap<>(); + for (PlateType type : PlateService.get().getPlateTypes()) + { + _plateTypeMap.put(new Pair<>(type.getRows(), type.getColumns()), type); + } + } + return getSupportedPlateSizes().stream().filter(size -> _plateTypeMap.containsKey(size)).map(size -> _plateTypeMap.get(size)).collect(Collectors.toList()); + } + @Override public boolean showEditorWarningPanel() { 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 b2f7c0f5339..2ebd73135f4 100644 --- a/assay/api-src/org/labkey/api/assay/plate/Plate.java +++ b/assay/api-src/org/labkey/api/assay/plate/Plate.java @@ -40,6 +40,8 @@ public interface Plate extends PropertySet, Identifiable boolean isTemplate(); + @Nullable PlateType getPlateType(); + @Nullable PlateSet getPlateSetObject(); /** diff --git a/assay/api-src/org/labkey/api/assay/plate/PlateTypeHandler.java b/assay/api-src/org/labkey/api/assay/plate/PlateLayoutHandler.java similarity index 86% rename from assay/api-src/org/labkey/api/assay/plate/PlateTypeHandler.java rename to assay/api-src/org/labkey/api/assay/plate/PlateLayoutHandler.java index 949b7f7a647..ab447e6b089 100644 --- a/assay/api-src/org/labkey/api/assay/plate/PlateTypeHandler.java +++ b/assay/api-src/org/labkey/api/assay/plate/PlateLayoutHandler.java @@ -16,25 +16,25 @@ package org.labkey.api.assay.plate; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.data.Container; import org.labkey.api.query.ValidationException; import org.labkey.api.security.User; -import org.labkey.api.util.Pair; import java.util.List; import java.sql.SQLException; import java.util.Map; /** - * User: jeckels - * Date: Apr 23, 2007 + * Represents a handler that can create assay specific plate layouts */ -public interface PlateTypeHandler +public interface PlateLayoutHandler { + @NotNull String getAssayType(); - List getTemplateTypes(Pair size); + @NotNull List getLayoutTypes(PlateType plateType); /** * createTemplate will be given a null value for templateTypeName when it is creating a new template which is a @@ -42,7 +42,7 @@ public interface PlateTypeHandler */ Plate createTemplate(@Nullable String templateTypeName, Container container, int rowCount, int colCount) throws SQLException; - List> getSupportedPlateSizes(); + List getSupportedPlateTypes(); List getWellGroupTypes(); 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 9a065b1fd95..43293aca0ee 100644 --- a/assay/api-src/org/labkey/api/assay/plate/PlateService.java +++ b/assay/api-src/org/labkey/api/assay/plate/PlateService.java @@ -164,6 +164,13 @@ static PlateService get() */ @Nullable PlateSet getPlateSet(Container container, int plateSetId); + /** + * Returns the list of available plate types. + * @return + */ + @NotNull List getPlateTypes(); + + /** * Returns the number of assay runs that are linked to the specified plate. Currently, this only works * for the standard assay with plate support since other assays types do not store the plate ID with the @@ -235,7 +242,7 @@ static PlateService get() /** * Registers a handler for a particular type of plate */ - void registerPlateTypeHandler(PlateTypeHandler handler); + void registerPlateLayoutHandler(PlateLayoutHandler handler); /** * Calculates a dilution curve for the specified well groups. diff --git a/assay/api-src/org/labkey/api/assay/plate/PlateType.java b/assay/api-src/org/labkey/api/assay/plate/PlateType.java new file mode 100644 index 00000000000..e2794a3377f --- /dev/null +++ b/assay/api-src/org/labkey/api/assay/plate/PlateType.java @@ -0,0 +1,8 @@ +package org.labkey.api.assay.plate; + +public interface PlateType +{ + String getDescription(); + Integer getRows(); + Integer getColumns(); +} diff --git a/assay/resources/schemas/assay.xml b/assay/resources/schemas/assay.xml index e92a7890cd5..e29f3cea650 100644 --- a/assay/resources/schemas/assay.xml +++ b/assay/resources/schemas/assay.xml @@ -37,6 +37,15 @@ assay + + PlateType + The plate type of this plate. + + RowId + PlateType + assay + + int Created By @@ -186,4 +195,15 @@ + + Contains one row per plate type. + + + true + + + + + +
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql new file mode 100644 index 00000000000..b041c8383d5 --- /dev/null +++ b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql @@ -0,0 +1,20 @@ +CREATE TABLE assay.PlateType +( + RowId SERIAL, + Rows INT NOT NULL, + Columns INT NOT NULL, + Description VARCHAR(200) NOT NULL, + + CONSTRAINT PK_PlateType PRIMARY KEY (RowId), + CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns) +); + +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (3, 4, '12 well (3x4)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well (4x6)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (32, 48, '1536 well (32x48)'); + +ALTER TABLE assay.Plate ADD COLUMN PlateTypeId INTEGER; +ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateTypeId FOREIGN KEY (PlateTypeId) REFERENCES assay.PlateType (RowId); diff --git a/assay/src/org/labkey/assay/AssayModule.java b/assay/src/org/labkey/assay/AssayModule.java index 8906d021081..9964ef19f6e 100644 --- a/assay/src/org/labkey/assay/AssayModule.java +++ b/assay/src/org/labkey/assay/AssayModule.java @@ -70,7 +70,7 @@ import org.labkey.assay.plate.AssayPlateMetadataServiceImpl; import org.labkey.assay.plate.PlateDocumentProvider; import org.labkey.assay.plate.PlateManager; -import org.labkey.assay.plate.TsvPlateTypeHandler; +import org.labkey.assay.plate.TsvPlateLayoutHandler; import org.labkey.assay.plate.query.PlateSchema; import org.labkey.assay.query.AssayDbSchema; import org.labkey.assay.query.AssaySchemaImpl; @@ -149,7 +149,7 @@ protected void init() ExperimentService.get().registerExperimentDataHandler(new PlateMetadataDataHandler()); AssayPlateMetadataService.registerService(PlateMetadataDataHandler.DATA_TYPE, new AssayPlateMetadataServiceImpl()); PropertyService.get().registerDomainKind(new AssayPlateDataDomainKind()); - PlateService.get().registerPlateTypeHandler(new TsvPlateTypeHandler()); + PlateService.get().registerPlateLayoutHandler(new TsvPlateLayoutHandler()); PropertyService.get().registerDomainKind(new DefaultAssayDomainKind()); PropertyService.get().registerDomainKind(new AssayBatchDomainKind()); diff --git a/assay/src/org/labkey/assay/PlateController.java b/assay/src/org/labkey/assay/PlateController.java index 46fb1a08ee0..f83e406e7c1 100644 --- a/assay/src/org/labkey/assay/PlateController.java +++ b/assay/src/org/labkey/assay/PlateController.java @@ -35,6 +35,7 @@ import org.labkey.api.assay.plate.Plate; import org.labkey.api.assay.plate.PlateCustomField; import org.labkey.api.assay.plate.PlateService; +import org.labkey.api.assay.plate.PlateType; import org.labkey.api.assay.security.DesignAssayPermission; import org.labkey.api.collections.RowMapFactory; import org.labkey.api.data.Container; @@ -65,7 +66,6 @@ import org.labkey.assay.plate.PlateImpl; import org.labkey.assay.plate.PlateManager; import org.labkey.assay.plate.PlateUrls; -import org.labkey.assay.plate.model.PlateType; import org.labkey.assay.view.AssayGWTView; import org.springframework.validation.BindException; import org.springframework.validation.Errors; @@ -545,7 +545,7 @@ public void setPlateId(Integer plateId) public static class CreatePlateForm implements ApiJsonForm { private String _name; - private PlateType _plateType; + private Integer _plateType; private List> _data = new ArrayList<>(); public String getName() @@ -553,7 +553,7 @@ public String getName() return _name; } - public PlateType getPlateType() + public Integer getPlateType() { return _plateType; } @@ -572,7 +572,7 @@ public void bindJson(JSONObject json) _name = json.getString("name"); if (json.has("plateType")) - _plateType = objectMapper.convertValue(json.getJSONObject("plateType"), PlateType.class); + _plateType = json.getInt("plateType"); if (json.has("data")) { @@ -596,6 +596,8 @@ public void bindJson(JSONObject json) @RequiresAnyOf({InsertPermission.class, DesignAssayPermission.class}) public static class CreatePlateAction extends MutatingApiAction { + private PlateType _plateType; + @Override public void validateForm(CreatePlateForm form, Errors errors) { @@ -603,6 +605,10 @@ public void validateForm(CreatePlateForm form, Errors errors) errors.reject(ERROR_REQUIRED, "Plate \"name\" is required."); if (form.getPlateType() == null) errors.reject(ERROR_REQUIRED, "Plate \"plateType\" is required."); + + _plateType = PlateManager.get().getPlateType(form.getPlateType()); + if (_plateType == null) + errors.reject(ERROR_REQUIRED, "Plate type id \"" + form.getPlateType() + "\" is invalid."); } @Override @@ -610,7 +616,7 @@ public Object execute(CreatePlateForm form, BindException errors) throws Excepti { try { - Plate plate = PlateManager.get().createAndSavePlate(getContainer(), getUser(), form.getPlateType(), form.getName(), form.getData()); + Plate plate = PlateManager.get().createAndSavePlate(getContainer(), getUser(), _plateType, form.getName(), null, form.getData()); return success(plate); } catch (Exception e) diff --git a/assay/src/org/labkey/assay/TsvProviderSchema.java b/assay/src/org/labkey/assay/TsvProviderSchema.java index a48058a8875..1990d298e53 100644 --- a/assay/src/org/labkey/assay/TsvProviderSchema.java +++ b/assay/src/org/labkey/assay/TsvProviderSchema.java @@ -9,7 +9,7 @@ import org.labkey.api.query.FieldKey; import org.labkey.api.query.SimpleUserSchema; import org.labkey.api.security.User; -import org.labkey.assay.plate.TsvPlateTypeHandler; +import org.labkey.assay.plate.TsvPlateLayoutHandler; import org.labkey.assay.query.AssayDbSchema; import java.util.Collections; @@ -49,7 +49,7 @@ public PlateTemplateTable(TsvProviderSchema schema, ContainerFilter cf) setName(PLATE_TEMPLATE_TABLE); setTitleColumn("Name"); - addCondition(new SimpleFilter(FieldKey.fromParts("Type"), TsvPlateTypeHandler.TYPE)); + addCondition(new SimpleFilter(FieldKey.fromParts("Type"), TsvPlateLayoutHandler.TYPE)); } @Override diff --git a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java index 9b7a2c78d9b..618ba9d8648 100644 --- a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java @@ -24,7 +24,7 @@ import org.apache.logging.log4j.Logger; import org.labkey.api.assay.plate.Plate; import org.labkey.api.assay.plate.PlateService; -import org.labkey.api.assay.plate.PlateTypeHandler; +import org.labkey.api.assay.plate.PlateLayoutHandler; import org.labkey.api.assay.plate.Position; import org.labkey.api.assay.plate.WellGroup; import org.labkey.api.gwt.server.BaseRemoteService; @@ -60,7 +60,7 @@ public GWTPlate getTemplateDefinition(String templateName, int plateId, String a try { Plate template; - PlateTypeHandler handler; + PlateLayoutHandler handler; if (templateName != null) { @@ -69,14 +69,14 @@ public GWTPlate getTemplateDefinition(String templateName, int plateId, String a if (template == null) throw new Exception("Plate " + templateName + " does not exist."); - handler = PlateManager.get().getPlateTypeHandler(template.getType()); + handler = PlateManager.get().getPlateLayoutHandler(template.getType()); if (handler == null) throw new Exception("Plate template type " + template.getType() + " does not exist."); } else { // new default template - handler = PlateManager.get().getPlateTypeHandler(assayTypeName); + handler = PlateManager.get().getPlateLayoutHandler(assayTypeName); if (handler == null) throw new Exception("Plate template type " + assayTypeName + " does not exist."); @@ -133,7 +133,7 @@ private List getTypeList(Plate template) WellGroup.Type.CONTROL, WellGroup.Type.SPECIMEN, WellGroup.Type.REPLICATE, WellGroup.Type.OTHER); - PlateTypeHandler handler = PlateManager.get().getPlateTypeHandler(template.getType()); + PlateLayoutHandler handler = PlateManager.get().getPlateLayoutHandler(template.getType()); if (handler != null) wellTypes = handler.getWellGroupTypes(); @@ -229,7 +229,7 @@ public int saveChanges(GWTPlate gwtPlate, boolean replaceIfExisting) throws Exce group.setProperties(gwtGroup.getProperties()); } - PlateManager.get().getPlateTypeHandler(template.getType()).validateTemplate(getContainer(), getUser(), template); + PlateManager.get().getPlateLayoutHandler(template.getType()).validateTemplate(getContainer(), getUser(), template); return PlateService.get().save(getContainer(), getUser(), template); } catch (BatchValidationException | ValidationException e) diff --git a/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java b/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java index 8dfa7381403..78717bd01bb 100644 --- a/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java +++ b/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; import org.json.JSONObject; import org.labkey.api.assay.plate.Plate; +import org.labkey.api.assay.plate.PlateType; import org.labkey.api.data.Container; import org.labkey.api.exp.Lsid; import org.labkey.api.search.SearchService; @@ -15,7 +16,6 @@ import org.labkey.api.view.ActionURL; import org.labkey.api.webdav.SimpleDocumentResource; import org.labkey.api.webdav.WebdavResource; -import org.labkey.assay.plate.model.PlateType; import java.util.Collection; import java.util.Date; @@ -73,7 +73,7 @@ public static WebdavResource createDocument(@NotNull Plate plate) StringBuilder body = new StringBuilder(); - PlateType plateType = PlateManager.get().getPlateType(plate); + 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 a3a72ff0b37..e31a8a7dc17 100644 --- a/assay/src/org/labkey/assay/plate/PlateImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateImpl.java @@ -24,6 +24,7 @@ import org.labkey.api.assay.plate.PlateCustomField; import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.PlateSet; +import org.labkey.api.assay.plate.PlateType; import org.labkey.api.assay.plate.Position; import org.labkey.api.assay.plate.PositionImpl; import org.labkey.api.assay.plate.Well; @@ -60,6 +61,7 @@ public class PlateImpl extends PropertySetImpl implements Plate, Cloneable private String _type; private boolean _isTemplate; private Integer _plateSetId; + private Integer _plateTypeId; private Map> _groups; private List _deletedGroups; @@ -543,6 +545,23 @@ public Integer getPlateSet() return _plateSetId; } + public Integer getPlateTypeId() + { + return _plateTypeId; + } + + public void setPlateTypeId(Integer plateTypeId) + { + _plateTypeId = plateTypeId; + } + + @Override + @JsonIgnore + public @Nullable PlateType getPlateType() + { + return PlateManager.get().getPlateType(_plateTypeId); + } + @Override @JsonIgnore public @Nullable PlateSet getPlateSetObject() diff --git a/assay/src/org/labkey/assay/plate/PlateLayout.java b/assay/src/org/labkey/assay/plate/PlateLayout.java new file mode 100644 index 00000000000..6c0ae06b0f2 --- /dev/null +++ b/assay/src/org/labkey/assay/plate/PlateLayout.java @@ -0,0 +1,42 @@ +package org.labkey.assay.plate; + +import org.labkey.api.assay.plate.PlateType; + +/** + * Plate layouts encompass plate types but also include assay specific information + */ +public class PlateLayout +{ + private PlateType _plateType; + private String _assayType; + private String _description; + private String _name; + + public PlateLayout(String name, PlateType type, String assayType, String description) + { + _name = name; + _plateType = type; + _assayType = assayType; + _description = description; + } + + public String getName() + { + return _name; + } + + public PlateType getPlateType() + { + return _plateType; + } + + public String getAssayType() + { + return _assayType; + } + + public String getDescription() + { + return _description; + } +} diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 0f5033a5520..e1a38c8aaac 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -27,12 +27,13 @@ import org.labkey.api.assay.AssayProvider; import org.labkey.api.assay.AssayService; import org.labkey.api.assay.dilution.DilutionCurve; -import org.labkey.api.assay.plate.AbstractPlateTypeHandler; +import org.labkey.api.assay.plate.AbstractPlateLayoutHandler; import org.labkey.api.assay.plate.Plate; import org.labkey.api.assay.plate.PlateCustomField; +import org.labkey.api.assay.plate.PlateLayoutHandler; import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.PlateSet; -import org.labkey.api.assay.plate.PlateTypeHandler; +import org.labkey.api.assay.plate.PlateType; import org.labkey.api.assay.plate.PlateUtils; import org.labkey.api.assay.plate.Position; import org.labkey.api.assay.plate.PositionImpl; @@ -94,7 +95,7 @@ import org.labkey.api.view.ActionURL; import org.labkey.api.webdav.WebdavResource; import org.labkey.assay.TsvAssayProvider; -import org.labkey.assay.plate.model.PlateType; +import org.labkey.assay.plate.model.PlateTypeImpl; import org.labkey.assay.plate.model.WellGroupBean; import org.labkey.assay.plate.query.PlateSchema; import org.labkey.assay.plate.query.PlateSetTable; @@ -136,7 +137,7 @@ public class PlateManager implements PlateService private final List _detailsLinkResolvers = new ArrayList<>(); private boolean _lsidHandlersRegistered = false; - private final Map _plateTypeHandlers = new HashMap<>(); + private final Map _plateLayoutHandlers = new HashMap<>(); // name expressions, currently not configurable private static final String PLATE_SET_NAME_EXPRESSION = "PLS-${now:date('yyyyMMdd')}-${RowId}"; @@ -157,7 +158,7 @@ public static PlateManager get() public PlateManager() { - registerPlateTypeHandler(new AbstractPlateTypeHandler() + registerPlateLayoutHandler(new AbstractPlateLayoutHandler() { @Override public Plate createTemplate(@Nullable String templateTypeName, Container container, int rowCount, int colCount) @@ -172,15 +173,16 @@ public String getAssayType() } @Override - public List getTemplateTypes(Pair size) + @NotNull + public List getLayoutTypes(PlateType plateType) { return new ArrayList<>(); } @Override - public List> getSupportedPlateSizes() + protected List> getSupportedPlateSizes() { - return Collections.singletonList(new Pair<>(8, 12)); + return List.of(new Pair<>(8, 12)); } @Override @@ -215,14 +217,14 @@ public List getWellGroupTypes() @NotNull User user, @NotNull PlateType plateType, @Nullable String plateName, + @Nullable String assayType, @Nullable List> data ) throws Exception { Plate plate = null; try (DbScope.Transaction tx = ensureTransaction()) { - PlateTypeHandler plateTypeHandler = getPlateTypeHandler(plateType.getAssayType()); - Plate plateTemplate = plateTypeHandler.createTemplate(plateType.getType(), container, plateType.getRows(), plateType.getCols()); + Plate plateTemplate = PlateService.get().createPlateTemplate(container, assayType, plateType.getRows(), plateType.getColumns()); plate = createPlate(plateTemplate, null, null); if (StringUtils.trimToNull(plateName) != null) @@ -1034,16 +1036,17 @@ public ActionURL getDetailsURL(Plate plate) return null; } - public List getPlateTypeHandlers() + public List getPlateLayoutHandlers() { - List result = new ArrayList<>(_plateTypeHandlers.values()); - result.sort(Comparator.comparing(PlateTypeHandler::getAssayType, String.CASE_INSENSITIVE_ORDER)); + List result = new ArrayList<>(_plateLayoutHandlers.values()); + result.sort(Comparator.comparing(PlateLayoutHandler::getAssayType, String.CASE_INSENSITIVE_ORDER)); return result; } - public PlateTypeHandler getPlateTypeHandler(String plateTypeName) + @Nullable + public PlateLayoutHandler getPlateLayoutHandler(String plateTypeName) { - return _plateTypeHandlers.get(plateTypeName); + return _plateLayoutHandlers.get(plateTypeName); } private UserSchema getPlateUserSchema(Container container, User user) @@ -1220,13 +1223,13 @@ public Plate copyPlate(Plate source, User user, Container destContainer) } @Override - public void registerPlateTypeHandler(PlateTypeHandler handler) + public void registerPlateLayoutHandler(PlateLayoutHandler handler) { - if (_plateTypeHandlers.containsKey(handler.getAssayType())) + if (_plateLayoutHandlers.containsKey(handler.getAssayType())) { throw new IllegalArgumentException(handler.getAssayType()); } - _plateTypeHandlers.put(handler.getAssayType(), handler); + _plateLayoutHandlers.put(handler.getAssayType(), handler); } public void clearCache(Container c, Plate plate) @@ -1245,55 +1248,54 @@ public DilutionCurve getDilutionCurve(List wellGroups, boolean assume return CurveFitFactory.getCurveImpl(wellGroups, assumeDecreasing, percentCalculator, type); } - public List getPlateTypes() + @Override + public List getPlateTypes() + { + return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getArrayList(PlateTypeImpl.class); + } + + @Nullable + public PlateType getPlateType(int rows, int columns) { - List plateTypes = new ArrayList<>(); + SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("Rows"), rows); + filter.addCondition(FieldKey.fromParts("Columns"), columns); - for (PlateTypeHandler handler : getPlateTypeHandlers()) + return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType(), filter, null).getObject(PlateTypeImpl.class); + } + + @NotNull + public List getPlateLayouts() + { + List layouts = new ArrayList<>(); + for (PlateLayoutHandler handler : getPlateLayoutHandlers()) { - for (Pair size : handler.getSupportedPlateSizes()) + for (PlateType type : handler.getSupportedPlateTypes()) { - int rows = size.first; - int cols = size.second; + int wellCount = type.getRows() * type.getColumns(); + String sizeDescription = wellCount + " well (" + type.getRows() + "x" + type.getColumns() + ") "; - int wellCount = rows * cols; - String sizeDescription = wellCount + " well (" + rows + "x" + cols + ") "; - - List types = handler.getTemplateTypes(size); - if (types == null || types.isEmpty()) + List layoutTypes = handler.getLayoutTypes(type); + if (layoutTypes.isEmpty()) { String description = sizeDescription + handler.getAssayType(); - plateTypes.add(new PlateType(handler.getAssayType(), null, description, rows, cols)); + layouts.add(new PlateLayout(null, type, handler.getAssayType(), description)); } else { - for (String type : types) + for (String layoutName : layoutTypes) { - String description = sizeDescription + handler.getAssayType() + " " + type; - plateTypes.add(new PlateType(handler.getAssayType(), type, description, rows, cols)); + String description = sizeDescription + handler.getAssayType() + " " + layoutName; + layouts.add(new PlateLayout(layoutName, type, handler.getAssayType(), description)); } } } } - - return plateTypes; + return layouts; } - public PlateType getPlateType(@NotNull Plate plate) + public PlateType getPlateType(Integer plateTypeId) { - for (PlateType plateType : getPlateTypes()) - { - if ( - plateType.getRows() == plate.getRows() && - Objects.equals(plateType.getCols(), plateType.getCols()) && - Objects.equals(plateType.getType(), plate.getType()) - ) - { - return plateType; - } - } - - return null; + return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getObject(plateTypeId, PlateTypeImpl.class); } public @NotNull Map>> getPlateOperationConfirmationData( @@ -1734,7 +1736,7 @@ public void createPlateTemplate() throws Exception // INSERT // - PlateTypeHandler handler = PlateManager.get().getPlateTypeHandler(TsvPlateTypeHandler.TYPE); + PlateLayoutHandler handler = PlateManager.get().getPlateLayoutHandler(TsvPlateLayoutHandler.TYPE); Plate template = handler.createTemplate("UNUSED", container, 8, 12); template.setName("bob"); template.setProperty("friendly", "yes"); @@ -1843,10 +1845,11 @@ public void createPlateTemplate() throws Exception public void testCreateAndSavePlate() throws Exception { // Arrange - PlateType plateType = new PlateType(TsvPlateTypeHandler.TYPE, TsvPlateTypeHandler.BLANK_PLATE, "Test plate type", 8, 12); + PlateType plateType = PlateManager.get().getPlateType(8, 12); + assertNotNull("96 well plate type was not found", plateType); // Act - Plate plate = PlateManager.get().createAndSavePlate(container, user, plateType, "testCreateAndSavePlate plate", null); + Plate plate = PlateManager.get().createAndSavePlate(container, user, plateType, "testCreateAndSavePlate plate", null, null); // Assert assertTrue("Expected plate to have been persisted and provided with a rowId", plate.getRowId() > 0); @@ -1863,7 +1866,7 @@ public void testCreateAndSavePlate() throws Exception public void testCreatePlateTemplates() throws Exception { // Verify plate service assumptions about plate templates - Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateTypeHandler.TYPE, 16, 24); + Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateLayoutHandler.TYPE, 16, 24); plate.setName("my plate template"); int plateId = PlateService.get().save(container, user, plate); @@ -1872,7 +1875,7 @@ public void testCreatePlateTemplates() throws Exception assertTrue("Expected saved plate to have the template field set to true", PlateService.get().getPlate(container, plateId).isTemplate()); // Verify only plate templates are returned - plate = PlateService.get().createPlate(container, TsvPlateTypeHandler.TYPE, 8, 12); + plate = PlateService.get().createPlate(container, TsvPlateLayoutHandler.TYPE, 8, 12); plate.setName("non plate template"); PlateService.get().save(container, user, plate); @@ -1887,7 +1890,7 @@ public void testCreatePlateTemplates() throws Exception @Test public void testCreatePlateMetadata() throws Exception { - Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateTypeHandler.TYPE, 16, 24); + Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateLayoutHandler.TYPE, 16, 24); plate.setName("new plate with metadata"); int plateId = PlateService.get().save(container, user, plate); @@ -1993,7 +1996,8 @@ else if (row == 1) public void testCreateAndSavePlateWithData() throws Exception { // Arrange - PlateType plateType = new PlateType(TsvPlateTypeHandler.TYPE, TsvPlateTypeHandler.BLANK_PLATE, "Standard 96 well plate", 8, 12); + PlateType plateType = PlateManager.get().getPlateType(8, 12); + assertNotNull("96 well plate type was not found", plateType); // Act List> rows = List.of( @@ -2008,7 +2012,7 @@ public void testCreateAndSavePlateWithData() throws Exception "properties/barcode", "B5678" ) ); - Plate plate = PlateManager.get().createAndSavePlate(container, user, plateType, "hit selection plate", rows); + Plate plate = PlateManager.get().createAndSavePlate(container, user, plateType, "hit selection plate", null, rows); assertEquals("Expected 2 plate custom fields", 2, plate.getCustomFields().size()); TableInfo wellTable = QueryService.get().getUserSchema(user, container, PlateSchema.SCHEMA_NAME).getTable(WellTable.NAME); diff --git a/assay/src/org/labkey/assay/plate/TsvPlateTypeHandler.java b/assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java similarity index 67% rename from assay/src/org/labkey/assay/plate/TsvPlateTypeHandler.java rename to assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java index 1bfb6dc2a11..a01c4700943 100644 --- a/assay/src/org/labkey/assay/plate/TsvPlateTypeHandler.java +++ b/assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java @@ -1,19 +1,20 @@ package org.labkey.assay.plate; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.labkey.api.assay.plate.AbstractPlateTypeHandler; +import org.labkey.api.assay.plate.AbstractPlateLayoutHandler; import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.Plate; +import org.labkey.api.assay.plate.PlateType; import org.labkey.api.assay.plate.WellGroup; import org.labkey.api.data.Container; import org.labkey.api.util.Pair; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -public class TsvPlateTypeHandler extends AbstractPlateTypeHandler +public class TsvPlateLayoutHandler extends AbstractPlateLayoutHandler { public static final String BLANK_PLATE = "blank"; public static final String TYPE = "Standard"; @@ -25,7 +26,8 @@ public String getAssayType() } @Override - public List getTemplateTypes(Pair size) + @NotNull + public List getLayoutTypes(PlateType plateType) { return Collections.singletonList(BLANK_PLATE); } @@ -42,17 +44,14 @@ public Plate createTemplate(@Nullable String templateTypeName, Container contain } @Override - public List> getSupportedPlateSizes() + protected List> getSupportedPlateSizes() { - List> sizes = new ArrayList<>(); - sizes.add(new Pair<>(3, 4)); - sizes.add(new Pair<>(4, 6)); - sizes.add(new Pair<>(6, 8)); - sizes.add(new Pair<>(8, 12)); - sizes.add(new Pair<>(16, 24)); - sizes.add(new Pair<>(32, 48)); - - return sizes; + return List.of(new Pair<>(3, 4), + new Pair<>(4, 6), + new Pair<>(6, 8), + new Pair<>(8, 12), + new Pair<>(16, 24), + new Pair<>(32, 48)); } @Override diff --git a/assay/src/org/labkey/assay/plate/model/PlateType.java b/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java similarity index 68% rename from assay/src/org/labkey/assay/plate/model/PlateType.java rename to assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java index d1ffd7bd02b..2cf9cafc221 100644 --- a/assay/src/org/labkey/assay/plate/model/PlateType.java +++ b/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java @@ -1,21 +1,23 @@ package org.labkey.assay.plate.model; import com.fasterxml.jackson.annotation.JsonInclude; +import org.labkey.api.assay.plate.PlateType; @JsonInclude(JsonInclude.Include.NON_NULL) -public class PlateType +public class PlateTypeImpl implements PlateType { + private Integer _rowId; private String _assayType; private Integer _cols; private String _description; private Integer _rows; private String _type; - public PlateType() + public PlateTypeImpl() { } - public PlateType(String assayType, String type, String description, Integer rows, Integer cols) + public PlateTypeImpl(String assayType, String type, String description, Integer rows, Integer cols) { _assayType = assayType; _type = type; @@ -24,6 +26,16 @@ public PlateType(String assayType, String type, String description, Integer rows _rows = rows; } + public Integer getRowId() + { + return _rowId; + } + + public void setRowId(Integer rowId) + { + _rowId = rowId; + } + public String getAssayType() { return _assayType; @@ -39,6 +51,17 @@ public Integer getCols() return _cols; } + @Override + public Integer getColumns() + { + return _cols; + } + + public void setColumns(Integer cols) + { + _cols = cols; + } + public void setCols(Integer cols) { _cols = cols; diff --git a/assay/src/org/labkey/assay/plate/query/PlateSchema.java b/assay/src/org/labkey/assay/plate/query/PlateSchema.java index b4e3f33f18c..bb58aed7fbe 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateSchema.java +++ b/assay/src/org/labkey/assay/plate/query/PlateSchema.java @@ -44,7 +44,8 @@ public class PlateSchema extends SimpleUserSchema PlateTable.NAME, WellGroupTable.NAME, WellTable.NAME, - PlateSetTable.NAME + PlateSetTable.NAME, + PlateTypeTable.NAME )); public PlateSchema(User user, Container container) @@ -70,6 +71,8 @@ public TableInfo createTable(String name, ContainerFilter cf) return new WellTable(this, cf).init(); if (name.equalsIgnoreCase(PlateSetTable.NAME)) return new PlateSetTable(this, cf).init(); + if (name.equalsIgnoreCase(PlateTypeTable.NAME)) + return new PlateTypeTable(this, cf).init(); return null; } diff --git a/assay/src/org/labkey/assay/plate/query/PlateTable.java b/assay/src/org/labkey/assay/plate/query/PlateTable.java index ab76d068226..3f54b86206d 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateTable.java @@ -91,6 +91,7 @@ public class PlateTable extends SimpleUserSchema.SimpleTable defaultVisibleColumns.add(FieldKey.fromParts("Modified")); defaultVisibleColumns.add(FieldKey.fromParts("ModifiedBy")); defaultVisibleColumns.add(FieldKey.fromParts("Template")); + defaultVisibleColumns.add(FieldKey.fromParts("PlateTypeId")); defaultVisibleColumns.add(FieldKey.fromParts("Rows")); defaultVisibleColumns.add(FieldKey.fromParts("Columns")); defaultVisibleColumns.add(FieldKey.fromParts("Type")); diff --git a/assay/src/org/labkey/assay/plate/query/PlateTypeTable.java b/assay/src/org/labkey/assay/plate/query/PlateTypeTable.java new file mode 100644 index 00000000000..b1dc0ff2dad --- /dev/null +++ b/assay/src/org/labkey/assay/plate/query/PlateTypeTable.java @@ -0,0 +1,37 @@ +package org.labkey.assay.plate.query; + +import org.jetbrains.annotations.Nullable; +import org.labkey.api.data.ContainerFilter; +import org.labkey.api.query.FieldKey; +import org.labkey.api.query.SimpleUserSchema; +import org.labkey.api.query.UserSchema; +import org.labkey.assay.query.AssayDbSchema; + +import java.util.ArrayList; +import java.util.List; + +public class PlateTypeTable extends SimpleUserSchema.SimpleTable +{ + private static final List defaultVisibleColumns = new ArrayList<>(); + + static + { + defaultVisibleColumns.add(FieldKey.fromParts("Description")); + defaultVisibleColumns.add(FieldKey.fromParts("Rows")); + defaultVisibleColumns.add(FieldKey.fromParts("Columns")); + } + + public static final String NAME = "PlateType"; + + public PlateTypeTable(PlateSchema schema, @Nullable ContainerFilter cf) + { + super(schema, AssayDbSchema.getInstance().getTableInfoPlateType(), cf); + setTitleColumn("Description"); + } + + @Override + public List getDefaultVisibleColumns() + { + return defaultVisibleColumns; + } +} diff --git a/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp b/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp index 9d09936f2ba..0a37618e52a 100644 --- a/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp +++ b/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp @@ -15,8 +15,8 @@ * limitations under the License. */ %> -<%@ page import="org.labkey.api.assay.plate.PlateService" %> <%@ page import="org.labkey.api.assay.plate.Plate" %> +<%@ page import="org.labkey.api.assay.plate.PlateService" %> <%@ page import="org.labkey.api.assay.security.DesignAssayPermission" %> <%@ page import="org.labkey.api.data.Container" %> <%@ page import="org.labkey.api.security.permissions.DeletePermission" %> @@ -30,13 +30,12 @@ <%@ page import="org.labkey.api.view.HttpView" %> <%@ page import="org.labkey.api.view.JspView" %> <%@ page import="org.labkey.assay.PlateController" %> +<%@ page import="org.labkey.assay.plate.PlateLayout" %> <%@ page import="org.labkey.assay.plate.PlateManager" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashMap" %> <%@ page import="java.util.List" %> <%@ page import="java.util.Map" %> -<%@ page import="org.labkey.assay.plate.model.PlateType" %> -<%@ page import="org.labkey.api.assay.plate.Plate" %> <%@ page extends="org.labkey.api.jsp.JspBase" %> <%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> @@ -205,18 +204,18 @@ if (isAssayDesigner || c.hasPermission(getUser(), InsertPermission.class)) { List
- PlateType The plate type of this plate. RowId diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java index 618ba9d8648..5532bf97867 100644 --- a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java @@ -23,8 +23,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.labkey.api.assay.plate.Plate; -import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.PlateLayoutHandler; +import org.labkey.api.assay.plate.PlateService; +import org.labkey.api.assay.plate.PlateType; import org.labkey.api.assay.plate.Position; import org.labkey.api.assay.plate.WellGroup; import org.labkey.api.gwt.server.BaseRemoteService; @@ -80,7 +81,10 @@ public GWTPlate getTemplateDefinition(String templateName, int plateId, String a if (handler == null) throw new Exception("Plate template type " + assayTypeName + " does not exist."); - template = handler.createTemplate(templateTypeName, getContainer(), rowCount, columnCount); + PlateType plateType = PlateService.get().getPlateType(rowCount, columnCount); + if (plateType == null) + throw new Exception("The plate type : (" + rowCount + " x " + columnCount + ") does not exist"); + template = handler.createTemplate(templateTypeName, getContainer(), plateType); } // Translate PlateTemplate to GWTPlate @@ -183,7 +187,10 @@ public int saveChanges(GWTPlate gwtPlate, boolean replaceIfExisting) throws Exce PlateService.get().deletePlate(getContainer(), getUser(), other.getRowId()); } - template = PlateManager.get().createPlateTemplate(getContainer(), gwtPlate.getType(), gwtPlate.getRows(), gwtPlate.getCols()); + PlateType plateType = PlateService.get().getPlateType(gwtPlate.getRows(), gwtPlate.getCols()); + if (plateType == null) + throw new Exception("The plate type : (" + gwtPlate.getRows() + " x " + gwtPlate.getCols() + ") does not exist"); + template = PlateManager.get().createPlateTemplate(getContainer(), gwtPlate.getType(), plateType); } template.setName(gwtPlate.getName()); diff --git a/assay/src/org/labkey/assay/plate/PlateImpl.java b/assay/src/org/labkey/assay/plate/PlateImpl.java index e31a8a7dc17..de2386e21f8 100644 --- a/assay/src/org/labkey/assay/plate/PlateImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateImpl.java @@ -51,8 +51,6 @@ public class PlateImpl extends PropertySetImpl implements Plate, Cloneable { private String _name; private Integer _rowId; - private int _rows; - private int _columns; private int _createdBy; private long _created; private int _modifiedBy; @@ -84,20 +82,19 @@ public PlateImpl() _plateNumber = 1; } - public PlateImpl(Container container, String name, String type, int rowCount, int colCount) + public PlateImpl(Container container, String name, String type, @NotNull PlateType plateType) { super(container); _name = name; _type = type; - _rows = rowCount; - _columns = colCount; _container = container; _dataFileId = GUID.makeGUID(); + _plateTypeId = plateType.getRowId(); } public PlateImpl(PlateImpl plate, double[][] wellValues, boolean[][] excluded, int runId, int plateNumber) { - this(plate.getContainer(), plate.getName(), plate.getType(), plate.getRows(), plate.getColumns()); + this(plate.getContainer(), plate.getName(), plate.getType(), plate.getPlateType()); if (wellValues == null) wellValues = new double[plate.getRows()][plate.getColumns()]; @@ -285,9 +282,10 @@ public Map> getWellGroupMap() } @Override + @JsonIgnore public int getColumns() { - return _columns; + return getPlateType().getColumns(); } @Override @@ -297,9 +295,10 @@ public String getName() } @Override + @JsonIgnore public int getRows() { - return _rows; + return getPlateType().getRows(); } @JsonIgnore @@ -319,16 +318,6 @@ public void setRowId(Integer rowId) _rowId = rowId; } - public void setColumns(int columns) - { - _columns = columns; - } - - public void setRows(int rows) - { - _rows = rows; - } - @Override public void setName(String name) { @@ -557,7 +546,7 @@ public void setPlateTypeId(Integer plateTypeId) @Override @JsonIgnore - public @Nullable PlateType getPlateType() + public @NotNull PlateType getPlateType() { return PlateManager.get().getPlateType(_plateTypeId); } diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index e1a38c8aaac..bd13b8c94a0 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -161,9 +161,10 @@ public PlateManager() registerPlateLayoutHandler(new AbstractPlateLayoutHandler() { @Override - public Plate createTemplate(@Nullable String templateTypeName, Container container, int rowCount, int colCount) + public Plate createTemplate(@Nullable String templateTypeName, Container container, @NotNull PlateType plateType) { - return PlateService.get().createPlateTemplate(container, getAssayType(), rowCount, colCount); + validatePlateType(plateType); + return PlateService.get().createPlateTemplate(container, getAssayType(), plateType); } @Override @@ -224,7 +225,7 @@ public List getWellGroupTypes() Plate plate = null; try (DbScope.Transaction tx = ensureTransaction()) { - Plate plateTemplate = PlateService.get().createPlateTemplate(container, assayType, plateType.getRows(), plateType.getColumns()); + Plate plateTemplate = PlateService.get().createPlateTemplate(container, assayType, plateType); plate = createPlate(plateTemplate, null, null); if (StringUtils.trimToNull(plateName) != null) @@ -396,16 +397,16 @@ public int getRunCountUsingPlate(@NotNull Container c, @NotNull User user, @NotN @Override @NotNull - public Plate createPlate(Container container, String templateType, int rowCount, int colCount) + public Plate createPlate(Container container, String templateType, @NotNull PlateType plateType) { - return new PlateImpl(container, null, templateType, rowCount, colCount); + return new PlateImpl(container, null, templateType, plateType); } @Override @NotNull - public Plate createPlateTemplate(Container container, String templateType, int rowCount, int colCount) + public Plate createPlateTemplate(Container container, String templateType, @NotNull PlateType plateType) { - Plate plate = createPlate(container, templateType, rowCount, colCount); + Plate plate = createPlate(container, templateType, plateType); ((PlateImpl)plate).setTemplate(true); return plate; @@ -1205,7 +1206,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.getType(), source.getRows(), source.getColumns()); + Plate newPlate = createPlateTemplate(destContainer, source.getType(), source.getPlateType()); newPlate.setName(source.getName()); for (String property : source.getPropertyNames()) newPlate.setProperty(property, source.getProperty(property)); @@ -1254,6 +1255,7 @@ public List getPlateTypes() return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getArrayList(PlateTypeImpl.class); } + @Override @Nullable public PlateType getPlateType(int rows, int columns) { @@ -1737,7 +1739,10 @@ public void createPlateTemplate() throws Exception // PlateLayoutHandler handler = PlateManager.get().getPlateLayoutHandler(TsvPlateLayoutHandler.TYPE); - Plate template = handler.createTemplate("UNUSED", container, 8, 12); + PlateType plateType = PlateManager.get().getPlateType(8, 12); + assertNotNull("96 well plate type was not found", plateType); + + Plate template = handler.createTemplate("UNUSED", container, plateType); template.setName("bob"); template.setProperty("friendly", "yes"); assertNull(template.getRowId()); @@ -1762,6 +1767,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, savedTemplate.getPlateType()); List wellGroups = savedTemplate.getWellGroups(); assertEquals(3, wellGroups.size()); @@ -1831,6 +1837,10 @@ public void createPlateTemplate() throws Exception // verify added positions assertEquals(2, updatedControlWellGroups.get(0).getPositions().size()); + // verify plate type information + assertEquals(plateType.getRows().intValue(), updatedTemplate.getRows()); + assertEquals(plateType.getColumns().intValue(), updatedTemplate.getColumns()); + // // DELETE // @@ -1866,7 +1876,9 @@ public void testCreateAndSavePlate() throws Exception public void testCreatePlateTemplates() throws Exception { // Verify plate service assumptions about plate templates - Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateLayoutHandler.TYPE, 16, 24); + PlateType plateType = PlateManager.get().getPlateType(16, 24); + assertNotNull("384 well plate type was not found", plateType); + Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateLayoutHandler.TYPE, plateType); plate.setName("my plate template"); int plateId = PlateService.get().save(container, user, plate); @@ -1875,7 +1887,10 @@ public void testCreatePlateTemplates() throws Exception assertTrue("Expected saved plate to have the template field set to true", PlateService.get().getPlate(container, plateId).isTemplate()); // Verify only plate templates are returned - plate = PlateService.get().createPlate(container, TsvPlateLayoutHandler.TYPE, 8, 12); + plateType = PlateManager.get().getPlateType(8, 12); + assertNotNull("96 well plate type was not found", plateType); + + plate = PlateService.get().createPlate(container, TsvPlateLayoutHandler.TYPE, plateType); plate.setName("non plate template"); PlateService.get().save(container, user, plate); @@ -1890,7 +1905,10 @@ public void testCreatePlateTemplates() throws Exception @Test public void testCreatePlateMetadata() throws Exception { - Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateLayoutHandler.TYPE, 16, 24); + PlateType plateType = PlateManager.get().getPlateType(16, 24); + assertNotNull("384 well plate type was not found", plateType); + + Plate plate = PlateService.get().createPlateTemplate(container, TsvPlateLayoutHandler.TYPE, plateType); plate.setName("new plate with metadata"); int plateId = PlateService.get().save(container, user, plate); diff --git a/assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java b/assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java index a01c4700943..f3111b99c95 100644 --- a/assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java +++ b/assay/src/org/labkey/assay/plate/TsvPlateLayoutHandler.java @@ -3,8 +3,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.assay.plate.AbstractPlateLayoutHandler; -import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.Plate; +import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.PlateType; import org.labkey.api.assay.plate.WellGroup; import org.labkey.api.data.Container; @@ -33,9 +33,10 @@ public List getLayoutTypes(PlateType plateType) } @Override - public Plate createTemplate(@Nullable String templateTypeName, Container container, int rowCount, int colCount) + public Plate createTemplate(@Nullable String templateTypeName, Container container, @NotNull PlateType plateType) { - Plate template = PlateService.get().createPlateTemplate(container, getAssayType(), rowCount, colCount); + validatePlateType(plateType); + Plate template = PlateService.get().createPlateTemplate(container, getAssayType(), plateType); template.addWellGroup("Positive", WellGroup.Type.CONTROL, Collections.emptyList()); template.addWellGroup("Negative", WellGroup.Type.CONTROL, Collections.emptyList()); diff --git a/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java b/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java index 2cf9cafc221..dcc811ed883 100644 --- a/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java +++ b/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java @@ -3,6 +3,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import org.labkey.api.assay.plate.PlateType; +import java.util.Objects; + @JsonInclude(JsonInclude.Include.NON_NULL) public class PlateTypeImpl implements PlateType { @@ -26,6 +28,7 @@ public PlateTypeImpl(String assayType, String type, String description, Integer _rows = rows; } + @Override public Integer getRowId() { return _rowId; @@ -96,4 +99,20 @@ public void setType(String type) { _type = type; } + + @Override + public int hashCode() + { + return (31 * _rows) + _cols; + } + + @Override + 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); + } } From d97fba51796a0c72709d90ee81315480b19ec652 Mon Sep 17 00:00:00 2001 From: Lum Date: Tue, 16 Jan 2024 13:20:09 -0800 Subject: [PATCH 03/21] plate type upgrade scripts --- api/webapp/WEB-INF/web.xml | 26 +++++++++++++ assay/resources/schemas/assay.xml | 8 ---- .../postgresql/assay-24.001-24.002.sql | 18 +++++++++ .../sqlserver/assay-24.001-24.002.sql | 39 +++++++++++++++++++ assay/src/org/labkey/assay/AssayModule.java | 2 +- .../labkey/assay/plate/query/PlateTable.java | 11 ++---- 6 files changed, 87 insertions(+), 17 deletions(-) diff --git a/api/webapp/WEB-INF/web.xml b/api/webapp/WEB-INF/web.xml index 02ceab19a7a..5f38c2469ff 100755 --- a/api/webapp/WEB-INF/web.xml +++ b/api/webapp/WEB-INF/web.xml @@ -66,6 +66,32 @@ *.post + + Content Security Policy Filter Filter + org.labkey.filters.ContentSecurityPolicyFilter + + policy + + default-src 'self' https: http: ; + connect-src 'self' ${LABKEY.ALLOWED.CONNECTIONS} ; + object-src 'none' ; + style-src 'self' https: 'unsafe-inline' ; + img-src 'self' https: data: http://chart.apis.google.com ; + script-src 'unsafe-eval' 'strict-dynamic' + 'nonce-${REQUEST.SCRIPT.NONCE}' ; + base-uri 'self' ; + frame-ancestors 'self' ; + report-uri + http://localhost:8080/labkey/admin-contentsecuritypolicyreport.api ; + report-to + http://localhost:8080/labkey/admin-contentsecuritypolicyreport.api ; + + + + + Content Security Policy Filter Filter + /* + / diff --git a/assay/resources/schemas/assay.xml b/assay/resources/schemas/assay.xml index 02e6f84c6ad..2b1d8b755eb 100644 --- a/assay/resources/schemas/assay.xml +++ b/assay/resources/schemas/assay.xml @@ -87,14 +87,6 @@ Boolean indicating whether each plate is a template versus an uploaded instance of a plate template. false - - The number of rows in each plate. - false - - - The number of columns in each plate. - false - false A unique text identifier (a GUID) for the data file associated with each plate. diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql index b041c8383d5..0157ae8f025 100644 --- a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql +++ b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql @@ -15,6 +15,24 @@ INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)'); INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)'); INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (32, 48, '1536 well (32x48)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)'); ALTER TABLE assay.Plate ADD COLUMN PlateTypeId INTEGER; ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateTypeId FOREIGN KEY (PlateTypeId) REFERENCES assay.PlateType (RowId); + +UPDATE assay.Plate +SET PlateTypeId = + CASE + WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4) + WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6) + WHEN (Rows = 6 AND Columns = 8) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 6 AND Columns = 8) + WHEN (Rows = 8 AND Columns = 12) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 8 AND Columns = 12) + WHEN (Rows = 16 AND Columns = 24) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 16 AND Columns = 24) + WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48) + ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0) + END +WHERE PlateTypeId IS NULL; + +ALTER TABLE assay.Plate ALTER COLUMN PlateTypeId SET NOT NULL; +ALTER TABLE assay.Plate DROP COLUMN Rows; +ALTER TABLE assay.Plate DROP COLUMN Columns; \ No newline at end of file diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql index e69de29bb2d..7556036dd79 100644 --- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql +++ b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql @@ -0,0 +1,39 @@ +CREATE TABLE assay.PlateType +( + RowId INT IDENTITY(1,1), + Rows INT NOT NULL, + Columns INT NOT NULL, + Description NVARCHAR(200) NOT NULL, + + CONSTRAINT PK_PlateType PRIMARY KEY (RowId), + CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns) +); + +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (3, 4, '12 well (3x4)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well (4x6)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (32, 48, '1536 well (32x48)'); +INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)'); + +ALTER TABLE assay.Plate ADD PlateTypeId INT; +GO +ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateTypeId FOREIGN KEY (PlateTypeId) REFERENCES assay.PlateType (RowId); + +UPDATE assay.Plate +SET PlateTypeId = + CASE + WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4) + WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6) + WHEN (Rows = 6 AND Columns = 8) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 6 AND Columns = 8) + WHEN (Rows = 8 AND Columns = 12) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 8 AND Columns = 12) + WHEN (Rows = 16 AND Columns = 24) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 16 AND Columns = 24) + WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48) + ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0) + END +WHERE PlateTypeId IS NULL; + +ALTER TABLE assay.Plate ALTER COLUMN PlateTypeId INT NOT NULL; +ALTER TABLE assay.Plate DROP COLUMN Rows; +ALTER TABLE assay.Plate DROP COLUMN Columns; \ No newline at end of file diff --git a/assay/src/org/labkey/assay/AssayModule.java b/assay/src/org/labkey/assay/AssayModule.java index 9964ef19f6e..08d8565b86e 100644 --- a/assay/src/org/labkey/assay/AssayModule.java +++ b/assay/src/org/labkey/assay/AssayModule.java @@ -107,7 +107,7 @@ public String getName() @Override public Double getSchemaVersion() { - return 24.001; + return 24.002; } @Override diff --git a/assay/src/org/labkey/assay/plate/query/PlateTable.java b/assay/src/org/labkey/assay/plate/query/PlateTable.java index 68221f4e266..aa45166df04 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateTable.java @@ -81,8 +81,6 @@ public class PlateTable extends SimpleUserSchema.SimpleTable static { defaultVisibleColumns.add(FieldKey.fromParts("Name")); - defaultVisibleColumns.add(FieldKey.fromParts("Rows")); - defaultVisibleColumns.add(FieldKey.fromParts("Columns")); defaultVisibleColumns.add(FieldKey.fromParts("Type")); defaultVisibleColumns.add(FieldKey.fromParts("PlateTypeId")); defaultVisibleColumns.add(FieldKey.fromParts("Created")); @@ -235,12 +233,9 @@ protected Map updateRow(User user, Container container, Map 0) throw new QueryUpdateServiceException(String.format("%s is used by %d runs and cannot be updated", plate.isTemplate() ? "Plate template" : "Plate", runsInUse)); - // disallow plate size changes - if ((row.containsKey("rows") && ObjectUtils.notEqual(oldRow.get("rows"), row.get("rows"))) || - (row.containsKey("columns") && ObjectUtils.notEqual(oldRow.get("columns"), row.get("columns")))) - { - throw new QueryUpdateServiceException("Changing the plate size (rows or columns) is not allowed."); - } + // disallow plate type changes + if (row.containsKey("plateTypeId") && ObjectUtils.notEqual(oldRow.get("plateTypeId"), row.get("plateTypeId"))) + throw new QueryUpdateServiceException("Changing the plate type is not allowed."); // if the name is changing, check for duplicates String oldName = (String) oldRow.get("Name"); From d5227fa0b3ce460c6b897ecba1cd0e339384c3a8 Mon Sep 17 00:00:00 2001 From: Lum Date: Tue, 16 Jan 2024 13:21:56 -0800 Subject: [PATCH 04/21] revert CSP change --- api/webapp/WEB-INF/web.xml | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/api/webapp/WEB-INF/web.xml b/api/webapp/WEB-INF/web.xml index 5f38c2469ff..2b90954f52e 100755 --- a/api/webapp/WEB-INF/web.xml +++ b/api/webapp/WEB-INF/web.xml @@ -66,33 +66,6 @@ *.post - - Content Security Policy Filter Filter - org.labkey.filters.ContentSecurityPolicyFilter - - policy - - default-src 'self' https: http: ; - connect-src 'self' ${LABKEY.ALLOWED.CONNECTIONS} ; - object-src 'none' ; - style-src 'self' https: 'unsafe-inline' ; - img-src 'self' https: data: http://chart.apis.google.com ; - script-src 'unsafe-eval' 'strict-dynamic' - 'nonce-${REQUEST.SCRIPT.NONCE}' ; - base-uri 'self' ; - frame-ancestors 'self' ; - report-uri - http://localhost:8080/labkey/admin-contentsecuritypolicyreport.api ; - report-to - http://localhost:8080/labkey/admin-contentsecuritypolicyreport.api ; - - - - - Content Security Policy Filter Filter - /* - - / From d97c5d0e196e74686c39f825caaece2e717511b7 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Tue, 16 Jan 2024 14:24:24 -0800 Subject: [PATCH 05/21] CreatePlateAction: pass optional plateSetId --- assay/src/org/labkey/assay/PlateController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assay/src/org/labkey/assay/PlateController.java b/assay/src/org/labkey/assay/PlateController.java index b24e76e74ed..07f18262d35 100644 --- a/assay/src/org/labkey/assay/PlateController.java +++ b/assay/src/org/labkey/assay/PlateController.java @@ -623,7 +623,7 @@ public Object execute(CreatePlateForm form, BindException errors) throws Excepti { try { - Plate plate = PlateManager.get().createAndSavePlate(getContainer(), getUser(), _plateType, form.getName(), null, null, form.getData()); + Plate plate = PlateManager.get().createAndSavePlate(getContainer(), getUser(), _plateType, form.getName(), form.getPlateSetId(), null, form.getData()); return success(plate); } catch (Exception e) From 4bc58798143084640e7d2a93c8ada81a6b27cd1c Mon Sep 17 00:00:00 2001 From: Lum Date: Wed, 17 Jan 2024 16:41:01 -0800 Subject: [PATCH 06/21] support for plate and plateSet IDs, schema changes --- .../org/labkey/api/assay/plate/Plate.java | 2 +- .../org/labkey/api/assay/plate/PlateSet.java | 2 + assay/resources/schemas/assay.xml | 13 ++- .../postgresql/assay-24.001-24.002.sql | 36 ++++++-- .../sqlserver/assay-24.001-24.002.sql | 24 +++-- .../org/labkey/assay/AssayUpgradeCode.java | 66 ++++++++++++++ .../assay/plate/PlateDocumentProvider.java | 2 +- .../src/org/labkey/assay/plate/PlateImpl.java | 22 ++--- .../org/labkey/assay/plate/PlateManager.java | 5 +- .../org/labkey/assay/plate/PlateSetImpl.java | 12 +++ .../plate/query/NamePlusIdDataIterator.java | 88 +++++++++++++++++++ .../assay/plate/query/PlateSetTable.java | 13 ++- .../labkey/assay/plate/query/PlateTable.java | 22 +++-- 13 files changed, 266 insertions(+), 41 deletions(-) create mode 100644 assay/src/org/labkey/assay/plate/query/NamePlusIdDataIterator.java 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 b28384a3380..c4b6a48283d 100644 --- a/assay/api-src/org/labkey/api/assay/plate/Plate.java +++ b/assay/api-src/org/labkey/api/assay/plate/Plate.java @@ -40,7 +40,7 @@ public interface Plate extends PropertySet, Identifiable boolean isTemplate(); - @NotNull PlateType getPlateType(); + @NotNull PlateType getPlateTypeObject(); @Nullable PlateSet getPlateSetObject(); diff --git a/assay/api-src/org/labkey/api/assay/plate/PlateSet.java b/assay/api-src/org/labkey/api/assay/plate/PlateSet.java index 348b0779248..d59e3e2a31c 100644 --- a/assay/api-src/org/labkey/api/assay/plate/PlateSet.java +++ b/assay/api-src/org/labkey/api/assay/plate/PlateSet.java @@ -15,6 +15,8 @@ public interface PlateSet String getName(); + String getPlateSetId(); + boolean isArchived(); List getPlates(User user); diff --git a/assay/resources/schemas/assay.xml b/assay/resources/schemas/assay.xml index 2b1d8b755eb..74a3c6b538c 100644 --- a/assay/resources/schemas/assay.xml +++ b/assay/resources/schemas/assay.xml @@ -29,6 +29,9 @@ The unique admin-provided name of each plate template (""NAb: 5 specimens in duplicate", for example). + + false + The Plate Set that this plate is assigned to. @@ -37,7 +40,7 @@ assay - + The plate type of this plate. RowId @@ -91,8 +94,8 @@ false A unique text identifier (a GUID) for the data file associated with each plate. - - A text label of the plate type ("NAb", for example). + + A text label of the plate assay type ("NAb", for example). @@ -178,6 +181,9 @@ + + false + @@ -195,6 +201,7 @@ + diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql index 0157ae8f025..5ae0ebd1668 100644 --- a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql +++ b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql @@ -4,6 +4,7 @@ CREATE TABLE assay.PlateType Rows INT NOT NULL, Columns INT NOT NULL, Description VARCHAR(200) NOT NULL, + Archived BOOLEAN NOT NULL DEFAULT FALSE, CONSTRAINT PK_PlateType PRIMARY KEY (RowId), CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns) @@ -14,14 +15,23 @@ INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)'); INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)'); INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)'); -INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (32, 48, '1536 well (32x48)'); -INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)'); +INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (32, 48, '1536 well (32x48)', TRUE); +INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)', TRUE); -ALTER TABLE assay.Plate ADD COLUMN PlateTypeId INTEGER; -ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateTypeId FOREIGN KEY (PlateTypeId) REFERENCES assay.PlateType (RowId); +-- Rename type column to assayType +ALTER TABLE assay.Plate RENAME COLUMN Type TO AssayType; +-- Add plateType as a FK to assay.PlateType +ALTER TABLE assay.Plate ADD COLUMN PlateType INTEGER; +ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId); + +-- Add ID columns to Plate and PlateSet tables +ALTER TABLE assay.Plate ADD COLUMN PlateId VARCHAR(200); +ALTER TABLE assay.PlateSet ADD COLUMN PlateSetId VARCHAR(200); + +UPDATE assay.PlateSet SET PlateSetId = Name; UPDATE assay.Plate -SET PlateTypeId = +SET PlateType = CASE WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4) WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6) @@ -31,8 +41,18 @@ SET PlateTypeId = WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48) ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0) END -WHERE PlateTypeId IS NULL; +WHERE PlateType IS NULL; -ALTER TABLE assay.Plate ALTER COLUMN PlateTypeId SET NOT NULL; +ALTER TABLE assay.Plate ALTER COLUMN PlateType SET NOT NULL; ALTER TABLE assay.Plate DROP COLUMN Rows; -ALTER TABLE assay.Plate DROP COLUMN Columns; \ No newline at end of file +ALTER TABLE assay.Plate DROP COLUMN Columns; + +-- upgrade script to initialize plate and plateSet IDs +SELECT core.executeJavaUpgradeCode('initializePlateAndPlateSetIDs'); + +-- finalize plate and plateSet ID columns +ALTER TABLE assay.Plate ALTER COLUMN PlateId SET NOT NULL; +ALTER TABLE assay.Plate ADD CONSTRAINT UQ_Plate_PlateId UNIQUE (PlateId); + +ALTER TABLE assay.PlateSet ALTER COLUMN PlateSetId SET NOT NULL; +ALTER TABLE assay.PlateSet ADD CONSTRAINT UQ_PlateSet_PlateSetId UNIQUE (PlateSetId); diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql index 7556036dd79..de5551f0a52 100644 --- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql +++ b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql @@ -4,6 +4,7 @@ CREATE TABLE assay.PlateType Rows INT NOT NULL, Columns INT NOT NULL, Description NVARCHAR(200) NOT NULL, + Archived BIT NOT NULL DEFAULT 0, CONSTRAINT PK_PlateType PRIMARY KEY (RowId), CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns) @@ -14,12 +15,23 @@ INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)'); INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)'); INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)'); -INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (32, 48, '1536 well (32x48)'); -INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)'); +INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (32, 48, '1536 well (32x48)', 1); +INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)', 1); -ALTER TABLE assay.Plate ADD PlateTypeId INT; +-- Rename type column to assayType +EXEC sp_rename 'assay.Plate.Type', 'AssayType', 'COLUMN'; +-- Add type as a FK to assay.PlateType +ALTER TABLE assay.Plate ADD PlateType INT; GO -ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateTypeId FOREIGN KEY (PlateTypeId) REFERENCES assay.PlateType (RowId); +ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId); + +-- Add ID columns to Plate and PlateSet tables +ALTER TABLE assay.Plate ADD PlateId NVARCHAR(200); +GO +ALTER TABLE assay.PlateSet ADD PlateSetId NVARCHAR(200); +GO + +UPDATE assay.PlateSet SET PlateSetId = Name; UPDATE assay.Plate SET PlateTypeId = @@ -36,4 +48,6 @@ WHERE PlateTypeId IS NULL; ALTER TABLE assay.Plate ALTER COLUMN PlateTypeId INT NOT NULL; ALTER TABLE assay.Plate DROP COLUMN Rows; -ALTER TABLE assay.Plate DROP COLUMN Columns; \ No newline at end of file +ALTER TABLE assay.Plate DROP COLUMN Columns; + +-- upgrade script to set the plate ID value in assay.Plate diff --git a/assay/src/org/labkey/assay/AssayUpgradeCode.java b/assay/src/org/labkey/assay/AssayUpgradeCode.java index ab4b1eb6921..18773a21391 100644 --- a/assay/src/org/labkey/assay/AssayUpgradeCode.java +++ b/assay/src/org/labkey/assay/AssayUpgradeCode.java @@ -40,6 +40,7 @@ import org.labkey.api.security.UserManager; import org.labkey.api.security.roles.SiteAdminRole; import org.labkey.api.util.Pair; +import org.labkey.assay.plate.PlateImpl; import org.labkey.assay.plate.PlateManager; import org.labkey.assay.plate.PlateSetImpl; import org.labkey.assay.query.AssayDbSchema; @@ -254,4 +255,69 @@ public static void updatePlateSetNames(ModuleContext ctx) throws Exception tx.commit(); } } + + /** + * Called from assay-24.000-24.001.sql + *

+ * The referenced upgrade script creates a new plate set for every plate in the system. We now + * want to iterate over each plate set to set the name using the configured name expression. + */ + public static void initializePlateAndPlateSetIDs(ModuleContext ctx) throws Exception + { + if (ctx.isNewInstall()) + return; + + DbScope scope = AssayDbSchema.getInstance().getSchema().getScope(); + try (DbScope.Transaction tx = scope.ensureTransaction()) + { + _log.info("Start initializing Plate IDs"); + List plates = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlate()).getArrayList(PlateImpl.class); + + NameGenerator nameGenerator = new NameGenerator(PlateManager.get().getPlateNameExpression(), AssayDbSchema.getInstance().getTableInfoPlate(), false, ContainerManager.getSharedContainer(), null, null); + NameGenerator.State state = nameGenerator.createState(false); + for (PlateImpl plate : plates) + { + Map plateRow = ObjectFactory.Registry.getFactory(PlateImpl.class).toMap(plate, new ArrayListMap<>()); + plateRow.put("name", null); + String name = nameGenerator.generateName(state, plateRow); + state.cleanUp(); + + SQLFragment sql = new SQLFragment("UPDATE ").append(AssayDbSchema.getInstance().getTableInfoPlate(), "") + .append(" SET PlateId = ?") + .add(name) + .append(" WHERE RowId = ?") + .add(plate.getRowId()); + new SqlExecutor(AssayDbSchema.getInstance().getSchema()).execute(sql); + } + _log.info("Successfully updated " + plates.size() + " plate IDs"); + + _log.info("Start initializing PlateSet IDs"); + // for plate sets, they should have a valid PlateSetId, but if the name was not generated (or mutated), regenerate a new + // plate set id + List plateSets = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateSet()).getArrayList(PlateSetImpl.class); + + nameGenerator = new NameGenerator(PlateManager.get().getPlateSetNameExpression(), AssayDbSchema.getInstance().getTableInfoPlateSet(), false, null, null, null); + state = nameGenerator.createState(false); + for (PlateSetImpl plateSet : plateSets) + { + Map plateSetRow = ObjectFactory.Registry.getFactory(PlateSetImpl.class).toMap(plateSet, new ArrayListMap<>()); + if (!String.valueOf(plateSetRow.get("name")).startsWith("PLS-")) + { + plateSetRow.put("name", null); + String name = nameGenerator.generateName(state, plateSetRow); + state.cleanUp(); + + SQLFragment sql = new SQLFragment("UPDATE ").append(AssayDbSchema.getInstance().getTableInfoPlateSet(), "") + .append(" SET PlateSetId = ?") + .add(name) + .append(" WHERE RowId = ?") + .add(plateSet.getRowId()); + new SqlExecutor(AssayDbSchema.getInstance().getSchema()).execute(sql); + } + } + _log.info("Successfully updated " + plateSets.size() + " plate set IDs"); + + tx.commit(); + } + } } diff --git a/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java b/assay/src/org/labkey/assay/plate/PlateDocumentProvider.java index 78717bd01bb..165d68896a6 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.getPlateType(); + PlateType plateType = plate.getPlateTypeObject(); 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 de2386e21f8..f5b3231e119 100644 --- a/assay/src/org/labkey/assay/plate/PlateImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateImpl.java @@ -59,7 +59,7 @@ public class PlateImpl extends PropertySetImpl implements Plate, Cloneable private String _type; private boolean _isTemplate; private Integer _plateSetId; - private Integer _plateTypeId; + private Integer _plateType; private Map> _groups; private List _deletedGroups; @@ -89,12 +89,12 @@ public PlateImpl(Container container, String name, String type, @NotNull PlateTy _type = type; _container = container; _dataFileId = GUID.makeGUID(); - _plateTypeId = plateType.getRowId(); + _plateType = plateType.getRowId(); } public PlateImpl(PlateImpl plate, double[][] wellValues, boolean[][] excluded, int runId, int plateNumber) { - this(plate.getContainer(), plate.getName(), plate.getType(), plate.getPlateType()); + this(plate.getContainer(), plate.getName(), plate.getType(), plate.getPlateTypeObject()); if (wellValues == null) wellValues = new double[plate.getRows()][plate.getColumns()]; @@ -285,7 +285,7 @@ public Map> getWellGroupMap() @JsonIgnore public int getColumns() { - return getPlateType().getColumns(); + return getPlateTypeObject().getColumns(); } @Override @@ -298,7 +298,7 @@ public String getName() @JsonIgnore public int getRows() { - return getPlateType().getRows(); + return getPlateTypeObject().getRows(); } @JsonIgnore @@ -534,21 +534,21 @@ public Integer getPlateSet() return _plateSetId; } - public Integer getPlateTypeId() + public void setPlateType(Integer plateType) { - return _plateTypeId; + _plateType = plateType; } - public void setPlateTypeId(Integer plateTypeId) + public Integer getPlateType() { - _plateTypeId = plateTypeId; + return _plateType; } @Override @JsonIgnore - public @NotNull PlateType getPlateType() + public @NotNull PlateType getPlateTypeObject() { - return PlateManager.get().getPlateType(_plateTypeId); + return PlateManager.get().getPlateType(_plateType); } @Override diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 2a0e57cd519..4eeaa40acce 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -86,7 +86,6 @@ import org.labkey.api.query.ValidationException; import org.labkey.api.search.SearchService; import org.labkey.api.security.User; -import org.labkey.api.security.permissions.DeletePermission; import org.labkey.api.security.permissions.InsertPermission; import org.labkey.api.security.permissions.Permission; import org.labkey.api.security.permissions.ReadPermission; @@ -1220,7 +1219,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.getType(), source.getPlateType()); + Plate newPlate = createPlateTemplate(destContainer, source.getType(), source.getPlateTypeObject()); newPlate.setName(source.getName()); for (String property : source.getPropertyNames()) newPlate.setProperty(property, source.getProperty(property)); @@ -1885,7 +1884,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, savedTemplate.getPlateType()); + assertEquals(plateType, savedTemplate.getPlateTypeObject()); List wellGroups = savedTemplate.getWellGroups(); assertEquals(3, wellGroups.size()); diff --git a/assay/src/org/labkey/assay/plate/PlateSetImpl.java b/assay/src/org/labkey/assay/plate/PlateSetImpl.java index a5611f74def..ae07413d690 100644 --- a/assay/src/org/labkey/assay/plate/PlateSetImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateSetImpl.java @@ -26,6 +26,7 @@ public class PlateSetImpl extends Entity implements PlateSet { private Integer _rowId; private String _name; + private String _plateSetId; private boolean _archived; private Container _container; @@ -68,6 +69,17 @@ public void setName(String name) _name = name; } + @Override + public String getPlateSetId() + { + return _plateSetId; + } + + public void setPlateSetId(String plateSetId) + { + _plateSetId = plateSetId; + } + @Override public boolean isArchived() { diff --git a/assay/src/org/labkey/assay/plate/query/NamePlusIdDataIterator.java b/assay/src/org/labkey/assay/plate/query/NamePlusIdDataIterator.java new file mode 100644 index 00000000000..200a7ba37b8 --- /dev/null +++ b/assay/src/org/labkey/assay/plate/query/NamePlusIdDataIterator.java @@ -0,0 +1,88 @@ +package org.labkey.assay.plate.query; + +import org.apache.commons.lang3.StringUtils; +import org.labkey.api.collections.CaseInsensitiveHashMap; +import org.labkey.api.data.Container; +import org.labkey.api.data.NameGenerator; +import org.labkey.api.data.TableInfo; +import org.labkey.api.dataiterator.DataIterator; +import org.labkey.api.dataiterator.DataIteratorContext; +import org.labkey.api.dataiterator.DataIteratorUtil; +import org.labkey.api.dataiterator.MapDataIterator; +import org.labkey.api.dataiterator.WrapperDataIterator; +import org.labkey.api.query.BatchValidationException; +import org.labkey.api.query.ValidationException; + +import java.util.Map; + +public class NamePlusIdDataIterator extends WrapperDataIterator +{ + private final DataIteratorContext _context; + private final Integer _nameCol; + private final Integer _idCol; + private final NameGenerator _nameGenerator; + private final NameGenerator.State _state; + private String _generatedName; + + public NamePlusIdDataIterator(DataIterator di, DataIteratorContext context, TableInfo parentTable, Container container, + String nameColumn, String idColumn, String nameExpression) + { + super(DataIteratorUtil.wrapMap(di, false)); + + _context = context; + Map map = DataIteratorUtil.createColumnNameMap(di); + _nameCol = map.get(nameColumn); + _idCol = map.get(idColumn); + + _nameGenerator = new NameGenerator(nameExpression, parentTable, false, container, null, null); + _state = _nameGenerator.createState(false); + } + + MapDataIterator getInput() + { + return (MapDataIterator) _delegate; + } + + @Override + public boolean next() throws BatchValidationException + { + boolean next = super.next(); + if (next) + { + try + { + Map currentRow = new CaseInsensitiveHashMap<>(getInput().getMap()); + // remove the name field so we don't use it + currentRow.put("name", null); + _generatedName = _nameGenerator.generateName(_state, currentRow); + _state.cleanUp(); + } + catch (NameGenerator.NameGenerationException e) + { + _context.getErrors().addRowError(new ValidationException(e.getMessage())); + } + } + return next; + } + + @Override + public Object get(int i) + { + if (i == _nameCol) + { + Object curName = super.get(_nameCol); + if (curName instanceof String) + curName = StringUtils.isEmpty((String) curName) ? null : curName; + + if (curName != null) + return curName; + else + return _generatedName; + } + else if (i == _idCol) + { + return _generatedName; + } + return super.get(i); + } +} diff --git a/assay/src/org/labkey/assay/plate/query/PlateSetTable.java b/assay/src/org/labkey/assay/plate/query/PlateSetTable.java index c59d2a0bf9a..ebd318452b8 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateSetTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateSetTable.java @@ -142,11 +142,18 @@ public DataIteratorBuilder createImportDIB(User user, Container container, DataI ColumnInfo nameCol = plateSetTable.getColumn("name"); nameExpressionTranslator.addColumn(nameCol, (Supplier) () -> null); } - nameExpressionTranslator.addColumn(new BaseColumnInfo("nameExpression", JdbcType.VARCHAR), - (Supplier) () -> PlateService.get().getPlateSetNameExpression()); + if (!nameMap.containsKey("plateSetId")) + { + ColumnInfo nameCol = plateSetTable.getColumn("plateSetId"); + nameExpressionTranslator.addColumn(nameCol, (Supplier) () -> null); + } DataIterator builtInColumnsTranslator = SimpleTranslator.wrapBuiltInColumns(nameExpressionTranslator, context, container, user, plateSetTable); - DataIterator di = LoggingDataIterator.wrap(new NameExpressionDataIterator(builtInColumnsTranslator, context, plateSetTable, container, null, null, null)); + DataIterator di = LoggingDataIterator.wrap(new NamePlusIdDataIterator(builtInColumnsTranslator, context, plateSetTable, + container, + "name", + "plateSetId", + PlateManager.get().getPlateSetNameExpression())); DataIteratorBuilder insertBuilder = LoggingDataIterator.wrap(StandardDataIteratorBuilder.forInsert(getDbTable(), di, container, user, context)); DataIteratorBuilder dib = new TableInsertDataIteratorBuilder(insertBuilder, plateSetTable, container) .setKeyColumns(new CaseInsensitiveHashSet("RowId")); diff --git a/assay/src/org/labkey/assay/plate/query/PlateTable.java b/assay/src/org/labkey/assay/plate/query/PlateTable.java index aa45166df04..9541a07487d 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateTable.java @@ -81,8 +81,9 @@ public class PlateTable extends SimpleUserSchema.SimpleTable static { defaultVisibleColumns.add(FieldKey.fromParts("Name")); - defaultVisibleColumns.add(FieldKey.fromParts("Type")); - defaultVisibleColumns.add(FieldKey.fromParts("PlateTypeId")); + defaultVisibleColumns.add(FieldKey.fromParts("PlateType")); + defaultVisibleColumns.add(FieldKey.fromParts("PlateSet")); + defaultVisibleColumns.add(FieldKey.fromParts("AssayType")); defaultVisibleColumns.add(FieldKey.fromParts("Created")); defaultVisibleColumns.add(FieldKey.fromParts("CreatedBy")); defaultVisibleColumns.add(FieldKey.fromParts("Modified")); @@ -197,10 +198,19 @@ public DataIteratorBuilder createImportDIB(User user, Container container, DataI nameExpressionTranslator.addColumn(nameCol, (Supplier) () -> null); } - nameExpressionTranslator.addColumn(new BaseColumnInfo("nameExpression", JdbcType.VARCHAR), - (Supplier) () -> PlateService.get().getPlateNameExpression()); + if (!nameMap.containsKey("plateId")) + { + ColumnInfo nameCol = plateTable.getColumn("plateId"); + nameExpressionTranslator.addColumn(nameCol, (Supplier) () -> null); + } + DataIterator builtInColumnsTranslator = SimpleTranslator.wrapBuiltInColumns(nameExpressionTranslator, context, container, user, plateTable); - DataIterator di = LoggingDataIterator.wrap(new NameExpressionDataIterator(builtInColumnsTranslator, context, plateTable, container, null, null, null)); + + DataIterator di = LoggingDataIterator.wrap(new NamePlusIdDataIterator(builtInColumnsTranslator, context, plateTable, + container, + "name", + "plateId", + PlateManager.get().getPlateNameExpression())); ValidatorIterator vi = new ValidatorIterator(di, context, container, user); vi.addValidator(nameMap.get("name"), new UniquePlateNameValidator(container)); @@ -234,7 +244,7 @@ protected Map updateRow(User user, Container container, Map Date: Thu, 18 Jan 2024 11:43:51 -0800 Subject: [PATCH 07/21] upgrade script changes, add description field to plate and plateSet tables --- .../org/labkey/api/assay/plate/Plate.java | 2 +- assay/resources/schemas/assay.xml | 2 ++ .../postgresql/assay-24.001-24.002.sql | 7 +++-- .../sqlserver/assay-24.001-24.002.sql | 22 ++++++++++----- .../assay/plate/PlateDataServiceImpl.java | 14 +++++----- .../src/org/labkey/assay/plate/PlateImpl.java | 27 +++++++++++++------ .../org/labkey/assay/plate/PlateManager.java | 2 +- .../org/labkey/assay/plate/PlateSetImpl.java | 11 ++++++++ .../assay/plate/query/PlateSetTable.java | 1 + .../labkey/assay/plate/query/PlateTable.java | 1 + .../assay/plate/view/plateTemplateList.jsp | 2 +- 11 files changed, 65 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 c4b6a48283d..dd44b2bab97 100644 --- a/assay/api-src/org/labkey/api/assay/plate/Plate.java +++ b/assay/api-src/org/labkey/api/assay/plate/Plate.java @@ -78,7 +78,7 @@ public interface Plate extends PropertySet, Identifiable int getWellGroupCount(WellGroup.Type type); - String getType(); + String getAssayType(); @Override @Nullable ActionURL detailsURL(); diff --git a/assay/resources/schemas/assay.xml b/assay/resources/schemas/assay.xml index 74a3c6b538c..4f3c9899a42 100644 --- a/assay/resources/schemas/assay.xml +++ b/assay/resources/schemas/assay.xml @@ -29,6 +29,7 @@ The unique admin-provided name of each plate template (""NAb: 5 specimens in duplicate", for example). + false @@ -181,6 +182,7 @@ + false diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql index 5ae0ebd1668..371e9cbbca9 100644 --- a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql +++ b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql @@ -3,7 +3,7 @@ CREATE TABLE assay.PlateType RowId SERIAL, Rows INT NOT NULL, Columns INT NOT NULL, - Description VARCHAR(200) NOT NULL, + Description VARCHAR(300) NOT NULL, Archived BOOLEAN NOT NULL DEFAULT FALSE, CONSTRAINT PK_PlateType PRIMARY KEY (RowId), @@ -24,10 +24,13 @@ ALTER TABLE assay.Plate RENAME COLUMN Type TO AssayType; ALTER TABLE assay.Plate ADD COLUMN PlateType INTEGER; ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId); --- Add ID columns to Plate and PlateSet tables +-- Add ID and description columns to Plate and PlateSet tables ALTER TABLE assay.Plate ADD COLUMN PlateId VARCHAR(200); +ALTER TABLE assay.Plate ADD COLUMN Description VARCHAR(300); ALTER TABLE assay.PlateSet ADD COLUMN PlateSetId VARCHAR(200); +ALTER TABLE assay.PlateSet ADD COLUMN Description VARCHAR(300); +-- Most existing plate sets will have a generated name, but mutated ones will get fixed up by the java upgrade script UPDATE assay.PlateSet SET PlateSetId = Name; UPDATE assay.Plate diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql index de5551f0a52..7bc1ade63be 100644 --- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql +++ b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql @@ -3,7 +3,7 @@ CREATE TABLE assay.PlateType RowId INT IDENTITY(1,1), Rows INT NOT NULL, Columns INT NOT NULL, - Description NVARCHAR(200) NOT NULL, + Description NVARCHAR(300) NOT NULL, Archived BIT NOT NULL DEFAULT 0, CONSTRAINT PK_PlateType PRIMARY KEY (RowId), @@ -25,16 +25,18 @@ ALTER TABLE assay.Plate ADD PlateType INT; GO ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId); --- Add ID columns to Plate and PlateSet tables +-- Add ID and description columns to Plate and PlateSet tables ALTER TABLE assay.Plate ADD PlateId NVARCHAR(200); -GO +ALTER TABLE assay.Plate ADD Description NVARCHAR(300); ALTER TABLE assay.PlateSet ADD PlateSetId NVARCHAR(200); +ALTER TABLE assay.PlateSet ADD Description NVARCHAR(300); GO +-- Most existing plate sets will have a generated name, but mutated ones will get fixed up by the java upgrade script UPDATE assay.PlateSet SET PlateSetId = Name; UPDATE assay.Plate -SET PlateTypeId = +SET PlateType = CASE WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4) WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6) @@ -44,10 +46,18 @@ SET PlateTypeId = WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48) ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0) END -WHERE PlateTypeId IS NULL; +WHERE PlateType IS NULL; -ALTER TABLE assay.Plate ALTER COLUMN PlateTypeId INT NOT NULL; +ALTER TABLE assay.Plate ALTER COLUMN PlateType INT NOT NULL; ALTER TABLE assay.Plate DROP COLUMN Rows; ALTER TABLE assay.Plate DROP COLUMN Columns; -- upgrade script to set the plate ID value in assay.Plate +EXEC core.executeJavaUpgradeCode 'initializePlateAndPlateSetIDs'; + +-- finalize plate and plateSet ID columns +ALTER TABLE assay.Plate ALTER COLUMN PlateId NVARCHAR(200) NOT NULL; +ALTER TABLE assay.Plate ADD CONSTRAINT UQ_Plate_PlateId UNIQUE (PlateId); + +ALTER TABLE assay.PlateSet ALTER COLUMN PlateSetId NVARCHAR(200) NOT NULL; +ALTER TABLE assay.PlateSet ADD CONSTRAINT UQ_PlateSet_PlateSetId UNIQUE (PlateSetId); diff --git a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java index 5532bf97867..93013be7761 100644 --- a/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateDataServiceImpl.java @@ -70,9 +70,9 @@ public GWTPlate getTemplateDefinition(String templateName, int plateId, String a if (template == null) throw new Exception("Plate " + templateName + " does not exist."); - handler = PlateManager.get().getPlateLayoutHandler(template.getType()); + handler = PlateManager.get().getPlateLayoutHandler(template.getAssayType()); if (handler == null) - throw new Exception("Plate template type " + template.getType() + " does not exist."); + throw new Exception("Plate template type " + template.getAssayType() + " does not exist."); } else { @@ -111,7 +111,7 @@ public GWTPlate getTemplateDefinition(String templateName, int plateId, String a int newPlateId = copyTemplate || template.getRowId() == null ? -1 : template.getRowId(); GWTPlate plate = new GWTPlate(newPlateId, - template.getName(), template.getType(), template.getRows(), + template.getName(), template.getAssayType(), template.getRows(), template.getColumns(), getTypeList(template), handler.showEditorWarningPanel()); plate.setGroups(translated); plate.setTypesToDefaultGroups(handler.getDefaultGroupsForTypes()); @@ -137,7 +137,7 @@ private List getTypeList(Plate template) WellGroup.Type.CONTROL, WellGroup.Type.SPECIMEN, WellGroup.Type.REPLICATE, WellGroup.Type.OTHER); - PlateLayoutHandler handler = PlateManager.get().getPlateLayoutHandler(template.getType()); + PlateLayoutHandler handler = PlateManager.get().getPlateLayoutHandler(template.getAssayType()); if (handler != null) wellTypes = handler.getWellGroupTypes(); @@ -164,8 +164,8 @@ public int saveChanges(GWTPlate gwtPlate, boolean replaceIfExisting) throws Exce if (PlateManager.get().plateExists(getContainer(), gwtPlate.getName()) && !replaceIfExisting) throw new Exception("A plate template with name '" + gwtPlate.getName() + "' already exists."); - if (!template.getType().equals(gwtPlate.getType())) - throw new Exception("Plate template type '" + template.getType() + "' cannot be changed for '" + gwtPlate.getName() + "'"); + if (!template.getAssayType().equals(gwtPlate.getType())) + throw new Exception("Plate template type '" + template.getAssayType() + "' cannot be changed for '" + gwtPlate.getName() + "'"); if (template.getRows() != gwtPlate.getRows() || template.getColumns() != gwtPlate.getCols()) throw new Exception("Plate template dimensions cannot be changed for '" + gwtPlate.getName() + "'"); @@ -236,7 +236,7 @@ public int saveChanges(GWTPlate gwtPlate, boolean replaceIfExisting) throws Exce group.setProperties(gwtGroup.getProperties()); } - PlateManager.get().getPlateLayoutHandler(template.getType()).validateTemplate(getContainer(), getUser(), template); + PlateManager.get().getPlateLayoutHandler(template.getAssayType()).validateTemplate(getContainer(), getUser(), template); return PlateService.get().save(getContainer(), getUser(), template); } catch (BatchValidationException | ValidationException e) diff --git a/assay/src/org/labkey/assay/plate/PlateImpl.java b/assay/src/org/labkey/assay/plate/PlateImpl.java index f5b3231e119..f6c6d1ee25d 100644 --- a/assay/src/org/labkey/assay/plate/PlateImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateImpl.java @@ -56,10 +56,11 @@ public class PlateImpl extends PropertySetImpl implements Plate, Cloneable private int _modifiedBy; private long _modified; private String _dataFileId; - private String _type; + private String _assayType; private boolean _isTemplate; private Integer _plateSetId; private Integer _plateType; + private String _description; private Map> _groups; private List _deletedGroups; @@ -82,11 +83,11 @@ public PlateImpl() _plateNumber = 1; } - public PlateImpl(Container container, String name, String type, @NotNull PlateType plateType) + public PlateImpl(Container container, String name, String assayType, @NotNull PlateType plateType) { super(container); _name = name; - _type = type; + _assayType = assayType; _container = container; _dataFileId = GUID.makeGUID(); _plateType = plateType.getRowId(); @@ -94,7 +95,7 @@ public PlateImpl(Container container, String name, String type, @NotNull PlateTy public PlateImpl(PlateImpl plate, double[][] wellValues, boolean[][] excluded, int runId, int plateNumber) { - this(plate.getContainer(), plate.getName(), plate.getType(), plate.getPlateTypeObject()); + this(plate.getContainer(), plate.getName(), plate.getAssayType(), plate.getPlateTypeObject()); if (wellValues == null) wellValues = new double[plate.getRows()][plate.getColumns()]; @@ -411,14 +412,14 @@ public int getWellGroupCount(WellGroup.Type type) } @Override - public String getType() + public String getAssayType() { - return _type; + return _assayType; } - public void setType(String type) + public void setAssayType(String type) { - _type = type; + _assayType = type; } @JsonIgnore @@ -544,6 +545,16 @@ public Integer getPlateType() return _plateType; } + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + _description = description; + } + @Override @JsonIgnore public @NotNull PlateType getPlateTypeObject() diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 4eeaa40acce..bd51f4662c1 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -1219,7 +1219,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.getType(), source.getPlateTypeObject()); + Plate newPlate = createPlateTemplate(destContainer, source.getAssayType(), source.getPlateTypeObject()); newPlate.setName(source.getName()); for (String property : source.getPropertyNames()) newPlate.setProperty(property, source.getProperty(property)); diff --git a/assay/src/org/labkey/assay/plate/PlateSetImpl.java b/assay/src/org/labkey/assay/plate/PlateSetImpl.java index ae07413d690..c7fe2f52a14 100644 --- a/assay/src/org/labkey/assay/plate/PlateSetImpl.java +++ b/assay/src/org/labkey/assay/plate/PlateSetImpl.java @@ -29,6 +29,7 @@ public class PlateSetImpl extends Entity implements PlateSet private String _plateSetId; private boolean _archived; private Container _container; + private String _description; public PlateSetImpl() { @@ -118,4 +119,14 @@ public Integer getPlateCount() return new SqlSelector(table.getSchema(), sql).getObject(Integer.class); } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + _description = description; + } } diff --git a/assay/src/org/labkey/assay/plate/query/PlateSetTable.java b/assay/src/org/labkey/assay/plate/query/PlateSetTable.java index ebd318452b8..8d30a39345a 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateSetTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateSetTable.java @@ -54,6 +54,7 @@ public class PlateSetTable extends SimpleUserSchema.SimpleTable { defaultVisibleColumns.add(FieldKey.fromParts("Name")); defaultVisibleColumns.add(FieldKey.fromParts("Container")); + defaultVisibleColumns.add(FieldKey.fromParts("Description")); defaultVisibleColumns.add(FieldKey.fromParts("PlateCount")); defaultVisibleColumns.add(FieldKey.fromParts("Created")); defaultVisibleColumns.add(FieldKey.fromParts("CreatedBy")); diff --git a/assay/src/org/labkey/assay/plate/query/PlateTable.java b/assay/src/org/labkey/assay/plate/query/PlateTable.java index 9541a07487d..c11811acefd 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateTable.java @@ -81,6 +81,7 @@ public class PlateTable extends SimpleUserSchema.SimpleTable static { defaultVisibleColumns.add(FieldKey.fromParts("Name")); + defaultVisibleColumns.add(FieldKey.fromParts("Description")); defaultVisibleColumns.add(FieldKey.fromParts("PlateType")); defaultVisibleColumns.add(FieldKey.fromParts("PlateSet")); defaultVisibleColumns.add(FieldKey.fromParts("AssayType")); diff --git a/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp b/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp index 0a37618e52a..49717a81a6e 100644 --- a/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp +++ b/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp @@ -132,7 +132,7 @@ %> <%= h(template.getName()) %> - <%= h(template.getType()) %> + <%= h(template.getAssayType()) %> <%= h(runCount) %> <% From 5946bb0046af9a00b0aac688c3ab144aea5005aa Mon Sep 17 00:00:00 2001 From: lum Date: Thu, 18 Jan 2024 14:41:15 -0800 Subject: [PATCH 08/21] use plate set ID for name expression --- assay/src/org/labkey/assay/plate/PlateManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index bd51f4662c1..d5b6d8772a7 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -145,7 +145,7 @@ public class PlateManager implements PlateService // name expressions, currently not configurable private static final String PLATE_SET_NAME_EXPRESSION = "PLS-${now:date('yyyyMMdd')}-${RowId}"; - private static final String PLATE_NAME_EXPRESSION = "${${PlateSet/Name}-:withCounter}"; + private static final String PLATE_NAME_EXPRESSION = "${${PlateSet/PlateSetId}-:withCounter}"; public SearchService.SearchCategory PLATE_CATEGORY = new SearchService.SearchCategory("plate", "Plate") { @Override From 4ca6a1579eb6e80e08a1f6b7be4a1f274235ba3d Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Thu, 18 Jan 2024 16:21:43 -0800 Subject: [PATCH 09/21] Name, Description support --- .../src/org/labkey/assay/PlateController.java | 31 +++++-------------- .../org/labkey/assay/plate/PlateManager.java | 18 +++++++---- .../assay/plate/query/PlateSetTable.java | 10 +----- .../labkey/assay/plate/query/PlateTable.java | 13 +++++--- 4 files changed, 28 insertions(+), 44 deletions(-) diff --git a/assay/src/org/labkey/assay/PlateController.java b/assay/src/org/labkey/assay/PlateController.java index 00a283534bd..2e64702f2ad 100644 --- a/assay/src/org/labkey/assay/PlateController.java +++ b/assay/src/org/labkey/assay/PlateController.java @@ -871,7 +871,7 @@ public Object execute(GetPlateForm form, BindException errors) throws Exception public static class CreatePlateSetForm { private String _name; - private List _plateTypes = new ArrayList<>(); + private List _plates = new ArrayList<>(); public String getName() { @@ -883,38 +883,21 @@ public void setName(String name) _name = name; } - public List getPlateTypes() + public List getPlates() { - return _plateTypes; + return _plates; } - public void setPlateTypes(List plateTypes) + public void setPlates(List plates) { - _plateTypes = plateTypes; + _plates = plates; } } - @Marshal(Marshaller.JSONObject) + @Marshal(Marshaller.Jackson) @RequiresPermission(InsertPermission.class) public static class CreatePlateSetAction extends MutatingApiAction { - List _plateTypes = new ArrayList<>(); - - @Override - public void validateForm(CreatePlateSetForm form, Errors errors) - { - for (Integer plateTypeId : form.getPlateTypes()) - { - PlateType plateType = PlateManager.get().getPlateType(plateTypeId); - if (plateType == null) - { - errors.reject(ERROR_REQUIRED, "Plate type id \"" + plateTypeId + "\" is invalid."); - break; - } - _plateTypes.add(plateType); - } - } - @Override public Object execute(CreatePlateSetForm form, BindException errors) throws Exception { @@ -923,7 +906,7 @@ public Object execute(CreatePlateSetForm form, BindException errors) throws Exce PlateSetImpl plateSet = new PlateSetImpl(); plateSet.setName(form.getName()); - plateSet = PlateManager.get().createPlateSet(getContainer(), getUser(), plateSet, _plateTypes); + plateSet = PlateManager.get().createPlateSet(getContainer(), getUser(), plateSet, form.getPlates()); return success(plateSet); } catch (Exception e) diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index d5b6d8772a7..51cc013e255 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -1310,6 +1310,7 @@ public List getPlateLayouts() public PlateType getPlateType(Integer plateTypeId) { + if (plateTypeId == null) return null; return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType()).getObject(plateTypeId, PlateTypeImpl.class); } @@ -1737,7 +1738,9 @@ public List setFields(Container container, User user, Integer return PLATE_NAME_EXPRESSION; } - public PlateSetImpl createPlateSet(Container container, User user, @NotNull PlateSetImpl plateSet, @Nullable List plateTypes) throws Exception + public record CreatePlateSetPlate(String name, Integer plateType) {} + + public PlateSetImpl createPlateSet(Container container, User user, @NotNull PlateSetImpl plateSet, @Nullable List plates) throws Exception { if (!container.hasPermission(user, InsertPermission.class)) throw new UnauthorizedException("Failed to create plate set. Insufficient permissions."); @@ -1745,7 +1748,7 @@ public PlateSetImpl createPlateSet(Container container, User user, @NotNull Plat if (plateSet.getRowId() != null) throw new ValidationException("Failed to create plate set. Cannot create plate set with rowId (" + plateSet.getRowId() + ")."); - if (plateTypes != null && plateTypes.size() > MAX_PLATES) + if (plates != null && plates.size() > MAX_PLATES) throw new ValidationException(String.format("Failed to create plate set. Plate sets can have a maximum of %d plates.", MAX_PLATES)); try (DbScope.Transaction tx = ensureTransaction()) @@ -1760,13 +1763,16 @@ public PlateSetImpl createPlateSet(Container container, User user, @NotNull Plat Integer plateSetId = (Integer) rows.get(0).get("RowId"); - if (plateTypes != null) + if (plates != null) { - for (PlateType plateType : plateTypes) + for (var plate : plates) { + var plateType = getPlateType(plate.plateType); + if (plateType == null) + throw new ValidationException("Failed to create plate set. Plate Type (" + plate.plateType + ") is invalid."); + // TODO: Write a cheaper plate create/save for multiple plates - if (plateType != null) - createAndSavePlate(container, user, plateType, null, plateSetId, null, null); + createAndSavePlate(container, user, plateType, plate.name, plateSetId, null, null); } } diff --git a/assay/src/org/labkey/assay/plate/query/PlateSetTable.java b/assay/src/org/labkey/assay/plate/query/PlateSetTable.java index 8d30a39345a..9e4927ea587 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateSetTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateSetTable.java @@ -2,10 +2,8 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.assay.plate.Plate; -import org.labkey.api.assay.plate.PlateService; import org.labkey.api.assay.plate.PlateSet; import org.labkey.api.collections.CaseInsensitiveHashSet; -import org.labkey.api.data.BaseColumnInfo; import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; @@ -19,7 +17,6 @@ import org.labkey.api.dataiterator.DataIteratorContext; import org.labkey.api.dataiterator.DetailedAuditLogDataIterator; import org.labkey.api.dataiterator.LoggingDataIterator; -import org.labkey.api.dataiterator.NameExpressionDataIterator; import org.labkey.api.dataiterator.SimpleTranslator; import org.labkey.api.dataiterator.StandardDataIteratorBuilder; import org.labkey.api.dataiterator.TableInsertDataIteratorBuilder; @@ -80,12 +77,7 @@ public MutableColumnInfo wrapColumn(ColumnInfo col) { var columnInfo = super.wrapColumn(col); - // the name field is always generated via name expression - if (columnInfo.getName().equalsIgnoreCase("Name")) - { - columnInfo.setUserEditable(false); - } - else if (columnInfo.getName().equalsIgnoreCase("RowId")) + if (columnInfo.getName().equalsIgnoreCase("RowId")) { // this is necessary in order to use rowId as a name expression token columnInfo.setKeyField(true); diff --git a/assay/src/org/labkey/assay/plate/query/PlateTable.java b/assay/src/org/labkey/assay/plate/query/PlateTable.java index c11811acefd..6be1f4707d7 100644 --- a/assay/src/org/labkey/assay/plate/query/PlateTable.java +++ b/assay/src/org/labkey/assay/plate/query/PlateTable.java @@ -249,12 +249,15 @@ protected Map updateRow(User user, Container container, Map newRow = super.updateRow(user, container, row, oldRow); From 47b2822458758bb397b243668f0d11bb3b2db883 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Thu, 18 Jan 2024 16:55:14 -0800 Subject: [PATCH 10/21] Remove GetPlateTypesAction --- assay/src/org/labkey/assay/PlateController.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/assay/src/org/labkey/assay/PlateController.java b/assay/src/org/labkey/assay/PlateController.java index 2e64702f2ad..2f35288fd83 100644 --- a/assay/src/org/labkey/assay/PlateController.java +++ b/assay/src/org/labkey/assay/PlateController.java @@ -635,16 +635,6 @@ public Object execute(CreatePlateForm form, BindException errors) throws Excepti } } - @RequiresAnyOf({ReadPermission.class, DesignAssayPermission.class}) - public static class GetPlateTypesAction extends ReadOnlyApiAction - { - @Override - public Object execute(Object o, BindException errors) throws Exception - { - return PlateManager.get().getPlateTypes(); - } - } - @RequiresPermission(ReadPermission.class) public static class GetPlateOperationConfirmationDataAction extends ReadOnlyApiAction { From 54b23455cd9bdd469478d28d6e586b76830217e3 Mon Sep 17 00:00:00 2001 From: lum Date: Fri, 19 Jan 2024 09:46:18 -0800 Subject: [PATCH 11/21] code review feedback --- .../org/labkey/assay/plate/PlateLayout.java | 42 ------------------- .../org/labkey/assay/plate/PlateManager.java | 2 + .../assay/plate/model/PlateTypeImpl.java | 32 +++----------- .../assay/plate/view/plateTemplateList.jsp | 15 ++++--- 4 files changed, 15 insertions(+), 76 deletions(-) delete mode 100644 assay/src/org/labkey/assay/plate/PlateLayout.java diff --git a/assay/src/org/labkey/assay/plate/PlateLayout.java b/assay/src/org/labkey/assay/plate/PlateLayout.java deleted file mode 100644 index 6c0ae06b0f2..00000000000 --- a/assay/src/org/labkey/assay/plate/PlateLayout.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.labkey.assay.plate; - -import org.labkey.api.assay.plate.PlateType; - -/** - * Plate layouts encompass plate types but also include assay specific information - */ -public class PlateLayout -{ - private PlateType _plateType; - private String _assayType; - private String _description; - private String _name; - - public PlateLayout(String name, PlateType type, String assayType, String description) - { - _name = name; - _plateType = type; - _assayType = assayType; - _description = description; - } - - public String getName() - { - return _name; - } - - public PlateType getPlateType() - { - return _plateType; - } - - public String getAssayType() - { - return _assayType; - } - - public String getDescription() - { - return _description; - } -} diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 51cc013e255..a46440f07cc 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -1278,6 +1278,8 @@ public PlateType getPlateType(int rows, int columns) return new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateType(), filter, null).getObject(PlateTypeImpl.class); } + public record PlateLayout(String name, PlateType type, String assayType, String description){} + @NotNull public List getPlateLayouts() { diff --git a/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java b/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java index dcc811ed883..c9ee38c54fe 100644 --- a/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java +++ b/assay/src/org/labkey/assay/plate/model/PlateTypeImpl.java @@ -9,25 +9,15 @@ public class PlateTypeImpl implements PlateType { private Integer _rowId; - private String _assayType; + private Integer _rows; private Integer _cols; private String _description; - private Integer _rows; - private String _type; + private boolean _archived; public PlateTypeImpl() { } - public PlateTypeImpl(String assayType, String type, String description, Integer rows, Integer cols) - { - _assayType = assayType; - _type = type; - _description = description; - _cols = cols; - _rows = rows; - } - @Override public Integer getRowId() { @@ -39,16 +29,6 @@ public void setRowId(Integer rowId) _rowId = rowId; } - public String getAssayType() - { - return _assayType; - } - - public void setAssayType(String assayType) - { - _assayType = assayType; - } - public Integer getCols() { return _cols; @@ -90,14 +70,14 @@ public void setRows(Integer rows) _rows = rows; } - public String getType() + public boolean isArchived() { - return _type; + return _archived; } - public void setType(String type) + public void setArchived(boolean archived) { - _type = type; + _archived = archived; } @Override diff --git a/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp b/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp index 49717a81a6e..b7655a412ad 100644 --- a/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp +++ b/assay/src/org/labkey/assay/plate/view/plateTemplateList.jsp @@ -30,7 +30,6 @@ <%@ page import="org.labkey.api.view.HttpView" %> <%@ page import="org.labkey.api.view.JspView" %> <%@ page import="org.labkey.assay.PlateController" %> -<%@ page import="org.labkey.assay.plate.PlateLayout" %> <%@ page import="org.labkey.assay.plate.PlateManager" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashMap" %> @@ -204,18 +203,18 @@ if (isAssayDesigner || c.hasPermission(getUser(), InsertPermission.class)) { List