/* * Copyright 2015 herd contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.finra.herd.dao.impl; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import javax.persistence.Tuple; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Join; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Repository; import org.finra.herd.dao.BusinessObjectDefinitionDao; import org.finra.herd.model.api.xml.BusinessObjectDefinitionKey; import org.finra.herd.model.jpa.BusinessObjectDefinitionEntity; import org.finra.herd.model.jpa.BusinessObjectDefinitionEntity_; import org.finra.herd.model.jpa.BusinessObjectDefinitionTagEntity; import org.finra.herd.model.jpa.BusinessObjectDefinitionTagEntity_; import org.finra.herd.model.jpa.NamespaceEntity; import org.finra.herd.model.jpa.NamespaceEntity_; import org.finra.herd.model.jpa.TagEntity; @Repository public class BusinessObjectDefinitionDaoImpl extends AbstractHerdDao implements BusinessObjectDefinitionDao { @Override public List<BusinessObjectDefinitionEntity> getAllBusinessObjectDefinitions() { return getAllBusinessObjectDefinitions(null, null); } @Override public List<BusinessObjectDefinitionEntity> getAllBusinessObjectDefinitions(Integer startPosition, Integer maxResult) { // Create the criteria builder and a tuple style criteria query. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<BusinessObjectDefinitionEntity> criteria = builder.createQuery(BusinessObjectDefinitionEntity.class); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntityRoot = criteria.from(BusinessObjectDefinitionEntity.class); // Join to the other tables we can filter on. Join<BusinessObjectDefinitionEntity, NamespaceEntity> namespaceEntity = businessObjectDefinitionEntityRoot.join(BusinessObjectDefinitionEntity_.namespace); // Get the columns. Path<String> namespaceCodeColumn = namespaceEntity.get(NamespaceEntity_.code); Path<String> businessObjectDefinitionNameColumn = businessObjectDefinitionEntityRoot.get(BusinessObjectDefinitionEntity_.name); // Add all clauses to the query. criteria.select(businessObjectDefinitionEntityRoot).orderBy(builder.asc(businessObjectDefinitionNameColumn), builder.asc(namespaceCodeColumn)); // Get an instance of the query ready for execution. TypedQuery<BusinessObjectDefinitionEntity> query = entityManager.createQuery(criteria); // If start position is specified, set it for the query. if (startPosition != null) { query.setFirstResult(startPosition.intValue()); } // If start position is specified, set it for the query. if (maxResult != null) { query.setMaxResults(maxResult.intValue()); } // Execute the query and return the results. return query.getResultList(); } @Override public List<BusinessObjectDefinitionEntity> getAllBusinessObjectDefinitionsByIds(List<Integer> ids) { // Create the criteria builder and a tuple style criteria query. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<BusinessObjectDefinitionEntity> criteria = builder.createQuery(BusinessObjectDefinitionEntity.class); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntityRoot = criteria.from(BusinessObjectDefinitionEntity.class); // Create the standard restrictions (i.e. the standard where clauses). Expression<Integer> expression = businessObjectDefinitionEntityRoot.get(BusinessObjectDefinitionEntity_.id); Predicate queryRestriction = expression.in(ids); criteria.select(businessObjectDefinitionEntityRoot).where(queryRestriction); return entityManager.createQuery(criteria).getResultList(); } @Override public BusinessObjectDefinitionEntity getBusinessObjectDefinitionByKey(BusinessObjectDefinitionKey businessObjectDefinitionKey) { // Create the criteria builder and the criteria. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<BusinessObjectDefinitionEntity> criteria = builder.createQuery(BusinessObjectDefinitionEntity.class); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntity = criteria.from(BusinessObjectDefinitionEntity.class); // Join to the other tables we can filter on. Join<BusinessObjectDefinitionEntity, NamespaceEntity> namespaceEntity = businessObjectDefinitionEntity.join(BusinessObjectDefinitionEntity_.namespace); // Create the standard restrictions (i.e. the standard where clauses). Predicate queryRestriction = builder.equal(builder.upper(namespaceEntity.get(NamespaceEntity_.code)), businessObjectDefinitionKey.getNamespace().toUpperCase()); queryRestriction = builder.and(queryRestriction, builder.equal(builder.upper(businessObjectDefinitionEntity.get(BusinessObjectDefinitionEntity_.name)), businessObjectDefinitionKey.getBusinessObjectDefinitionName().toUpperCase())); criteria.select(businessObjectDefinitionEntity).where(queryRestriction); return executeSingleResultQuery(criteria, String .format("Found more than one business object definition with parameters {namespace=\"%s\", businessObjectDefinitionName=\"%s\"}.", businessObjectDefinitionKey.getNamespace(), businessObjectDefinitionKey.getBusinessObjectDefinitionName())); } @Override public List<BusinessObjectDefinitionKey> getBusinessObjectDefinitionKeys() { return getBusinessObjectDefinitionKeysByNamespace(null); } @Override public List<BusinessObjectDefinitionKey> getBusinessObjectDefinitionKeysByNamespace(String namespaceCode) { // Create the criteria builder and a tuple style criteria query. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Tuple> criteria = builder.createTupleQuery(); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntity = criteria.from(BusinessObjectDefinitionEntity.class); // Join to the other tables we can filter on. Join<BusinessObjectDefinitionEntity, NamespaceEntity> namespaceEntity = businessObjectDefinitionEntity.join(BusinessObjectDefinitionEntity_.namespace); // Get the columns. Path<String> namespaceCodeColumn = namespaceEntity.get(NamespaceEntity_.code); Path<String> businessObjectDefinitionNameColumn = businessObjectDefinitionEntity.get(BusinessObjectDefinitionEntity_.name); // Add the select clause. criteria.multiselect(namespaceCodeColumn, businessObjectDefinitionNameColumn); // If namespace code is specified, add the where clause. if (StringUtils.isNotBlank(namespaceCode)) { criteria.where(builder.equal(builder.upper(namespaceEntity.get(NamespaceEntity_.code)), namespaceCode.toUpperCase())); } // Add the order by clause. if (StringUtils.isNotBlank(namespaceCode)) { criteria.orderBy(builder.asc(businessObjectDefinitionNameColumn)); } else { criteria.orderBy(builder.asc(businessObjectDefinitionNameColumn), builder.asc(namespaceCodeColumn)); } // Run the query to get a list of tuples back. List<Tuple> tuples = entityManager.createQuery(criteria).getResultList(); // Populate the "keys" objects from the returned tuples (i.e. 1 tuple for each row). List<BusinessObjectDefinitionKey> businessObjectDefinitionKeys = new ArrayList<>(); for (Tuple tuple : tuples) { BusinessObjectDefinitionKey businessObjectDefinitionKey = new BusinessObjectDefinitionKey(); businessObjectDefinitionKeys.add(businessObjectDefinitionKey); businessObjectDefinitionKey.setNamespace(tuple.get(namespaceCodeColumn)); businessObjectDefinitionKey.setBusinessObjectDefinitionName(tuple.get(businessObjectDefinitionNameColumn)); } return businessObjectDefinitionKeys; } @Override public List<BusinessObjectDefinitionEntity> getBusinessObjectDefinitions(List<TagEntity> tagEntities) { // Create the criteria builder and a tuple style criteria query. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<BusinessObjectDefinitionEntity> criteria = builder.createQuery(BusinessObjectDefinitionEntity.class); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntityRoot = criteria.from(BusinessObjectDefinitionEntity.class); // Join to the other tables we can filter on. Join<BusinessObjectDefinitionEntity, NamespaceEntity> namespaceEntity = businessObjectDefinitionEntityRoot.join(BusinessObjectDefinitionEntity_.namespace); // Get the columns. Path<String> namespaceCodeColumn = namespaceEntity.get(NamespaceEntity_.code); Path<String> businessObjectDefinitionNameColumn = businessObjectDefinitionEntityRoot.get(BusinessObjectDefinitionEntity_.name); Predicate predicate; if (!CollectionUtils.isEmpty(tagEntities)) { //join the business object definition tags Join<BusinessObjectDefinitionEntity, BusinessObjectDefinitionTagEntity> businessObjectDefinitionTagEntityJoin = businessObjectDefinitionEntityRoot.join(BusinessObjectDefinitionEntity_.businessObjectDefinitionTags); // Create the standard restrictions (i.e. the standard where clauses). predicate = getPredicateForInClause(builder, businessObjectDefinitionTagEntityJoin.get(BusinessObjectDefinitionTagEntity_.tag), tagEntities); // Add all clauses to the query. criteria.select(businessObjectDefinitionEntityRoot).where(predicate) .orderBy(builder.asc(businessObjectDefinitionNameColumn), builder.asc(namespaceCodeColumn)); } else { criteria.select(businessObjectDefinitionEntityRoot).orderBy(builder.asc(businessObjectDefinitionNameColumn), builder.asc(namespaceCodeColumn)); } //Returns duplicate business object definition. When a bdef is associated with multiple tags. return entityManager.createQuery(criteria).getResultList(); } @Override public List<BusinessObjectDefinitionEntity> getPercentageOfAllBusinessObjectDefinitions(double percentage) { // Create the criteria builder and a tuple style criteria query. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Integer> criteria = builder.createQuery(Integer.class); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntityRoot = criteria.from(BusinessObjectDefinitionEntity.class); // Get the columns. Path<Integer> idColumn = businessObjectDefinitionEntityRoot.get(BusinessObjectDefinitionEntity_.id); criteria.select(idColumn); List<Integer> allBusinessObjectDefinitionIdsList = entityManager.createQuery(criteria).getResultList(); List<Integer> percentageOfBusinessObjectDefinitionIdsList = new ArrayList<>(); /* * Gets a percentage of all business object definition entities. * The percentage is randomly selected from all the business object definitions. * * For each business object id in the list of all business object definition ids, get a random double value between 0 and 1. * If that value is below the percentage double value, also a number between 0 and 1 (inclusive), * then add the business object id to the list of business object definition ids that will be used to return a random percentage * of business object definition entities retrieved from the database. */ allBusinessObjectDefinitionIdsList.forEach(id -> { if (ThreadLocalRandom.current().nextDouble() < percentage) { percentageOfBusinessObjectDefinitionIdsList.add(id); } }); return getAllBusinessObjectDefinitionsByIds(percentageOfBusinessObjectDefinitionIdsList); } @Override public List<BusinessObjectDefinitionEntity> getMostRecentBusinessObjectDefinitions(int numberOfResults) { // Create the criteria builder and a tuple style criteria query. CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<BusinessObjectDefinitionEntity> criteria = builder.createQuery(BusinessObjectDefinitionEntity.class); // The criteria root is the business object definition. Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntityRoot = criteria.from(BusinessObjectDefinitionEntity.class); // Get the columns. Path<Timestamp> businessObjectDefinitionUpdatedOnColumn = businessObjectDefinitionEntityRoot.get(BusinessObjectDefinitionEntity_.updatedOn); // Select the business object definitions and order descending by the updated on column criteria.select(businessObjectDefinitionEntityRoot).orderBy(builder.desc(businessObjectDefinitionUpdatedOnColumn)); return entityManager.createQuery(criteria).setMaxResults(numberOfResults).getResultList(); } @Override public long getCountOfAllBusinessObjectDefinitions() { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Long> criteria = builder.createQuery(Long.class); Root<BusinessObjectDefinitionEntity> businessObjectDefinitionEntityRoot = criteria.from(BusinessObjectDefinitionEntity.class); criteria.select(builder.count(businessObjectDefinitionEntityRoot)); return entityManager.createQuery(criteria).getSingleResult(); } }