Project

General

Profile

Download (46.3 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.Collection;
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Optional;
17
import java.util.Set;
18
import java.util.UUID;
19

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

    
35
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
36
import eu.etaxonomy.cdm.model.common.RelationshipBase;
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.INonViralName;
41
import eu.etaxonomy.cdm.model.name.IZoologicalName;
42
import eu.etaxonomy.cdm.model.name.NameRelationship;
43
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
44
import eu.etaxonomy.cdm.model.name.Rank;
45
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
46
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
47
import eu.etaxonomy.cdm.model.name.TaxonName;
48
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
49
import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
50
import eu.etaxonomy.cdm.model.taxon.Synonym;
51
import eu.etaxonomy.cdm.model.taxon.Taxon;
52
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
53
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
54
import eu.etaxonomy.cdm.model.view.AuditEvent;
55
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
56
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
57
import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
58
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
59
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
60
import eu.etaxonomy.cdm.persistence.dto.TaxonNameParts;
61
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
62
import eu.etaxonomy.cdm.persistence.query.MatchMode;
63
import eu.etaxonomy.cdm.persistence.query.OrderHint;
64

    
65
/**
66
 * @author a.mueller
67
 *
68
 */
69
@Repository
70
@Qualifier("taxonNameDaoHibernateImpl")
71
public class TaxonNameDaoHibernateImpl extends IdentifiableDaoBase<TaxonName> implements ITaxonNameDao {
72

    
73
    private static final Logger logger = Logger.getLogger(TaxonNameDaoHibernateImpl.class);
74

    
75
    @Autowired
76
    private ITaxonDao taxonDao;
77

    
78
    @Autowired
79

    
80
    private IHomotypicalGroupDao homotypicalGroupDao;
81

    
82
    public TaxonNameDaoHibernateImpl() {
83
        super(TaxonName.class);
84
        indexedClasses = new Class[1];
85
        indexedClasses[0] = TaxonName.class;
86
    }
87

    
88
    @Override
89
    public int countHybridNames(INonViralName 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 long countNames(String queryString) {
116
        checkNotInPriorView("TaxonNameDaoHibernateImpl.countNames(String queryString)");
117
        Criteria criteria = getCriteria(null);
118

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

    
124
        return (Long)criteria.uniqueResult();
125
    }
126

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

    
130
        Criteria crit = getCriteria(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 (Long)crit.uniqueResult();
144
    }
145

    
146
    @Override
147
    public long 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 = getCriteria(TaxonName.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 (Long)criteria.uniqueResult();
186
        } else {
187
            AuditQuery query = makeAuditQuery(TaxonName.class, auditEvent);
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();
219
        }
220
    }
221

    
222
    @Override
223
    public int countNameRelationships(TaxonName 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 long countTypeDesignations(TaxonName name, SpecimenTypeDesignationStatus status) {
252
        checkNotInPriorView("countTypeDesignations(TaxonName 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();
262
    }
263

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

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

    
284
            addOrder(criteria, orderHints);
285

    
286
            @SuppressWarnings("unchecked")
287
            List<HybridRelationship> results = criteria.list();
288
            defaultBeanInitializer.initializeAll(results, propertyPaths);
289
            return results;
290
        } else {
291
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(HybridRelationship.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
            @SuppressWarnings("unchecked")
308
            List<HybridRelationship> results =  query.getResultList();
309
            defaultBeanInitializer.initializeAll(results, propertyPaths);
310
            return results;
311
        }
312
    }
313

    
314
    @Override
315
    public List<NameRelationship> getNameRelationships(TaxonName name, NameRelationship.Direction direction,
316
            NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,
317
            List<String> propertyPaths) {
318

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

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

    
339
            @SuppressWarnings("unchecked")
340
            List<NameRelationship> results = criteria.list();
341
            defaultBeanInitializer.initializeAll(results, propertyPaths);
342
            return results;
343
        } else {
344
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(NameRelationship.class,auditEvent.getRevisionNumber());
345
            query.add(AuditEntity.relatedId(direction.toString()).eq(name.getId()));
346

    
347
            if(type != null) {
348
                query.add(AuditEntity.relatedId("type").eq(type.getId()));
349
            }
350

    
351
            if(pageSize != null) {
352
                query.setMaxResults(pageSize);
353
                if(pageNumber != null) {
354
                    query.setFirstResult(pageNumber * pageSize);
355
                } else {
356
                    query.setFirstResult(0);
357
                }
358
            }
359

    
360
            @SuppressWarnings("unchecked")
361
            List<NameRelationship> results = query.getResultList();
362
            defaultBeanInitializer.initializeAll(results, propertyPaths);
363
            return results;
364
        }
365
    }
366

    
367
    @Override
368
    public List<TypeDesignationBase> getTypeDesignations(TaxonName name, TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,	List<String> propertyPaths){
369
        return getTypeDesignations(name, null, status, pageSize, pageNumber, propertyPaths);
370
    }
371

    
372
    @Override
373
    public List<Integer> getTypeSpecimenIdsForTaxonName(TaxonName name,
374
            TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber){
375
        Query query = getTypeDesignationQuery("designation.typeSpecimen.id", name, SpecimenTypeDesignation.class, status);
376

    
377
        if(pageSize != null) {
378
            query.setMaxResults(pageSize);
379
            if(pageNumber != null) {
380
                query.setFirstResult(pageNumber * pageSize);
381
            } else {
382
                query.setFirstResult(0);
383
            }
384
        }
385
        @SuppressWarnings("unchecked")
386
        List<Integer> result = query.list();
387
        return result;
388
    }
389

    
390
    @Override
391
    public <T extends TypeDesignationBase> List<T> getTypeDesignations(TaxonName name,
392
                Class<T> type,
393
                TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,
394
                List<String> propertyPaths){
395
        checkNotInPriorView("getTypeDesignations(TaxonName name,TypeDesignationStatusBase status, Integer pageSize, Integer pageNumber,	List<String> propertyPaths)");
396

    
397
        Query query = getTypeDesignationQuery("designation", name, type, status);
398

    
399
        if(pageSize != null) {
400
            query.setMaxResults(pageSize);
401
            if(pageNumber != null) {
402
                query.setFirstResult(pageNumber * pageSize);
403
            } else {
404
                query.setFirstResult(0);
405
            }
406
        }
407
        @SuppressWarnings("unchecked")
408
        List<T> result = defaultBeanInitializer.initializeAll((List<T>)query.list(), propertyPaths);
409
        return result;
410
    }
411

    
412
    private <T extends TypeDesignationBase> Query getTypeDesignationQuery(String select, TaxonName name,
413
            Class<T> type, TypeDesignationStatusBase status){
414
        Query query = null;
415
        String queryString = "select "+select+" from TypeDesignationBase designation join designation.typifiedNames name where name = :name";
416

    
417
        if(status != null) {
418
            queryString +=  " and designation.typeStatus = :status";
419
        }
420
        if(type != null){
421
            queryString +=  " and designation.class = :type";
422
        }
423

    
424
        query = getSession().createQuery(queryString);
425

    
426
        if(status != null) {
427
            query.setParameter("status", status);
428
        }
429
        if(type != null){
430
            query.setParameter("type", type.getSimpleName());
431
        }
432

    
433
        query.setParameter("name",name);
434
        return query;
435
    }
436

    
437
    public List<TaxonName> searchNames(String queryString, MatchMode matchMode, Integer pageSize, Integer pageNumber) {
438
        checkNotInPriorView("TaxonNameDaoHibernateImpl.searchNames(String queryString, Integer pageSize, Integer pageNumber)");
439
        Criteria criteria = getSession().createCriteria(TaxonName.class);
440

    
441
        if (queryString != null) {
442
            criteria.add(Restrictions.ilike("nameCache", queryString));
443
        }
444
        if(pageSize != null) {
445
            criteria.setMaxResults(pageSize);
446
            if(pageNumber != null) {
447
                criteria.setFirstResult(pageNumber * pageSize);
448
            } else {
449
                criteria.setFirstResult(0);
450
            }
451
        }
452
        @SuppressWarnings("unchecked")
453
        List<TaxonName> results = criteria.list();
454
        return results;
455
    }
456

    
457

    
458
    @Override
459
    public List<TaxonName> searchNames(String queryString, Integer pageSize, Integer pageNumber) {
460
        return searchNames(queryString, MatchMode.BEGINNING, pageSize, pageNumber);
461
    }
462

    
463

    
464
    @Override
465
    public List<TaxonName> searchNames(String genusOrUninomial,String infraGenericEpithet, String specificEpithet,	String infraSpecificEpithet, Rank rank, Integer pageSize,Integer pageNumber, List<OrderHint> orderHints,
466
            List<String> propertyPaths) {
467
        AuditEvent auditEvent = getAuditEventFromContext();
468
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
469
            Criteria criteria = getSession().createCriteria(TaxonName.class);
470

    
471
            /**
472
             * Given HHH-2951 - "Restrictions.eq when passed null, should create a NullRestriction"
473
             * We need to convert nulls to NullRestrictions for now
474
             */
475
            if(genusOrUninomial != null) {
476
                criteria.add(Restrictions.eq("genusOrUninomial",genusOrUninomial));
477
            } else {
478
                criteria.add(Restrictions.isNull("genusOrUninomial"));
479
            }
480

    
481
            if(infraGenericEpithet != null) {
482
                criteria.add(Restrictions.eq("infraGenericEpithet", infraGenericEpithet));
483
            } else {
484
                criteria.add(Restrictions.isNull("infraGenericEpithet"));
485
            }
486

    
487
            if(specificEpithet != null) {
488
                criteria.add(Restrictions.eq("specificEpithet", specificEpithet));
489
            } else {
490
                criteria.add(Restrictions.isNull("specificEpithet"));
491
            }
492

    
493
            if(infraSpecificEpithet != null) {
494
                criteria.add(Restrictions.eq("infraSpecificEpithet",infraSpecificEpithet));
495
            } else {
496
                criteria.add(Restrictions.isNull("infraSpecificEpithet"));
497
            }
498

    
499
            if(rank != null) {
500
                criteria.add(Restrictions.eq("rank", rank));
501
            }
502

    
503
            if(pageSize != null) {
504
                criteria.setMaxResults(pageSize);
505
                if(pageNumber != null) {
506
                    criteria.setFirstResult(pageNumber * pageSize);
507
                } else {
508
                    criteria.setFirstResult(0);
509
                }
510
            }
511

    
512
            addOrder(criteria, orderHints);
513

    
514
            @SuppressWarnings("unchecked")
515
            List<TaxonName> results = criteria.list();
516
            defaultBeanInitializer.initializeAll(results, propertyPaths);
517
            return results;
518
        } else {
519
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonName.class,auditEvent.getRevisionNumber());
520

    
521
            if(genusOrUninomial != null) {
522
                query.add(AuditEntity.property("genusOrUninomial").eq(genusOrUninomial));
523
            } else {
524
                query.add(AuditEntity.property("genusOrUninomial").isNull());
525
            }
526

    
527
            if(infraGenericEpithet != null) {
528
                query.add(AuditEntity.property("infraGenericEpithet").eq(infraGenericEpithet));
529
            } else {
530
                query.add(AuditEntity.property("infraGenericEpithet").isNull());
531
            }
532

    
533
            if(specificEpithet != null) {
534
                query.add(AuditEntity.property("specificEpithet").eq(specificEpithet));
535
            } else {
536
                query.add(AuditEntity.property("specificEpithet").isNull());
537
            }
538

    
539
            if(infraSpecificEpithet != null) {
540
                query.add(AuditEntity.property("infraSpecificEpithet").eq(infraSpecificEpithet));
541
            } else {
542
                query.add(AuditEntity.property("infraSpecificEpithet").isNull());
543
            }
544

    
545
            if(rank != null) {
546
                query.add(AuditEntity.relatedId("rank").eq(rank.getId()));
547
            }
548

    
549
            if(pageSize != null) {
550
                query.setMaxResults(pageSize);
551
                if(pageNumber != null) {
552
                    query.setFirstResult(pageNumber * pageSize);
553
                } else {
554
                    query.setFirstResult(0);
555
                }
556
            }
557

    
558
            @SuppressWarnings("unchecked")
559
            List<TaxonName> results = query.getResultList();
560
            defaultBeanInitializer.initializeAll(results, propertyPaths);
561
            return results;
562
        }
563
    }
564

    
565
    @Override
566
    public List<TaxonName> findByName(boolean doIncludeAuthors,
567
            String queryString, MatchMode matchmode, Integer pageSize,
568
            Integer pageNumber, List<Criterion> criteria, List<String> propertyPaths) {
569

    
570
        Criteria crit = getSession().createCriteria(type);
571
        Criterion nameCacheLike;
572
        if (matchmode == MatchMode.EXACT) {
573
            nameCacheLike = Restrictions.eq("nameCache", matchmode.queryStringFrom(queryString));
574
        } else {
575
            nameCacheLike = Restrictions.ilike("nameCache", matchmode.queryStringFrom(queryString));
576
        }
577
        Criterion notNull = Restrictions.isNotNull("nameCache");
578
        LogicalExpression nameCacheExpression = Restrictions.and(notNull, nameCacheLike);
579

    
580
        Criterion titleCacheLike;
581
        if (matchmode == MatchMode.EXACT) {
582
            titleCacheLike = Restrictions.eq("titleCache", matchmode.queryStringFrom(queryString));
583
        } else {
584
            titleCacheLike =Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString));
585
        }
586
        Criterion isNull = Restrictions.isNull("nameCache");
587
        LogicalExpression titleCacheExpression = Restrictions.and(isNull, titleCacheLike);
588

    
589
        LogicalExpression orExpression = Restrictions.or(titleCacheExpression, nameCacheExpression);
590

    
591
        Criterion finalCriterion = doIncludeAuthors ? titleCacheLike : orExpression;
592

    
593
        crit.add(finalCriterion);
594
        if(criteria != null){
595
            for (Criterion criterion : criteria) {
596
                crit.add(criterion);
597
            }
598
        }
599
        crit.addOrder(Order.asc("nameCache"));
600

    
601
        if(pageSize != null) {
602
            crit.setMaxResults(pageSize);
603
            if(pageNumber != null) {
604
                crit.setFirstResult(pageNumber * pageSize);
605
            }
606
        }
607

    
608
        @SuppressWarnings("unchecked")
609
        List<TaxonName> results = crit.list();
610
        defaultBeanInitializer.initializeAll(results, propertyPaths);
611

    
612
        return results;
613
    }
614

    
615
    @Override
616
    public List<TaxonName> findByFullTitle(String queryString,
617
            MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria, List<String> propertyPaths) {
618

    
619
        Criteria crit = getSession().createCriteria(type);
620
        if (matchmode == null){
621
            matchmode = MatchMode.LIKE;
622
        }
623
        if (matchmode == MatchMode.EXACT) {
624
            crit.add(Restrictions.eq("fullTitleCache", matchmode.queryStringFrom(queryString)));
625
        } else {
626
            crit.add(Restrictions.ilike("fullTitleCache", matchmode.queryStringFrom(queryString)));
627
        }
628
        if(criteria != null){
629
            for (Criterion criterion : criteria) {
630
                crit.add(criterion);
631
            }
632
        }
633
        crit.addOrder(Order.asc("fullTitleCache"));
634

    
635
        if(pageSize != null) {
636
            crit.setMaxResults(pageSize);
637
            if(pageNumber != null) {
638
                crit.setFirstResult(pageNumber * pageSize);
639
            }
640
        }
641

    
642
        @SuppressWarnings("unchecked")
643
        List<TaxonName> results = crit.list();
644
        defaultBeanInitializer.initializeAll(results, propertyPaths);
645

    
646
        return results;
647
    }
648

    
649
    @Override
650
    public List<TaxonName> findByTitle(String queryString,
651
            MatchMode matchmode, Integer pageSize, Integer pageNumber, List<Criterion> criteria, List<String> propertyPaths) {
652

    
653
        Criteria crit = getSession().createCriteria(type);
654
        if (matchmode == MatchMode.EXACT) {
655
            crit.add(Restrictions.eq("titleCache", matchmode.queryStringFrom(queryString)));
656
        } else {
657
            crit.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
658
        }
659
        if(criteria != null){
660
            for (Criterion criterion : criteria) {
661
                crit.add(criterion);
662
            }
663
        }
664
        crit.addOrder(Order.asc("titleCache"));
665

    
666
        if(pageSize != null) {
667
            crit.setMaxResults(pageSize);
668
            if(pageNumber != null) {
669
                crit.setFirstResult(pageNumber * pageSize);
670
            }
671
        }
672

    
673
        @SuppressWarnings("unchecked")
674
        List<TaxonName> results = crit.list();
675
        defaultBeanInitializer.initializeAll(results, propertyPaths);
676

    
677
        return results;
678
    }
679

    
680

    
681
    @Override
682
    public TaxonName findByUuid(UUID uuid, List<Criterion> criteria, List<String> propertyPaths) {
683

    
684
        Criteria crit = getSession().createCriteria(type);
685

    
686
        if (uuid != null) {
687
            crit.add(Restrictions.eq("uuid", uuid));
688
        } else {
689
            logger.warn("UUID is NULL");
690
            return null;
691
        }
692
        if(criteria != null){
693
            for (Criterion criterion : criteria) {
694
                crit.add(criterion);
695
            }
696
        }
697
        crit.addOrder(Order.asc("uuid"));
698

    
699
        @SuppressWarnings("unchecked")
700
        List<TaxonName> results = crit.list();
701
        if (results.size() == 1) {
702
            defaultBeanInitializer.initializeAll(results, propertyPaths);
703
            TaxonName taxonName = results.iterator().next();
704
            return taxonName;
705
        } else if (results.size() > 1) {
706
            logger.error("Multiple results for UUID: " + uuid);
707
        } else if (results.size() == 0) {
708
            logger.info("No results for UUID: " + uuid);
709
        }
710

    
711
        return null;
712
    }
713

    
714

    
715
    @Override
716
    public <S extends TaxonName> List<S> list(Class<S> type, List<Restriction<?>> restrictions, Integer limit,
717
            Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
718
        // TODO Auto-generated method stub
719
        return list(type, restrictions, limit, start, orderHints, propertyPaths, INCLUDE_UNPUBLISHED);
720
    }
721

    
722
    @Override
723
    public <S extends TaxonName> List<S> list(Class<S> type, List<Restriction<?>> restrictions, Integer limit,
724
            Integer start, List<OrderHint> orderHints, List<String> propertyPaths, boolean includePublished) {
725
        Criteria criteria = createCriteria(type, restrictions, false);
726

    
727
        if(!includePublished){
728
            criteria.add(Restrictions.eq("taxonBases.publish", true));
729
        }
730

    
731
        addLimitAndStart(criteria, limit, start);
732
        addOrder(criteria, orderHints);
733

    
734
        @SuppressWarnings("unchecked")
735
        List<S> result = criteria.list();
736
        defaultBeanInitializer.initializeAll(result, propertyPaths);
737
        return result;
738
    }
739

    
740
    @Override
741
    public long count(Class<? extends TaxonName> type, List<Restriction<?>> restrictions) {
742
        return count(type, restrictions, INCLUDE_UNPUBLISHED);
743
    }
744

    
745

    
746
    @Override
747
    public long count(Class<? extends TaxonName> type, List<Restriction<?>> restrictions, boolean includePublished) {
748

    
749
        Criteria criteria = createCriteria(type, restrictions, false);
750
        if(!includePublished){
751
            criteria.add(Restrictions.eq("taxonBases.publish", true));
752
        }
753
        criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
754
        return (Long) criteria.uniqueResult();
755
    }
756

    
757

    
758
    /**
759
     * TODO not yet in interface
760
     * @param clazz
761
     * @return
762
     */
763
    public int countAllRelationships(Class<? extends RelationshipBase> clazz) {
764
        if (clazz != null && ! NameRelationship.class.isAssignableFrom(clazz) && ! HybridRelationship.class.isAssignableFrom(clazz) ){
765
            throw new RuntimeException("Class must be assignable by a taxon or snonym relation");
766
        }
767
        int size = 0;
768

    
769
        if (clazz == null || NameRelationship.class.isAssignableFrom(clazz)){
770
            String hql = " SELECT count(rel) FROM NameRelationship rel";
771
            size += (Long)getSession().createQuery(hql).list().get(0);
772
        }
773
        if (clazz == null || HybridRelationship.class.isAssignableFrom(clazz)){
774
            String hql = " SELECT count(rel) FROM HybridRelationship rel";
775
            size += (Long)getSession().createQuery(hql).list().get(0);
776
        }
777
        return size;
778
    }
779

    
780

    
781
    @Override
782
    public Integer countByName(String queryString, MatchMode matchmode, List<Criterion> criteria) {
783
        //TODO improve performance
784
        boolean includeAuthors = false;
785
        List<TaxonName> results = findByName(
786
                includeAuthors,queryString, matchmode, null, null, criteria, null);
787
        return results.size();
788

    
789
    }
790

    
791
    @Override
792
    public List<UuidAndTitleCache> getUuidAndTitleCacheOfNames(Integer limit, String pattern) {
793
        String queryString = "SELECT uuid, id, fullTitleCache FROM TaxonName LIMIT " + limit;
794

    
795
        @SuppressWarnings("unchecked")
796
        List<Object[]> result = getSession().createSQLQuery(queryString).list();
797

    
798
        if(result.size() == 0){
799
            return null;
800
        }else{
801
            List<UuidAndTitleCache> list = new ArrayList<>(result.size());
802

    
803
            for (Object object : result){
804

    
805
                Object[] objectArray = (Object[]) object;
806

    
807
                UUID uuid = UUID.fromString((String) objectArray[0]);
808
                Integer id = (Integer) objectArray[1];
809
                String titleCache = (String) objectArray[2];
810

    
811
                list.add(new UuidAndTitleCache(type, uuid, id, titleCache));
812
            }
813

    
814
            return list;
815
        }
816
    }
817

    
818
    @Override
819
    public long countByName(Class<TaxonName> clazz,String queryString, MatchMode matchmode, List<Criterion> criteria) {
820
        return super.countByParam(clazz, "nameCache", queryString, matchmode, criteria);
821
    }
822

    
823
    @Override
824
    public long countByFullTitle(Class<TaxonName> clazz,String queryString, MatchMode matchmode, List<Criterion> criteria) {
825
        return super.countByParam(clazz, "fullTitleCache", queryString, matchmode, criteria);
826
    }
827

    
828
    @Override
829
    public List<TaxonName> findByName(Class<TaxonName> clazz,	String queryString, MatchMode matchmode, List<Criterion> criteria,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,	List<String> propertyPaths) {
830
        return super.findByParam(clazz, "nameCache", queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);
831
    }
832

    
833
    @Override
834
    public UUID delete (TaxonName persistentObject){
835
        @SuppressWarnings("rawtypes")
836
        Set<TaxonBase> taxonBases = persistentObject.getTaxonBases();
837

    
838
        getSession().saveOrUpdate(persistentObject);
839
        UUID homotypicalGroupUUID = persistentObject.getHomotypicalGroup().getUuid();
840

    
841

    
842
        for (TaxonBase<?> taxonBase: taxonBases){
843
            taxonDao.delete(taxonBase);
844
        }
845
        HomotypicalGroup homotypicalGroup = homotypicalGroupDao.load(homotypicalGroupUUID);
846
        homotypicalGroup = HibernateProxyHelper.deproxy(homotypicalGroup);
847

    
848
        if (homotypicalGroup != null){
849
            if (homotypicalGroup.getTypifiedNames().contains(persistentObject)){
850
                homotypicalGroup.getTypifiedNames().remove(persistentObject);
851
                homotypicalGroupDao.saveOrUpdate(homotypicalGroup);
852
            }
853
        }
854

    
855
        getSession().delete(persistentObject);
856
        if (homotypicalGroup.getTypifiedNames().isEmpty()){
857
            homotypicalGroupDao.delete(homotypicalGroup);
858
        }
859
        return persistentObject.getUuid();
860
    }
861

    
862

    
863
    @Override
864
    public IZoologicalName findZoologicalNameByUUID(UUID uuid){
865
        Criteria criteria = getSession().createCriteria(type);
866
        if (uuid != null) {
867
            criteria.add(Restrictions.eq("uuid", uuid));
868
        } else {
869
            logger.warn("UUID is NULL");
870
            return null;
871
        }
872

    
873
        @SuppressWarnings("unchecked")
874
        List<TaxonName> results = criteria.list();
875
        if (results.size() == 1) {
876
            defaultBeanInitializer.initializeAll(results, null);
877
            TaxonName taxonName = results.iterator().next();
878
            if (taxonName.isZoological()) {
879
                IZoologicalName zoologicalName = taxonName;
880
                return zoologicalName;
881
            } else {
882
                logger.warn("This UUID (" + uuid + ") does not belong to a ZoologicalName. It belongs to: " + taxonName.getUuid() + " (" + taxonName.getTitleCache() + ")");
883
            }
884
        } else if (results.size() > 1) {
885
            logger.error("Multiple results for UUID: " + uuid);
886
        } else if (results.size() == 0) {
887
            logger.info("No results for UUID: " + uuid);
888
        }
889
        return null;
890
    }
891

    
892
    @Override
893
    public List<HashMap<String,String>> getNameRecords(){
894
    	String sql= "SELECT"
895
    			+ "  (SELECT famName.namecache FROM TaxonNode famNode"
896
    			+ "  LEFT OUTER JOIN TaxonBase famTax ON famNode.taxon_id = famTax.id"
897
    			+ " LEFT OUTER JOIN TaxonName famName ON famTax.name_id = famName.id"
898
    			+ " WHERE famName.rank_id = 795 AND famNode.treeIndex = SUBSTRING(tn.treeIndex, 1, length(famNode.treeIndex))"
899
    			+ "	) as famName, "
900
    			+ " (SELECT famName.namecache FROM TaxonNode famNode "
901
    			+ " LEFT OUTER JOIN TaxonBase famTax ON famNode.taxon_id = famTax.id "
902
    			+ " LEFT OUTER JOIN TaxonName famName ON famTax.name_id = famName.id "
903
    			+ " WHERE famName.rank_id = 795 AND famNode.treeIndex = SUBSTRING(tnAcc.treeIndex, 1, length(famNode.treeIndex))"
904
    			+ "	) as accFamName,tb.DTYPE, tb.id as TaxonID ,tb.titleCache taxonTitle,  tnb.rank_id as RankID, tnb.id as NameID,"
905
    			+ " tnb.namecache as name, tnb.titleCache as nameAuthor, tnb.fullTitleCache nameAndNomRef,"
906
    			+ "	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,"
907
    			+ "	nameType.namecache nameType, nameType.titleCache nameTypeAuthor, nameType.fullTitleCache nameTypeFullTitle, nameTypeRef.titleCache nameTypeRef, "
908
    			+ " inRef.seriespart as inRefSeries, inRef.datepublished_start inRefPublishedStart, inRef.datepublished_end inRefPublishedEnd, inRef.volume as inRefVolume"
909
    			+ " FROM TaxonBase tb"
910
    			+ " LEFT OUTER JOIN TaxonName tnb ON tb.name_id = tnb.id"
911
    			+ "	LEFT OUTER JOIN OriginalSourceBase nosb ON tnb.nomenclaturalSource_id = nosb.id"
912
    			+ " LEFT OUTER JOIN Reference r ON nosb.citation_id = r.id"
913
                + "	LEFT OUTER JOIN TaxonNode tn ON tn.taxon_id = tb.id"
914
    			+ "	LEFT OUTER JOIN TaxonName_TypeDesignationBase typeMN ON typeMN.TaxonName_id = tnb.id"
915
    			+ " LEFT OUTER JOIN TypeDesignationBase tdb ON tdb.id = typeMN.typedesignations_id"
916
    			+ "	LEFT OUTER JOIN TaxonName nameType ON tdb.typename_id = nameType.id"
917
    			+ " LEFT OUTER JOIN OriginalSourceBase nameTypeOsb ON nameType.nomenclaturalSource_id = nameTypeOsb.id"
918
    			+ "	LEFT OUTER JOIN Reference nameTypeRef ON nameTypeOsb.citation_id = nameTypeRef.id"
919
                + "		LEFT OUTER JOIN Reference inRef ON inRef.id = r.inreference_id"
920
    			+ "	LEFT OUTER JOIN TaxonBase accT ON accT.id = tb.acceptedTaxon_id"
921
    			+ "		LEFT OUTER JOIN TaxonNode tnAcc ON tnAcc.taxon_id = accT.id"
922
    			+ "	ORDER BY DTYPE, famName, accFamName,  tnb.rank_id ,tb.titleCache";
923

    
924
    	String hqlQueryStringFrom = "FROM TaxonBase taxonBase "
925
    	        + " LEFT OUTER JOIN taxonBase.name as tnb "
926
    	        + " LEFT OUTER JOIN tnb.nomenclaturalSource as nomSource "
927
    	        + " LEFT OUTER JOIN nomSource.citation as nomRef "
928
                + " LEFT OUTER JOIN taxonBase.taxonNodes as node "
929
    	        + " LEFT OUTER JOIN tnb.typeDesignations as type "
930
    	        + " LEFT OUTER JOIN type.typifiedNames as nameType "
931
    	        + " LEFT OUTER JOIN nameType.nomenclaturalSource as nameTypeSource "
932
    	        + " LEFT OUTER JOIN nameTypeSource.citation as nameTypeRef "
933
                + " LEFT OUTER JOIN nomRef.inReference as inRef "
934
    	        + " LEFT OUTER JOIN taxonBase.acceptedTaxon as accTaxon "
935
    	        + " LEFT OUTER JOIN accTaxon.taxonNodes as accTaxonNodes";
936

    
937

    
938
    	Query hqlQuery = getSession().createQuery(hqlQueryStringFrom);
939
    	List<?> hqlResult = hqlQuery.list();
940

    
941

    
942
		List<HashMap<String,String>> nameRecords = new ArrayList<>();
943
		HashMap<String,String> nameRecord = new HashMap<>();
944
		TaxonNode familyNode = null;
945
		for(Object object : hqlResult){
946
			Object[] row = (Object[])object;
947
			nameRecord = new HashMap<>();
948
			TaxonBase<?> taxonBase = (TaxonBase<?>)row[0];
949
			Taxon accTaxon = null;
950
			if (taxonBase instanceof Taxon){
951
			    accTaxon = HibernateProxyHelper.deproxy(taxonBase, Taxon.class);
952
			} else{
953
			    nameRecord.put("famName", "");
954
			    Synonym syn = HibernateProxyHelper.deproxy(taxonBase, Synonym.class);
955
			    accTaxon = syn.getAcceptedTaxon();
956
			}
957
			Set<TaxonNode> nodes = accTaxon.getTaxonNodes();
958
            if (nodes.size() == 1){
959
                TaxonNode node = nodes.iterator().next();
960
                familyNode = node.getAncestorOfRank(Rank.FAMILY());
961
            }
962

    
963
            nameRecord.put("famName",familyNode.getTaxon().getName().getNameCache());
964
            nameRecord.put("accFamName","");
965

    
966

    
967
			//nameRecord.put("famName",(String)row[0]);
968

    
969
			nameRecord.put("accFamName",(String)row[1]);
970

    
971
			nameRecord.put("DTYPE",(String)row[2]);
972
			nameRecord.put("TaxonID",String.valueOf(row[3]));
973
			nameRecord.put("taxonTitle",(String)row[4]);
974
            nameRecord.put("RankID",String.valueOf(row[5]));
975
            nameRecord.put("NameID",String.valueOf(row[6]));
976
            nameRecord.put("name",(String)row[7]);
977
            nameRecord.put("nameAuthor",(String)row[8]);
978
            nameRecord.put("nameAndNomRef",(String)row[9]);
979
            nameRecord.put("nomRef",(String)row[10]);
980
            nameRecord.put("nomRefAbbrevTitle",(String)row[11]);
981
            nameRecord.put("nomRefTitle",(String)row[12]);
982
            nameRecord.put("nomRefPublishedStart",(String)row[13]);
983
            nameRecord.put("nomRefPublishedEnd",(String)row[14]);
984
            nameRecord.put("nomRefPages",(String)row[15]);
985
            nameRecord.put("inRefAbbrevTitle",(String)row[16]);
986
            nameRecord.put("detail",(String)row[17]);
987
            nameRecord.put("nameType",(String)row[18]);
988
            nameRecord.put("nameTypeAuthor",(String)row[19]);
989
            nameRecord.put("nameTypeFullTitle",(String)row[20]);
990
            nameRecord.put("nameTypeRef",(String)row[21]);
991
            nameRecord.put("inRefSeries",(String)row[22]);
992
            nameRecord.put("inRefPublishedStart",(String)row[23]);
993
            nameRecord.put("inRefPublishedEnd",(String)row[24]);
994
            nameRecord.put("inRefVolume",(String)row[25]);
995
            nameRecords.add(nameRecord);
996
	   }
997

    
998
		return nameRecords;
999
    }
1000

    
1001
    /**
1002
     * {@inheritDoc}
1003
     */
1004
    @Override
1005
    public List<TaxonNameParts> findTaxonNameParts(Optional<String> genusOrUninomial,
1006
            Optional<String> infraGenericEpithet, Optional<String> specificEpithet,
1007
            Optional<String> infraSpecificEpithet, Rank rank, Collection<UUID> excludedNamesUuids, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints) {
1008

    
1009
        StringBuilder hql = prepareFindTaxonNameParts(false, genusOrUninomial, infraGenericEpithet,
1010
                specificEpithet, infraSpecificEpithet, rank, excludedNamesUuids);
1011
        addOrder(hql, "n", orderHints);
1012
        Query query = getSession().createQuery(hql.toString());
1013
        if(rank != null){
1014
            query.setParameter("rank", rank);
1015
        }
1016
        if(excludedNamesUuids != null && excludedNamesUuids.size() > 0){
1017
            query.setParameterList("excludedNamesUuids", excludedNamesUuids);
1018
        }
1019
        setPagingParameter(query, pageSize, pageIndex);
1020
        @SuppressWarnings("unchecked")
1021
        List<TaxonNameParts> result = query.list();
1022
        return result;
1023
    }
1024

    
1025

    
1026

    
1027
    /**
1028
     * {@inheritDoc}
1029
     */
1030
    @Override
1031
    public long countTaxonNameParts(Optional<String> genusOrUninomial, Optional<String> infraGenericEpithet,
1032
            Optional<String> specificEpithet, Optional<String> infraSpecificEpithet, Rank rank, Collection<UUID> excludedNamesUUIDs) {
1033

    
1034
        StringBuilder hql = prepareFindTaxonNameParts(true, genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet, rank, excludedNamesUUIDs);
1035
        Query query = getSession().createQuery(hql.toString());
1036
        if(rank != null){
1037
            query.setParameter("rank", rank);
1038
        }
1039
        if(excludedNamesUUIDs != null && excludedNamesUUIDs.size() > 0){
1040
            query.setParameterList("excludedNamesUuids", excludedNamesUUIDs);
1041
        }
1042

    
1043
        Object count = query.uniqueResult();
1044
        return (Long) count;
1045
    }
1046

    
1047
    /**
1048
     * @return
1049
     */
1050
    private StringBuilder prepareFindTaxonNameParts(boolean doCount, Optional<String> genusOrUninomial,
1051
            Optional<String> infraGenericEpithet, Optional<String> specificEpithet,
1052
            Optional<String> infraSpecificEpithet, Rank rank, Collection<UUID> excludedNamesUuids) {
1053

    
1054
        StringBuilder hql = new StringBuilder();
1055
        if(doCount){
1056
            hql.append("select count(n.id) ");
1057
        } else {
1058
            hql.append("select new eu.etaxonomy.cdm.persistence.dto.TaxonNameParts(n.id, n.uuid, n.rank, n.genusOrUninomial, n.infraGenericEpithet, n.specificEpithet, n.infraSpecificEpithet) ");
1059
        }
1060
        hql.append("from TaxonName n where 1 = 1 ");
1061

    
1062
        if(rank != null){
1063
            hql.append("and n.rank = :rank ");
1064
        }
1065
        if(excludedNamesUuids != null && excludedNamesUuids.size() > 0){
1066
            hql.append("and n.uuid not in ( :excludedNamesUuids ) ");
1067
        }
1068

    
1069
        addFieldPredicate(hql, "n.genusOrUninomial", genusOrUninomial);
1070
        addFieldPredicate(hql, "n.infraGenericEpithet", infraGenericEpithet);
1071
        addFieldPredicate(hql, "n.specificEpithet", specificEpithet);
1072
        addFieldPredicate(hql, "n.infraSpecificEpithet", infraSpecificEpithet);
1073

    
1074
        return hql;
1075
    }
1076

    
1077
    @Override
1078
    public long countNameRelationships(Set<NameRelationshipType> types) {
1079
        Criteria criteria = getSession().createCriteria(NameRelationship.class);
1080

    
1081
        if (types != null) {
1082
            if (types.isEmpty()){
1083
                return 0l;
1084
            }else{
1085
                criteria.add(Restrictions.in("type", types) );
1086
            }
1087
        }
1088
        //count
1089
        criteria.setProjection(Projections.rowCount());
1090
        long result = (Long)criteria.uniqueResult();
1091

    
1092
        return result;
1093
    }
1094

    
1095
    @Override
1096
    public List<NameRelationship> getNameRelationships(Set<NameRelationshipType> types,
1097
            Integer pageSize, Integer pageNumber,
1098
            List<OrderHint> orderHints, List<String> propertyPaths) {
1099

    
1100
        Criteria criteria = getCriteria(NameRelationship.class);
1101
        if (types != null) {
1102
            if (types.isEmpty()){
1103
                return new ArrayList<>();
1104
            }else{
1105
                criteria.add(Restrictions.in("type", types) );
1106
            }
1107
        }
1108
        addOrder(criteria,orderHints);
1109
        addPageSizeAndNumber(criteria, pageSize, pageNumber);
1110

    
1111
        @SuppressWarnings("unchecked")
1112
        List<NameRelationship> results = criteria.list();
1113
        defaultBeanInitializer.initializeAll(results, propertyPaths);
1114

    
1115
        return results;
1116
    }
1117

    
1118
    @Override
1119
    public long countHybridRelationships(Set<HybridRelationshipType> types) {
1120
        Criteria criteria = getSession().createCriteria(HybridRelationship.class);
1121

    
1122
        if (types != null) {
1123
            if (types.isEmpty()){
1124
                return 0l;
1125
            }else{
1126
                criteria.add(Restrictions.in("type", types) );
1127
            }
1128
        }
1129
        //count
1130
        criteria.setProjection(Projections.rowCount());
1131
        long result = (Long)criteria.uniqueResult();
1132

    
1133
        return result;
1134
    }
1135

    
1136
    @Override
1137
    public List<HybridRelationship> getHybridRelationships(Set<HybridRelationshipType> types,
1138
            Integer pageSize, Integer pageNumber,
1139
            List<OrderHint> orderHints, List<String> propertyPaths) {
1140

    
1141
        Criteria criteria = getCriteria(HybridRelationship.class);
1142
        if (types != null) {
1143
            if (types.isEmpty()){
1144
                return new ArrayList<>();
1145
            }else{
1146
                criteria.add(Restrictions.in("type", types) );
1147
            }
1148
        }
1149
        addOrder(criteria,orderHints);
1150
        addPageSizeAndNumber(criteria, pageSize, pageNumber);
1151

    
1152
        @SuppressWarnings("unchecked")
1153
        List<HybridRelationship> results = criteria.list();
1154
        defaultBeanInitializer.initializeAll(results, propertyPaths);
1155

    
1156
        return results;
1157
    }
1158

    
1159

    
1160
}
(4-4/5)