Java tutorial
/** * ***************************************************************************** * This file is part of the EEG-database project * * ========================================== * * Copyright (C) 2013 by University of West Bohemia (http://www.zcu.cz/en/) * * *********************************************************************************************************************** * * 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. * * *********************************************************************************************************************** * * SimpleExperimentDao.java, 2013/10/02 00:01 Jakub Rinkes * **************************************************************************** */ package cz.zcu.kiv.eegdatabase.data.dao; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery; import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.apache.commons.lang.NotImplementedException; import org.elasticsearch.index.query.AndFilterBuilder; import org.elasticsearch.index.query.BoolFilterBuilder; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.NestedFilterBuilder; import org.elasticsearch.index.query.OrFilterBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.hibernate.Query; import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.transaction.annotation.Transactional; import cz.zcu.kiv.eegdatabase.data.nosql.entities.ExperimentElastic; import cz.zcu.kiv.eegdatabase.data.nosql.entities.GenericParameter; import cz.zcu.kiv.eegdatabase.data.pojo.DataFile; import cz.zcu.kiv.eegdatabase.data.pojo.Experiment; import cz.zcu.kiv.eegdatabase.data.pojo.Person; import cz.zcu.kiv.eegdatabase.logic.controller.search.SearchRequest; import cz.zcu.kiv.eegdatabase.logic.util.ControllerUtils; /** * This class extends powers (extend from) class SimpleGenericDao. Class is * determined only for Experiment. * * @author Pavel Bok, A06208 */ public class SimpleExperimentDao extends SimpleGenericDao<Experiment, Integer> implements ExperimentDao { @Autowired private ElasticsearchTemplate elasticsearchTemplate; public SimpleExperimentDao() { super(Experiment.class); } @Override public ElasticsearchTemplate getElasticsearchTemplate() { return elasticsearchTemplate; } public void setElasticsearchTemplate(ElasticsearchTemplate elasticsearchTemplate) { this.elasticsearchTemplate = elasticsearchTemplate; } public List<DataFile> getDataFilesWhereExpId(int experimentId) { String HQLselect = "from DataFile file where file.experiment.experimentId = :experimentId"; return getHibernateTemplate().findByNamedParam(HQLselect, "experimentId", experimentId); } public List<DataFile> getDataFilesWhereId(int dataFileId) { String HQLselect = "from DataFile file where file.dataFileId = :dataFileId"; return getHibernateTemplate().findByNamedParam(HQLselect, "dataFileId", dataFileId); } @Override public int getCountForExperimentsWhereOwner(Person person) { String query = "select count(e) from Experiment e where e.personByOwnerId.personId = :personId"; return ((Long) getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).uniqueResult()).intValue(); } @Override public List<Experiment> getExperimentsWhereOwner(Person person, int limit) { return getExperimentsWhereOwner(person, 0, limit); } @Override public int getCountForExperimentsWhereOwnerOrExperimenter(Person person) { String query = "select count(e) from Experiment e left join e.persons p where e.personByOwnerId.personId = :personId or " + "p.personId = :personId"; return ((Long) getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).uniqueResult()).intValue(); } @Override public List<Experiment> getMyExperiments(Person person, int start, int limit) { String query = "select distinct e from Experiment e left join fetch e.scenario left join fetch e.persons p where e.personByOwnerId.personId = :personId or " + "p.personId = :personId order by e.startTime desc"; return getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).setFirstResult(start).setMaxResults(limit).list(); } @Override public List<Experiment> getMyExperiments(Person person, int limit) { return getMyExperiments(person, 0, limit); } @Override public List<Experiment> getExperimentsWhereOwner(Person person, int start, int limit) { String query = "from Experiment e left join fetch e.scenario where e.personByOwnerId.personId = :personId order by e.startTime desc"; return getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).setFirstResult(start).setMaxResults(limit).list(); } @Override public int getCountForExperimentsWhereSubject(Person person) { String query = "select count(e) from Experiment e where e.personBySubjectPersonId.personId = :personId"; return ((Long) getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).uniqueResult()).intValue(); } @Override public List<Experiment> getExperimentsWhereSubject(Person person, int limit) { return getExperimentsWhereSubject(person, 0, limit); } @Override public List<Experiment> getExperimentsWhereSubject(Person person, int start, int limit) { String query = "from Experiment e left join fetch e.scenario where e.personBySubjectPersonId.personId = :personId order by e.startTime desc"; return getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).setFirstResult(start).setMaxResults(limit).list(); } public Experiment getExperimentForDetail(int experimentId) { String query = "from Experiment e left join fetch e.dataFiles left join fetch e.hardwares left join fetch e.experimentOptParamVals left join fetch e.scenario " + "left join fetch e.weather left join fetch e.projectTypes left join fetch e.diseases left join fetch e.pharmaceuticals pharmaceuticals " + "left join fetch e.softwares left join fetch e.persons left join fetch e.experimentPackageConnections left join fetch e.experimentLicences " + "where e.experimentId = :experimentId"; return (Experiment) getSessionFactory().getCurrentSession().createQuery(query) .setParameter("experimentId", experimentId).uniqueResult(); } public int getCountForAllExperimentsForUser(Person person) { if (person.getAuthority().equals("ROLE_ADMIN")) { String query = "select count(distinct e) from Experiment e " + "left join e.researchGroup.researchGroupMemberships m "; return ((Long) getSessionFactory().getCurrentSession().createQuery(query).uniqueResult()).intValue(); } else { // String query = "select count(distinct e) from Experiment e " + // "left join e.researchGroup.researchGroupMemberships m " + // "where " + // "e.privateExperiment = false " + // "or m.person.personId = :personId"; String query = "select count(distinct epc.experiment) from ExperimentPackageConnection epc, ExperimentPackageLicense epl, " + " PersonalLicense pl where " + "epc.experimentPackage.experimentPackageId = epl.experimentPackage.experimentPackageId and " + "epl.license.licenseId = pl.license.licenseId and " + "pl.person.personId = :personId"; return ((Long) getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).uniqueResult()).intValue(); } } @Override @Transactional public List<Experiment> getAllExperimentsForUser(Person person, int start, int count) { if (person.getAuthority().equals("ROLE_ADMIN")) { String query = "select distinct e from Experiment e join fetch e.scenario s join fetch e.personBySubjectPersonId p " + "left join e.researchGroup.researchGroupMemberships m "; return getSessionFactory().getCurrentSession().createQuery(query).setFirstResult(start) .setMaxResults(count).list(); } else { // String query = "select distinct e from Experiment e join fetch e.scenario s join fetch e.personBySubjectPersonId p " + // "left join e.researchGroup.researchGroupMemberships m " + // "where " + // "e.privateExperiment = false " + // "or m.person.personId = :personId " + // "order by e.startTime desc"; String query = "select distinct e from Experiment e, ExperimentPackageConnection epc, ExperimentPackageLicense epl, PersonalLicense pl " + " join fetch e.scenario s join fetch e.personBySubjectPersonId p " + " where " + "e.experimentId = epc.experiment.experimentId and " + "epc.experimentPackage.experimentPackageId = epl.experimentPackage.experimentPackageId and " + "epl.license.licenseId = pl.license.licenseId and " + "pl.person.personId = :personId " + "order by e.startTime desc"; return getSessionFactory().getCurrentSession().createQuery(query) .setParameter("personId", person.getPersonId()).setFirstResult(start).setMaxResults(count) .list(); } } public List<Experiment> getRecordsNewerThan(int personId) { String HQLselect = "SELECT ex, s FROM Experiment ex LEFT JOIN FETCH ex.scenario s " + "WHERE ex.experimentId IN " + "(SELECT epc.experiment.experimentId from ExperimentPackageConnection epc, ExperimentPackageLicense epl, " + " PersonalLicense pl where " + "epc.experimentPackage.experimentPackageId = epl.experimentPackage.experimentPackageId and " + "epl.license.licenseId = pl.license.licenseId and " + "pl.person.personId = :personId) " + " ORDER BY ex.startTime DESC"; String[] stringParams = { "personId" }; Object[] objectParams = { personId }; return getHibernateTemplate().findByNamedParam(HQLselect, stringParams, objectParams); } public List<Experiment> getExperimentSearchResults(List<SearchRequest> requests, int personId) throws NumberFormatException { List<Experiment> results; boolean ignoreChoice = false; int index = 0; List<Date> datas = new ArrayList<Date>(); String hqlQuery = "from Experiment e left join fetch e.hardwares hw where "; try { for (SearchRequest request : requests) { if (request.getCondition().equals("")) { if (request.getChoice().equals("")) { ignoreChoice = true; } continue; } if (!ignoreChoice) { hqlQuery += request.getChoice(); } if (request.getSource().equals("usedHardware")) { hqlQuery += " (lower(hw.title) like lower('%" + request.getCondition() + "%') or lower(hw.type) like lower('%" + request.getCondition() + "%'))"; } else if (request.getSource().endsWith("Time")) { String[] times = request.getCondition().split(" "); if (times.length == 1) { datas.add(ControllerUtils.getDateFormat().parse(request.getCondition())); } if (times.length > 1) { datas.add(ControllerUtils.getDateFormatWithTime().parse(request.getCondition())); } hqlQuery += "e." + request.getSource() + getCondition(request.getSource()) + " :ts" + index; index++; } else if (request.getSource().startsWith("age")) { hqlQuery += "e.personBySubjectPersonId.dateOfBirth" + getCondition(request.getSource()) + "'" + getPersonYearOfBirth(request.getCondition()) + "'"; } else if (request.getSource().endsWith("gender")) { hqlQuery += "e.personBySubjectPersonId.gender = '" + request.getCondition().toUpperCase().charAt(0) + "'"; } else { hqlQuery += "lower(e." + request.getSource() + ")" + getCondition(request.getSource()) + "lower('%" + request.getCondition() + "%')"; } ignoreChoice = false; } // hqlQuery += " and e.experimentId IN(SELECT e.experimentId FROM Experiment e LEFT JOIN e.researchGroup.researchGroupMemberships membership WHERE e.privateExperiment = false OR membership.person.id = " + personId + ")"; hqlQuery += " and e.experimentId IN(SELECT epc.experiment.experimentId from ExperimentPackageConnection epc, ExperimentPackageLicense epl, " + " PersonalLicense pl where " + "epc.experimentPackage.experimentPackageId = epl.experimentPackage.experimentPackageId and " + "epl.license.licenseId = pl.license.licenseId and " + "pl.person.personId = " + personId + ")"; Session ses = getSession(); Query q = ses.createQuery(hqlQuery); int i = 0; for (Date date : datas) { q.setTimestamp("ts" + i, date); i++; } results = q.list(); } catch (ParseException e) { throw new RuntimeException("Inserted date and time is not in valid format \n" + "Valid format is DD/MM/YYYY HH:MM or DD/MM/YYYY."); } catch (Exception e) { return new ArrayList<Experiment>(); } return results; } @Override public List<Experiment> getVisibleExperiments(int personId, int start, int limit) { // Criteria criteria = getSession().createCriteria(Experiment.class); // criteria.setMaxResults(limit); // criteria.add(Restrictions.ge("experimentId", start)); // criteria.add(Restrictions.or(Restrictions.eq("personByOwnerId.personId", personId), Restrictions.eq("privateExperiment", false))); // return criteria.list(); String query = "select distinct e from Experiment e, ExperimentPackageConnection epc, ExperimentPackageLicense epl, PersonalLicense pl " + " join fetch e.scenario s join fetch e.personBySubjectPersonId p " + " where " + "e.experimentId = epc.experiment.experimentId and " + "epc.experimentPackage.experimentPackageId = epl.experimentPackage.experimentPackageId and " + "epl.license.licenseId = pl.license.licenseId and " + "pl.person.personId = :personId " + "order by e.startTime desc"; return getSessionFactory().getCurrentSession().createQuery(query).setParameter("personId", personId) .setFirstResult(start).setMaxResults(limit).list(); } @Override public int getVisibleExperimentsCount(int personId) { // Criteria criteria = getSession().createCriteria(Experiment.class); // criteria.add(Restrictions.or(Restrictions.eq("personByOwnerId.personId", personId), Restrictions.eq("privateExperiment", false))); // return criteria.list().size(); String query = "select count(distinct epc.experiment) from ExperimentPackageConnection epc, ExperimentPackageLicense epl, " + " PersonalLicense pl where " + "epc.experimentPackage.experimentPackageId = epl.experimentPackage.experimentPackageId and " + "epl.license.licenseId = pl.license.licenseId and " + "pl.person.personId = :personId"; return ((Long) getSessionFactory().getCurrentSession().createQuery(query).setParameter("personId", personId) .uniqueResult()).intValue(); } private String getCondition(String choice) { if (choice.equals("startTime") || (choice.equals("ageMax"))) { return ">="; } if (choice.equals("endTime") || (choice.equals("ageMin"))) { return "<="; } return " like "; } private String getPersonYearOfBirth(String age) throws NumberFormatException { // Create a calendar object with the date of birth Calendar today = Calendar.getInstance(); // Get age based on year int year = Integer.parseInt(age); if (year < 0) { throw new RuntimeException("Invalid age value. It has to be non-negative number"); } int yearOfBirth = today.get(Calendar.YEAR) - year; return today.get(Calendar.DATE) + "-" + (today.get(Calendar.MONTH) + 1) + "-" + yearOfBirth; } @Transactional(readOnly = true) @Override public List<Experiment> getAllRecordsFull() { return super.getAllRecordsFull(); } @Transactional(readOnly = true) private List<Experiment> transformEsResultToHibernate(List<ExperimentElastic> experiments) { List<Integer> ids = new ArrayList<Integer>(); for (ExperimentElastic e : experiments) { ids.add(Integer.parseInt(e.getExperimentId())); } return this.getExperimentsById(ids); } private List<Experiment> getExperimentsById(List<Integer> ids) { if (ids.isEmpty()) { return new ArrayList<Experiment>(); } String query = "from Experiment e where e.experimentId IN ( :ids )"; return getSessionFactory().getCurrentSession().createQuery(query).setParameterList("ids", ids).list(); } @Override @Transactional(readOnly = true) public List<Experiment> searchByParameter(String paramName, String paramValue) { GenericParameter[] p = { new GenericParameter(paramName, paramValue) }; return this.searchByParameters(p); } @Override @Transactional(readOnly = true) public List<Experiment> searchByParameter(String paramName, double paramValue) { GenericParameter[] p = { new GenericParameter(paramName, paramValue) }; return this.searchByParameters(p); } @Override @Transactional(readOnly = true) public List<Experiment> searchByParameterRange(String paramName, int min, int max) { NestedFilterBuilder b = new NestedFilterBuilder("params", rangeQuery("params.valueInteger").from(min).to(max)); SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(b).build(); searchQuery.setPageable(new PageRequest(0, 1000)); List<ExperimentElastic> list = this.elasticsearchTemplate.queryForList(searchQuery, ExperimentElastic.class); return this.transformEsResultToHibernate(list); } @Override @Transactional(readOnly = true) public List<Experiment> searchByParameters(GenericParameter[] params) { GenericParameter[] not = {}; return this.searchByParameters(params, not); } @Override @Transactional(readOnly = true) public List<Experiment> searchByParameters(GenericParameter[] contains, GenericParameter[] notContains) { AndFilterBuilder and = new AndFilterBuilder(); for (GenericParameter p : contains) { BoolQueryBuilder b = new BoolQueryBuilder(); Object value = p.getValueString() == null ? p.getValueInteger() : p.getValueString(); String fieldName = p.getValueString() == null ? "params.valueInteger" : "params.valueString"; b.must(termQuery("params.name", p.getName())).must(matchQuery(fieldName, value)); and.add(new NestedFilterBuilder("params", b)); } for (GenericParameter p : notContains) { BoolQueryBuilder b = new BoolQueryBuilder(); Object value = p.getValueString() == null ? p.getValueInteger() : p.getValueString(); String fieldName = p.getValueString() == null ? "params.valueInteger" : "params.valueString"; b.must(termQuery("params.name", p.getName())).must(matchQuery(fieldName, value)); BoolFilterBuilder not = new BoolFilterBuilder(); not.mustNot(new NestedFilterBuilder("params", b)); and.add(not); } SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(and).build(); searchQuery.setPageable(new PageRequest(0, 1000)); List<ExperimentElastic> list = this.elasticsearchTemplate.queryForList(searchQuery, ExperimentElastic.class); return this.transformEsResultToHibernate(list); } @Override @Transactional(readOnly = true) public List<Experiment> search(String value) { OrFilterBuilder or = new OrFilterBuilder(); or.add(new NestedFilterBuilder("params", new MatchQueryBuilder("params.valueString", value))); or.add(new NestedFilterBuilder("params.attributes", new MatchQueryBuilder("params.attributes.value", value))); SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(or).build(); searchQuery.setPageable(new PageRequest(0, 1000)); List<ExperimentElastic> list = this.elasticsearchTemplate.queryForList(searchQuery, ExperimentElastic.class); return this.transformEsResultToHibernate(list); } @Override @Transactional(readOnly = true) public List<Experiment> searchByAttribute(String attrName, String attrValue) { throw new NotImplementedException(); } @Override public void update(Experiment transientObject) { super.update(transientObject); ExperimentElastic elasticExperiment = transientObject.getElasticExperiment(); IndexQuery indexQuery = new IndexQuery(); elasticExperiment.setExperimentId("" + transientObject.getExperimentId()); elasticExperiment.setUserId(transientObject.getPersonByOwnerId().getPersonId()); elasticExperiment.setGroupId(transientObject.getResearchGroup().getResearchGroupId()); indexQuery.setObject(elasticExperiment); indexQuery.setId("" + transientObject.getExperimentId()); elasticsearchTemplate.index(indexQuery); } @Override public boolean deleteAndCreateExperimentIndexInES() { DeleteQuery dq = new DeleteQuery(); dq.setQuery(QueryBuilders.matchAllQuery()); dq.setIndex(ExperimentElastic.class.getAnnotation(Document.class).indexName()); dq.setType(ExperimentElastic.class.getAnnotation(Document.class).type()); // delete all experiments in index elasticsearchTemplate.delete(dq); // delete index elasticsearchTemplate.deleteIndex(ExperimentElastic.class); // test if index still exists if (elasticsearchTemplate.indexExists(ExperimentElastic.class)) { return false; } // create new index if (!elasticsearchTemplate.createIndex(ExperimentElastic.class)) { return false; } return true; } }