package eu.eudat.query.utils; import eu.eudat.commons.enums.DescriptionStatus; import eu.eudat.commons.enums.DmpAccessType; import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.DescriptionEntity; import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpUserEntity; import jakarta.persistence.criteria.*; import org.springframework.stereotype.Component; import java.util.UUID; @Component public class QueryUtilsServiceImpl implements QueryUtilsService { @Override public Subquery buildSubQuery(BuildSubQueryInput parameters){ Subquery subQuery = parameters.getQuery().subquery(parameters.getKeyType()); Root subQueryRoot = subQuery.from(parameters.getEntityType()); subQuery.select(parameters.getKeyPathFunc().apply(subQueryRoot)).distinct(true); subQuery.where(parameters.getFilterFunc().apply(subQueryRoot, parameters.getCriteriaBuilder())); return subQuery; } @Override public Subquery buildDmpAuthZSubQuery(AbstractQuery query, CriteriaBuilder criteriaBuilder, UUID userId, Boolean usePublic){ return this.buildSubQuery(new BuildSubQueryInput<>( new BuildSubQueryInput.Builder<>(DmpEntity.class, UUID.class) .query(query) .criteriaBuilder(criteriaBuilder) .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpEntity._id)) .filterFunc((subQueryRoot, cb) -> cb.or( usePublic ? cb.and( cb.equal(subQueryRoot.get(DmpEntity._accessType), DmpAccessType.Public), cb.equal(subQueryRoot.get(DmpEntity._status), DmpStatus.Finalized), cb.equal(subQueryRoot.get(DmpEntity._isActive), IsActive.Active) ): cb.or(), //Creates a false query userId != null ? cb.in(subQueryRoot.get(DmpEntity._id)).value(this.buildDmpUserAuthZSubQuery(query, criteriaBuilder, userId)) : cb.or() //Creates a false query ) ) )); } @Override public Subquery buildDescriptionAuthZSubQuery(AbstractQuery query, CriteriaBuilder criteriaBuilder, UUID userId, Boolean usePublic) { return this.buildSubQuery(new BuildSubQueryInput<>( new BuildSubQueryInput.Builder<>(DescriptionEntity.class, UUID.class) .query(query) .criteriaBuilder(criteriaBuilder) .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DescriptionEntity._id)) .filterFunc((subQueryRoot, cb) -> cb.or( usePublic ? cb.and( cb.equal(subQueryRoot.get(DescriptionEntity._status), DescriptionStatus.Finalized), cb.equal(subQueryRoot.get(DescriptionEntity._isActive), IsActive.Active), cb.in(subQueryRoot.get(DescriptionEntity._dmpId)).value(this.buildPublicDmpAuthZSubQuery(query, criteriaBuilder, usePublic)) ): cb.or(), //Creates a false query userId != null ? cb.or( cb.equal(subQueryRoot.get(DescriptionEntity._createdById), userId), cb.in(subQueryRoot.get(DescriptionEntity._dmpId)).value(this.buildDmpUserAuthZSubQuery(query, criteriaBuilder, userId)) ) : cb.or() //Creates a false query ) ) )); } @Override public Subquery buildPublicDmpAuthZSubQuery(AbstractQuery query, CriteriaBuilder criteriaBuilder, Boolean usePublic){ return this.buildSubQuery(new BuildSubQueryInput<>( new BuildSubQueryInput.Builder<>(DmpEntity.class, UUID.class) .query(query) .criteriaBuilder(criteriaBuilder) .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpEntity._id)) .filterFunc((subQueryRoot, cb) -> usePublic ? cb.and( cb.equal(subQueryRoot.get(DmpEntity._accessType), DmpAccessType.Public), cb.equal(subQueryRoot.get(DmpEntity._status), DmpStatus.Finalized), cb.equal(subQueryRoot.get(DmpEntity._isActive), IsActive.Active) ): cb.or() //Creates a false query ) )); } @Override public Subquery buildDmpUserAuthZSubQuery(AbstractQuery query, CriteriaBuilder criteriaBuilder, UUID userId){ return this.buildSubQuery(new BuildSubQueryInput<>(new BuildSubQueryInput.Builder<>(DmpUserEntity.class, UUID.class) .query(query) .criteriaBuilder(criteriaBuilder) .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._dmpId)) .filterFunc((subQueryRoot, cb) -> userId != null ? cb.and( cb.equal(subQueryRoot.get(DmpUserEntity._userId), userId), cb.equal(subQueryRoot.get(DmpUserEntity._isActive), IsActive.Active) ) : cb.or() //Creates a false query ) )); } }