Java tutorial
/*L * Copyright Georgetown University, Washington University. * * Distributed under the OSI-approved BSD 3-Clause License. * See http://ncip.github.com/cab2b/LICENSE.txt for details. */ package edu.wustl.cab2b.server.queryengine; import static edu.wustl.cab2b.common.util.Constants.MMC_ENTITY_GROUP_NAME; import static edu.wustl.cab2b.common.util.Constants.MULTIMODELCATEGORY; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.globus.gsi.GlobusCredential; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cache.EhCache; import edu.common.dynamicextensions.domaininterface.AttributeInterface; import edu.common.dynamicextensions.domaininterface.EntityGroupInterface; import edu.common.dynamicextensions.domaininterface.EntityInterface; import edu.common.dynamicextensions.domaininterface.TaggedValueInterface; import edu.common.dynamicextensions.entitymanager.EntityManager; import edu.wustl.cab2b.common.authentication.util.AuthenticationUtility; import edu.wustl.cab2b.common.cache.AbstractEntityCache; import edu.wustl.cab2b.common.exception.RuntimeException; import edu.wustl.cab2b.common.modelgroup.ModelGroupInterface; import edu.wustl.cab2b.common.queryengine.Cab2bQuery; import edu.wustl.cab2b.common.queryengine.Cab2bQueryObjectFactory; import edu.wustl.cab2b.common.queryengine.ICab2bQuery; import edu.wustl.cab2b.common.queryengine.KeywordQuery; import edu.wustl.cab2b.common.queryengine.KeywordQueryImpl; import edu.wustl.cab2b.common.queryengine.MultiModelCategoryQuery; import edu.wustl.cab2b.common.queryengine.QueryType; import edu.wustl.cab2b.common.queryengine.ServiceGroup; import edu.wustl.cab2b.common.queryengine.ServiceGroupItem; import edu.wustl.cab2b.common.queryengine.result.IQueryResult; import edu.wustl.cab2b.common.queryengine.result.IRecord; import edu.wustl.cab2b.common.util.Utility; import edu.wustl.cab2b.server.cache.DatalistCache; import edu.wustl.cab2b.server.cache.EntityCache; import edu.wustl.cab2b.server.category.CategoryCache; import edu.wustl.cab2b.server.category.PopularCategoryOperations; import edu.wustl.cab2b.server.queryengine.querybuilders.CategoryPreprocessor; import edu.wustl.cab2b.server.queryengine.querybuilders.CategoryPreprocessorResult; import edu.wustl.cab2b.server.queryengine.querybuilders.dcql.ConstraintsBuilder; import edu.wustl.cab2b.server.queryengine.querybuilders.dcql.ConstraintsBuilderResult; import edu.wustl.cab2b.server.queryengine.querybuilders.dcql.constraints.DcqlConstraint; import edu.wustl.cab2b.server.queryengine.querybuilders.dcql.constraints.GroupConstraint; import edu.wustl.cab2b.server.util.UtilityOperations; import edu.wustl.common.hibernate.HibernateDatabaseOperations; import edu.wustl.common.hibernate.HibernateUtil; import edu.wustl.common.querysuite.bizlogic.QueryBizLogic; import edu.wustl.common.querysuite.queryobject.IParameterizedQuery; import edu.wustl.common.querysuite.queryobject.IQueryEntity; import edu.wustl.common.querysuite.queryobject.impl.QueryEntity; import edu.wustl.common.querysuite.utils.ConstraintsObjectBuilder; import edu.wustl.common.util.dbManager.DBUtil; import gov.nih.nci.cagrid.dcql.ForeignAssociation; import gov.nih.nci.cagrid.dcql.Group; //import gov.nih.nci.cagrid.dcql.Object; /** * @author chetan_patil * */ public class QueryOperations extends QueryBizLogic<ICab2bQuery> { private static final Logger logger = Logger.getLogger(QueryOperations.class); /** * This method checks whether the given query name has already been used by the given user or not. * * @see edu.wustl.cab2b.common.ejb.queryengine.QueryEngineBusinessInterface#isQueryNameDuplicate(java.lang.String) * * @param queryName name of the query that is to be verified * @return true if the queryName is duplicate; false if not */ public boolean isQueryNameDuplicate(String queryName, String userName) { boolean isDuplicate = false; Collection<ICab2bQuery> queries = getUsersQueriesDetail(userName); for (IParameterizedQuery query : queries) { if (query.getName().equalsIgnoreCase(queryName)) { isDuplicate = true; break; } } return isDuplicate; } /** * This method returns all the queries created by given user with * only their name, description and created date populated. * * @see edu.wustl.cab2b.common.ejb.queryengine.QueryEngineBusinessInterface#getAllQueryNameAndDescription() * * @param userName * * @return list of IParameterizedQuery having only name, description and created date populated. */ public Collection<ICab2bQuery> getUsersQueriesDetail(String userName) { List<Object> params = new ArrayList<Object>(1); params.add(userName); List<ICab2bQuery> queries = null; try { queries = (List<ICab2bQuery>) Utility.executeHQL("getUserQueriesDetails", params); } catch (HibernateException e) { throw new RuntimeException("Error occured while executing the HQL:" + e.getMessage(), e); } return queries; } /** * This method returns all the regular queries created by the given user. * * @param userName creator/owner of the queries * @return */ public List<ICab2bQuery> getRegularQueriesByUserName(final String userName) { List<Object> params = new ArrayList<Object>(2); params.add(QueryType.ANDed.toString()); params.add(userName); List<ICab2bQuery> queries = null; try { queries = (List<ICab2bQuery>) Utility.executeHQL("getQueriesByTypeAndUserName", params); postProcessMMCQueries(queries); filterSystemGeneratedSubQueries(queries); } catch (HibernateException e) { throw new RuntimeException("Error occured while executing the HQL:" + e.getMessage(), e); } return queries; } /** * This method returns all queries that touch multiple object models. * * @param userName creator/owner of the queries * @return */ public List<ICab2bQuery> getAllMultiModelQueries() { List<ICab2bQuery> allQueries = this.getAllQueries(); postProcessMMCQueries(allQueries); filterSystemGeneratedSubQueries(allQueries); List<ICab2bQuery> regularQueries = new ArrayList<ICab2bQuery>(); for (ICab2bQuery query : allQueries) { if (query.getType().equals(QueryType.ANDed.toString()) && query.getConstraints().getQueryEntities() != null && query.getConstraints().getQueryEntities().size() > 1) { Set<String> models = new HashSet<String>(); for (IQueryEntity entity : query.getConstraints().getQueryEntities()) { models.add(((QueryEntity) entity).getEntityInterface().getEntityGroupCollection().iterator() .next().getName()); } if (models.size() > 1) { regularQueries.add(query); } } } return regularQueries; } /** * This method returns all the keyword search queries created by the given user. * * @param userName creator/owner of the queries * @return */ public List<KeywordQuery> getKeywordQueriesByUserName(final String userName) { List<Object> params = new ArrayList<Object>(1); params.add(userName); List<KeywordQuery> keywordQueries = null; try { keywordQueries = (List<KeywordQuery>) Utility.executeHQL("getKeywordQueriesByUserName", params); } catch (HibernateException e) { throw new RuntimeException("Error occured while executing the HQL:" + e.getMessage(), e); } return keywordQueries; } /** * This method returns all the keyword search queries created by the given user. * * @param userName creator/owner of the queries * @return */ public List<KeywordQuery> getKeywordQueriesByUserId(final Long userId) { List<Object> params = new ArrayList<Object>(1); params.add(userId); List<KeywordQuery> keywordQueries = null; try { keywordQueries = (List<KeywordQuery>) Utility.executeHQL("getKeywordQueriesByUserId", params); postProcessKeywordQueries(keywordQueries); } catch (HibernateException e) { throw new RuntimeException("Error occured while executing the HQL:" + e.getMessage(), e); } return keywordQueries; } /* * (non-Javadoc) * @see edu.wustl.common.querysuite.bizlogic.QueryBizLogic#getQueryById(java.lang.Long) */ public ICab2bQuery getQueryById(Long queryId) { Session session = HibernateUtil.newSession(); ICab2bQuery query = (ICab2bQuery) session.load(Cab2bQuery.class, queryId); if (query != null && query instanceof MultiModelCategoryQuery) { postProcessMMCQuery((MultiModelCategoryQuery) query); } return query; } /** * This method executes the given query and returns the result * @param query * @param serializedDCR * @return */ public IQueryResult<? extends IRecord> executeQuery(ICab2bQuery query, String serializedDCR) { GlobusCredential globusCredential = null; boolean hasAnySecureService = Utility.hasAnySecureService(query); // also test ForeignAssocs for secure services if (!hasAnySecureService) { hasAnySecureService = anySecureServices(query); } if (hasAnySecureService) { globusCredential = AuthenticationUtility.getGlobusCredential(serializedDCR); } //TODO may need to comment popularity for the time being //This is causing connection issues in case of Apply Datalist where client calls EJB in multiple threads //For each thread a new session is created due to ThreadLocal way of getting Session new PopularCategoryOperations().setPopularity(query); QueryExecutor queryExecutor = new QueryExecutor(query, globusCredential); queryExecutor.executeQuery(); return queryExecutor.getCompleteResults(); } /** * This method executes the given query and returns the result * @param query * @param serializedDCR * @return */ public IQueryResult<? extends IRecord> executeQueryForApplyDatalist(ICab2bQuery query, String serializedDCR) { GlobusCredential globusCredential = null; boolean hasAnySecureService = Utility.hasAnySecureService(query); // also test ForeignAssocs for secure services if (!hasAnySecureService) { hasAnySecureService = anySecureServices(query); } if (hasAnySecureService) { globusCredential = AuthenticationUtility.getGlobusCredential(serializedDCR); } QueryExecutor queryExecutor = new QueryExecutor(query, globusCredential); queryExecutor.executeQuery(); return queryExecutor.getCompleteResults(); } /** * This method saves the Cab2bQuery */ public void saveFormQuery(ICab2bQuery query, String serializedDCR) throws RemoteException { Long userId = UtilityOperations.getLocalUserId(serializedDCR); query.setCreatedBy(userId); if (isMultiModelCategoryQuery(query)) { query = new MultimodelCategoryQueryProcessor().process(query); } saveQuery(query); } /** * This method save the given regular query as keyword search query. * * @param query * @throws RemoteException */ public void saveKeywordQuery(ICab2bQuery query, String serializedDCR) throws RemoteException { Long userId = UtilityOperations.getLocalUserId(serializedDCR); query.setCreatedBy(userId); query.setName(query.getName() + "#"); QueryConverter converter = new QueryConverter(); if (isMultiModelCategoryQuery(query)) { query = new MultimodelCategoryQueryProcessor().process(query); MultiModelCategoryQuery mmcQuery = (MultiModelCategoryQuery) query; Collection<ICab2bQuery> subQueries = mmcQuery.getSubQueries(); for (ICab2bQuery subQuery : subQueries) { subQuery.setName(subQuery.getName() + "#"); subQuery = converter.convertToKeywordQuery(subQuery); } } query = converter.convertToKeywordQuery(query); saveInKeywordQuery(query, userId); } public Cab2bQuery addServiceGroupsToQuery(Long queryId, Collection<ServiceGroup> groups) { Session session = HibernateUtil.newSession(); HibernateDatabaseOperations<ServiceGroup> dbopr = new HibernateDatabaseOperations<ServiceGroup>(session); Cab2bQuery query = (Cab2bQuery) session.get(Cab2bQuery.class, queryId); for (ServiceGroup group : groups) { group.setQuery(query); session.persist(group); } query = (Cab2bQuery) session.get(Cab2bQuery.class, queryId); query.getServiceGroups(); session.close(); return query; } public void deleteAllServiceGroups(Long id) { Session session = HibernateUtil.newSession(); Cab2bQuery query = (Cab2bQuery) session.get(Cab2bQuery.class, id); if (query.getServiceGroups() != null && !query.getServiceGroups().isEmpty()) { List<Long> ids = new ArrayList<Long>(); List<Long> itemIds = new ArrayList<Long>(); for (ServiceGroup group : query.getServiceGroups()) { ids.add(group.getId()); for (ServiceGroupItem item : group.getItems()) { itemIds.add(item.getId()); } } if (itemIds.size() > 0) { Query deleteGroups = session.createQuery( "delete ServiceGroupItem where id in (" + StringUtils.join(itemIds.iterator(), ", ") + ")"); deleteGroups.executeUpdate(); } if (ids.size() > 0) { Query deleteQuery = session.createQuery( "delete ServiceGroup where id in (" + StringUtils.join(ids.iterator(), ", ") + ")"); deleteQuery.executeUpdate(); } } } public boolean anySecureServices(ICab2bQuery query) { boolean hasAnySecureService = false; logger.info("JJJ anySecureBack "); // don't need to look inside constraints if category since it has no foreign targets if (Utility.isCategory(query.getOutputEntity())) { return hasAnySecureService; } CategoryPreprocessorResult categoryPreprocessorResult = new CategoryPreprocessor().processCategories(query); ConstraintsBuilder cb = new ConstraintsBuilder(query, categoryPreprocessorResult); ConstraintsBuilderResult cbr = cb.buildConstraints(); DcqlConstraint constraint = cbr.getDcqlConstraintForClass(query.getOutputEntity()); if (constraint.getConstraintType().equals(DcqlConstraint.ConstraintType.Group)) { GroupConstraint gr = (GroupConstraint) constraint; Group[] gr1 = new Group[1]; gr1[0] = gr.getGroup(); Collection<ForeignAssociation> fc = getForeignAssociations(gr1); for (ForeignAssociation forAss : fc) { String furl = forAss.getTargetServiceURL(); if (furl != null) if (furl.trim().toLowerCase().startsWith("https://")) { logger.info("JJJ foreign secure service"); hasAnySecureService = true; break; } } } else { logger.info("JJJ anySecureServices NOT GROUP but:" + constraint.getConstraintType()); } logger.info("JJJ anySecureServices returning:" + hasAnySecureService); return hasAnySecureService; } public void deleteQuery(Long id) { logger.info("id to delete:" + id); Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); try { session.connection().createStatement() .execute("update query_abstract_query set created_by=-1 where identifier=" + id); } catch (Exception e) { logger.error(e); } tx.commit(); session.clear(); session.close(); EntityCache.getCache().refreshCache(); CategoryCache.getInstance().refreshCategoryCache(); UtilityOperations.refreshCache(); } /** * This method saves the given query as a subquery of the appropriate keyword query present in the system. * @param query * @param userId */ private void saveInKeywordQuery(ICab2bQuery query, Long userId) { EntityInterface queryEntity = query.getOutputEntity(); Collection<ModelGroupInterface> modelGroups = UtilityOperations.getModelGroups(queryEntity); List<KeywordQuery> queries = getKeywordQueriesByUserId(userId); List<KeywordQuery> keywordQueries = new ArrayList<KeywordQuery>(modelGroups.size()); for (ModelGroupInterface modelGroup : modelGroups) { boolean isPresent = false; for (KeywordQuery keywordQuery : queries) { String appGroupName = keywordQuery.getApplicationGroup().getModelGroupName(); if (modelGroup.getModelGroupName().equals(appGroupName)) { keywordQueries.add(keywordQuery); isPresent = true; } } if (!isPresent) { KeywordQuery keywordQuery = createAndSaveKeywordQuery(query.getOutputEntity(), modelGroup, userId); keywordQueries.add(keywordQuery); } } try { HibernateDatabaseOperations<KeywordQuery> dbopr = new HibernateDatabaseOperations<KeywordQuery>( DBUtil.currentSession()); for (KeywordQuery keywordQuery : keywordQueries) { keywordQuery.addSubQuery(query); dbopr.update(keywordQuery); } } catch (Exception e) { DBUtil.closeSession(); } } private static Collection<ForeignAssociation> getForeignAssociations(ForeignAssociation faa) { ArrayList<ForeignAssociation> fas = new ArrayList<ForeignAssociation>(); gov.nih.nci.cagrid.dcql.Object fo = faa.getForeignObject(); Group fog = fo.getGroup(); if (fog != null) { Group[] gr1 = new Group[1]; gr1[0] = fog; fas.addAll(getForeignAssociations(gr1)); } ForeignAssociation fofa = fo.getForeignAssociation(); if (fofa != null) { fas.add(fofa); fas.addAll(getForeignAssociations(fofa)); } return fas; } private static Collection<ForeignAssociation> getForeignAssociations(Group[] g) { ArrayList<ForeignAssociation> fas = new ArrayList<ForeignAssociation>(); for (int y = 0; y < g.length; y++) { ForeignAssociation[] faa = g[y].getForeignAssociation(); for (int x = 0; x < faa.length; x++) { fas.add(faa[x]); fas.addAll(getForeignAssociations(faa[x])); } Group[] g2 = g[y].getGroup(); if (g2.length > 0) { fas.addAll(getForeignAssociations(g2)); } } return fas; } /** * This method create and save the keyword query * @param en * @param modelGroup * @param userId * @return */ private KeywordQuery createAndSaveKeywordQuery(EntityInterface en, ModelGroupInterface modelGroup, Long userId) { ConstraintsObjectBuilder queryBuilder = new ConstraintsObjectBuilder( Cab2bQueryObjectFactory.createCab2bQuery()); queryBuilder.addRule(new ArrayList<AttributeInterface>(0), new ArrayList<String>(0), new ArrayList<String>(0), new ArrayList<String>(0), en); ICab2bQuery dummy = (ICab2bQuery) queryBuilder.getQuery(); dummy.setOutputEntity(en); KeywordQuery keywordQuery = new KeywordQueryImpl(dummy); keywordQuery.setName(modelGroup.getModelGroupName() + "_KeywordSearch_" + userId); keywordQuery.setCreatedBy(userId); keywordQuery.setApplicationGroup(modelGroup); keywordQuery.setCreatedDate(new Date()); keywordQuery.setIsSystemGenerated(Boolean.TRUE); keywordQuery.setIsKeywordSearch(Boolean.TRUE); saveQuery(keywordQuery); return keywordQuery; } /** * This method finds whether the given query is designated to be a MultiModelCategoryQuery. * @param query * @return */ private Boolean isMultiModelCategoryQuery(ICab2bQuery query) { EntityInterface outputEntity = query.getOutputEntity(); Boolean isTaggedAsMMC = Boolean.FALSE; for (TaggedValueInterface taggedValue : outputEntity.getTaggedValueCollection()) { if (MULTIMODELCATEGORY.equals(taggedValue.getKey()) && MULTIMODELCATEGORY.equals(taggedValue.getValue())) { isTaggedAsMMC = Boolean.TRUE; break; } } Boolean isMMC = Boolean.FALSE; EntityGroupInterface entityGroup = outputEntity.getEntityGroupCollection().iterator().next(); if (MMC_ENTITY_GROUP_NAME.equals(entityGroup.getName())) { isMMC = Boolean.TRUE; } return isTaggedAsMMC && isMMC; } /** * This method sends the MultiModelCategoryQuery for post processing, which is a child of the keyword query. * @param keywordQueries */ private void postProcessKeywordQueries(Collection<KeywordQuery> keywordQueries) { for (KeywordQuery keywordQuery : keywordQueries) { postProcessMMCQueries(keywordQuery.getSubQueries()); } } /** * This method process the given queries to set the sub-queries as system-generated queires * @param queries */ private void postProcessMMCQueries(Collection<ICab2bQuery> queries) { if (queries != null || !queries.isEmpty()) { for (ICab2bQuery query : queries) { if (query instanceof MultiModelCategoryQuery) { postProcessMMCQuery((MultiModelCategoryQuery) query); } } } } /** * This method process the MMCQuery to set the sub-queries as system-generated queires * @param query */ private void postProcessMMCQuery(MultiModelCategoryQuery mmcQuery) { Collection<ICab2bQuery> subQueries = mmcQuery.getSubQueries(); for (ICab2bQuery subQuery : subQueries) { subQuery.setIsSystemGenerated(Boolean.TRUE); } } /** * This method filters the system generated queries from the collections. * @param queries */ private void filterSystemGeneratedSubQueries(List<ICab2bQuery> queries) { if (queries != null || !queries.isEmpty()) { Iterator<ICab2bQuery> queryIterator = queries.iterator(); while (queryIterator.hasNext()) { ICab2bQuery query = queryIterator.next(); if (query.getIsSystemGenerated()) { queryIterator.remove(); } } } } }