From 76a344f52165571ada272d25eef4aa701cdac437 Mon Sep 17 00:00:00 2001 From: HMS17 Date: Wed, 18 Dec 2024 19:27:12 -0500 Subject: [PATCH 1/3] [BI-2055] - Remove missingValueString tablesaw values --- .../processors/ExperimentProcessor.java | 11 +++ .../experiment/ExperimentUtilities.java | 11 ++- .../service/ObservationService.java | 5 + .../validator/field/TextValidator.java | 99 +++++++++++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java index 34030b795..5e20fec24 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/ExperimentProcessor.java @@ -2428,6 +2428,13 @@ private void validateObservationValue(Trait variable, String value, addRowError(columnHeader, "Undefined nominal category detected", validationErrors, row); } break; + case TEXT: + //due to null as free text value messing stuff up in backend + if (!validText(value)) { + addRowError(columnHeader, "'Null' is not a valid value", validationErrors, row); + + } + break; default: break; } @@ -2477,6 +2484,10 @@ private boolean validCategory(List categories, return categoryValues.contains(value.toLowerCase()); } + private boolean validText(String value){ + return (value != null) && (!value.equalsIgnoreCase("null")); + } + /** * Converts year String to SeasonDbId *
diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/ExperimentUtilities.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/ExperimentUtilities.java index ae015aab6..718834887 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/ExperimentUtilities.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/ExperimentUtilities.java @@ -530,7 +530,7 @@ public static void validateObservationValue(Trait variable, String value, case NUMERICAL: Optional number = validNumericValue(value); if (number.isEmpty()) { - addRowError(columnHeader, "Non-numeric text detected detected", validationErrors, row); + addRowError(columnHeader, "Non-numeric text detected", validationErrors, row); } else if (!validNumericRange(number.get(), variable.getScale())) { addRowError(columnHeader, "Value outside of min/max range detected", validationErrors, row); } @@ -550,6 +550,11 @@ public static void validateObservationValue(Trait variable, String value, addRowError(columnHeader, "Undefined nominal category detected", validationErrors, row); } break; + case TEXT: + if (!validText(value)) { + addRowError(columnHeader, "'Null' is not a valid value", validationErrors, row); + } + break; default: break; } @@ -589,6 +594,10 @@ public static boolean validCategory(List catego return categoryValues.contains(value.toLowerCase()); } + public static boolean validText(String value){ + return (value != null) && (!value.equalsIgnoreCase("null")); + } + public static boolean isNAObservation(String value){ return value.equalsIgnoreCase("NA"); } diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/service/ObservationService.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/service/ObservationService.java index a6ecac2c0..728cac3b6 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/service/ObservationService.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/service/ObservationService.java @@ -97,6 +97,11 @@ public boolean validDateValue(String value) { } return true; } + + public boolean validText(String value){ + return (value != null) && (!value.equalsIgnoreCase("null")); + } + public String getObservationHash(String observationUnitName, String variableName, String studyName) { String concat = DigestUtils.sha256Hex(observationUnitName) + DigestUtils.sha256Hex(variableName) + diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java new file mode 100644 index 000000000..3979c2c63 --- /dev/null +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java @@ -0,0 +1,99 @@ +/* + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.breedinginsight.brapps.importer.services.processors.experiment.validator.field; + +import io.micronaut.http.HttpStatus; +import lombok.extern.slf4j.Slf4j; +import org.breedinginsight.api.model.v1.response.ValidationError; +import org.breedinginsight.brapps.importer.services.processors.experiment.service.ObservationService; +import org.breedinginsight.model.Trait; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Optional; + +import static org.breedinginsight.brapps.importer.services.processors.experiment.model.ExpImportProcessConstants.TIMESTAMP_PREFIX; +import static org.breedinginsight.dao.db.enums.DataType.TEXT; + +//so much todotodotod + + +/** + * This class represents a TextValidator which implements the ObservationValidator interface. + * It is responsible for validating text fields within observations. + */ +@Slf4j +@Singleton +public class TextValidator implements ObservationValidator { + + @Inject + ObservationService observationService; + + /** + * Constructor for TextValidator class that takes an ObservationService as a parameter. + * @param observationService the ObservationService used for validation + */ + public TextValidator(ObservationService observationService) { + this.observationService = observationService; + } + + /** + * Validates a field within an observation for text data. + * + * @param fieldName the name of the field being validated + * @param value the value of the field being validated + * @param variable the Trait variable associated with the field + * @return an Optional containing a ValidationError if validation fails, otherwise an empty Optional + */ + @Override + public Optional validateField(String fieldName, String value, Trait variable) { + // Skip validation if observation is blank + if (observationService.isBlankObservation(value)) { + log.debug(String.format("Skipping validation of observation because there is no value.\n\tvariable: %s", fieldName)); + return Optional.empty(); + } + + // Skip validation if observation is NA + if (observationService.isNAObservation(value)) { + log.debug(String.format("Skipping validation of observation because it is NA.\n\tvariable: %s", fieldName)); + return Optional.empty(); + } + + // Skip if field is a timestamp + if (fieldName.startsWith(TIMESTAMP_PREFIX)) { + return Optional.empty(); + } + + // Skip if there is no trait data + if (variable == null || variable.getScale() == null || variable.getScale().getDataType() == null) { + return Optional.empty(); + } + + // Skip if this is not a text trait + if (!TEXT.equals(variable.getScale().getDataType())) { + return Optional.empty(); + } + + // Validate text + if (!observationService.validText(value)) { + return Optional.of(new ValidationError(fieldName, "'Null' is not a valid value", HttpStatus.UNPROCESSABLE_ENTITY)); + } + + return Optional.empty(); + } +} \ No newline at end of file From 3ff0eb4655668b967854ac2a795c1b8998fabd3d Mon Sep 17 00:00:00 2001 From: rob-ouser-bi Date: Wed, 15 Jan 2025 16:05:57 +0000 Subject: [PATCH 2/3] [autocommit] bumping build number --- src/main/resources/version.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties index 4e43777d2..4ef6916c8 100644 --- a/src/main/resources/version.properties +++ b/src/main/resources/version.properties @@ -15,5 +15,5 @@ # -version=v1.1.0+899 -versionInfo=https://github.com/Breeding-Insight/bi-api/commit/1d19a829223e99b09324a69b51fa47c6b965de64 +version=v1.1.0+901 +versionInfo=https://github.com/Breeding-Insight/bi-api/commit/9c0fdb5b160215a40e5f2df57a7e922ec0036052 From f85bf8c671144dee1eb20a66af11d26382751d17 Mon Sep 17 00:00:00 2001 From: HMS17 <84345306+HMS17@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:08:13 -0500 Subject: [PATCH 3/3] [BI-2055] - Code review fix Co-authored-by: mlm483 <128052931+mlm483@users.noreply.github.com> --- .../processors/experiment/validator/field/TextValidator.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java index 3979c2c63..e444eb5f9 100644 --- a/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java +++ b/src/main/java/org/breedinginsight/brapps/importer/services/processors/experiment/validator/field/TextValidator.java @@ -30,7 +30,6 @@ import static org.breedinginsight.brapps.importer.services.processors.experiment.model.ExpImportProcessConstants.TIMESTAMP_PREFIX; import static org.breedinginsight.dao.db.enums.DataType.TEXT; -//so much todotodotod /**