4444import org .breedinginsight .brapps .importer .services .processors .experiment .appendoverwrite .model .AppendOverwriteMiddlewareContext ;
4545import org .breedinginsight .brapps .importer .services .processors .experiment .create .model .PendingData ;
4646import org .breedinginsight .brapps .importer .services .processors .experiment .create .model .ProcessedPhenotypeData ;
47+ import org .breedinginsight .brapps .importer .services .processors .experiment .model .EntityNotFoundException ;
4748import org .breedinginsight .brapps .importer .services .processors .experiment .model .ExpImportProcessConstants ;
4849import org .breedinginsight .model .Program ;
4950import org .breedinginsight .model .Scale ;
@@ -70,8 +71,7 @@ public class ExperimentUtilities {
7071 public static final String PREEXISTING_EXPERIMENT_TITLE = "Experiment Title already exists" ;
7172 public static final String MISSING_OBS_UNIT_ID_ERROR = "Experimental entities are missing ObsUnitIDs" ;
7273 public static final String UNMATCHED_COLUMN = "Ontology term(s) not found: " ;
73-
74-
74+ public static final String INVALID_OBS_UNIT_ID_ERROR = "Invalid ObsUnitID" ;
7575
7676
7777 Gson gson ;
@@ -294,44 +294,104 @@ public static void addYearToStudyAdditionalInfo(Program program, BrAPIStudy stud
294294 }
295295
296296 /**
297- * This method is responsible for collating unique ObsUnit IDs from the provided context data.
297+ * Collates unique Observation Unit IDs from the import context.
298+ *
299+ * This method iterates through all import rows in the given context and
300+ * extracts unique Observation Unit IDs (ObsUnit IDs) that are not null or blank.
301+ *
302+ * @param context The AppendOverwriteMiddlewareContext containing the import data.
303+ * @return A Set of String containing all unique, non-null, non-blank Observation Unit IDs.
298304 *
299- * @param context the AppendOverwriteMiddlewareContext containing the import rows to process
300- * @return a Set of unique ObsUnit IDs collated from the import rows
301- * @throws IllegalStateException if any ObsUnit ID is repeated in the import rows
302- * @throws HttpStatusException if there is a mix of ObsUnit IDs for some but not all rows
305+ * @implNote The method performs the following steps:
306+ * 1. Initializes an empty HashSet to store unique ObsUnit IDs.
307+ * 2. Iterates through each import row in the context.
308+ * 3. For each row, checks if the ObsUnit ID is not null and not blank.
309+ * 4. If valid, adds the ObsUnit ID to the set.
310+ * 5. Returns the set of unique ObsUnit IDs.
303311 */
304- public static Set <String > collateReferenceOUIds (AppendOverwriteMiddlewareContext context ) throws HttpStatusException , IllegalStateException {
312+ public static Set <String > collateUniqueOUIds (AppendOverwriteMiddlewareContext context ) {
305313 // Initialize variables to track the presence of ObsUnit IDs
306314 Set <String > referenceOUIds = new HashSet <>();
307- boolean hasNoReferenceUnitIds = true ;
308- boolean hasAllReferenceUnitIds = true ;
315+
316+ // Iterate through the import rows to process ObsUnit IDs
317+ for (int rowNum = 0 ; rowNum < context .getImportContext ().getImportRows ().size (); rowNum ++) {
318+ ExperimentObservation importRow = (ExperimentObservation ) context .getImportContext ().getImportRows ().get (rowNum );
319+ if (importRow .getObsUnitID () != null && !importRow .getObsUnitID ().isBlank ()) {
320+ referenceOUIds .add (importRow .getObsUnitID ());
321+ }
322+ }
323+ return referenceOUIds ;
324+ }
325+
326+ /**
327+ * Validates Observation Unit ID values in the import context.
328+ *
329+ * This method checks each import row for the validity of its Observation Unit ID (ObsUnitID).
330+ * It performs the following validations:
331+ * 1. Checks if the ObsUnitID is null or blank.
332+ * 2. Checks if the ObsUnitID is a duplicate within the import data.
333+ *
334+ * @param context The AppendOverwriteMiddlewareContext containing import data and validation error storage.
335+ * @throws HttpStatusException If there's an HTTP-related error during the validation process.
336+ * @throws IllegalStateException If the system encounters an unexpected state during validation.
337+ *
338+ * @implNote The method performs the following steps:
339+ * 1. Retrieves the ValidationErrors object from the context.
340+ * 2. Initializes a HashSet to track unique ObsUnitIDs.
341+ * 3. Iterates through each import row in the context.
342+ * 4. For each row:
343+ * - If ObsUnitID is null or blank, adds a "missing ObsUnitID" error.
344+ * - If ObsUnitID is already in the set (duplicate), adds a "duplicate ObsUnitID" error.
345+ * - Otherwise, adds the ObsUnitID to the set of unique IDs.
346+ * 5. Errors are added using the addRowError method, specifying the OBS_UNIT_ID column and appropriate error messages.
347+ */
348+ public static void validateReferenceOUIdValues (AppendOverwriteMiddlewareContext context ) throws HttpStatusException , IllegalStateException {
349+ ValidationErrors validationErrors = context .getAppendOverwriteWorkflowContext ().getValidationErrors ();
350+ Set <String > referenceOUIds = new HashSet <>();
309351
310352 // Iterate through the import rows to process ObsUnit IDs
311353 for (int rowNum = 0 ; rowNum < context .getImportContext ().getImportRows ().size (); rowNum ++) {
312354 ExperimentObservation importRow = (ExperimentObservation ) context .getImportContext ().getImportRows ().get (rowNum );
313355
314- // Check if ObsUnitID is blank
315356 if (importRow .getObsUnitID () == null || importRow .getObsUnitID ().isBlank ()) {
316- // Set flag to indicate missing ObsUnit ID for current row
317- hasAllReferenceUnitIds = false ;
357+ // Check if ObsUnitID is blank
358+ addRowError ( ExperimentObservation . Columns . OBS_UNIT_ID , ExpImportProcessConstants . ErrMessage . MISSING_OBS_UNIT_ID . getValue (), validationErrors , rowNum ) ;
318359 } else if (referenceOUIds .contains (importRow .getObsUnitID ())) {
319- // Throw exception if ObsUnitID is repeated
320- throw new IllegalStateException ( "ObsUnitId is repeated: " + importRow . getObsUnitID () );
360+ // Check if ObsUnitID is repeated
361+ addRowError ( ExperimentObservation . Columns . OBS_UNIT_ID , ExpImportProcessConstants . ErrMessage . DUPLICATE_OBS_UNIT_ID . getValue (), validationErrors , rowNum );
321362 } else {
322363 // Add ObsUnitID to referenceOUIds
323364 referenceOUIds .add (importRow .getObsUnitID ());
324- // Set flag to indicate presence of ObsUnit ID
325- hasNoReferenceUnitIds = false ;
326365 }
327366 }
367+ }
328368
329- if (!hasNoReferenceUnitIds && !hasAllReferenceUnitIds ) {
330- // Throw exception if there is a mix of ObsUnit IDs for some but not all rows
331- throw new HttpStatusException (HttpStatus .UNPROCESSABLE_ENTITY , ExpImportProcessConstants .ErrMessage .MISSING_OBS_UNIT_ID_ERROR .getValue ());
332- }
369+ /**
370+ * Adds validation errors for observation units that were not found in the database.
371+ *
372+ * This method processes an EntityNotFoundException and adds corresponding validation errors
373+ * to the context for each import row where the Observation Unit ID was not found.
374+ *
375+ * @param e The EntityNotFoundException containing information about missing Observation Unit IDs.
376+ * @param context The AppendOverwriteMiddlewareContext containing import data and validation error storage.
377+ *
378+ * @implNote The method performs the following steps:
379+ * 1. Retrieves the ValidationErrors object from the context.
380+ * 2. Iterates through each import row in the context.
381+ * 3. For each row, checks if its Observation Unit ID is in the set of missing entity IDs from the exception.
382+ * 4. If a match is found, adds a validation error for that row, indicating an invalid Observation Unit ID.
383+ * 5. The error is added using the addRowError method, specifying the OBS_UNIT_ID column and using a predefined error message.
384+ */
385+ public static void addValidationErrorsForObsUnitsNotFound (EntityNotFoundException e , AppendOverwriteMiddlewareContext context ) {
386+ ValidationErrors validationErrors = context .getAppendOverwriteWorkflowContext ().getValidationErrors ();
387+ List <ValidationError > errors = new ArrayList <>();
333388
334- return referenceOUIds ;
389+ for (int rowNum = 0 ; rowNum < context .getImportContext ().getImportRows ().size (); rowNum ++) {
390+ String rowObsUnitId = ((ExperimentObservation )context .getImportContext ().getImportRows ().get (rowNum )).getObsUnitID ();
391+ if (e .getMissingEntityIds ().contains (rowObsUnitId )) {
392+ addRowError (ExperimentObservation .Columns .OBS_UNIT_ID , ExperimentUtilities .INVALID_OBS_UNIT_ID_ERROR , validationErrors , rowNum );
393+ }
394+ }
335395 }
336396
337397 /**
0 commit comments