Project

General

Profile

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

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

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

    
69
    @Autowired
70
    private IDescriptionDao descriptionDao;
71

    
72
    @Autowired
73
    private ITaxonNameDao taxonNameDao;
74

    
75
    @Autowired
76
    private IHomotypicalGroupDao homotypicalGroupDao;
77

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
226
        for(SpecimenOrObservationBase<?> occurrence : list(null,null)) { // re-index all taxon base
227

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

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

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

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

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

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

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

    
290
        addOrder(criteria,orderHints);
291

    
292
        @SuppressWarnings("unchecked")
293
        List<SpecimenOrObservationBase> results = criteria.list();
294
        defaultBeanInitializer.initializeAll(results, propertyPaths);
295
        return results;
296
    }
297

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

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

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

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

    
322
        criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));
323

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

    
333
        addOrder(criteria,orderHints);
334

    
335
        @SuppressWarnings("unchecked")
336
        List<SpecimenOrObservationBase> results = criteria.list();
337
        defaultBeanInitializer.initializeAll(results, propertyPaths);
338
        return results;
339
    }
340

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

    
347
        Criteria criteria = createFindOccurrenceCriteria(clazz, queryString, significantIdentifier, recordBasis,
348
                associatedTaxon, associatedTaxonName, matchmode, limit, start, orderHints, propertyPaths);
349

    
350
        if(criteria!=null){
351

    
352
            if(limit != null) {
353
                if(start != null) {
354
                    criteria.setFirstResult(start);
355
                } else {
356
                    criteria.setFirstResult(0);
357
                }
358
                criteria.setMaxResults(limit);
359
            }
360

    
361
            if(orderHints!=null){
362
                addOrder(criteria,orderHints);
363
            }
364

    
365
            @SuppressWarnings("unchecked")
366
            List<T> results = criteria.list();
367
            defaultBeanInitializer.initializeAll(results, propertyPaths);
368
            return results;
369
        }
370
        return Collections.emptyList();
371
    }
372

    
373
    private <T extends SpecimenOrObservationBase> Criteria createFindOccurrenceCriteria(Class<T> clazz, String queryString,
374
            String significantIdentifier, SpecimenOrObservationType recordBasis, Taxon associatedTaxon, TaxonName associatedTaxonName, MatchMode matchmode, Integer limit,
375
            Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
376
        Criteria criteria = null;
377

    
378
        if(clazz == null) {
379
            criteria = getSession().createCriteria(type);
380
        } else {
381
            criteria = getSession().createCriteria(clazz);
382
        }
383

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

    
400
        //significant identifier
401
        if (significantIdentifier != null) {
402
            criteria.add(Restrictions.or(Restrictions.ilike("accessionNumber", significantIdentifier),
403
                    Restrictions.ilike("catalogNumber", significantIdentifier), Restrictions.ilike("barcode", significantIdentifier)));
404
        }
405

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

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

    
449
        return criteria;
450
    }
451

    
452

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

    
460
        if(criteria!=null){
461

    
462
            criteria.setProjection(Projections.rowCount());
463

    
464
            return ((Number)criteria.uniqueResult()).intValue();
465
        }
466
        return 0;
467
    }
468

    
469
    @Override
470
    public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache() {
471
        List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<UuidAndTitleCache<DerivedUnit>>();
472
        Session session = getSession();
473

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

    
476
        List<Object[]> result = query.list();
477

    
478
        for(Object[] object : result){
479
            list.add(new UuidAndTitleCache<DerivedUnit>(DerivedUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
480
        }
481

    
482
        return list;
483
    }
484

    
485
    @Override
486
    public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {
487
        List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<UuidAndTitleCache<FieldUnit>>();
488
        Session session = getSession();
489

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

    
492
        List<Object[]> result = query.list();
493

    
494
        for(Object[] object : result){
495
            list.add(new UuidAndTitleCache<FieldUnit>(FieldUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
496
        }
497

    
498
        return list;
499
    }
500

    
501
    @Override
502
    public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxonName(Class<T> type,
503
            TaxonName associatedTaxonName, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
504
        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
505

    
506
        // A Taxon name may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
507
        List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxonName, null, 0, null, null);
508
        setOfAll.addAll(byDetermination);
509

    
510
        if(setOfAll.size() == 0){
511
            // no need querying the data base
512
            return new ArrayList<T>();
513
        }
514

    
515
        String queryString =
516
            "select sob " +
517
            " from SpecimenOrObservationBase sob" +
518
            " where sob in (:setOfAll)";
519

    
520
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
521
            queryString += " and sob.class = :type";
522
        }
523

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

    
536
        Query query = getSession().createQuery(queryString);
537
        query.setParameterList("setOfAll", setOfAll);
538

    
539
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
540
            query.setParameter("type", type.getSimpleName());
541
        }
542

    
543
        if(limit != null) {
544
            if(start != null) {
545
                query.setFirstResult(start);
546
            } else {
547
                query.setFirstResult(0);
548
            }
549
            query.setMaxResults(limit);
550
        }
551

    
552

    
553
        List<T> results = query.list();
554
        defaultBeanInitializer.initializeAll(results, propertyPaths);
555
        return results;
556
    }
557

    
558
    @Override
559
    public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> type,
560
            Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
561

    
562
        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
563

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

    
577

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

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

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

    
600
        if(setOfAll.size() == 0){
601
            // no need querying the data base
602
            return new ArrayList<T>();
603
        }
604

    
605
        String queryString =
606
            "select sob " +
607
            " from SpecimenOrObservationBase sob" +
608
            " where sob in (:setOfAll)";
609

    
610
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
611
            queryString += " and sob.class = :type";
612
        }
613

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

    
626
        Query query = getSession().createQuery(queryString);
627
        query.setParameterList("setOfAll", setOfAll);
628

    
629
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
630
            query.setParameter("type", type.getSimpleName());
631
        }
632

    
633
        if(limit != null) {
634
            if(start != null) {
635
                query.setFirstResult(start);
636
            } else {
637
                query.setFirstResult(0);
638
            }
639
            query.setMaxResults(limit);
640
        }
641

    
642

    
643
        List<T> results = query.list();
644
        defaultBeanInitializer.initializeAll(results, propertyPaths);
645
        return results;
646
    }
647

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

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

    
664
        Query query = getSession().createQuery(queryString);
665
        query.setParameter("type", type);
666

    
667
        if(limit != null) {
668
            if(start != null) {
669
                query.setFirstResult(start);
670
            } else {
671
                query.setFirstResult(0);
672
            }
673
            query.setMaxResults(limit);
674
        }
675

    
676
        List results = query.list();
677
        defaultBeanInitializer.initializeAll(results, propertyPaths);
678
        return results;
679
    }
680

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

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

    
697
        Query query = getSession().createQuery(queryString);
698
        query.setParameter("specimen", specimen);
699

    
700
        if(limit != null) {
701
            if(start != null) {
702
                query.setFirstResult(start);
703
            } else {
704
                query.setFirstResult(0);
705
            }
706
            query.setMaxResults(limit);
707
        }
708

    
709
        List results = query.list();
710
        defaultBeanInitializer.initializeAll(results, propertyPaths);
711
        return results;
712
    }
713

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

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

    
730
        Query query = getSession().createQuery(queryString);
731
        query.setParameter("specimen", specimen);
732

    
733
        if(limit != null) {
734
            if(start != null) {
735
                query.setFirstResult(start);
736
            } else {
737
                query.setFirstResult(0);
738
            }
739
            query.setMaxResults(limit);
740
        }
741

    
742
        List results = query.list();
743
        defaultBeanInitializer.initializeAll(results, propertyPaths);
744
        return results;
745
    }
746

    
747
    @Override
748
    public Collection<IndividualsAssociation> listIndividualsAssociations(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
749
        //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
750
        String queryString = "FROM IndividualsAssociation associations WHERE associations.associatedSpecimenOrObservation = :specimen";
751

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

    
764
        Query query = getSession().createQuery(queryString);
765
        query.setParameter("specimen", specimen);
766

    
767
        if(limit != null) {
768
            if(start != null) {
769
                query.setFirstResult(start);
770
            } else {
771
                query.setFirstResult(0);
772
            }
773
            query.setMaxResults(limit);
774
        }
775

    
776
        List results = query.list();
777
        defaultBeanInitializer.initializeAll(results, propertyPaths);
778
        return results;
779
    }
780

    
781
    @Override
782
    public Collection<DescriptionBase<?>> listDescriptionsWithDescriptionSpecimen(SpecimenOrObservationBase<?> specimen, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
783
        //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
784
        String queryString = "FROM DescriptionBase descriptions WHERE descriptions.describedSpecimenOrObservation = :specimen";
785

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

    
798
        Query query = getSession().createQuery(queryString);
799
        query.setParameter("specimen", specimen);
800

    
801
        if(limit != null) {
802
            if(start != null) {
803
                query.setFirstResult(start);
804
            } else {
805
                query.setFirstResult(0);
806
            }
807
            query.setMaxResults(limit);
808
        }
809

    
810
        List results = query.list();
811
        defaultBeanInitializer.initializeAll(results, propertyPaths);
812
        return results;
813
    }
814

    
815
}
(2-2/2)