Skip to content

Commit

Permalink
TRUNK-6145: Allow validation to be disabled only within the current t… (
Browse files Browse the repository at this point in the history
openmrs#4176)

TRUNK-6145: Allow validation to be disabled only within the current thread
  • Loading branch information
mseaton committed Oct 25, 2022
1 parent 2ceb3c7 commit 5dc7a1f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 4 deletions.
36 changes: 32 additions & 4 deletions api/src/main/java/org/openmrs/validator/ValidateUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
*/
package org.openmrs.validator;

import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.openmrs.OpenmrsObject;
import org.openmrs.api.ValidationException;
Expand All @@ -23,6 +20,9 @@
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import java.util.LinkedHashSet;
import java.util.Set;

/**
* This class should be used in the *Services to validate objects before saving them. <br>
* <br>
Expand All @@ -49,6 +49,9 @@ private ValidateUtil() {
*/
private static Boolean disableValidation = false;

/** This enables consuming code to disable validation if needed for specific operations in the current thread */
private static final ThreadLocal<Boolean> disableValidationForThread = new ThreadLocal<>();

/**
* Test the given object against all validators that are registered as compatible with the
* object class
Expand All @@ -59,7 +62,7 @@ private ValidateUtil() {
* <strong>Should</strong> return immediately if validation is disabled
*/
public static void validate(Object obj) throws ValidationException {
if (disableValidation) {
if (disableValidation || isValidationDisabledForThread()) {
return;
}

Expand Down Expand Up @@ -146,4 +149,29 @@ public static void setDisableValidation(Boolean disableValidation) {
ValidateUtil.disableValidation = disableValidation;
}

/**
* @return true if validation has been disabled for the current thread, false otherwise
* @since 2.5.8
*/
public static boolean isValidationDisabledForThread() {
return disableValidationForThread.get() == Boolean.TRUE;
}

/**
* Used to indicate that validation should be disabled for the current thread
* NOTE: This should always be used in conjunction with the resumeValidationForThread method
* @since 2.5.8
*/
public static void disableValidationForThread() {
disableValidationForThread.set(Boolean.TRUE);
}

/**
* Used to indicate that validation should be re-enabled for the current thread
* Typically this would be placed in a `finally` block after the disableValidationForThread method is used
* @since 2.5.8
*/
public static void resumeValidationForThread() {
disableValidationForThread.remove();
}
}
44 changes: 44 additions & 0 deletions api/src/test/java/org/openmrs/validator/ValidateUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -72,6 +73,49 @@ public void validate_shouldReturnImmediatelyIfValidationIsDisabled() {

ValidateUtil.setDisableValidation(prevVal);
}

/**
* @see ValidateUtil#validate(Object)
*/
@Test
public void validate_shouldReturnImmediatelyIfValidationIsDisabledForThread() {

// Validation fails initially
ValidationException caughtException = null;
try {
assertFalse(ValidateUtil.isValidationDisabledForThread());
ValidateUtil.validate(new Patient());
}
catch (ValidationException e) {
caughtException = e;
}
assertNotNull(caughtException);

// Validation does not fail if disabled for thread
caughtException = null;
try {
ValidateUtil.disableValidationForThread();
assertTrue(ValidateUtil.isValidationDisabledForThread());
ValidateUtil.validate(new Patient());
}
catch (ValidationException e) {
caughtException = e;
}
finally {
ValidateUtil.resumeValidationForThread();
}
assertNull(caughtException);

// Validation fails again if re-enabled for thread
try {
assertFalse(ValidateUtil.isValidationDisabledForThread());
ValidateUtil.validate(new Patient());
}
catch (ValidationException e) {
caughtException = e;
}
assertNotNull(caughtException);
}

/**
* @see ValidateUtil#validateFieldLengths(org.springframework.validation.Errors, Class, String...)
Expand Down

0 comments on commit 5dc7a1f

Please sign in to comment.