java.lang.Object
com.broadleafcommerce.adminuser.resource.service.validation.AdminRoleValidator
All Implemented Interfaces:
com.broadleafcommerce.data.tracking.core.mapping.validation.EntityValidator

public class AdminRoleValidator extends Object implements com.broadleafcommerce.data.tracking.core.mapping.validation.EntityValidator
Basic validations for AdminRole.

Validations related to context (and any basic prerequisite validation for that) are performed by AdminRoleContextValidator, which is invoked before this validator.

Author:
Samarth Dhruva (samarthd)
See Also:
  • Constructor Details

    • AdminRoleValidator

      public AdminRoleValidator()
  • Method Details

    • setAdminRoleService

      @Autowired @Lazy public void setAdminRoleService(AdminRoleService<AdminRole> adminRoleService)
      Lazy injection since this validator is itself a service component. This avoids circular dependency exceptions
      Parameters:
      adminRoleService - the role service
    • supports

      public boolean supports(Class<?> serviceClass, com.broadleafcommerce.data.tracking.core.context.ContextInfo context)
      Specified by:
      supports in interface com.broadleafcommerce.data.tracking.core.mapping.validation.EntityValidator
    • validate

      public void validate(@NonNull Object businessInstance, @NonNull org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo context)
      Specified by:
      validate in interface com.broadleafcommerce.data.tracking.core.mapping.validation.EntityValidator
    • validateForReplace

      public void validateForReplace(Object businessInstance, org.springframework.validation.Errors errors, com.broadleafcommerce.data.tracking.core.context.ContextInfo context)
      Specified by:
      validateForReplace in interface com.broadleafcommerce.data.tracking.core.mapping.validation.EntityValidator
    • validateName

      protected void validateName(org.springframework.validation.Errors errors)
    • validatePermissions

      protected void validatePermissions(AdminRole role, org.springframework.validation.Errors errors)
      Permissions are validated for existence and accessibility by the DefaultAdminRoleContextValidator.

      This validation serves purely to guarantee that each permission reference has AdminPermissionRef.id and AdminPermissionRef.name.

      In the JPA domain, each permission's Object.equals(Object) and Object.hashCode() excludes the id field from comparison. Thus, in our refs, if we have no field but the id, they will collide with each other when added to the role's Set of permissions.

      Since we expect the AdminPermission.name and AdminPermission.tenantId combined to be unique, those fields should be hydrated on the references, thereby preventing collisions. AdminPermission.tenantId can be null for global permissions, so we will only validate AdminPermission.name is present.

      Parameters:
      role - the role to validate
      errors - the errors object bound to the role on which errors can be registered
    • validateParentRoleId

      protected void validateParentRoleId(AdminRole role, org.springframework.validation.Errors errors)
      At a minimum level, DefaultAdminRoleContextValidator validates that the direct parent of the role (if specified) in AdminRole.parentRoleId exists and is accessible from the child's context.

      On top of those validations, this validation:

      • traverses the full ancestry of the role to confirm each ancestor still exists and there are no cycles, either in the case that the ancestors already had cycles, or in the case that this role itself causes a cycle. See validateRoleAncestry(AdminRole, Errors) for more information.
      Parameters:
      role - the role to validate
      errors - the errors object bound to the role on which errors can be registered
    • validateRoleAncestry

      protected void validateRoleAncestry(AdminRole role, org.springframework.validation.Errors errors)
      For a cycle check, we could theoretically just compare the role's id against each of its ancestors instead of keeping a set of all seen ancestors. This is because we can be fairly confident that each already-persisted ancestor was also validated against having cycles in its own ancestry, and thus any cycle will almost definitely be caused by this role becoming a parent of itself.

      However, just in case there is a pre-existing cycle (perhaps an ancestor was persisted without any validation), we will check for it here. This also helps guard against an infinite loop in this logic which could be caused by such a cycle.

      Parameters:
      role - the role whose ancestry should be validated
      errors - the errors object bound to the role on which errors can be registered
    • prefixWithEntityValidationMessageKey

      protected String prefixWithEntityValidationMessageKey(String errorCode)
    • getAdminRoleService

      protected AdminRoleService<AdminRole> getAdminRoleService()