Project

General

Profile

Download (34.3 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2008 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*/
6

    
7
package eu.etaxonomy.cdm.persistence.dao.hibernate.occurrence;
8

    
9
import java.util.ArrayList;
10
import java.util.Collection;
11
import java.util.Collections;
12
import java.util.HashSet;
13
import java.util.List;
14
import java.util.Set;
15
import java.util.UUID;
16

    
17
import org.apache.log4j.Logger;
18
import org.hibernate.Criteria;
19
import org.hibernate.Hibernate;
20
import org.hibernate.Query;
21
import org.hibernate.Session;
22
import org.hibernate.criterion.Projections;
23
import org.hibernate.criterion.Restrictions;
24
import org.hibernate.envers.query.AuditEntity;
25
import org.hibernate.envers.query.AuditQuery;
26
import org.hibernate.search.FullTextSession;
27
import org.hibernate.search.Search;
28
import org.springframework.beans.factory.annotation.Autowired;
29
import org.springframework.stereotype.Repository;
30

    
31
import eu.etaxonomy.cdm.model.description.DescriptionBase;
32
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
33
import eu.etaxonomy.cdm.model.media.Media;
34
import eu.etaxonomy.cdm.model.molecular.DnaSample;
35
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
36
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
37
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
38
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
39
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
40
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
41
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
42
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
43
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
44
import eu.etaxonomy.cdm.model.taxon.Synonym;
45
import eu.etaxonomy.cdm.model.taxon.Taxon;
46
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
47
import eu.etaxonomy.cdm.model.view.AuditEvent;
48
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
49
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
50
import eu.etaxonomy.cdm.persistence.dao.hibernate.taxon.TaxonDaoHibernateImpl;
51
import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
52
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
53
import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;
54
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
55
import eu.etaxonomy.cdm.persistence.query.MatchMode;
56
import eu.etaxonomy.cdm.persistence.query.OrderHint;
57

    
58
/**
59
 * @author a.babadshanjan
60
 * @created 01.09.2008
61
 */
62
@Repository
63
public class OccurrenceDaoHibernateImpl extends IdentifiableDaoBase<SpecimenOrObservationBase> implements IOccurrenceDao {
64

    
65
    @SuppressWarnings("unused")
66
    private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);
67

    
68
    @Autowired
69
    private IDescriptionDao descriptionDao;
70

    
71
    @Autowired
72
    private ITaxonNameDao taxonNameDao;
73

    
74
    @Autowired
75
    private IHomotypicalGroupDao homotypicalGroupDao;
76

    
77
    public OccurrenceDaoHibernateImpl() {
78
        super(SpecimenOrObservationBase.class);
79
        indexedClasses = new Class[7];
80
        indexedClasses[0] = FieldUnit.class;
81
        indexedClasses[1] = DerivedUnit.class;
82
        indexedClasses[5] = DnaSample.class;
83
    }
84

    
85
    @Override
86
    public int countDerivationEvents(SpecimenOrObservationBase occurence) {
87
        checkNotInPriorView("OccurrenceDaoHibernateImpl.countDerivationEvents(SpecimenOrObservationBase occurence)");
88
        Query query = getSession().createQuery("select count(distinct derivationEvent) from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
89
        query.setParameter("occurence", occurence);
90

    
91
        return ((Long)query.uniqueResult()).intValue();
92
    }
93

    
94
    @Override
95
    public int countDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase) {
96
        AuditEvent auditEvent = getAuditEventFromContext();
97
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
98
            Criteria criteria = getSession().createCriteria(DeterminationEvent.class);
99
            if(occurrence != null) {
100
                criteria.add(Restrictions.eq("identifiedUnit",occurrence));
101
            }
102

    
103
            if(taxonBase != null) {
104
                criteria.add(Restrictions.eq("taxon",taxonBase));
105
            }
106

    
107
            criteria.setProjection(Projections.rowCount());
108
            return ((Number)criteria.uniqueResult()).intValue();
109
        } else {
110
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());
111

    
112
            if(occurrence != null) {
113
                query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));
114
            }
115

    
116
            if(taxonBase != null) {
117
                query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));
118
            }
119
            query.addProjection(AuditEntity.id().count());
120

    
121
            return ((Long)query.getSingleResult()).intValue();
122
        }
123
    }
124

    
125
    @Override
126
    public int countMedia(SpecimenOrObservationBase occurence) {
127
        checkNotInPriorView("OccurrenceDaoHibernateImpl.countMedia(SpecimenOrObservationBase occurence)");
128
        Query query = getSession().createQuery("select count(media) from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
129
        query.setParameter("occurence", occurence);
130

    
131
        return ((Long)query.uniqueResult()).intValue();
132
    }
133

    
134
    @Override
135
    public List<DerivationEvent> getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber, List<String> propertyPaths) {
136
        checkNotInPriorView("OccurrenceDaoHibernateImpl.getDerivationEvents(SpecimenOrObservationBase occurence, Integer pageSize,Integer pageNumber)");
137
        Query query = getSession().createQuery("select distinct derivationEvent from DerivationEvent derivationEvent join derivationEvent.originals occurence where occurence = :occurence");
138
        query.setParameter("occurence", occurence);
139

    
140
        if(pageSize != null) {
141
            query.setMaxResults(pageSize);
142
            if(pageNumber != null) {
143
                query.setFirstResult(pageNumber * pageSize);
144
            } else {
145
                query.setFirstResult(0);
146
            }
147
        }
148

    
149
        List<DerivationEvent> result = query.list();
150
        defaultBeanInitializer.initializeAll(result, propertyPaths);
151
        return result;
152
    }
153

    
154
    @Override
155
    public List<DeterminationEvent> getDeterminations(SpecimenOrObservationBase occurrence, TaxonBase taxonBase, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
156
        AuditEvent auditEvent = getAuditEventFromContext();
157
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
158
            Criteria criteria = getSession().createCriteria(DeterminationEvent.class);
159
            if(occurrence != null) {
160
                criteria.add(Restrictions.eq("identifiedUnit",occurrence));
161
            }
162

    
163
            if(taxonBase != null) {
164
                criteria.add(Restrictions.eq("taxon",taxonBase));
165
            }
166

    
167
            if(pageSize != null) {
168
                criteria.setMaxResults(pageSize);
169
                if(pageNumber != null) {
170
                    criteria.setFirstResult(pageNumber * pageSize);
171
                } else {
172
                    criteria.setFirstResult(0);
173
                }
174
            }
175
            List<DeterminationEvent> result = criteria.list();
176
            defaultBeanInitializer.initializeAll(result, propertyPaths);
177
            return result;
178
        } else {
179
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(DeterminationEvent.class,auditEvent.getRevisionNumber());
180
            if(occurrence != null) {
181
                query.add(AuditEntity.relatedId("identifiedUnit").eq(occurrence.getId()));
182
            }
183

    
184
            if(taxonBase != null) {
185
                query.add(AuditEntity.relatedId("taxon").eq(taxonBase.getId()));
186
            }
187
            if(pageSize != null) {
188
                query.setMaxResults(pageSize);
189
                if(pageNumber != null) {
190
                    query.setFirstResult(pageNumber * pageSize);
191
                } else {
192
                    query.setFirstResult(0);
193
                }
194
            }
195
            List<DeterminationEvent> result = query.getResultList();
196
            defaultBeanInitializer.initializeAll(result, propertyPaths);
197
            return result;
198
        }
199
    }
200

    
201
    @Override
202
    public List<Media> getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
203
        checkNotInPriorView("OccurrenceDaoHibernateImpl.getMedia(SpecimenOrObservationBase occurence, Integer pageSize, Integer pageNumber, List<String> propertyPaths)");
204
        Query query = getSession().createQuery("select media from SpecimenOrObservationBase occurence join occurence.media media where occurence = :occurence");
205
        query.setParameter("occurence", occurence);
206

    
207
        if(pageSize != null) {
208
            query.setMaxResults(pageSize);
209
            if(pageNumber != null) {
210
                query.setFirstResult(pageNumber * pageSize);
211
            } else {
212
                query.setFirstResult(0);
213
            }
214
        }
215

    
216
        List<Media> results = query.list();
217
        defaultBeanInitializer.initializeAll(results, propertyPaths);
218
        return results;
219
    }
220

    
221
    @Override
222
    public void rebuildIndex() {
223
        FullTextSession fullTextSession = Search.getFullTextSession(getSession());
224

    
225
        for(SpecimenOrObservationBase occurrence : list(null,null)) { // re-index all taxon base
226

    
227
            for(DeterminationEvent determination : (Set<DeterminationEvent>)occurrence.getDeterminations()) {
228
                Hibernate.initialize(determination.getActor());
229
                Hibernate.initialize(determination.getTaxon());
230
            }
231
            Hibernate.initialize(occurrence.getDefinition());
232
            if(occurrence instanceof DerivedUnit) {
233
                DerivedUnit derivedUnit = (DerivedUnit) occurrence;
234
                Hibernate.initialize(derivedUnit.getCollection());
235
                if(derivedUnit.getCollection() != null) {
236
                    Hibernate.initialize(derivedUnit.getCollection().getSuperCollection());
237
                    Hibernate.initialize(derivedUnit.getCollection().getInstitute());
238
                }
239
                Hibernate.initialize(derivedUnit.getStoredUnder());
240
                SpecimenOrObservationBase original = derivedUnit.getOriginalUnit();
241
                if(original != null && original.isInstanceOf(FieldUnit.class)) {
242
                    FieldUnit fieldUnit = original.deproxy(original, FieldUnit.class);
243
                    Hibernate.initialize(fieldUnit.getGatheringEvent());
244
                    if(fieldUnit.getGatheringEvent() != null) {
245
                        Hibernate.initialize(fieldUnit.getGatheringEvent().getActor());
246
                    }
247
                }
248
            }
249
            fullTextSession.index(occurrence);
250
        }
251
        fullTextSession.flushToIndexes();
252
    }
253

    
254
    @Override
255
    public int count(Class<? extends SpecimenOrObservationBase> clazz,	TaxonNameBase determinedAs) {
256

    
257
        Criteria criteria = null;
258
        if(clazz == null) {
259
            criteria = getSession().createCriteria(type);
260
        } else {
261
            criteria = getSession().createCriteria(clazz);
262
        }
263

    
264
        criteria.createCriteria("determinations").add(Restrictions.eq("taxonName", determinedAs));
265
        criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
266
        return ((Number)criteria.uniqueResult()).intValue();
267
    }
268

    
269
    @Override
270
    public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonNameBase determinedAs, Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths) {
271
        Criteria criteria = null;
272
        if(clazz == null) {
273
            criteria = getSession().createCriteria(type);
274
        } else {
275
            criteria = getSession().createCriteria(clazz);
276
        }
277

    
278
        criteria.createCriteria("determinations").add(Restrictions.eq("taxonName", determinedAs));
279

    
280
        if(limit != null) {
281
            if(start != null) {
282
                criteria.setFirstResult(start);
283
            } else {
284
                criteria.setFirstResult(0);
285
            }
286
            criteria.setMaxResults(limit);
287
        }
288

    
289
        addOrder(criteria,orderHints);
290

    
291
        List<SpecimenOrObservationBase> results = criteria.list();
292
        defaultBeanInitializer.initializeAll(results, propertyPaths);
293
        return results;
294
    }
295

    
296
    @Override
297
    public int count(Class<? extends SpecimenOrObservationBase> clazz,	TaxonBase determinedAs) {
298

    
299
        Criteria criteria = null;
300
        if(clazz == null) {
301
            criteria = getSession().createCriteria(type);
302
        } else {
303
            criteria = getSession().createCriteria(clazz);
304
        }
305

    
306
        criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));
307
        criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
308
        return ((Number)criteria.uniqueResult()).intValue();
309
    }
310

    
311
    @Override
312
    public List<SpecimenOrObservationBase> list(Class<? extends SpecimenOrObservationBase> clazz, TaxonBase determinedAs, Integer limit, Integer start,	List<OrderHint> orderHints, List<String> propertyPaths) {
313
        Criteria criteria = null;
314
        if(clazz == null) {
315
            criteria = getSession().createCriteria(type);
316
        } else {
317
            criteria = getSession().createCriteria(clazz);
318
        }
319

    
320
        criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));
321

    
322
        if(limit != null) {
323
            if(start != null) {
324
                criteria.setFirstResult(start);
325
            } else {
326
                criteria.setFirstResult(0);
327
            }
328
            criteria.setMaxResults(limit);
329
        }
330

    
331
        addOrder(criteria,orderHints);
332

    
333
        List<SpecimenOrObservationBase> results = criteria.list();
334
        defaultBeanInitializer.initializeAll(results, propertyPaths);
335
        return results;
336
    }
337

    
338
    @Override
339
    public <T extends SpecimenOrObservationBase> List<T> findOccurrences(Class<T> clazz, String queryString,
340
            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, TaxonNameBase associatedTaxonName,
341
            MatchMode matchmode, Integer limit,
342
            Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
343

    
344
        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,
345
                associatedTaxon, associatedTaxonName, matchmode, limit, start, orderHints, propertyPaths);
346

    
347
        if(criteria!=null){
348

    
349
            if(limit != null) {
350
                if(start != null) {
351
                    criteria.setFirstResult(start);
352
                } else {
353
                    criteria.setFirstResult(0);
354
                }
355
                criteria.setMaxResults(limit);
356
            }
357

    
358
            if(orderHints!=null){
359
                addOrder(criteria,orderHints);
360
            }
361

    
362
            List<T> results = criteria.list();
363
            defaultBeanInitializer.initializeAll(results, propertyPaths);
364
            return results;
365
        }
366
        return Collections.EMPTY_LIST;
367
    }
368

    
369
    private <T extends SpecimenOrObservationBase> Criteria createFindOccurrenceCriteria(Class<T> clazz, String queryString,
370
            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, TaxonNameBase associatedTaxonName, MatchMode matchmode, Integer limit,
371
            Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
372
        Criteria criteria = null;
373

    
374
        if(clazz == null) {
375
            criteria = getSession().createCriteria(type);
376
        } else {
377
            criteria = getSession().createCriteria(clazz);
378
        }
379

    
380
        //queryString
381
        if (queryString != null) {
382
            if(matchmode == null) {
383
                matchmode = MatchMode.ANYWHERE;
384
                criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString)));
385
            } else if(matchmode == MatchMode.BEGINNING) {
386
                criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.START));
387
            } else if(matchmode == MatchMode.END) {
388
                criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.END));
389
            } else if(matchmode == MatchMode.EXACT) {
390
                criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.EXACT));
391
            } else {
392
                criteria.add(Restrictions.ilike("titleCache", matchmode.queryStringFrom(queryString), org.hibernate.criterion.MatchMode.ANYWHERE));
393
            }
394
        }
395

    
396
        //significant identifier
397
        if (significantIdentifier != null) {
398
            criteria.add(Restrictions.or(Restrictions.ilike("accessionNumber", significantIdentifier),
399
                    Restrictions.ilike("catalogNumber", significantIdentifier), Restrictions.ilike("barcode", significantIdentifier)));
400
        }
401

    
402
        //recordBasis/SpecimenOrObservationType
403
        Set<SpecimenOrObservationType> typeAndSubtypes = new HashSet<SpecimenOrObservationType>();
404
        if(recordBasis==null){
405
            //add all types
406
            SpecimenOrObservationType[] values = SpecimenOrObservationType.values();
407
            for (SpecimenOrObservationType specimenOrObservationType : values) {
408
                typeAndSubtypes.add(specimenOrObservationType);
409
            }
410
        }
411
        else{
412
            typeAndSubtypes = recordBasis.getGeneralizationOf(true);
413
            typeAndSubtypes.add(recordBasis);
414
        }
415
        criteria.add(Restrictions.in("recordBasis", typeAndSubtypes));
416

    
417
        Set<UUID> associationUuids = new HashSet<UUID>();
418
        //taxon associations
419
        if(associatedTaxon!=null){
420
            List<? extends SpecimenOrObservationBase> associatedTaxaList = listByAssociatedTaxon(clazz, associatedTaxon, limit, start, orderHints, propertyPaths);
421
            if(associatedTaxaList!=null){
422
                for (SpecimenOrObservationBase specimenOrObservationBase : associatedTaxaList) {
423
                    associationUuids.add(specimenOrObservationBase.getUuid());
424
                }
425
            }
426
        }
427
        //taxon name associations
428
        else if(associatedTaxonName!=null){
429
            List<? extends SpecimenOrObservationBase> associatedTaxaList = listByAssociatedTaxonName(clazz, associatedTaxonName, limit, start, orderHints, propertyPaths);
430
            if(associatedTaxaList!=null){
431
                for (SpecimenOrObservationBase specimenOrObservationBase : associatedTaxaList) {
432
                    associationUuids.add(specimenOrObservationBase.getUuid());
433
                }
434
            }
435
        }
436
        if(associatedTaxon!=null || associatedTaxonName!=null){
437
            if(!associationUuids.isEmpty()){
438
                criteria.add(Restrictions.in("uuid", associationUuids));
439
            }
440
            else{
441
                return null;
442
            }
443
        }
444

    
445
        return criteria;
446
    }
447

    
448

    
449
    @Override
450
    public <T extends SpecimenOrObservationBase> int countOccurrences(Class<T> clazz, String queryString,
451
            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, TaxonNameBase associatedTaxonName,
452
            MatchMode matchmode, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
453
        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,
454
                associatedTaxon, associatedTaxonName, matchmode, limit, start, orderHints, propertyPaths);
455

    
456
        if(criteria!=null){
457

    
458
            criteria.setProjection(Projections.rowCount());
459

    
460
            return ((Number)criteria.uniqueResult()).intValue();
461
        }
462
        return 0;
463
    }
464

    
465
    @Override
466
    public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache() {
467
        List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<UuidAndTitleCache<DerivedUnit>>();
468
        Session session = getSession();
469

    
470
        Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where NOT dtype = " + FieldUnit.class.getSimpleName());
471

    
472
        List<Object[]> result = query.list();
473

    
474
        for(Object[] object : result){
475
            list.add(new UuidAndTitleCache<DerivedUnit>(DerivedUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
476
        }
477

    
478
        return list;
479
    }
480

    
481
    @Override
482
    public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {
483
        List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<UuidAndTitleCache<FieldUnit>>();
484
        Session session = getSession();
485

    
486
        Query query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where dtype = " + FieldUnit.class.getSimpleName());
487

    
488
        List<Object[]> result = query.list();
489

    
490
        for(Object[] object : result){
491
            list.add(new UuidAndTitleCache<FieldUnit>(FieldUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
492
        }
493

    
494
        return list;
495
    }
496

    
497
    @Override
498
    public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxonName(Class<T> type,
499
            TaxonNameBase associatedTaxonName, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
500
        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
501

    
502
        // A Taxon name may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
503
        List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxonName, null, 0, null, null);
504
        setOfAll.addAll(byDetermination);
505

    
506
        if(setOfAll.size() == 0){
507
            // no need querying the data base
508
            return new ArrayList<T>();
509
        }
510

    
511
        String queryString =
512
            "select sob " +
513
            " from SpecimenOrObservationBase sob" +
514
            " where sob in (:setOfAll)";
515

    
516
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
517
            queryString += " and sob.class = :type";
518
        }
519

    
520
        if(orderHints != null && orderHints.size() > 0){
521
            queryString += " order by ";
522
            String orderStr = "";
523
            for(OrderHint orderHint : orderHints){
524
                if(orderStr.length() > 0){
525
                    orderStr += ", ";
526
                }
527
                queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
528
            }
529
            queryString += orderStr;
530
        }
531

    
532
        Query query = getSession().createQuery(queryString);
533
        query.setParameterList("setOfAll", setOfAll);
534

    
535
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
536
            query.setParameter("type", type.getSimpleName());
537
        }
538

    
539
        if(limit != null) {
540
            if(start != null) {
541
                query.setFirstResult(start);
542
            } else {
543
                query.setFirstResult(0);
544
            }
545
            query.setMaxResults(limit);
546
        }
547

    
548

    
549
        List<T> results = query.list();
550
        defaultBeanInitializer.initializeAll(results, propertyPaths);
551
        return results;
552
    }
553

    
554
    @Override
555
    public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type,
556
            Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
557

    
558
        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
559

    
560
        // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
561
        List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxon, null, 0, null, null);
562
        setOfAll.addAll(byDetermination);
563
        //check also for synonyms
564
        for (Synonym synonym : associatedTaxon.getSynonyms()) {
565
            setOfAll.addAll(list(type, synonym, null, 0, null, null));
566
        }
567
        //check also for name determinations
568
        setOfAll.addAll(list(type, associatedTaxon.getName(), null, 0, null, null));
569
        for (TaxonNameBase synonymName : associatedTaxon.getSynonymNames()) {
570
            setOfAll.addAll(list(type, synonymName, null, 0, null, null));
571
        }
572

    
573

    
574
        // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits
575
        List<IndividualsAssociation> byIndividualsAssociation = descriptionDao.getDescriptionElementForTaxon(
576
                associatedTaxon.getUuid(), null, IndividualsAssociation.class, null, 0, null);
577
        for(IndividualsAssociation individualsAssociation : byIndividualsAssociation){
578
            setOfAll.add(individualsAssociation.getAssociatedSpecimenOrObservation());
579
        }
580

    
581
        // SpecimenTypeDesignations may be associated with the TaxonName.
582
        List<SpecimenTypeDesignation> bySpecimenTypeDesignation = taxonNameDao.getTypeDesignations(associatedTaxon.getName(),
583
                SpecimenTypeDesignation.class, null, null, 0, null);
584
        for (SpecimenTypeDesignation specimenTypeDesignation : bySpecimenTypeDesignation) {
585
            setOfAll.add(specimenTypeDesignation.getTypeSpecimen());
586
        }
587

    
588
        // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.
589
        for(HomotypicalGroup homotypicalGroup :  associatedTaxon.getHomotypicSynonymyGroups()) {
590
            List<SpecimenTypeDesignation> byHomotypicalGroup = homotypicalGroupDao.getTypeDesignations(homotypicalGroup, SpecimenTypeDesignation.class, null, null, 0, null);
591
            for (SpecimenTypeDesignation specimenTypeDesignation : byHomotypicalGroup) {
592
                setOfAll.add(specimenTypeDesignation.getTypeSpecimen());
593
            }
594
        }
595

    
596
        if(setOfAll.size() == 0){
597
            // no need querying the data base
598
            return new ArrayList<T>();
599
        }
600

    
601
        String queryString =
602
            "select sob " +
603
            " from SpecimenOrObservationBase sob" +
604
            " where sob in (:setOfAll)";
605

    
606
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
607
            queryString += " and sob.class = :type";
608
        }
609

    
610
        if(orderHints != null && orderHints.size() > 0){
611
            queryString += " order by ";
612
            String orderStr = "";
613
            for(OrderHint orderHint : orderHints){
614
                if(orderStr.length() > 0){
615
                    orderStr += ", ";
616
                }
617
                queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
618
            }
619
            queryString += orderStr;
620
        }
621

    
622
        Query query = getSession().createQuery(queryString);
623
        query.setParameterList("setOfAll", setOfAll);
624

    
625
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
626
            query.setParameter("type", type.getSimpleName());
627
        }
628

    
629
        if(limit != null) {
630
            if(start != null) {
631
                query.setFirstResult(start);
632
            } else {
633
                query.setFirstResult(0);
634
            }
635
            query.setMaxResults(limit);
636
        }
637

    
638

    
639
        List<T> results = query.list();
640
        defaultBeanInitializer.initializeAll(results, propertyPaths);
641
        return results;
642
    }
643

    
644
    @Override
645
    public Collection<SpecimenOrObservationBase> listBySpecimenOrObservationType(SpecimenOrObservationType type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
646
        String queryString = "FROM SpecimenOrObservationBase specimens WHERE specimens.recordBasis = :type";
647

    
648
        if(orderHints != null && orderHints.size() > 0){
649
            queryString += " order by ";
650
            String orderStr = "";
651
            for(OrderHint orderHint : orderHints){
652
                if(orderStr.length() > 0){
653
                    orderStr += ", ";
654
                }
655
                queryString += "specimens." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
656
            }
657
            queryString += orderStr;
658
        }
659

    
660
        Query query = getSession().createQuery(queryString);
661
        query.setParameter("type", type);
662

    
663
        if(limit != null) {
664
            if(start != null) {
665
                query.setFirstResult(start);
666
            } else {
667
                query.setFirstResult(0);
668
            }
669
            query.setMaxResults(limit);
670
        }
671

    
672
        List results = query.list();
673
        defaultBeanInitializer.initializeAll(results, propertyPaths);
674
        return results;
675
    }
676

    
677
    @Override
678
    public Collection<DeterminationEvent> listDeterminationEvents(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
679
        String queryString = "FROM DeterminationEvent determination WHERE determination.identifiedUnit = :specimen";
680

    
681
        if(orderHints != null && orderHints.size() > 0){
682
            queryString += " order by ";
683
            String orderStr = "";
684
            for(OrderHint orderHint : orderHints){
685
                if(orderStr.length() > 0){
686
                    orderStr += ", ";
687
                }
688
                queryString += "determination." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
689
            }
690
            queryString += orderStr;
691
        }
692

    
693
        Query query = getSession().createQuery(queryString);
694
        query.setParameter("specimen", specimen);
695

    
696
        if(limit != null) {
697
            if(start != null) {
698
                query.setFirstResult(start);
699
            } else {
700
                query.setFirstResult(0);
701
            }
702
            query.setMaxResults(limit);
703
        }
704

    
705
        List results = query.list();
706
        defaultBeanInitializer.initializeAll(results, propertyPaths);
707
        return results;
708
    }
709

    
710
    @Override
711
    public Collection<SpecimenTypeDesignation> listTypeDesignations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
712
        String queryString = "FROM SpecimenTypeDesignation designations WHERE designations.typeSpecimen = :specimen";
713

    
714
        if(orderHints != null && orderHints.size() > 0){
715
            queryString += " order by ";
716
            String orderStr = "";
717
            for(OrderHint orderHint : orderHints){
718
                if(orderStr.length() > 0){
719
                    orderStr += ", ";
720
                }
721
                queryString += "designations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
722
            }
723
            queryString += orderStr;
724
        }
725

    
726
        Query query = getSession().createQuery(queryString);
727
        query.setParameter("specimen", specimen);
728

    
729
        if(limit != null) {
730
            if(start != null) {
731
                query.setFirstResult(start);
732
            } else {
733
                query.setFirstResult(0);
734
            }
735
            query.setMaxResults(limit);
736
        }
737

    
738
        List results = query.list();
739
        defaultBeanInitializer.initializeAll(results, propertyPaths);
740
        return results;
741
    }
742

    
743
    @Override
744
    public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
745
        //DISTINCT is necessary if more than one description exists for a taxon because we create the cross product of all taxon descriptions and description elements
746
        String queryString = "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";
747

    
748
        if(orderHints != null && orderHints.size() > 0){
749
            queryString += " order by ";
750
            String orderStr = "";
751
            for(OrderHint orderHint : orderHints){
752
                if(orderStr.length() > 0){
753
                    orderStr += ", ";
754
                }
755
                queryString += "associations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
756
            }
757
            queryString += orderStr;
758
        }
759

    
760
        Query query = getSession().createQuery(queryString);
761
        query.setParameter("specimen", specimen);
762

    
763
        if(limit != null) {
764
            if(start != null) {
765
                query.setFirstResult(start);
766
            } else {
767
                query.setFirstResult(0);
768
            }
769
            query.setMaxResults(limit);
770
        }
771

    
772
        List results = query.list();
773
        defaultBeanInitializer.initializeAll(results, propertyPaths);
774
        return results;
775
    }
776

    
777
    @Override
778
    public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
779
        //DISTINCT is necessary if more than one description exists for a taxon because we create the cross product of all taxon descriptions and description elements
780
        String queryString = "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";
781

    
782
        if(orderHints != null && orderHints.size() > 0){
783
            queryString += " order by ";
784
            String orderStr = "";
785
            for(OrderHint orderHint : orderHints){
786
                if(orderStr.length() > 0){
787
                    orderStr += ", ";
788
                }
789
                queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
790
            }
791
            queryString += orderStr;
792
        }
793

    
794
        Query query = getSession().createQuery(queryString);
795
        query.setParameter("specimen", specimen);
796

    
797
        if(limit != null) {
798
            if(start != null) {
799
                query.setFirstResult(start);
800
            } else {
801
                query.setFirstResult(0);
802
            }
803
            query.setMaxResults(limit);
804
        }
805

    
806
        List results = query.list();
807
        defaultBeanInitializer.initializeAll(results, propertyPaths);
808
        return results;
809
    }
810

    
811
}
(2-2/2)