From c508b04f35e5438b339326d14f5b6956bebb169f Mon Sep 17 00:00:00 2001 From: labkey-matthewb Date: Tue, 4 Nov 2025 10:38:53 -0800 Subject: [PATCH 1/3] avoid Collections.unmodifiableMap for internal uses --- .../org/labkey/api/data/TableViewForm.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/api/src/org/labkey/api/data/TableViewForm.java b/api/src/org/labkey/api/data/TableViewForm.java index 3f82dc0cc88..ce4b34dc622 100644 --- a/api/src/org/labkey/api/data/TableViewForm.java +++ b/api/src/org/labkey/api/data/TableViewForm.java @@ -143,7 +143,7 @@ public void doInsert() throws SQLException if (null != _tinfo.getColumn("container")) setValueToBind("container", _c.getId()); - Map newMap = Table.insert(_user, _tinfo, getTypedValues()); + Map newMap = Table.insert(_user, _tinfo, _getTypedValues()); setTypedValues(newMap, false); } @@ -168,7 +168,7 @@ public void doUpdate() throws SQLException setValueToBind("container", _c.getId()); Object[] pkVal = getPkVals(); - Map newMap = Table.update(_user, _tinfo, getTypedValues(), pkVal); + Map newMap = Table.update(_user, _tinfo, _getTypedValues(), pkVal); setTypedValues(newMap, true); } @@ -230,7 +230,7 @@ public void refreshFromDb() if (maps.length > 0) { setTypedValues(maps[0], false); - setOldValues(new CaseInsensitiveHashMap<>(getTypedValues())); + setOldValues(new CaseInsensitiveHashMap<>(_getTypedValues())); } } @@ -339,7 +339,7 @@ public Object[] getPkVals() { String pkName = pkNames.get(i); Object pkVal; - pkVal = getTypedValues().get(pkName); + pkVal = _getTypedValues().get(pkName); if (null == pkVal) { Object oldValues = getOldValues(); @@ -514,28 +514,28 @@ public boolean isValid() public Object getTypedValue(String propName) { - return getTypedValues().get(propName); + return _getTypedValues().get(propName); } public Object getTypedValue(ColumnInfo column) { - return getTypedValues().get(getFormFieldName(column)); + return _getTypedValues().get(getFormFieldName(column)); } public boolean hasTypedValue(String propName) { - return getTypedValues().containsKey(propName); + return _getTypedValues().containsKey(propName); } public boolean hasTypedValue(ColumnInfo column) { - return getTypedValues().containsKey(getFormFieldName(column)); + return _getTypedValues().containsKey(getFormFieldName(column)); } public void setTypedValue(String propName, Object val) { // call _populate() if necessary - getTypedValues(); + _getTypedValues(); _values.put(propName, val); // We don't use setValueToBind() here because we want to avoid its side effect of clearing _values // To convert or not to convert??? @@ -551,11 +551,18 @@ public void setTypedValue(String propName, Object val) * setTypedValues */ public Map getTypedValues() + { + return Collections.unmodifiableMap(_getTypedValues()); + } + + private Map _getTypedValues() { if (null == _values) + { + // TODO we don't usually enter this code path, but we should still throw if there is a conversion error populateValues(null); - - return Collections.unmodifiableMap(_values); + } + return _values; } /** @@ -580,7 +587,7 @@ else if (includeUntyped && _stringValues.containsKey(getFormFieldName(column))) else if (getRequest() instanceof MultipartHttpServletRequest request) { String fieldName = getMultiPartFormFieldName(column); - Object typedValue = getTypedValues().get(fieldName); + Object typedValue = _getTypedValues().get(fieldName); if (typedValue != null) values.put(column.getName(), typedValue); From 2a49d400692eee354163eb7b82dbeb4b1ed35053 Mon Sep 17 00:00:00 2001 From: labkey-matthewb Date: Tue, 4 Nov 2025 10:52:28 -0800 Subject: [PATCH 2/3] use setTypedValue() --- study/src/org/labkey/study/controllers/StudyController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/study/src/org/labkey/study/controllers/StudyController.java b/study/src/org/labkey/study/controllers/StudyController.java index 55aa0fee64b..5b217efb322 100644 --- a/study/src/org/labkey/study/controllers/StudyController.java +++ b/study/src/org/labkey/study/controllers/StudyController.java @@ -1757,8 +1757,8 @@ public ApiResponse execute(TableViewForm form, BindException errors) throws Exce if (!getContainer().hasPermission(getUser(),AdminPermission.class)) throw new UnauthorizedException(); + form.setTypedValue("container", getContainer().getId()); Map values = form.getTypedValues(); - values.put("container", getContainer().getId()); TableInfo studyProperties = form.getTable(); QueryUpdateService qus = studyProperties.getUpdateService(); From 467b3e48a36086a9f6de1ba69eb7165ed3ca77d5 Mon Sep 17 00:00:00 2001 From: labkey-matthewb Date: Tue, 4 Nov 2025 10:58:58 -0800 Subject: [PATCH 3/3] comment --- api/src/org/labkey/api/data/TableViewForm.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/org/labkey/api/data/TableViewForm.java b/api/src/org/labkey/api/data/TableViewForm.java index ce4b34dc622..229525bbda2 100644 --- a/api/src/org/labkey/api/data/TableViewForm.java +++ b/api/src/org/labkey/api/data/TableViewForm.java @@ -560,6 +560,7 @@ private Map _getTypedValues() if (null == _values) { // TODO we don't usually enter this code path, but we should still throw if there is a conversion error + // or maybe enforce that populateValues() has been called and throw IllegalStateException here? populateValues(null); } return _values;