Skip to content

Instantly share code, notes, and snippets.

@walshe
Created July 3, 2014 16:51
Show Gist options
  • Save walshe/99a470930ea5297ea838 to your computer and use it in GitHub Desktop.
Save walshe/99a470930ea5297ea838 to your computer and use it in GitHub Desktop.
More Specs
import com.cassidian.ip.data.*
import com.cassidian.ip.data.repository.specification.*
import com.cassidian.ip.data.repository.specification.util.JoinBuilder
import groovy.util.logging.Slf4j
import org.springframework.data.jpa.domain.Specification
import javax.persistence.criteria.CriteriaBuilder
import javax.persistence.criteria.CriteriaQuery
import javax.persistence.criteria.Join
import javax.persistence.criteria.JoinType
import javax.persistence.criteria.Predicate
import javax.persistence.criteria.Root
import javax.persistence.criteria.Subquery
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Sort
import org.springframework.data.jpa.domain.Specification
import org.springframework.data.jpa.domain.Specifications
import org.apache.log4j.Level
import org.apache.log4j.Logger
Logger.getLogger('org.hibernate.SQL').level = Level.toLevel('debug')
/**
* gets all affected orgs of an event i.e. union of all its activationScenario.affectedGeographicArea's
*/
class AffectedGeographicalAreaOfEventSpec extends JoinBuilder implements Specification {
long eventId
AffectedGeographicalAreaOfEventSpec(long eventId) {
this.eventId = eventId
}
@Override
Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Subquery<Event> eventQuery = query.subquery(Event)
Root<Event> eventRoot = eventQuery.from(Event)
eventQuery.select(
eventRoot.join("activationScenarios")
).where(
cb.equal(eventRoot.get("id"), eventId)
)
Subquery<ActivationScenario> activationScenariosQuery = query.subquery(ActivationScenario)
Root<ActivationScenario> activationScenariosRoot = activationScenariosQuery.from(ActivationScenario)
activationScenariosQuery.select(
activationScenariosRoot.join("affectedGeographicArea")
).where(
cb.in(activationScenariosRoot, eventQuery)
)
cb.in(root, activationScenariosQuery)
}
}
class UserJurisdictionIntersectsAffectedGeographicalAreaOfEventSpec extends JoinBuilder implements Specification<Organization> {
long userOrganizationId
long eventId
UserJurisdictionIntersectsAffectedGeographicalAreaOfEventSpec(long userOrganizationId, long eventId) {
this.userOrganizationId = userOrganizationId
this.eventId = eventId
}
Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
Subquery<Organization> orgQuery = query.subquery(Organization)
Root<Organization> orgRoot = orgQuery.from(Organization)
orgQuery.select(
root.get("id")
).where(new AffectedGeographicalAreaOfEventSpec(eventId).toPredicate(root, query, cb))
Subquery<Organization> q = query.subquery(Organization)
Root<Organization> r = q.from(Organization)
q.select(
r.get("id")
).where(cb.or(
new OrganizationAndDescendants(userOrganizationId).toPredicate(root, query, cb),
new SharedOrganizationsAndDescendants(userOrganizationId).toPredicate(root, query, cb)
))
return cb.and(
cb.in(root.get("id"), orgQuery),
cb.in(root.get("id"), q)
)
}
}
class NewOrganizationsByUserJurisdiction implements Specification<Organization> {
/**
* User's organizationId
*/
Long userOrganizationId
NewOrganizationsByUserJurisdiction(Long userOrganizationId) {
this.userOrganizationId = userOrganizationId
}
@Override
Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.or(
new NewOrganizationAndDescendants(userOrganizationId).toPredicate(root, query, cb),
new NewSharedOrganizationsAndDescendants(userOrganizationId).toPredicate(root, query, cb)
)
return predicate
}
}
class NewOrganizationAndDescendants implements Specification<Organization> {
/**
* ancestor organization id
*/
private Long ancestorOrganizationId
NewOrganizationAndDescendants(Long ancestorOrganizationId) {
this.ancestorOrganizationId = ancestorOrganizationId
}
@Override
Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Subquery<Organization> orgQuery = query.subquery(Organization)
Root<Organization> orgRoot = orgQuery.from(Organization)
Join ancestors = orgRoot.join("ancestors", JoinType.LEFT)
orgQuery.select(orgRoot.get("id")).where(
cb.or(
cb.equal(orgRoot.get("id"),cb.literal(ancestorOrganizationId)),//user's organization
cb.in(ancestors).value(cb.literal(ancestorOrganizationId)),//descendants of user's organization
)
)
return cb.in(root.get("id"), orgQuery)
}
}
class NewSharedOrganizationsAndDescendants implements Specification<Organization> {
/**
* The id of the organization that receives the shared resources from all its Shared Organizations
*/
private Long receivingOrganizationId
NewSharedOrganizationsAndDescendants(Long receivingOrganizationId) {
this.receivingOrganizationId = receivingOrganizationId
}
@Override
Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//Shared organizations
Subquery<OrganizationSharing> orgSharingQuery = query.subquery(OrganizationSharing)
Root<OrganizationSharing> orgSharingRoot = orgSharingQuery.from(OrganizationSharing)
orgSharingQuery.select(orgSharingRoot.get("shared"))
.where(cb.equal(orgSharingRoot.get("master"), cb.literal(receivingOrganizationId)))
//Descendants of shared organizations
Subquery<Organization> descendantsQuery = query.subquery(Organization)
Root<Organization> descendantsRoot = descendantsQuery.from(Organization)
Join ancestors = descendantsRoot.join("ancestors", JoinType.LEFT)
descendantsQuery.select(descendantsRoot.get("id"))
.where(cb.in(ancestors).value(orgSharingQuery))
return cb.or(
cb.in(root.get("id")).value(orgSharingQuery),
cb.in(root.get("id")).value(descendantsQuery)
)
}
}
def time = System.currentTimeMillis()
//def usersJurisdiction = ctx.organizationRepository.findAll(Specifications.where(new OrganizationsByUserJurisdiction(21624L))).collect{it.id}.toSet()
//def geoAre = ctx.organizationRepository.findAll(Specifications.where(new AffectedGeographicalAreaOfEventSpec( 59660L))).collect{it.id}.toSet()
//ctx.organizationRepository.count(Specifications.where(new OrganizationsByUserJurisdiction(21621L))); //takes LONG
//ctx.organizationRepository.count(Specifications.where(new OrganizationsByUserJurisdiction(21624L))); //faster
def usersJurisdiction = ctx.organizationRepository.findAll(Specifications.where(new NewOrganizationsByUserJurisdiction(21624L))); //faster
println "jur: ${usersJurisdiction.size()} }"
//println "geoa: ${geoAre.size()} }"
//println "interset : ${usersJurisdiction.intersect(geoAre).size()}"
//ctx.organizationRepository.count(Specifications.where(new UserJurisdictionIntersectsAffectedGeographicalAreaOfEventSpec( 21621L,59660L)))
//print ctx.organizationRepository.count(Specifications.where(new UserJurisdictionIntersectsAffectedGeographicalAreaOfEventSpec( 21624L,59660L)))
time = System.currentTimeMillis() - time
println "took ${time}"
//ctx.organizationRepository.count(Specifications.where(new AffectedGeographicalAreaOfEventSpec( 59660L)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment