Fixed name/specimen type designation status mapping
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / name / TaxonNameDaoHibernateImpl.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 *
9 */
10 package eu.etaxonomy.cdm.persistence.dao.hibernate.name;
11
12 import java.util.List;
13
14 import org.apache.log4j.Logger;
15 import org.hibernate.Criteria;
16 import org.hibernate.Query;
17 import org.hibernate.criterion.Criterion;
18 import org.hibernate.criterion.Order;
19 import org.hibernate.criterion.Projections;
20 import org.hibernate.criterion.Restrictions;
21 import org.hibernate.envers.query.AuditEntity;
22 import org.hibernate.envers.query.AuditQuery;
23 import org.springframework.beans.factory.annotation.Qualifier;
24 import org.springframework.stereotype.Repository;
25
26 import eu.etaxonomy.cdm.model.common.RelationshipBase;
27 import eu.etaxonomy.cdm.model.name.BotanicalName;
28 import eu.etaxonomy.cdm.model.name.HybridRelationship;
29 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
30 import eu.etaxonomy.cdm.model.name.NameRelationship;
31 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
32 import eu.etaxonomy.cdm.model.name.NonViralName;
33 import eu.etaxonomy.cdm.model.name.Rank;
34 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
35 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
36 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
37 import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
38 import eu.etaxonomy.cdm.model.view.AuditEvent;
39 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
40 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
41 import eu.etaxonomy.cdm.persistence.query.MatchMode;
42 import eu.etaxonomy.cdm.persistence.query.OrderHint;
43
44 /**
45 * @author a.mueller
46 *
47 */
48 @Repository
49 @Qualifier("taxonNameDaoHibernateImpl")
50 public class TaxonNameDaoHibernateImpl
51 extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
52
53 @SuppressWarnings("unused")
54 private static final Logger logger = Logger.getLogger(TaxonNameDaoHibernateImpl.class);
55
56 public TaxonNameDaoHibernateImpl() {
57 super(TaxonNameBase.class);
58 }
59
60 public int countHybridNames(BotanicalName name, HybridRelationshipType type) {
61 AuditEvent auditEvent = getAuditEventFromContext();
62 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
63 Query query = null;
64 if(type == null) {
65 query = getSession().createQuery("select count(relation) from HybridRelationship relation where relation.relatedFrom = :name");
66 } else {
67 query = getSession().createQuery("select count(relation) from HybridRelationship relation where relation.relatedFrom = :name and relation.type = :type");
68 query.setParameter("type", type);
69 }
70 query.setParameter("name",name);
71 return ((Long)query.uniqueResult()).intValue();
72 } else {
73 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(HybridRelationship.class,auditEvent.getRevisionNumber());
74 query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));
75 query.addProjection(AuditEntity.id().count("id"));
76
77 if(type != null) {
78 query.add(AuditEntity.relatedId("type").eq(type.getId()));
79 }
80
81 return ((Long)query.getSingleResult()).intValue();
82 }
83 }
84
85 public int countNames(String queryString) {
86 checkNotInPriorView("TaxonNameDaoHibernateImpl.countNames(String queryString)");
87 Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
88
89 if (queryString != null) {
90 criteria.add(Restrictions.ilike("nameCache", queryString));
91 }
92 criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
93
94 return (Integer)criteria.uniqueResult();
95 }
96
97 public int countNames(String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank) {
98 AuditEvent auditEvent = getAuditEventFromContext();
99 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
100 Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
101
102 /**
103 * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"
104 * We need to convert nulls to NullRestrictions for now
105 */
106 if(genusOrUninomial != null) {
107 criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));
108 } else {
109 criteria.add(Restrictions.isNull("genusOrUninomial"));
110 }
111
112 if(infraGenericEpithet != null) {
113 criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));
114 } else {
115 criteria.add(Restrictions.isNull("infraGenericEpithet"));
116 }
117
118 if(specificEpithet != null) {
119 criteria.add(Restrictions.eq("specificEpithet", specificEpithet));
120 } else {
121 criteria.add(Restrictions.isNull("specificEpithet"));
122 }
123
124 if(infraSpecificEpithet != null) {
125 criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));
126 } else {
127 criteria.add(Restrictions.isNull("infraSpecificEpithet"));
128 }
129
130 if(rank != null) {
131 criteria.add(Restrictions.eq("rank", rank));
132 }
133
134 criteria.setProjection(Projections.rowCount());
135 return (Integer)criteria.uniqueResult();
136 } else {
137 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameBase.class,auditEvent.getRevisionNumber());
138
139 if(genusOrUninomial != null) {
140 query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));
141 } else {
142 query.add(AuditEntity.property("genusOrUninomial").isNull());
143 }
144
145 if(infraGenericEpithet != null) {
146 query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));
147 } else {
148 query.add(AuditEntity.property("infraGenericEpithet").isNull());
149 }
150
151 if(specificEpithet != null) {
152 query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));
153 } else {
154 query.add(AuditEntity.property("specificEpithet").isNull());
155 }
156
157 if(infraSpecificEpithet != null) {
158 query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));
159 } else {
160 query.add(AuditEntity.property("infraSpecificEpithet").isNull());
161 }
162
163 if(rank != null) {
164 query.add(AuditEntity.relatedId("rank").eq(rank.getId()));
165 }
166
167 query.addProjection(AuditEntity.id().count("id"));
168 return ((Long)query.getSingleResult()).intValue();
169 }
170 }
171
172 public int countRelatedNames(TaxonNameBase name, NameRelationshipType type) {
173 AuditEvent auditEvent = getAuditEventFromContext();
174 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
175 Query query = null;
176 if(type == null) {
177 query = getSession().createQuery("select count(relation) from NameRelationship relation where relation.relatedFrom = :name");
178 } else {
179 query = getSession().createQuery("select count(relation) from NameRelationship relation where relation.relatedFrom = :name and relation.type = :type");
180 query.setParameter("type", type);
181 }
182 query.setParameter("name",name);
183 return ((Long)query.uniqueResult()).intValue();
184 } else {
185 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());
186 query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));
187 query.addProjection(AuditEntity.id().count("id"));
188
189 if(type != null) {
190 query.add(AuditEntity.relatedId("type").eq(type.getId()));
191 }
192
193 return ((Long)query.getSingleResult()).intValue();
194 }
195 }
196
197 public int countTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status) {
198 AuditEvent auditEvent = getAuditEventFromContext();
199 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
200 Query query = null;
201 if(status == null) {
202 query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name");
203 } else {
204 query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name and designation.typeStatus = :status");
205 query.setParameter("status", status);
206 }
207 query.setParameter("name",name);
208 return ((Long)query.uniqueResult()).intValue();
209 } else {
210 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TypeDesignationBase.class,auditEvent.getRevisionNumber());
211 query.add(AuditEntity.relatedId("typifiedNames").eq(name.getId()));
212 query.addProjection(AuditEntity.id().count("id"));
213
214 if(type != null) {
215 query.add(AuditEntity.relatedId("typeStatus").eq(status.getId()));
216 }
217
218 return ((Long)query.getSingleResult()).intValue();
219 }
220 }
221
222 public List<HybridRelationship> getHybridNames(BotanicalName name, HybridRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
223 AuditEvent auditEvent = getAuditEventFromContext();
224 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
225 Criteria criteria = getSession().createCriteria(HybridRelationship.class);
226 criteria.add(Restrictions.eq("relatedFrom", name));
227 if(type != null) {
228 criteria.add(Restrictions.eq("type", type));
229 }
230
231 if(pageSize != null) {
232 criteria.setMaxResults(pageSize);
233 if(pageNumber != null) {
234 criteria.setFirstResult(pageNumber * pageSize);
235 } else {
236 criteria.setFirstResult(0);
237 }
238 }
239
240 addOrder(criteria, orderHints);
241
242 List<HybridRelationship> results = (List<HybridRelationship>)criteria.list();
243 defaultBeanInitializer.initializeAll(results, propertyPaths);
244 return results;
245 } else {
246 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(HybridRelationship.class,auditEvent.getRevisionNumber());
247 query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));
248
249 if(type != null) {
250 query.add(AuditEntity.relatedId("type").eq(type.getId()));
251 }
252
253 if(pageSize != null) {
254 query.setMaxResults(pageSize);
255 if(pageNumber != null) {
256 query.setFirstResult(pageNumber * pageSize);
257 } else {
258 query.setFirstResult(0);
259 }
260 }
261
262 List<HybridRelationship> results = (List<HybridRelationship>)query.getResultList();
263 defaultBeanInitializer.initializeAll(results, propertyPaths);
264 return results;
265 }
266 }
267
268 public List<NameRelationship> getRelatedNames(TaxonNameBase name, NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
269 AuditEvent auditEvent = getAuditEventFromContext();
270 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
271 Criteria criteria = getSession().createCriteria(NameRelationship.class);
272 criteria.add(Restrictions.eq("relatedFrom", name));
273 if(type != null) {
274 criteria.add(Restrictions.eq("type", type));
275 }
276
277 if(pageSize != null) {
278 criteria.setMaxResults(pageSize);
279 if(pageNumber != null) {
280 criteria.setFirstResult(pageNumber * pageSize);
281 } else {
282 criteria.setFirstResult(0);
283 }
284 }
285 addOrder(criteria, orderHints);
286
287 List<NameRelationship> results = (List<NameRelationship>)criteria.list();
288 defaultBeanInitializer.initializeAll(results, propertyPaths);
289 return results;
290 } else {
291 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());
292 query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));
293
294 if(type != null) {
295 query.add(AuditEntity.relatedId("type").eq(type.getId()));
296 }
297
298 if(pageSize != null) {
299 query.setMaxResults(pageSize);
300 if(pageNumber != null) {
301 query.setFirstResult(pageNumber * pageSize);
302 } else {
303 query.setFirstResult(0);
304 }
305 }
306
307 List<NameRelationship> results = (List<NameRelationship>)query.getResultList();
308 defaultBeanInitializer.initializeAll(results, propertyPaths);
309 return results;
310 }
311 }
312
313 public List<TypeDesignationBase> getTypeDesignations(TaxonNameBase name,
314 TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber) {
315 return getTypeDesignations(name, status, pageSize, pageNumber, null);
316 }
317
318 public List<TypeDesignationBase> getTypeDesignations(TaxonNameBase name,
319 TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,
320 List<String> propertyPaths){
321 AuditEvent auditEvent = getAuditEventFromContext();
322 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
323 Query query = null;
324 if(status == null) {
325 query = getSession().createQuery("select designation from TypeDesignationBase designation join designation.typifiedNames name where name = :name");
326 } else {
327 query = getSession().createQuery("select designation from TypeDesignationBase designation join designation.typifiedNames name where name = :name and designation.typeStatus = :status");
328 query.setParameter("status", status);
329 }
330 query.setParameter("name",name);
331
332 if(pageSize != null) {
333 query.setMaxResults(pageSize);
334 if(pageNumber != null) {
335 query.setFirstResult(pageNumber * pageSize);
336 } else {
337 query.setFirstResult(0);
338 }
339 }
340 return defaultBeanInitializer.initializeAll((List<TypeDesignationBase>)query.list(), propertyPaths);
341 } else {
342 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TypeDesignationBase.class,auditEvent.getRevisionNumber());
343 query.add(AuditEntity.relatedId("typifiedNames").eq(name.getId()));
344
345 if(type != null) {
346 query.add(AuditEntity.relatedId("typeStatus").eq(status.getId()));
347 }
348
349 if(pageSize != null) {
350 query.setMaxResults(pageSize);
351 if(pageNumber != null) {
352 query.setFirstResult(pageNumber * pageSize);
353 } else {
354 query.setFirstResult(0);
355 }
356 }
357
358 return (List<TypeDesignationBase>)query.getResultList();
359 }
360 }
361
362
363 public List<TaxonNameBase<?,?>> searchNames(String queryString, MatchMode matchMode, Integer pageSize, Integer pageNumber) {
364 checkNotInPriorView("TaxonNameDaoHibernateImpl.searchNames(String queryString, Integer pageSize, Integer pageNumber)");
365 Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
366
367 if (queryString != null) {
368 criteria.add(Restrictions.ilike("nameCache", queryString));
369 }
370 if(pageSize != null) {
371 criteria.setMaxResults(pageSize);
372 if(pageNumber != null) {
373 criteria.setFirstResult(pageNumber * pageSize);
374 } else {
375 criteria.setFirstResult(0);
376 }
377 }
378 List<TaxonNameBase<?,?>> results = criteria.list();
379 return results;
380 }
381
382
383 public List<TaxonNameBase<?,?>> searchNames(String queryString, Integer pageSize, Integer pageNumber) {
384 return searchNames(queryString, MatchMode.BEGINNING, pageSize, pageNumber);
385 }
386
387
388 public List<TaxonNameBase> searchNames(String genusOrUninomial,String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
389 AuditEvent auditEvent = getAuditEventFromContext();
390 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
391 Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
392
393 /**
394 * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"
395 * We need to convert nulls to NullRestrictions for now
396 */
397 if(genusOrUninomial != null) {
398 criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));
399 } else {
400 criteria.add(Restrictions.isNull("genusOrUninomial"));
401 }
402
403 if(infraGenericEpithet != null) {
404 criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));
405 } else {
406 criteria.add(Restrictions.isNull("infraGenericEpithet"));
407 }
408
409 if(specificEpithet != null) {
410 criteria.add(Restrictions.eq("specificEpithet", specificEpithet));
411 } else {
412 criteria.add(Restrictions.isNull("specificEpithet"));
413 }
414
415 if(infraSpecificEpithet != null) {
416 criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));
417 } else {
418 criteria.add(Restrictions.isNull("infraSpecificEpithet"));
419 }
420
421 if(rank != null) {
422 criteria.add(Restrictions.eq("rank", rank));
423 }
424
425 if(pageSize != null) {
426 criteria.setMaxResults(pageSize);
427 if(pageNumber != null) {
428 criteria.setFirstResult(pageNumber * pageSize);
429 } else {
430 criteria.setFirstResult(0);
431 }
432 }
433
434 return (List<TaxonNameBase>)criteria.list();
435 } else {
436 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameBase.class,auditEvent.getRevisionNumber());
437
438 if(genusOrUninomial != null) {
439 query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));
440 } else {
441 query.add(AuditEntity.property("genusOrUninomial").isNull());
442 }
443
444 if(infraGenericEpithet != null) {
445 query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));
446 } else {
447 query.add(AuditEntity.property("infraGenericEpithet").isNull());
448 }
449
450 if(specificEpithet != null) {
451 query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));
452 } else {
453 query.add(AuditEntity.property("specificEpithet").isNull());
454 }
455
456 if(infraSpecificEpithet != null) {
457 query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));
458 } else {
459 query.add(AuditEntity.property("infraSpecificEpithet").isNull());
460 }
461
462 if(rank != null) {
463 query.add(AuditEntity.relatedId("rank").eq(rank.getId()));
464 }
465
466 if(pageSize != null) {
467 query.setMaxResults(pageSize);
468 if(pageNumber != null) {
469 query.setFirstResult(pageNumber * pageSize);
470 } else {
471 query.setFirstResult(0);
472 }
473 }
474
475 return (List<TaxonNameBase>)query.getResultList();
476 }
477 }
478
479 public List<? extends TaxonNameBase<?,?>> findByName(String queryString,
480 MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria) {
481
482 Criteria crit = getSession().createCriteria(type);
483 if (matchmode == MatchMode.EXACT) {
484 crit.add(Restrictions.eq("nameCache", matchmode.queryStringFrom(queryString)));
485 } else {
486 crit.add(Restrictions.ilike("nameCache", matchmode.queryStringFrom(queryString)));
487 }
488 if(criteria != null){
489 for (Criterion criterion : criteria) {
490 crit.add(criterion);
491 }
492 }
493 crit.addOrder(Order.asc("nameCache"));
494
495 if(pageSize != null) {
496 crit.setMaxResults(pageSize);
497 if(pageNumber != null) {
498 crit.setFirstResult(pageNumber * pageSize);
499 }
500 }
501
502 List<? extends TaxonNameBase<?,?>> results = crit.list();
503 return results;
504 }
505
506 public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
507 AuditEvent auditEvent = getAuditEventFromContext();
508 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
509 //FIXME only NameRelationships
510 Criteria criteria = getSession().createCriteria(RelationshipBase.class);
511 return (List<RelationshipBase>)criteria.list();
512 } else {
513 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
514 return (List<RelationshipBase>)query.getResultList();
515 }
516 }
517
518
519 public Integer countByName(String queryString,
520 MatchMode matchmode, List<Criterion> criteria) {
521 //TODO improve performance
522 List<? extends TaxonNameBase<?,?>> results = findByName(queryString, matchmode, null, null, criteria);
523 return results.size();
524
525 }
526 }