Project

General

Profile

Download (37.6 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.Disjunction;
23
import org.hibernate.criterion.Projections;
24
import org.hibernate.criterion.Restrictions;
25
import org.hibernate.envers.query.AuditEntity;
26
import org.hibernate.envers.query.AuditQuery;
27
import org.hibernate.search.FullTextSession;
28
import org.hibernate.search.Search;
29
import org.springframework.beans.factory.annotation.Autowired;
30
import org.springframework.stereotype.Repository;
31

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

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

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

    
71
    @Autowired
72
    private IDescriptionDao descriptionDao;
73

    
74
    @Autowired
75
    private ITaxonNameDao taxonNameDao;
76

    
77
    @Autowired
78
    private IHomotypicalGroupDao homotypicalGroupDao;
79

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

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

    
94
        return ((Long)query.uniqueResult()).intValue();
95
    }
96

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

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

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

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

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

    
124
            return ((Long)query.getSingleResult()).intValue();
125
        }
126
    }
127

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

    
134
        return ((Long)query.uniqueResult()).intValue();
135
    }
136

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
281
        criteria.createCriteria("determinations").add(Restrictions.eq("taxonName", determinedAs));
282

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

    
292
        addOrder(criteria,orderHints);
293

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

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

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

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

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

    
324
        criteria.createCriteria("determinations").add(Restrictions.eq("taxon", determinedAs));
325

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

    
335
        addOrder(criteria,orderHints);
336

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

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

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

    
352
        if(criteria!=null){
353

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

    
363
            if(orderHints!=null){
364
                addOrder(criteria,orderHints);
365
            }
366

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

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

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

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

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

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

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

    
451
        return criteria;
452
    }
453

    
454

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

    
462
        if(criteria!=null){
463

    
464
            criteria.setProjection(Projections.rowCount());
465

    
466
            return ((Number)criteria.uniqueResult()).intValue();
467
        }
468
        return 0;
469
    }
470

    
471
    @Override
472
    public List<UuidAndTitleCache<DerivedUnit>> getDerivedUnitUuidAndTitleCache(Integer limit, String pattern) {
473
        List<UuidAndTitleCache<DerivedUnit>> list = new ArrayList<UuidAndTitleCache<DerivedUnit>>();
474
        Session session = getSession();
475
        Query query;
476
        if (pattern != null){
477
            query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() + " where NOT dtype = " + FieldUnit.class.getSimpleName() +" AND titleCache like :pattern");
478
            pattern = pattern.replace("*", "%");
479
            pattern = pattern.replace("?", "_");
480
            pattern = pattern + "%";
481
            query.setParameter("pattern", pattern);
482
        } else {
483
            query = session.createQuery("select uuid, id, titleCache from " + type.getSimpleName() +" where NOT dtype = " + FieldUnit.class.getSimpleName());
484
        }
485
        if (limit != null){
486
           query.setMaxResults(limit);
487
        }
488

    
489

    
490

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

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

    
497
        return list;
498
    }
499

    
500
    @Override
501
    public List<UuidAndTitleCache<FieldUnit>> getFieldUnitUuidAndTitleCache() {
502
        List<UuidAndTitleCache<FieldUnit>> list = new ArrayList<UuidAndTitleCache<FieldUnit>>();
503
        Session session = getSession();
504

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

    
507
        List<Object[]> result = query.list();
508

    
509
        for(Object[] object : result){
510
            list.add(new UuidAndTitleCache<FieldUnit>(FieldUnit.class, (UUID) object[0], (Integer)object[1], (String) object[2]));
511
        }
512

    
513
        return list;
514
    }
515

    
516
    @Override
517
    public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxonName(Class<T> type,
518
            TaxonName associatedTaxonName, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
519
        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
520

    
521
        // A Taxon name may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
522
        List<SpecimenOrObservationBase> byDetermination = list(type, associatedTaxonName, null, 0, null, null);
523
        setOfAll.addAll(byDetermination);
524

    
525
        if(setOfAll.size() == 0){
526
            // no need querying the data base
527
            return new ArrayList<T>();
528
        }
529

    
530
        String queryString =
531
            "select sob " +
532
            " from SpecimenOrObservationBase sob" +
533
            " where sob in (:setOfAll)";
534

    
535
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
536
            queryString += " and sob.class = :type";
537
        }
538

    
539
        if(orderHints != null && orderHints.size() > 0){
540
            queryString += " order by ";
541
            String orderStr = "";
542
            for(OrderHint orderHint : orderHints){
543
                if(orderStr.length() > 0){
544
                    orderStr += ", ";
545
                }
546
                queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
547
            }
548
            queryString += orderStr;
549
        }
550

    
551
        Query query = getSession().createQuery(queryString);
552
        query.setParameterList("setOfAll", setOfAll);
553

    
554
        if(type != null && !type.equals(SpecimenOrObservationBase.class)){
555
            query.setParameter("type", type.getSimpleName());
556
        }
557

    
558
        if(limit != null) {
559
            if(start != null) {
560
                query.setFirstResult(start);
561
            } else {
562
                query.setFirstResult(0);
563
            }
564
            query.setMaxResults(limit);
565
        }
566

    
567

    
568
        List<T> results = query.list();
569
        defaultBeanInitializer.initializeAll(results, propertyPaths);
570
        return results;
571
    }
572

    
573
    @Override
574
    public <T extends SpecimenOrObservationBase> List<T> listByAssociatedTaxon(Class<T> clazz,
575
            Taxon associatedTaxon, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
576

    
577
        Set<SpecimenOrObservationBase> setOfAll = new HashSet<SpecimenOrObservationBase>();
578

    
579
        Criteria criteria = null;
580
        if(clazz == null) {
581
            criteria = getSession().createCriteria(type, "specimen");
582
        } else {
583
            criteria = getSession().createCriteria(clazz, "specimen");
584
        }
585

    
586
        Disjunction determinationOr = Restrictions.disjunction();
587

    
588
        // A Taxon may be referenced by the DeterminationEvent of the SpecimenOrObservationBase
589
        Criteria determinationsCriteria = criteria.createCriteria("determinations");
590

    
591
        determinationOr.add(Restrictions.eq("taxon", associatedTaxon));
592
        //check also for synonyms
593
        for (Synonym synonym : associatedTaxon.getSynonyms()) {
594
            determinationOr.add(Restrictions.eq("taxon", synonym));
595
        }
596

    
597
        //check also for name determinations
598
        determinationOr.add(Restrictions.eq("taxonName", associatedTaxon.getName()));
599
        for (TaxonName synonymName : associatedTaxon.getSynonymNames()) {
600
            determinationOr.add(Restrictions.eq("taxonName", synonymName));
601
        }
602

    
603
        determinationsCriteria.add(determinationOr);
604

    
605
        if(limit != null) {
606
            if(start != null) {
607
                criteria.setFirstResult(start);
608
            } else {
609
                criteria.setFirstResult(0);
610
            }
611
            criteria.setMaxResults(limit);
612
        }
613

    
614
        addOrder(criteria,orderHints);
615

    
616
        @SuppressWarnings("unchecked")
617
        List<SpecimenOrObservationBase> detResults = criteria.list();
618
        defaultBeanInitializer.initializeAll(detResults, propertyPaths);
619
        setOfAll.addAll(detResults);
620

    
621
        // The IndividualsAssociation elements in a TaxonDescription contain DerivedUnits
622
        Criteria descriptionElementCriteria = getSession().createCriteria(DescriptionElementBase.class);
623
        Criteria inDescriptionCriteria = descriptionElementCriteria.createCriteria("inDescription").add(Restrictions.eqOrIsNull("class", "TaxonDescription"));
624
        Criteria taxonCriteria = inDescriptionCriteria.createCriteria("taxon");
625
        taxonCriteria.add(Restrictions.eq("uuid", associatedTaxon.getUuid()));
626
        descriptionElementCriteria.setProjection(Projections.property("associatedSpecimenOrObservation"));
627

    
628

    
629
        setOfAll.addAll(descriptionElementCriteria.list());
630

    
631

    
632
        // SpecimenTypeDesignations may be associated with the TaxonName.
633
        List<SpecimenTypeDesignation> bySpecimenTypeDesignation = taxonNameDao.getTypeDesignations(associatedTaxon.getName(),
634
                SpecimenTypeDesignation.class, null, null, 0, null);
635
        for (SpecimenTypeDesignation specimenTypeDesignation : bySpecimenTypeDesignation) {
636
            setOfAll.add(specimenTypeDesignation.getTypeSpecimen());
637
        }
638

    
639
        // SpecimenTypeDesignations may be associated with any HomotypicalGroup related to the specific Taxon.
640
        for(HomotypicalGroup homotypicalGroup :  associatedTaxon.getHomotypicSynonymyGroups()) {
641
            List<SpecimenTypeDesignation> byHomotypicalGroup = homotypicalGroupDao.getTypeDesignations(homotypicalGroup, SpecimenTypeDesignation.class, null, null, 0, null);
642
            for (SpecimenTypeDesignation specimenTypeDesignation : byHomotypicalGroup) {
643
                setOfAll.add(specimenTypeDesignation.getTypeSpecimen());
644
            }
645
        }
646

    
647
        if(setOfAll.size() == 0){
648
            // no need querying the data base
649
            return new ArrayList<T>();
650
        }
651

    
652
        String queryString =
653
            "select sob " +
654
            " from SpecimenOrObservationBase sob" +
655
            " where sob in (:setOfAll)";
656

    
657
        if(clazz != null && !clazz.equals(SpecimenOrObservationBase.class)){
658
            queryString += " and sob.class = :type ";
659
        }
660

    
661
        if(orderHints != null && orderHints.size() > 0){
662
            queryString += " order by ";
663
            String orderStr = "";
664
            for(OrderHint orderHint : orderHints){
665
                if(orderStr.length() > 0){
666
                    orderStr += ", ";
667
                }
668
                queryString += "sob." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
669
            }
670
            queryString += orderStr;
671
        }
672

    
673
        Query query = getSession().createQuery(queryString);
674
        query.setParameterList("setOfAll", setOfAll);
675

    
676
        if(clazz != null && !clazz.equals(SpecimenOrObservationBase.class)){
677
            query.setParameter("type", clazz.getSimpleName());
678
        }
679

    
680
        if(limit != null) {
681
            if(start != null) {
682
                query.setFirstResult(start);
683
            } else {
684
                query.setFirstResult(0);
685
            }
686
            query.setMaxResults(limit);
687
        }
688

    
689

    
690
        List<T> results = query.list();
691
        defaultBeanInitializer.initializeAll(results, propertyPaths);
692
        return results;
693
    }
694

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

    
699
        if(orderHints != null && orderHints.size() > 0){
700
            queryString += " order by ";
701
            String orderStr = "";
702
            for(OrderHint orderHint : orderHints){
703
                if(orderStr.length() > 0){
704
                    orderStr += ", ";
705
                }
706
                queryString += "specimens." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
707
            }
708
            queryString += orderStr;
709
        }
710

    
711
        Query query = getSession().createQuery(queryString);
712
        query.setParameter("type", type);
713

    
714
        if(limit != null) {
715
            if(start != null) {
716
                query.setFirstResult(start);
717
            } else {
718
                query.setFirstResult(0);
719
            }
720
            query.setMaxResults(limit);
721
        }
722

    
723
        List results = query.list();
724
        defaultBeanInitializer.initializeAll(results, propertyPaths);
725
        return results;
726
    }
727

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

    
732
        if(orderHints != null && orderHints.size() > 0){
733
            queryString += " order by ";
734
            String orderStr = "";
735
            for(OrderHint orderHint : orderHints){
736
                if(orderStr.length() > 0){
737
                    orderStr += ", ";
738
                }
739
                queryString += "determination." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
740
            }
741
            queryString += orderStr;
742
        }
743

    
744
        Query query = getSession().createQuery(queryString);
745
        query.setParameter("specimen", specimen);
746

    
747
        if(limit != null) {
748
            if(start != null) {
749
                query.setFirstResult(start);
750
            } else {
751
                query.setFirstResult(0);
752
            }
753
            query.setMaxResults(limit);
754
        }
755

    
756
        List results = query.list();
757
        defaultBeanInitializer.initializeAll(results, propertyPaths);
758
        return results;
759
    }
760

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

    
765
        if(orderHints != null && orderHints.size() > 0){
766
            queryString += " ORDER BY ";
767
            String orderStr = "";
768
            for(OrderHint orderHint : orderHints){
769
                if(orderStr.length() > 0){
770
                    orderStr += ", ";
771
                }
772
                queryString += "designations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
773
            }
774
            queryString += orderStr;
775
        }
776

    
777
        Query query = getSession().createQuery(queryString);
778
        query.setParameter("specimen", specimen);
779

    
780
        if(limit != null) {
781
            if(start != null) {
782
                query.setFirstResult(start);
783
            } else {
784
                query.setFirstResult(0);
785
            }
786
            query.setMaxResults(limit);
787
        }
788

    
789
        @SuppressWarnings("unchecked")
790
        List<SpecimenTypeDesignation> results = query.list();
791
        defaultBeanInitializer.initializeAll(results, propertyPaths);
792
        return results;
793
    }
794

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

    
800
        if(orderHints != null && orderHints.size() > 0){
801
            queryString += " order by ";
802
            String orderStr = "";
803
            for(OrderHint orderHint : orderHints){
804
                if(orderStr.length() > 0){
805
                    orderStr += ", ";
806
                }
807
                queryString += "associations." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
808
            }
809
            queryString += orderStr;
810
        }
811

    
812
        Query query = getSession().createQuery(queryString);
813
        query.setParameter("specimen", specimen);
814

    
815
        if(limit != null) {
816
            if(start != null) {
817
                query.setFirstResult(start);
818
            } else {
819
                query.setFirstResult(0);
820
            }
821
            query.setMaxResults(limit);
822
        }
823

    
824
        List results = query.list();
825
        defaultBeanInitializer.initializeAll(results, propertyPaths);
826
        return results;
827
    }
828

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

    
834
        if(orderHints != null && orderHints.size() > 0){
835
            queryString += " order by ";
836
            String orderStr = "";
837
            for(OrderHint orderHint : orderHints){
838
                if(orderStr.length() > 0){
839
                    orderStr += ", ";
840
                }
841
                queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
842
            }
843
            queryString += orderStr;
844
        }
845

    
846
        Query query = getSession().createQuery(queryString);
847
        query.setParameter("specimen", specimen);
848

    
849
        if(limit != null) {
850
            if(start != null) {
851
                query.setFirstResult(start);
852
            } else {
853
                query.setFirstResult(0);
854
            }
855
            query.setMaxResults(limit);
856
        }
857

    
858
        List results = query.list();
859
        defaultBeanInitializer.initializeAll(results, propertyPaths);
860
        return results;
861
    }
862

    
863
    /**
864
     * {@inheritDoc}
865
     */
866
    @Override
867
    public List<FieldUnit> getFieldUnitsForGatheringEvent(UUID gatheringEventUuid, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
868
        String queryString = "FROM SpecimenOrObservationBase s WHERE s.gatheringEvent.uuid = :gatheringEventUuid";
869

    
870
        if(orderHints != null && orderHints.size() > 0){
871
            queryString += " order by ";
872
            String orderStr = "";
873
            for(OrderHint orderHint : orderHints){
874
                if(orderStr.length() > 0){
875
                    orderStr += ", ";
876
                }
877
                queryString += "descriptions." + orderHint.getPropertyName() + " " + orderHint.getSortOrder().toHql();
878
            }
879
            queryString += orderStr;
880
        }
881

    
882
        Query query = getSession().createQuery(queryString);
883
        query.setParameter("gatheringEventUuid", gatheringEventUuid);
884

    
885
        if(limit != null) {
886
            if(start != null) {
887
                query.setFirstResult(start);
888
            } else {
889
                query.setFirstResult(0);
890
            }
891
            query.setMaxResults(limit);
892
        }
893

    
894
        List results = query.list();
895
        defaultBeanInitializer.initializeAll(results, propertyPaths);
896
        return results;
897
    }
898

    
899
}
(2-2/2)