2023-10-24 17:47:13 +02:00
package eu.eudat.query ;
import eu.eudat.authorization.AuthorizationFlags ;
2024-03-12 17:27:16 +01:00
import eu.eudat.authorization.Permission ;
2023-10-24 17:47:13 +02:00
import eu.eudat.commons.enums.IsActive ;
2023-10-27 17:29:06 +02:00
import eu.eudat.commons.enums.ReferenceSourceType ;
2024-03-12 17:27:16 +01:00
import eu.eudat.commons.scope.user.UserScope ;
import eu.eudat.data.DmpEntity ;
2023-12-06 13:18:19 +01:00
import eu.eudat.data.DmpReferenceEntity ;
2023-10-26 11:07:04 +02:00
import eu.eudat.data.ReferenceEntity ;
2023-11-14 15:08:48 +01:00
import eu.eudat.model.PublicReference ;
2023-11-06 14:25:04 +01:00
import eu.eudat.model.Reference ;
2024-03-12 17:27:16 +01:00
import eu.eudat.query.utils.BuildSubQueryInput ;
import eu.eudat.query.utils.QueryUtilsService ;
import gr.cite.commons.web.authz.service.AuthorizationService ;
2023-10-24 17:47:13 +02:00
import gr.cite.tools.data.query.FieldResolver ;
import gr.cite.tools.data.query.QueryBase ;
import gr.cite.tools.data.query.QueryContext ;
import jakarta.persistence.Tuple ;
import jakarta.persistence.criteria.CriteriaBuilder ;
import jakarta.persistence.criteria.Predicate ;
import org.springframework.beans.factory.config.ConfigurableBeanFactory ;
import org.springframework.context.annotation.Scope ;
import org.springframework.stereotype.Component ;
import java.time.Instant ;
import java.util.* ;
@Component
@Scope ( value = ConfigurableBeanFactory . SCOPE_PROTOTYPE )
2023-10-26 11:07:04 +02:00
public class ReferenceQuery extends QueryBase < ReferenceEntity > {
2023-10-24 17:47:13 +02:00
private String like ;
private Collection < UUID > ids ;
private Collection < IsActive > isActives ;
2023-10-27 17:29:06 +02:00
private Collection < ReferenceSourceType > referenceSourceTypes ;
2023-10-24 17:47:13 +02:00
2024-02-08 17:12:47 +01:00
private Collection < UUID > typeIds ;
2023-10-24 17:47:13 +02:00
2023-12-13 16:35:29 +01:00
private Collection < String > references ;
2024-04-12 12:49:13 +02:00
2024-02-07 16:23:47 +01:00
private Collection < String > sources ;
2023-12-13 16:35:29 +01:00
2023-10-24 17:47:13 +02:00
private Collection < UUID > excludedIds ;
2024-04-12 12:49:13 +02:00
private Instant after ;
2023-12-06 13:18:19 +01:00
2024-04-12 12:49:13 +02:00
private DmpReferenceQuery dmpReferenceQuery ;
2023-11-15 15:09:24 +01:00
2023-10-24 17:47:13 +02:00
private EnumSet < AuthorizationFlags > authorize = EnumSet . of ( AuthorizationFlags . None ) ;
2023-10-26 11:07:04 +02:00
public ReferenceQuery like ( String value ) {
2023-10-24 17:47:13 +02:00
this . like = value ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery ids ( UUID value ) {
2023-10-24 17:47:13 +02:00
this . ids = List . of ( value ) ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery ids ( UUID . . . value ) {
2023-10-24 17:47:13 +02:00
this . ids = Arrays . asList ( value ) ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery ids ( Collection < UUID > values ) {
2023-10-24 17:47:13 +02:00
this . ids = values ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery isActive ( IsActive value ) {
2023-10-24 17:47:13 +02:00
this . isActives = List . of ( value ) ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery isActive ( IsActive . . . value ) {
2023-10-24 17:47:13 +02:00
this . isActives = Arrays . asList ( value ) ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery isActive ( Collection < IsActive > values ) {
2023-10-24 17:47:13 +02:00
this . isActives = values ;
return this ;
}
2024-02-08 17:12:47 +01:00
public ReferenceQuery typeIds ( UUID value ) {
this . typeIds = List . of ( value ) ;
2023-10-24 17:47:13 +02:00
return this ;
}
2024-02-08 17:12:47 +01:00
public ReferenceQuery typeIds ( UUID . . . value ) {
this . typeIds = Arrays . asList ( value ) ;
2023-10-24 17:47:13 +02:00
return this ;
}
2024-02-08 17:12:47 +01:00
public ReferenceQuery typeIds ( Collection < UUID > values ) {
this . typeIds = values ;
2023-10-24 17:47:13 +02:00
return this ;
}
2023-12-13 16:35:29 +01:00
public ReferenceQuery references ( String value ) {
this . references = List . of ( value ) ;
return this ;
}
public ReferenceQuery references ( String . . . value ) {
this . references = Arrays . asList ( value ) ;
return this ;
}
public ReferenceQuery references ( Collection < String > values ) {
this . references = values ;
return this ;
}
2024-02-07 16:23:47 +01:00
public ReferenceQuery sources ( String value ) {
this . sources = List . of ( value ) ;
return this ;
}
public ReferenceQuery sources ( String . . . value ) {
this . sources = Arrays . asList ( value ) ;
return this ;
}
public ReferenceQuery sources ( Collection < String > values ) {
this . sources = values ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery excludedIds ( Collection < UUID > values ) {
2023-10-24 17:47:13 +02:00
this . excludedIds = values ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery excludedIds ( UUID value ) {
2023-10-24 17:47:13 +02:00
this . excludedIds = List . of ( value ) ;
return this ;
}
2023-10-26 11:07:04 +02:00
public ReferenceQuery excludedIds ( UUID . . . value ) {
2023-10-24 17:47:13 +02:00
this . excludedIds = Arrays . asList ( value ) ;
return this ;
}
2023-10-30 09:43:50 +01:00
public ReferenceQuery sourceTypes ( ReferenceSourceType value ) {
2023-10-27 17:29:06 +02:00
this . referenceSourceTypes = List . of ( value ) ;
2023-10-24 17:47:13 +02:00
return this ;
}
2023-10-30 09:43:50 +01:00
public ReferenceQuery sourceTypes ( ReferenceSourceType . . . value ) {
2023-10-27 17:29:06 +02:00
this . referenceSourceTypes = Arrays . asList ( value ) ;
2023-10-24 17:47:13 +02:00
return this ;
}
2023-10-30 09:43:50 +01:00
public ReferenceQuery sourceTypes ( Collection < ReferenceSourceType > values ) {
2023-10-27 17:29:06 +02:00
this . referenceSourceTypes = values ;
2023-10-24 17:47:13 +02:00
return this ;
}
2024-04-12 12:49:13 +02:00
public ReferenceQuery after ( Instant value ) {
this . after = value ;
return this ;
}
2023-12-06 13:18:19 +01:00
public ReferenceQuery dmpReferenceSubQuery ( DmpReferenceQuery value ) {
this . dmpReferenceQuery = value ;
return this ;
}
2023-11-15 15:09:24 +01:00
2023-10-26 11:07:04 +02:00
public ReferenceQuery authorize ( EnumSet < AuthorizationFlags > values ) {
2023-10-24 17:47:13 +02:00
this . authorize = values ;
return this ;
}
2024-04-12 12:49:13 +02:00
2024-03-12 17:27:16 +01:00
private final UserScope userScope ;
private final AuthorizationService authService ;
2024-04-12 12:49:13 +02:00
2024-03-12 17:27:16 +01:00
private final QueryUtilsService queryUtilsService ;
2023-10-24 17:47:13 +02:00
2023-10-26 11:07:04 +02:00
public ReferenceQuery (
2024-04-12 12:49:13 +02:00
UserScope userScope , AuthorizationService authService , QueryUtilsService queryUtilsService ) {
this . userScope = userScope ;
this . authService = authService ;
this . queryUtilsService = queryUtilsService ;
2023-10-24 17:47:13 +02:00
}
@Override
2023-10-26 11:07:04 +02:00
protected Class < ReferenceEntity > entityClass ( ) {
return ReferenceEntity . class ;
2023-10-24 17:47:13 +02:00
}
@Override
protected Boolean isFalseQuery ( ) {
2024-04-12 12:49:13 +02:00
return this . isEmpty ( this . ids ) | | this . isEmpty ( this . isActives ) | | this . isEmpty ( this . sources ) | | this . isEmpty ( this . excludedIds ) | | this . isEmpty ( this . typeIds ) | | this . isEmpty ( this . referenceSourceTypes ) | | this . isFalseQuery ( this . dmpReferenceQuery ) ;
2023-10-24 17:47:13 +02:00
}
2024-03-12 17:27:16 +01:00
@Override
protected < X , Y > Predicate applyAuthZ ( QueryContext < X , Y > queryContext ) {
2024-04-12 12:49:13 +02:00
if ( this . authorize . contains ( AuthorizationFlags . None ) )
return null ;
if ( this . authorize . contains ( AuthorizationFlags . Permission ) & & this . authService . authorize ( Permission . BrowseReference ) )
return null ;
2024-03-12 17:27:16 +01:00
UUID userId ;
boolean usePublic = this . authorize . contains ( AuthorizationFlags . Public ) ;
2024-04-12 12:49:13 +02:00
if ( this . authorize . contains ( AuthorizationFlags . DmpAssociated ) )
userId = this . userScope . getUserIdSafe ( ) ;
else
userId = null ;
2024-03-12 17:27:16 +01:00
List < Predicate > predicates = new ArrayList < > ( ) ;
2024-04-12 12:49:13 +02:00
if ( userId ! = null | | usePublic ) {
2024-03-12 17:27:16 +01:00
predicates . add ( queryContext . CriteriaBuilder . or (
2024-04-12 12:49:13 +02:00
userId ! = null ? queryContext . CriteriaBuilder . equal ( queryContext . Root . get ( ReferenceEntity . _createdById ) , userId ) : queryContext . CriteriaBuilder . or ( ) , //Creates a false query
2024-03-13 09:02:04 +01:00
queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _id ) ) . value ( queryUtilsService . buildSubQuery ( new BuildSubQueryInput < > ( new BuildSubQueryInput . Builder < > ( DmpReferenceEntity . class , UUID . class )
2024-03-12 17:27:16 +01:00
. query ( queryContext . Query )
. criteriaBuilder ( queryContext . CriteriaBuilder )
. keyPathFunc ( ( subQueryRoot ) - > subQueryRoot . get ( DmpReferenceEntity . _referenceId ) )
. filterFunc ( ( subQueryRoot , cb ) - >
cb . in ( subQueryRoot . get ( DmpReferenceEntity . _dmpId ) ) . value ( queryUtilsService . buildDmpAuthZSubQuery ( queryContext . Query , queryContext . CriteriaBuilder , userId , usePublic ) )
)
2024-03-13 09:02:04 +01:00
) ) ) //Creates a false query
2024-03-12 17:27:16 +01:00
) ) ;
}
if ( ! predicates . isEmpty ( ) ) {
Predicate [ ] predicatesArray = predicates . toArray ( new Predicate [ 0 ] ) ;
return queryContext . CriteriaBuilder . and ( predicatesArray ) ;
} else {
return queryContext . CriteriaBuilder . or ( ) ; //Creates a false query
}
}
2024-04-12 12:49:13 +02:00
2023-10-24 17:47:13 +02:00
@Override
protected < X , Y > Predicate applyFilters ( QueryContext < X , Y > queryContext ) {
List < Predicate > predicates = new ArrayList < > ( ) ;
if ( this . ids ! = null ) {
2023-10-26 11:07:04 +02:00
CriteriaBuilder . In < UUID > inClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _id ) ) ;
2023-10-24 17:47:13 +02:00
for ( UUID item : this . ids )
inClause . value ( item ) ;
predicates . add ( inClause ) ;
}
if ( this . like ! = null & & ! this . like . isEmpty ( ) ) {
2024-04-05 11:43:33 +02:00
predicates . add ( queryContext . CriteriaBuilder . or ( queryUtilsService . ilike ( queryContext . CriteriaBuilder , queryContext . Root . get ( ReferenceEntity . _label ) , this . like ) ,
queryUtilsService . ilike ( queryContext . CriteriaBuilder , queryContext . Root . get ( ReferenceEntity . _description ) , this . like ) ,
queryUtilsService . ilike ( queryContext . CriteriaBuilder , queryContext . Root . get ( ReferenceEntity . _source ) , this . like )
2023-10-25 11:42:34 +02:00
) ) ;
2023-10-24 17:47:13 +02:00
}
if ( this . isActives ! = null ) {
2023-10-26 11:07:04 +02:00
CriteriaBuilder . In < IsActive > inClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _isActive ) ) ;
2023-10-24 17:47:13 +02:00
for ( IsActive item : this . isActives )
inClause . value ( item ) ;
predicates . add ( inClause ) ;
}
2023-10-27 17:29:06 +02:00
if ( this . referenceSourceTypes ! = null ) {
CriteriaBuilder . In < ReferenceSourceType > inClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _sourceType ) ) ;
for ( ReferenceSourceType item : this . referenceSourceTypes )
2023-10-24 17:47:13 +02:00
inClause . value ( item ) ;
predicates . add ( inClause ) ;
}
2024-02-08 17:12:47 +01:00
if ( this . typeIds ! = null ) {
CriteriaBuilder . In < UUID > inClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _typeId ) ) ;
for ( UUID item : this . typeIds )
2023-10-24 17:47:13 +02:00
inClause . value ( item ) ;
predicates . add ( inClause ) ;
}
2023-12-13 16:35:29 +01:00
if ( this . references ! = null ) {
CriteriaBuilder . In < String > inClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _reference ) ) ;
for ( String item : this . references )
inClause . value ( item ) ;
predicates . add ( inClause ) ;
}
2024-02-07 16:23:47 +01:00
if ( this . sources ! = null ) {
CriteriaBuilder . In < String > inClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _source ) ) ;
for ( String item : this . sources )
inClause . value ( item ) ;
predicates . add ( inClause ) ;
}
2023-10-24 17:47:13 +02:00
if ( this . excludedIds ! = null ) {
2023-10-26 11:07:04 +02:00
CriteriaBuilder . In < UUID > notInClause = queryContext . CriteriaBuilder . in ( queryContext . Root . get ( ReferenceEntity . _id ) ) ;
2023-10-24 17:47:13 +02:00
for ( UUID item : this . excludedIds )
notInClause . value ( item ) ;
predicates . add ( notInClause . not ( ) ) ;
}
2024-04-12 12:49:13 +02:00
if ( this . after ! = null ) {
Predicate afterClause = queryContext . CriteriaBuilder . greaterThanOrEqualTo ( queryContext . Root . get ( DmpEntity . _createdAt ) , this . after ) ;
predicates . add ( afterClause ) ;
}
2023-12-06 13:18:19 +01:00
if ( this . dmpReferenceQuery ! = null ) {
QueryContext < DmpReferenceEntity , UUID > subQuery = this . applySubQuery ( this . dmpReferenceQuery , queryContext , UUID . class , root - > root . get ( DmpReferenceEntity . _referenceId ) ) ;
predicates . add ( queryContext . CriteriaBuilder . in ( queryContext . Root . get ( DmpReferenceEntity . _id ) ) . value ( subQuery . Query ) ) ;
}
2023-10-24 17:47:13 +02:00
if ( ! predicates . isEmpty ( ) ) {
Predicate [ ] predicatesArray = predicates . toArray ( new Predicate [ 0 ] ) ;
return queryContext . CriteriaBuilder . and ( predicatesArray ) ;
} else {
return null ;
}
}
@Override
2023-10-26 11:07:04 +02:00
protected ReferenceEntity convert ( Tuple tuple , Set < String > columns ) {
ReferenceEntity item = new ReferenceEntity ( ) ;
item . setId ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _id , UUID . class ) ) ;
2024-04-03 12:22:22 +02:00
item . setTenantId ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _tenantId , UUID . class ) ) ;
2023-10-26 11:07:04 +02:00
item . setLabel ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _label , String . class ) ) ;
item . setDescription ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _description , String . class ) ) ;
item . setCreatedAt ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _createdAt , Instant . class ) ) ;
item . setUpdatedAt ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _updatedAt , Instant . class ) ) ;
item . setIsActive ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _isActive , IsActive . class ) ) ;
item . setDefinition ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _definition , String . class ) ) ;
item . setAbbreviation ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _abbreviation , String . class ) ) ;
item . setReference ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _reference , String . class ) ) ;
item . setSource ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _source , String . class ) ) ;
2023-10-30 09:43:50 +01:00
item . setSourceType ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _sourceType , ReferenceSourceType . class ) ) ;
2024-02-08 17:12:47 +01:00
item . setTypeId ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _typeId , UUID . class ) ) ;
2023-11-20 16:09:24 +01:00
item . setCreatedById ( QueryBase . convertSafe ( tuple , columns , ReferenceEntity . _createdById , UUID . class ) ) ;
2023-10-24 17:47:13 +02:00
return item ;
}
@Override
protected String fieldNameOf ( FieldResolver item ) {
2024-04-12 12:49:13 +02:00
if ( item . match ( Reference . _id ) | | item . match ( PublicReference . _id ) )
return ReferenceEntity . _id ;
else if ( item . match ( Reference . _label ) | | item . match ( PublicReference . _label ) )
return ReferenceEntity . _label ;
else if ( item . match ( Reference . _description ) | | item . match ( PublicReference . _description ) )
return ReferenceEntity . _description ;
else if ( item . match ( Reference . _createdAt ) )
return ReferenceEntity . _createdAt ;
else if ( item . match ( Reference . _updatedAt ) )
return ReferenceEntity . _updatedAt ;
else if ( item . match ( Reference . _hash ) )
return ReferenceEntity . _updatedAt ;
else if ( item . match ( Reference . _isActive ) )
return ReferenceEntity . _isActive ;
else if ( item . prefix ( Reference . _definition ) )
return ReferenceEntity . _definition ;
else if ( item . match ( Reference . _abbreviation ) )
return ReferenceEntity . _abbreviation ;
else if ( item . match ( Reference . _reference ) | | item . match ( PublicReference . _reference ) )
return ReferenceEntity . _reference ;
else if ( item . match ( Reference . _source ) )
return ReferenceEntity . _source ;
else if ( item . match ( Reference . _sourceType ) )
return ReferenceEntity . _sourceType ;
else if ( item . match ( Reference . _type ) | | item . match ( PublicReference . _type ) )
return ReferenceEntity . _typeId ;
else if ( item . prefix ( Reference . _type ) | | item . prefix ( PublicReference . _type ) )
return ReferenceEntity . _typeId ;
else if ( item . prefix ( Reference . _createdBy ) )
return ReferenceEntity . _createdById ;
else if ( item . prefix ( Reference . _belongsToCurrentTenant ) )
return ReferenceEntity . _tenantId ;
else
return null ;
2023-10-24 17:47:13 +02:00
}
}