Project

General

Profile

Download (35.7 KB) Statistics
| Branch: | Tag: | Revision:
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.ArrayList;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import org.apache.log4j.Logger;
19
import org.hibernate.Criteria;
20
import org.hibernate.Query;
21
import org.hibernate.SQLQuery;
22
import org.hibernate.criterion.Criterion;
23
import org.hibernate.criterion.Order;
24
import org.hibernate.criterion.Projections;
25
import org.hibernate.criterion.Restrictions;
26
import org.hibernate.envers.query.AuditEntity;
27
import org.hibernate.envers.query.AuditQuery;
28
import org.springframework.beans.factory.annotation.Autowired;
29
import org.springframework.beans.factory.annotation.Qualifier;
30
import org.springframework.stereotype.Repository;
31

    
32
import eu.etaxonomy.cdm.model.common.CdmBase;
33
import eu.etaxonomy.cdm.model.common.RelationshipBase;
34
import eu.etaxonomy.cdm.model.name.BacterialName;
35
import eu.etaxonomy.cdm.model.name.BotanicalName;
36
import eu.etaxonomy.cdm.model.name.CultivarPlantName;
37
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
38
import eu.etaxonomy.cdm.model.name.HybridRelationship;
39
import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
40
import eu.etaxonomy.cdm.model.name.NameRelationship;
41
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
42
import eu.etaxonomy.cdm.model.name.NonViralName;
43
import eu.etaxonomy.cdm.model.name.Rank;
44
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
45
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
46
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
47
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
48
import eu.etaxonomy.cdm.model.name.ViralName;
49
import eu.etaxonomy.cdm.model.name.ZoologicalName;
50
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
51
import eu.etaxonomy.cdm.model.view.AuditEvent;
52
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
53
import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
54
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
55
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
56
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
57
import eu.etaxonomy.cdm.persistence.query.MatchMode;
58
import eu.etaxonomy.cdm.persistence.query.OrderHint;
59

    
60
/**
61
 * @author a.mueller
62
 *
63
 */
64
@Repository
65
@Qualifier("taxonNameDaoHibernateImpl")
66
public class TaxonNameDaoHibernateImpl extends IdentifiableDaoBase<TaxonNameBase> implements ITaxonNameDao {
67

    
68
    private static final Logger logger = Logger.getLogger(TaxonNameDaoHibernateImpl.class);
69

    
70
    @Autowired
71
    private ITaxonDao taxonDao;
72

    
73
    @Autowired
74

    
75
    private IHomotypicalGroupDao homotypicalGroupDao;
76

    
77
    public TaxonNameDaoHibernateImpl() {
78
        super(TaxonNameBase.class);
79
        indexedClasses = new Class[6];
80
        indexedClasses[0] = BacterialName.class;
81
        indexedClasses[1] = BotanicalName.class;
82
        indexedClasses[2] = CultivarPlantName.class;
83
        indexedClasses[3] = NonViralName.class;
84
        indexedClasses[4] = ViralName.class;
85
        indexedClasses[5] = ZoologicalName.class;
86
    }
87

    
88
    @Override
89
    public int countHybridNames(NonViralName name, HybridRelationshipType type) {
90
        AuditEvent auditEvent = getAuditEventFromContext();
91
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
92
            Query query = null;
93
            if(type == null) {
94
                query = getSession().createQuery("select count(relation) from HybridRelationship relation where relation.relatedFrom = :name");
95
            } else {
96
                query = getSession().createQuery("select count(relation) from HybridRelationship relation where relation.relatedFrom = :name and relation.type = :type");
97
                query.setParameter("type", type);
98
            }
99
            query.setParameter("name",name);
100
            return ((Long)query.uniqueResult()).intValue();
101
        } else {
102
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(HybridRelationship.class,auditEvent.getRevisionNumber());
103
            query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));
104
            query.addProjection(AuditEntity.id().count());
105

    
106
            if(type != null) {
107
                query.add(AuditEntity.relatedId("type").eq(type.getId()));
108
            }
109

    
110
            return ((Long)query.getSingleResult()).intValue();
111
        }
112
    }
113

    
114
    @Override
115
    public int countNames(String queryString) {
116
        checkNotInPriorView("TaxonNameDaoHibernateImpl.countNames(String queryString)");
117
        Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
118

    
119
        if (queryString != null) {
120
            criteria.add(Restrictions.ilike("nameCache", queryString));
121
        }
122
        criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
123

    
124
        return ((Number)criteria.uniqueResult()).intValue();
125
    }
126

    
127
    @Override
128
    public int countNames(String queryString, MatchMode matchMode, List<Criterion> criteria) {
129

    
130
        Criteria crit = getSession().createCriteria(type);
131
        if (matchMode == MatchMode.EXACT) {
132
            crit.add(Restrictions.eq("nameCache", matchMode.queryStringFrom(queryString)));
133
        } else {
134
            crit.add(Restrictions.ilike("nameCache", matchMode.queryStringFrom(queryString)));
135
        }
136
        if(criteria != null) {
137
            for (Criterion criterion : criteria) {
138
                crit.add(criterion);
139
            }
140
        }
141

    
142
        crit.setProjection(Projections.projectionList().add(Projections.rowCount()));
143
        return ((Number)crit.uniqueResult()).intValue();
144
    }
145

    
146
    @Override
147
    public int countNames(String genusOrUninomial, String infraGenericEpithet,	String specificEpithet, String infraSpecificEpithet, Rank rank) {
148
        AuditEvent auditEvent = getAuditEventFromContext();
149
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
150
            Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
151

    
152
            /**
153
             * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"
154
             * We need to convert nulls to NullRestrictions for now
155
             */
156
            if(genusOrUninomial != null) {
157
                criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));
158
            } else {
159
                criteria.add(Restrictions.isNull("genusOrUninomial"));
160
            }
161

    
162
            if(infraGenericEpithet != null) {
163
                criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));
164
            } else {
165
                criteria.add(Restrictions.isNull("infraGenericEpithet"));
166
            }
167

    
168
            if(specificEpithet != null) {
169
                criteria.add(Restrictions.eq("specificEpithet", specificEpithet));
170
            } else {
171
                criteria.add(Restrictions.isNull("specificEpithet"));
172
            }
173

    
174
            if(infraSpecificEpithet != null) {
175
                criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));
176
            } else {
177
                criteria.add(Restrictions.isNull("infraSpecificEpithet"));
178
            }
179

    
180
            if(rank != null) {
181
                criteria.add(Restrictions.eq("rank", rank));
182
            }
183

    
184
            criteria.setProjection(Projections.rowCount());
185
            return ((Number)criteria.uniqueResult()).intValue();
186
        } else {
187
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameBase.class,auditEvent.getRevisionNumber());
188

    
189
            if(genusOrUninomial != null) {
190
                query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));
191
            } else {
192
                query.add(AuditEntity.property("genusOrUninomial").isNull());
193
            }
194

    
195
            if(infraGenericEpithet != null) {
196
                query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));
197
            } else {
198
                query.add(AuditEntity.property("infraGenericEpithet").isNull());
199
            }
200

    
201
            if(specificEpithet != null) {
202
                query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));
203
            } else {
204
                query.add(AuditEntity.property("specificEpithet").isNull());
205
            }
206

    
207
            if(infraSpecificEpithet != null) {
208
                query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));
209
            } else {
210
                query.add(AuditEntity.property("infraSpecificEpithet").isNull());
211
            }
212

    
213
            if(rank != null) {
214
                query.add(AuditEntity.relatedId("rank").eq(rank.getId()));
215
            }
216

    
217
            query.addProjection(AuditEntity.id().count());
218
            return ((Long)query.getSingleResult()).intValue();
219
        }
220
    }
221

    
222
    @Override
223
    public int countNameRelationships(TaxonNameBase name, NameRelationship.Direction direction, NameRelationshipType type) {
224

    
225
        AuditEvent auditEvent = getAuditEventFromContext();
226
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
227
            Query query = null;
228
            if(type == null) {
229
                query = getSession().createQuery("select count(relation) from NameRelationship relation where relation." + direction +" = :name");
230
            } else {
231
                query = getSession().createQuery("select count(relation) from NameRelationship relation where relation." + direction +" = :name and relation.type = :type");
232
                query.setParameter("type", type);
233
            }
234
            query.setParameter("name",name);
235
            return ((Long)query.uniqueResult()).intValue();
236
        } else {
237
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());
238
            query.add(AuditEntity.relatedId(direction.toString()).eq(name.getId()));
239
            query.addProjection(AuditEntity.id().count());
240

    
241
            if(type != null) {
242
                query.add(AuditEntity.relatedId("type").eq(type.getId()));
243
            }
244

    
245
            return ((Long)query.getSingleResult()).intValue();
246
        }
247
    }
248

    
249

    
250
    @Override
251
    public int countTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status) {
252
        checkNotInPriorView("countTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status)");
253
        Query query = null;
254
        if(status == null) {
255
            query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name");
256
        } else {
257
            query = getSession().createQuery("select count(designation) from TypeDesignationBase designation join designation.typifiedNames name where name = :name and designation.typeStatus = :status");
258
            query.setParameter("status", status);
259
        }
260
        query.setParameter("name",name);
261
        return ((Long)query.uniqueResult()).intValue();
262
    }
263

    
264
    @Override
265
    public List<HybridRelationship> getHybridNames(NonViralName name, HybridRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
266
        AuditEvent auditEvent = getAuditEventFromContext();
267
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
268
            Criteria criteria = getSession().createCriteria(HybridRelationship.class);
269
            criteria.add(Restrictions.eq("relatedFrom", name));
270
            if(type != null) {
271
                criteria.add(Restrictions.eq("type", type));
272
            }
273

    
274
            if(pageSize != null) {
275
                criteria.setMaxResults(pageSize);
276
                if(pageNumber != null) {
277
                    criteria.setFirstResult(pageNumber * pageSize);
278
                } else {
279
                    criteria.setFirstResult(0);
280
                }
281
            }
282

    
283
            addOrder(criteria, orderHints);
284

    
285
            List<HybridRelationship> results = criteria.list();
286
            defaultBeanInitializer.initializeAll(results, propertyPaths);
287
            return results;
288
        } else {
289
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(HybridRelationship.class,auditEvent.getRevisionNumber());
290
            query.add(AuditEntity.relatedId("relatedFrom").eq(name.getId()));
291

    
292
            if(type != null) {
293
                query.add(AuditEntity.relatedId("type").eq(type.getId()));
294
            }
295

    
296
            if(pageSize != null) {
297
                query.setMaxResults(pageSize);
298
                if(pageNumber != null) {
299
                    query.setFirstResult(pageNumber * pageSize);
300
                } else {
301
                    query.setFirstResult(0);
302
                }
303
            }
304

    
305
            List<HybridRelationship> results =  query.getResultList();
306
            defaultBeanInitializer.initializeAll(results, propertyPaths);
307
            return results;
308
        }
309
    }
310

    
311
    @Override
312
    public List<NameRelationship> getNameRelationships(TaxonNameBase name, NameRelationship.Direction direction,
313
            NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,
314
            List<String> propertyPaths) {
315

    
316
        AuditEvent auditEvent = getAuditEventFromContext();
317
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
318
            Criteria criteria = getSession().createCriteria(NameRelationship.class);
319
            if (name != null || direction != null){
320
                criteria.add(Restrictions.eq(direction.toString(), name));
321
            }
322
            if(type != null) {
323
                criteria.add(Restrictions.eq("type", type));
324
            }
325

    
326
            if(pageSize != null) {
327
                criteria.setMaxResults(pageSize);
328
                if(pageNumber != null) {
329
                    criteria.setFirstResult(pageNumber * pageSize);
330
                } else {
331
                    criteria.setFirstResult(0);
332
                }
333
            }
334
            addOrder(criteria, orderHints);
335

    
336
            List<NameRelationship> results = criteria.list();
337
            defaultBeanInitializer.initializeAll(results, propertyPaths);
338
            return results;
339
        } else {
340
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());
341
            query.add(AuditEntity.relatedId(direction.toString()).eq(name.getId()));
342

    
343
            if(type != null) {
344
                query.add(AuditEntity.relatedId("type").eq(type.getId()));
345
            }
346

    
347
            if(pageSize != null) {
348
                query.setMaxResults(pageSize);
349
                if(pageNumber != null) {
350
                    query.setFirstResult(pageNumber * pageSize);
351
                } else {
352
                    query.setFirstResult(0);
353
                }
354
            }
355

    
356
            List<NameRelationship> results = query.getResultList();
357
            defaultBeanInitializer.initializeAll(results, propertyPaths);
358
            return results;
359
        }
360
    }
361

    
362
    @Override
363
    public List<TypeDesignationBase> getTypeDesignations(TaxonNameBase name, TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,	List<String> propertyPaths){
364
        return getTypeDesignations(name, null, status, pageSize, pageNumber, propertyPaths);
365
    }
366

    
367
    @Override
368
    public <T extends TypeDesignationBase> List<T> getTypeDesignations(TaxonNameBase name,
369
                Class<T> type,
370
                TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,
371
                List<String> propertyPaths){
372
        checkNotInPriorView("getTypeDesignations(TaxonNameBase name,TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,	List<String> propertyPaths)");
373
        Query query = null;
374
        String queryString = "select designation from TypeDesignationBase designation join designation.typifiedNames name where name = :name";
375

    
376
        if(status != null) {
377
            queryString +=  " and designation.typeStatus = :status";
378
        }
379
        if(type != null){
380
            queryString +=  " and designation.class = :type";
381
        }
382

    
383
        query = getSession().createQuery(queryString);
384

    
385
        if(status != null) {
386
            query.setParameter("status", status);
387
        }
388
        if(type != null){
389
            query.setParameter("type", type.getSimpleName());
390
        }
391

    
392
        query.setParameter("name",name);
393

    
394
        if(pageSize != null) {
395
            query.setMaxResults(pageSize);
396
            if(pageNumber != null) {
397
                query.setFirstResult(pageNumber * pageSize);
398
            } else {
399
                query.setFirstResult(0);
400
            }
401
        }
402
        return defaultBeanInitializer.initializeAll((List<T>)query.list(), propertyPaths);
403
    }
404

    
405

    
406
    public List<TaxonNameBase<?,?>> searchNames(String queryString, MatchMode matchMode, Integer pageSize, Integer pageNumber) {
407
        checkNotInPriorView("TaxonNameDaoHibernateImpl.searchNames(String queryString, Integer pageSize, Integer pageNumber)");
408
        Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
409

    
410
        if (queryString != null) {
411
            criteria.add(Restrictions.ilike("nameCache", queryString));
412
        }
413
        if(pageSize != null) {
414
            criteria.setMaxResults(pageSize);
415
            if(pageNumber != null) {
416
                criteria.setFirstResult(pageNumber * pageSize);
417
            } else {
418
                criteria.setFirstResult(0);
419
            }
420
        }
421
        List<TaxonNameBase<?,?>> results = criteria.list();
422
        return results;
423
    }
424

    
425

    
426
    @Override
427
    public List<TaxonNameBase<?,?>> searchNames(String queryString, Integer pageSize, Integer pageNumber) {
428
        return searchNames(queryString, MatchMode.BEGINNING, pageSize, pageNumber);
429
    }
430

    
431

    
432
    @Override
433
    public List<TaxonNameBase> searchNames(String genusOrUninomial,String infraGenericEpithet, String specificEpithet,	String infraSpecificEpithet, Rank rank, Integer pageSize,Integer pageNumber, List<OrderHint> orderHints,
434
            List<String> propertyPaths) {
435
        AuditEvent auditEvent = getAuditEventFromContext();
436
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
437
            Criteria criteria = getSession().createCriteria(TaxonNameBase.class);
438

    
439
            /**
440
             * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"
441
             * We need to convert nulls to NullRestrictions for now
442
             */
443
            if(genusOrUninomial != null) {
444
                criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));
445
            } else {
446
                criteria.add(Restrictions.isNull("genusOrUninomial"));
447
            }
448

    
449
            if(infraGenericEpithet != null) {
450
                criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));
451
            } else {
452
                criteria.add(Restrictions.isNull("infraGenericEpithet"));
453
            }
454

    
455
            if(specificEpithet != null) {
456
                criteria.add(Restrictions.eq("specificEpithet", specificEpithet));
457
            } else {
458
                criteria.add(Restrictions.isNull("specificEpithet"));
459
            }
460

    
461
            if(infraSpecificEpithet != null) {
462
                criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));
463
            } else {
464
                criteria.add(Restrictions.isNull("infraSpecificEpithet"));
465
            }
466

    
467
            if(rank != null) {
468
                criteria.add(Restrictions.eq("rank", rank));
469
            }
470

    
471
            if(pageSize != null) {
472
                criteria.setMaxResults(pageSize);
473
                if(pageNumber != null) {
474
                    criteria.setFirstResult(pageNumber * pageSize);
475
                } else {
476
                    criteria.setFirstResult(0);
477
                }
478
            }
479

    
480
            addOrder(criteria, orderHints);
481

    
482
            List<TaxonNameBase> results = criteria.list();
483
            defaultBeanInitializer.initializeAll(results, propertyPaths);
484
            return results;
485
        } else {
486
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameBase.class,auditEvent.getRevisionNumber());
487

    
488
            if(genusOrUninomial != null) {
489
                query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));
490
            } else {
491
                query.add(AuditEntity.property("genusOrUninomial").isNull());
492
            }
493

    
494
            if(infraGenericEpithet != null) {
495
                query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));
496
            } else {
497
                query.add(AuditEntity.property("infraGenericEpithet").isNull());
498
            }
499

    
500
            if(specificEpithet != null) {
501
                query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));
502
            } else {
503
                query.add(AuditEntity.property("specificEpithet").isNull());
504
            }
505

    
506
            if(infraSpecificEpithet != null) {
507
                query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));
508
            } else {
509
                query.add(AuditEntity.property("infraSpecificEpithet").isNull());
510
            }
511

    
512
            if(rank != null) {
513
                query.add(AuditEntity.relatedId("rank").eq(rank.getId()));
514
            }
515

    
516
            if(pageSize != null) {
517
                query.setMaxResults(pageSize);
518
                if(pageNumber != null) {
519
                    query.setFirstResult(pageNumber * pageSize);
520
                } else {
521
                    query.setFirstResult(0);
522
                }
523
            }
524

    
525
            List<TaxonNameBase> results = query.getResultList();
526
            defaultBeanInitializer.initializeAll(results, propertyPaths);
527
            return results;
528
        }
529
    }
530

    
531
    @Override
532
    public List<? extends TaxonNameBase<?,?>> findByName(String queryString,
533
            MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria, List<String> propertyPaths) {
534

    
535
        Criteria crit = getSession().createCriteria(type);
536
        if (matchmode == MatchMode.EXACT) {
537
            crit.add(Restrictions.eq("nameCache", matchmode.queryStringFrom(queryString)));
538
        } else {
539
            crit.add(Restrictions.ilike("nameCache", matchmode.queryStringFrom(queryString)));
540
        }
541
        if(criteria != null){
542
            for (Criterion criterion : criteria) {
543
                crit.add(criterion);
544
            }
545
        }
546
        crit.addOrder(Order.asc("nameCache"));
547

    
548
        if(pageSize != null) {
549
            crit.setMaxResults(pageSize);
550
            if(pageNumber != null) {
551
                crit.setFirstResult(pageNumber * pageSize);
552
            }
553
        }
554

    
555
        List<? extends TaxonNameBase<?,?>> results = crit.list();
556
        defaultBeanInitializer.initializeAll(results, propertyPaths);
557

    
558
        return results;
559
    }
560

    
561
    @Override
562
    public List<? extends TaxonNameBase<?,?>> findByTitle(String queryString,
563
            MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria, List<String> propertyPaths) {
564

    
565
        Criteria crit = getSession().createCriteria(type);
566
        if (matchmode == MatchMode.EXACT) {
567
            crit.add(Restrictions.eq("titleCache", matchmode.queryStringFrom(queryString)));
568
        } else {
569
            crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
570
        }
571
        if(criteria != null){
572
            for (Criterion criterion : criteria) {
573
                crit.add(criterion);
574
            }
575
        }
576
        crit.addOrder(Order.asc("titleCache"));
577

    
578
        if(pageSize != null) {
579
            crit.setMaxResults(pageSize);
580
            if(pageNumber != null) {
581
                crit.setFirstResult(pageNumber * pageSize);
582
            }
583
        }
584

    
585
        List<? extends TaxonNameBase<?,?>> results = crit.list();
586
        defaultBeanInitializer.initializeAll(results, propertyPaths);
587

    
588
        return results;
589
    }
590

    
591

    
592
    @Override
593
    public TaxonNameBase<?,?> findByUuid(UUID uuid, List<Criterion> criteria, List<String> propertyPaths) {
594

    
595
        Criteria crit = getSession().createCriteria(type);
596

    
597
        if (uuid != null) {
598
            crit.add(Restrictions.eq("uuid", uuid));
599
        } else {
600
            logger.warn("UUID is NULL");
601
            return null;
602
        }
603
        if(criteria != null){
604
            for (Criterion criterion : criteria) {
605
                crit.add(criterion);
606
            }
607
        }
608
        crit.addOrder(Order.asc("uuid"));
609

    
610
        List<? extends TaxonNameBase<?,?>> results = crit.list();
611
        if (results.size() == 1) {
612
            defaultBeanInitializer.initializeAll(results, propertyPaths);
613
            TaxonNameBase<?, ?> taxonName = results.iterator().next();
614
            return taxonName;
615
        } else if (results.size() > 1) {
616
            logger.error("Multiple results for UUID: " + uuid);
617
        } else if (results.size() == 0) {
618
            logger.info("No results for UUID: " + uuid);
619
        }
620

    
621
        return null;
622
    }
623

    
624
    @Override
625
    public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {
626
        AuditEvent auditEvent = getAuditEventFromContext();
627
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
628
            // for some reason the HQL .class discriminator didn't work here so I created this preliminary
629
            // implementation for now. Should be cleaned in future.
630

    
631
            List<RelationshipBase> result = new ArrayList<RelationshipBase>();
632

    
633
            int nameRelSize = countAllRelationships(NameRelationship.class);
634
            if (nameRelSize > start){
635

    
636
                String hql = " FROM %s as rb ORDER BY rb.id ";
637
                hql = String.format(hql, NameRelationship.class.getSimpleName());
638
                Query query = getSession().createQuery(hql);
639
                query.setFirstResult(start);
640
                if (limit != null){
641
                    query.setMaxResults(limit);
642
                }
643
                result = query.list();
644
            }
645
            limit = limit - result.size();
646
            if (limit > 0){
647
                String hql = " FROM HybridRelationship as rb ORDER BY rb.id ";
648
                hql = String.format(hql, HybridRelationship.class.getSimpleName());
649
                Query query = getSession().createQuery(hql);
650
                start = (nameRelSize > start) ? 0 : (start - nameRelSize);
651
                query.setFirstResult(start);
652
                if (limit != null){
653
                    query.setMaxResults(limit);
654
                }
655
                result.addAll( query.list());
656
            }
657
            return result;
658
        } else {
659
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(RelationshipBase.class,auditEvent.getRevisionNumber());
660
            return query.getResultList();
661
        }
662
    }
663

    
664

    
665
    /**
666
     * TODO not yet in interface
667
     * @param clazz
668
     * @return
669
     */
670
    public int countAllRelationships(Class<? extends RelationshipBase> clazz) {
671
        if (clazz != null && ! NameRelationship.class.isAssignableFrom(clazz) && ! HybridRelationship.class.isAssignableFrom(clazz) ){
672
            throw new RuntimeException("Class must be assignable by a taxon or snonym relation");
673
        }
674
        int size = 0;
675

    
676
        if (clazz == null || NameRelationship.class.isAssignableFrom(clazz)){
677
            String hql = " SELECT count(rel) FROM NameRelationship rel";
678
            size += (Long)getSession().createQuery(hql).list().get(0);
679
        }
680
        if (clazz == null || HybridRelationship.class.isAssignableFrom(clazz)){
681
            String hql = " SELECT count(rel) FROM HybridRelationship rel";
682
            size += (Long)getSession().createQuery(hql).list().get(0);
683
        }
684
        return size;
685
    }
686

    
687

    
688
    @Override
689
    public Integer countByName(String queryString, MatchMode matchmode, List<Criterion> criteria) {
690
        //TODO improve performance
691
        List<? extends TaxonNameBase<?,?>> results = findByName(queryString, matchmode, null, null, criteria, null);
692
        return results.size();
693

    
694
    }
695

    
696
    @Override
697
    public List<UuidAndTitleCache> getUuidAndTitleCacheOfNames() {
698
        String queryString = "SELECT uuid, id, fullTitleCache FROM TaxonNameBase";
699

    
700
        @SuppressWarnings("unchecked")
701
        List<Object[]> result = getSession().createSQLQuery(queryString).list();
702

    
703
        if(result.size() == 0){
704
            return null;
705
        }else{
706
            List<UuidAndTitleCache> list = new ArrayList<UuidAndTitleCache>(result.size());
707

    
708
            for (Object object : result){
709

    
710
                Object[] objectArray = (Object[]) object;
711

    
712
                UUID uuid = UUID.fromString((String) objectArray[0]);
713
                Integer id = (Integer) objectArray[1];
714
                String titleCache = (String) objectArray[2];
715

    
716
                list.add(new UuidAndTitleCache(type, uuid, id, titleCache));
717
            }
718

    
719
            return list;
720
        }
721
    }
722

    
723
    @Override
724
    public Integer countByName(Class<? extends TaxonNameBase> clazz,String queryString, MatchMode matchmode, List<Criterion> criteria) {
725
        return super.countByParam(clazz, "nameCache", queryString, matchmode, criteria);
726
    }
727

    
728
    @Override
729
    public List<TaxonNameBase> findByName(Class<? extends TaxonNameBase> clazz,	String queryString, MatchMode matchmode, List<Criterion> criteria,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,	List<String> propertyPaths) {
730
        return super.findByParam(clazz, "nameCache", queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);
731
    }
732

    
733
    @Override
734
    public UUID delete (TaxonNameBase persistentObject){
735
        Set<TaxonBase> taxonBases = persistentObject.getTaxonBases();
736

    
737
        if (persistentObject == null){
738
            logger.warn(type.getName() + " was 'null'");
739
            return null;
740
        }
741
        getSession().saveOrUpdate(persistentObject);
742
        UUID persUuid = persistentObject.getUuid();
743
        persistentObject = this.load(persUuid);
744
        UUID homotypicalGroupUUID = persistentObject.getHomotypicalGroup().getUuid();
745

    
746

    
747
        for (TaxonBase taxonBase: taxonBases){
748
            taxonDao.delete(taxonBase);
749
        }
750
        HomotypicalGroup homotypicalGroup = homotypicalGroupDao.load(homotypicalGroupUUID);
751
        if (homotypicalGroup != null){
752
        	if (homotypicalGroup.getTypifiedNames().isEmpty()){
753
        		homotypicalGroupDao.delete(homotypicalGroup);
754
        	}
755
        }
756

    
757
        getSession().delete(persistentObject);
758
        return persistentObject.getUuid();
759
    }
760

    
761

    
762
    @Override
763
    public ZoologicalName findZoologicalNameByUUID(UUID uuid){
764
        Criteria criteria = getSession().createCriteria(type);
765
        if (uuid != null) {
766
            criteria.add(Restrictions.eq("uuid", uuid));
767
        } else {
768
            logger.warn("UUID is NULL");
769
            return null;
770
        }
771

    
772
        List<? extends TaxonNameBase<?,?>> results = criteria.list();
773
        if (results.size() == 1) {
774
            defaultBeanInitializer.initializeAll(results, null);
775
            TaxonNameBase<?, ?> taxonName = results.iterator().next();
776
            if (taxonName.isInstanceOf(ZoologicalName.class)) {
777
                ZoologicalName zoologicalName = CdmBase.deproxy(taxonName, ZoologicalName.class);
778
                return zoologicalName;
779
            } else {
780
                logger.warn("This UUID (" + uuid + ") does not belong to a ZoologicalName. It belongs to: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
781
            }
782
        } else if (results.size() > 1) {
783
            logger.error("Multiple results for UUID: " + uuid);
784
        } else if (results.size() == 0) {
785
            logger.info("No results for UUID: " + uuid);
786
        }
787
        return null;
788
    }
789
@Override
790
public List<HashMap<String,String>> getNameRecords(){
791
    	String sql= "SELECT"
792
    			+ "  (SELECT famName.namecache FROM TaxonNode famNode"
793
    			+ "  LEFT OUTER JOIN TaxonBase famTax ON famNode.taxon_id = famTax.id"
794
    			+ " LEFT OUTER JOIN TaxonNameBase famName ON famTax.name_id = famName.id"
795
    			+ " WHERE famName.rank_id = 795 AND famNode.treeIndex = SUBSTRING(tn.treeIndex, 1, length(famNode.treeIndex))"
796
    			+ "	) as famName, "
797
    			+ " (SELECT famName.namecache FROM TaxonNode famNode "
798
    			+ " LEFT OUTER JOIN TaxonBase famTax ON famNode.taxon_id = famTax.id "
799
    			+ " LEFT OUTER JOIN TaxonNameBase famName ON famTax.name_id = famName.id "
800
    			+ " WHERE famName.rank_id = 795 AND famNode.treeIndex = SUBSTRING(tnAcc.treeIndex, 1, length(famNode.treeIndex))"
801
    			+ "	) as accFamName,tb.DTYPE, tb.id as TaxonID ,tb.titleCache taxonTitle,  tnb.rank_id as RankID, tnb.id as NameID,"
802
    			+ " tnb.namecache as name, tnb.titleCache as nameAuthor, tnb.fullTitleCache nameAndNomRef,"
803
    			+ "	r.titleCache as nomRef, r.abbrevTitle nomRefAbbrevTitle, r.title nomRefTitle, r.datepublished_start nomRefPublishedStart, r.datepublished_end nomRefPublishedEnd, r.pages nomRefPages, inRef.abbrevTitle inRefAbbrevTitle,tnb.nomenclaturalmicroreference as detail,"
804
    			+ "	nameType.namecache nameType, nameType.titleCache nameTypeAuthor, nameType.fullTitleCache nameTypeFullTitle, nameTypeRef.titleCache nameTypeRef, inRef.seriespart as inRefSeries, inRef.datepublished_start inRefPublishedStart, inRef.datepublished_end inRefPublishedEnd, inRef.volume as inRefVolume"
805
    			+ " FROM TaxonBase tb"
806
    			+ " LEFT OUTER JOIN TaxonNameBase tnb ON tb.name_id = tnb.id"
807
    			+ "	LEFT OUTER JOIN Reference r ON tnb.nomenclaturalreference_id = r.id"
808
    			+ "	LEFT OUTER JOIN TaxonNode tn ON tn.taxon_id = tb.id"
809
    			+ "	LEFT OUTER JOIN TaxonNameBase_TypeDesignationBase typeMN ON typeMN.TaxonNameBase_id = tnb.id"
810
    			+ " LEFT OUTER JOIN TypeDesignationBase tdb ON tdb.id = typeMN.typedesignations_id"
811
    			+ "	LEFT OUTER JOIN TaxonNameBase nameType ON tdb.typename_id = nameType.id"
812
    			+ "	LEFT OUTER JOIN Reference nameTypeRef ON nameType.nomenclaturalreference_id = nameTypeRef.id"
813
    			+ "		LEFT OUTER JOIN Reference inRef ON inRef.id = r.inreference_id"
814
    			+ "	LEFT OUTER JOIN SynonymRelationship sr ON tb.id = sr.relatedfrom_id"
815
    			+ "	LEFT OUTER JOIN TaxonBase accT ON accT.id = sr.relatedto_id"
816
    			+ "		LEFT OUTER JOIN TaxonNode tnAcc ON tnAcc.taxon_id = accT.id"
817
    			+ "	ORDER BY DTYPE, famName, accFamName,  tnb.rank_id ,tb.titleCache";
818

    
819

    
820
    	SQLQuery query = getSession().createSQLQuery(sql);
821
    	List result = query.list();
822
    	 //Delimiter used in CSV file
823

    
824

    
825
		List<HashMap<String,String>> nameRecords = new ArrayList();
826
		HashMap<String,String> nameRecord = new HashMap<String,String>();
827
		for(Object object : result)
828
         {
829
			Object[] row = (Object[])object;
830
			nameRecord = new HashMap<String,String>();
831
			nameRecord.put("famName",(String)row[0]);
832
			nameRecord.put("accFamName",(String)row[1]);
833

    
834
			nameRecord.put("DTYPE",(String)row[2]);
835
			nameRecord.put("TaxonID",String.valueOf(row[3]));
836
			nameRecord.put("taxonTitle",(String)row[4]);
837
            nameRecord.put("RankID",String.valueOf(row[5]));
838
            nameRecord.put("NameID",String.valueOf(row[6]));
839
            nameRecord.put("name",(String)row[7]);
840
            nameRecord.put("nameAuthor",(String)row[8]);
841
            nameRecord.put("nameAndNomRef",(String)row[9]);
842
            nameRecord.put("nomRef",(String)row[10]);
843
            nameRecord.put("nomRefAbbrevTitle",(String)row[11]);
844
            nameRecord.put("nomRefTitle",(String)row[12]);
845
            nameRecord.put("nomRefPublishedStart",(String)row[13]);
846
            nameRecord.put("nomRefPublishedEnd",(String)row[14]);
847
            nameRecord.put("nomRefPages",(String)row[15]);
848
            nameRecord.put("inRefAbbrevTitle",(String)row[16]);
849
            nameRecord.put("detail",(String)row[17]);
850
            nameRecord.put("nameType",(String)row[18]);
851
            nameRecord.put("nameTypeAuthor",(String)row[19]);
852
            nameRecord.put("nameTypeFullTitle",(String)row[20]);
853
            nameRecord.put("nameTypeRef",(String)row[21]);
854
            nameRecord.put("inRefSeries",(String)row[22]);
855
            nameRecord.put("inRefPublishedStart",(String)row[23]);
856
            nameRecord.put("inRefPublishedEnd",(String)row[24]);
857
            nameRecord.put("inRefVolume",(String)row[25]);
858
            nameRecords.add(nameRecord);
859
	   }
860

    
861
		return nameRecords;
862

    
863

    
864

    
865
    }
866

    
867

    
868

    
869

    
870
}
(3-3/4)