Project

General

Profile

Download (36 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.cdm.persistence.dao.hibernate.description;
11

    
12
import java.util.ArrayList;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import org.apache.log4j.Logger;
19
import org.hibernate.Criteria;
20
import org.hibernate.Query;
21
import org.hibernate.criterion.ProjectionList;
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.springframework.beans.factory.annotation.Qualifier;
27
import org.springframework.stereotype.Repository;
28

    
29
import eu.etaxonomy.cdm.model.common.DefinedTerm;
30
import eu.etaxonomy.cdm.model.common.LSID;
31
import eu.etaxonomy.cdm.model.common.MarkerType;
32
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
33
import eu.etaxonomy.cdm.model.description.DescriptionBase;
34
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
35
import eu.etaxonomy.cdm.model.description.Feature;
36
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
37
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
38
import eu.etaxonomy.cdm.model.description.TaxonDescription;
39
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
40
import eu.etaxonomy.cdm.model.location.NamedArea;
41
import eu.etaxonomy.cdm.model.media.Media;
42
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
43
import eu.etaxonomy.cdm.model.taxon.Taxon;
44
import eu.etaxonomy.cdm.model.view.AuditEvent;
45
import eu.etaxonomy.cdm.persistence.dao.common.OperationNotSupportedInPriorViewException;
46
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
47
import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;
48
import eu.etaxonomy.cdm.persistence.query.MatchMode;
49
import eu.etaxonomy.cdm.persistence.query.OrderHint;
50

    
51
@Repository
52
@Qualifier("descriptionDaoImpl")
53
public class DescriptionDaoImpl extends IdentifiableDaoBase<DescriptionBase> implements IDescriptionDao{
54

    
55
    private static final Logger logger = Logger.getLogger(DescriptionDaoImpl.class);
56

    
57
    public DescriptionDaoImpl() {
58
        super(DescriptionBase.class);
59
        indexedClasses = new Class[3];
60
        indexedClasses[0] = TaxonDescription.class;
61
        indexedClasses[1] = TaxonNameDescription.class;
62
        indexedClasses[2] = SpecimenDescription.class;
63
    }
64

    
65
//    @Override  //Override for testing
66
//    public DescriptionBase load(UUID uuid, List<String> propertyPaths){
67
//    	DescriptionBase bean = findByUuid(uuid);
68
//        if(bean == null){
69
//            return bean;
70
//        }
71
//        defaultBeanInitializer.initialize(bean, propertyPaths);
72
//
73
//        return bean;
74
//    }
75

    
76
    @Override
77
    public int countDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status) {
78
        checkNotInPriorView("DescriptionDaoImpl.countDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status)");
79
        Query query = null;
80

    
81
        if(status == null) {
82
            query = getSession().createQuery("select count(distinct description) from TaxonDescription description left join description.descriptionElements element join element.area area where area in (:namedAreas)");
83
        } else {
84
            query = getSession().createQuery("select count(distinct description) from TaxonDescription description left join description.descriptionElements element join element.area area  join element.status status where area in (:namedAreas) and status = :status");
85
            query.setParameter("status", status);
86
        }
87
        query.setParameterList("namedAreas", namedAreas);
88

    
89
        return ((Long)query.uniqueResult()).intValue();
90
    }
91

    
92
    @Override
93
    public int countDescriptionElements(DescriptionBase description, Set<Feature> features, Class<? extends DescriptionElementBase> clazz) {
94
        return countDescriptionElements(description, null, features, clazz);
95
    }
96

    
97
    @Override
98
    public int countDescriptionElements(DescriptionBase description, Class<? extends DescriptionBase> descriptionType,
99
            Set<Feature> features, Class<? extends DescriptionElementBase> clazz) {
100
        AuditEvent auditEvent = getAuditEventFromContext();
101
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
102
            Criteria criteria = null;
103
            if(clazz == null) {
104
                criteria = getSession().createCriteria(DescriptionElementBase.class);
105
            } else {
106
                criteria = getSession().createCriteria(clazz);
107
            }
108

    
109
            if(description != null) {
110
                criteria.add(Restrictions.eq("inDescription", description));
111
            }
112

    
113
            if(descriptionType != null) {
114
                criteria.createAlias("inDescription", "d").add(Restrictions.eq("d.class", descriptionType));
115
            }
116

    
117
            if(features != null && !features.isEmpty()) {
118
                criteria.add(Restrictions.in("feature", features));
119
            }
120

    
121
            criteria.setProjection(Projections.rowCount());
122

    
123
            return ((Number)criteria.uniqueResult()).intValue();
124
        } else {
125
            if(features != null && !features.isEmpty()) {
126
                Integer count = 0;
127
                for(Feature f : features) {
128
                    AuditQuery query = null;
129
                    if(clazz == null) {
130
                        query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
131
                    } else {
132
                        query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
133
                    }
134

    
135
                    if(description != null) {
136
                        query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
137
                    }
138

    
139
                    if(descriptionType != null) {
140
                        query.add(AuditEntity.property("inDescription.class").eq(descriptionType));
141
                    }
142

    
143
                    query.add(AuditEntity.relatedId("feature").eq(f.getId()));
144
                    query.addProjection(AuditEntity.id().count("id"));
145
                    count += ((Long)query.getSingleResult()).intValue();
146
                }
147

    
148
                return count;
149
            } else {
150
                AuditQuery query = null;
151
                if(clazz == null) {
152
                    query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
153
                } else {
154
                    query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
155
                }
156

    
157
                if(description != null) {
158
                    query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
159
                }
160
                if(descriptionType != null) {
161
                    query.add(AuditEntity.property("inDescription.class").eq(descriptionType));
162
                }
163

    
164
                query.addProjection(AuditEntity.id().count("id"));
165
                return ((Long)query.getSingleResult()).intValue();
166
            }
167
        }
168
    }
169

    
170
    @Override
171
    public int countDescriptions(Class<? extends DescriptionBase> clazz, Boolean hasImages, Boolean hasText, Set<Feature> features) {
172
        checkNotInPriorView("DescriptionDaoImpl.countDescriptions(Class<TYPE> type, Boolean hasImages, Boolean hasText, Set<Feature> features)");
173
        Criteria inner = null;
174

    
175
        if(clazz == null) {
176
            inner = getSession().createCriteria(type);
177
        } else {
178
            inner = getSession().createCriteria(clazz);
179
        }
180

    
181
        Criteria elementsCriteria = inner.createCriteria("descriptionElements");
182
        if(hasText != null) {
183
            if(hasText) {
184
                elementsCriteria.add(Restrictions.isNotEmpty("multilanguageText"));
185
            } else {
186
                elementsCriteria.add(Restrictions.isEmpty("multilanguageText"));
187
            }
188
        }
189

    
190
        if(hasImages != null) {
191
            if(hasImages) {
192
                elementsCriteria.add(Restrictions.isNotEmpty("media"));
193
            } else {
194
                elementsCriteria.add(Restrictions.isEmpty("media"));
195
            }
196
        }
197

    
198
        if(features != null && !features.isEmpty()) {
199
            elementsCriteria.add(Restrictions.in("feature", features));
200
        }
201

    
202
        inner.setProjection(Projections.countDistinct("id"));
203

    
204
        return ((Number) inner.uniqueResult()).intValue();
205
    }
206

    
207
    @Override
208
    public int countTaxonDescriptions(Taxon taxon, Set<DefinedTerm> scopes,Set<NamedArea> geographicalScopes, Set<MarkerType> markerTypes) {
209
        AuditEvent auditEvent = getAuditEventFromContext();
210
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
211
            Criteria criteria = getSession().createCriteria(TaxonDescription.class);
212

    
213
            if(taxon != null) {
214
                criteria.add(Restrictions.eq("taxon", taxon));
215
            }
216

    
217
            if(scopes != null && !scopes.isEmpty()) {
218
                Set<Integer> scopeIds = new HashSet<Integer>();
219
                for(DefinedTerm s : scopes) {
220
                    scopeIds.add(s.getId());
221
                }
222
                criteria.createCriteria("scopes").add(Restrictions.in("id", scopeIds));
223
            }
224

    
225
            if(geographicalScopes != null && !geographicalScopes.isEmpty()) {
226
                Set<Integer> geoScopeIds = new HashSet<Integer>();
227
                for(NamedArea n : geographicalScopes) {
228
                    geoScopeIds.add(n.getId());
229
                }
230
                criteria.createCriteria("geoScopes").add(Restrictions.in("id", geoScopeIds));
231
            }
232

    
233

    
234
            addMarkerTypesCriterion(markerTypes, criteria);
235

    
236

    
237
            criteria.setProjection(Projections.rowCount());
238

    
239
            return ((Number)criteria.uniqueResult()).intValue();
240
        } else {
241
            if((scopes == null || scopes.isEmpty())&& (geographicalScopes == null || geographicalScopes.isEmpty()) && (markerTypes == null || markerTypes.isEmpty())) {
242
                AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonDescription.class,auditEvent.getRevisionNumber());
243
                if(taxon != null) {
244
                    query.add(AuditEntity.relatedId("taxon").eq(taxon.getId()));
245
                }
246

    
247
                query.addProjection(AuditEntity.id().count("id"));
248

    
249
                return ((Long)query.getSingleResult()).intValue();
250
            } else {
251
                throw new OperationNotSupportedInPriorViewException("countTaxonDescriptions(Taxon taxon, Set<Scope> scopes,Set<NamedArea> geographicalScopes)");
252
            }
253
        }
254
    }
255

    
256
    /**
257
     * @param markerTypes
258
     * @param criteria
259
     *
260
     */
261
    //TODO move to AnnotatableEntityDao(?)
262
    private void addMarkerTypesCriterion(Set<MarkerType> markerTypes, Criteria criteria) {
263

    
264
        if(markerTypes != null && !markerTypes.isEmpty()) {
265
            Set<Integer> markerTypeIds = new HashSet<Integer>();
266
            for(MarkerType markerType : markerTypes) {
267
                markerTypeIds.add(markerType.getId());
268
            }
269
            criteria.createCriteria("markers").add(Restrictions.eq("flag", true))
270
                    .createAlias("markerType", "mt")
271
                     .add(Restrictions.in("mt.id", markerTypeIds));
272
        } else if (markerTypes != null && markerTypes.isEmpty()){
273
            //AT: added in case the projects requires an third state description, An empty Marker type set
274
        }
275
    }
276
    @Override
277
    public List<DescriptionElementBase> getDescriptionElements(
278
            DescriptionBase description, Set<Feature> features,
279
            Class<? extends DescriptionElementBase> clazz, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
280
        return getDescriptionElements(description, null, features, clazz, pageSize, pageNumber, propertyPaths);
281
    }
282

    
283
    @Override
284
    public List<DescriptionElementBase> getDescriptionElements(
285
            DescriptionBase description, Class<? extends DescriptionBase> descriptionType,
286
            Set<Feature> features,
287
            Class<? extends DescriptionElementBase> clazz,
288
            Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
289

    
290
        AuditEvent auditEvent = getAuditEventFromContext();
291
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
292
            Criteria criteria = null;
293
            if(clazz == null) {
294
                criteria = getSession().createCriteria(DescriptionElementBase.class);
295
            } else {
296
                criteria = getSession().createCriteria(clazz);
297
            }
298

    
299
            if(description != null) {
300
                criteria.add(Restrictions.eq("inDescription", description));
301
            }
302
            if(descriptionType != null) {
303
                criteria.createAlias("inDescription", "d").add(Restrictions.eq("d.class", descriptionType));
304
            }
305

    
306
            if(features != null && !features.isEmpty()) {
307
                criteria.add(Restrictions.in("feature", features));
308
            }
309

    
310
            if(pageSize != null) {
311
                criteria.setMaxResults(pageSize);
312
                if(pageNumber != null) {
313
                    criteria.setFirstResult(pageNumber * pageSize);
314
                }
315
            }
316

    
317
            List<DescriptionElementBase> results = criteria.list();
318

    
319
            defaultBeanInitializer.initializeAll(results, propertyPaths);
320

    
321
            return results;
322
        } else {
323
            List<DescriptionElementBase> result = new ArrayList<DescriptionElementBase>();
324
            if(features != null && !features.isEmpty()) {
325

    
326
                for(Feature f : features) {
327
                    AuditQuery query = null;
328
                    if(clazz == null) {
329
                        query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
330
                    } else {
331
                        query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
332
                    }
333

    
334
                    if(description != null) {
335
                        query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
336
                    }
337

    
338
                    if(descriptionType != null) {
339
                        query.add(AuditEntity.property("inDescription.class").eq(descriptionType));
340
                    }
341

    
342
                    query.add(AuditEntity.relatedId("feature").eq(f.getId()));
343
                    result.addAll(query.getResultList());
344
                }
345
            } else {
346
                AuditQuery query = null;
347
                if(clazz == null) {
348
                    query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
349
                } else {
350
                    query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
351
                }
352

    
353
                if(description != null) {
354
                    query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
355
                }
356

    
357
                if(descriptionType != null) {
358
                    query.add(AuditEntity.property("inDescription.class").eq(descriptionType));
359
                }
360

    
361
                result = query.getResultList();
362
            }
363

    
364
            defaultBeanInitializer.initializeAll(result, propertyPaths);
365

    
366
            return result;
367
        }
368
    }
369

    
370
    @Override
371
    public List<TaxonDescription> listTaxonDescriptions(Taxon taxon, Set<DefinedTerm> scopes, Set<NamedArea> geographicalScopes, Set<MarkerType> markerTypes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
372
        AuditEvent auditEvent = getAuditEventFromContext();
373
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
374
            Criteria criteria = getSession().createCriteria(TaxonDescription.class);
375

    
376
            if(taxon != null) {
377
                criteria.add(Restrictions.eq("taxon", taxon));
378
            }
379

    
380
            if(scopes != null && !scopes.isEmpty()) {
381
                Set<Integer> scopeIds = new HashSet<Integer>();
382
                for(DefinedTerm s : scopes) {
383
                    scopeIds.add(s.getId());
384
                }
385
                criteria.createCriteria("scopes").add(Restrictions.in("id", scopeIds));
386
            }
387

    
388
            if(geographicalScopes != null && !geographicalScopes.isEmpty()) {
389
                Set<Integer> geoScopeIds = new HashSet<Integer>();
390
                for(NamedArea n : geographicalScopes) {
391
                    geoScopeIds.add(n.getId());
392
                }
393
                criteria.createCriteria("geoScopes").add(Restrictions.in("id", geoScopeIds));
394
            }
395

    
396
            addMarkerTypesCriterion(markerTypes, criteria);
397

    
398
            if(pageSize != null) {
399
                criteria.setMaxResults(pageSize);
400
                if(pageNumber != null) {
401
                    criteria.setFirstResult(pageNumber * pageSize);
402
                }
403
            }
404

    
405
            List<TaxonDescription> results = criteria.list();
406

    
407
            defaultBeanInitializer.initializeAll(results, propertyPaths);
408

    
409
            return results;
410
        } else {
411
            if((scopes == null || scopes.isEmpty())&& (geographicalScopes == null || geographicalScopes.isEmpty())&& (markerTypes == null || markerTypes.isEmpty())) {
412
                AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonDescription.class,auditEvent.getRevisionNumber());
413
                if(taxon != null) {
414
                    query.add(AuditEntity.relatedId("taxon").eq(taxon.getId()));
415
                }
416

    
417
                if(pageSize != null) {
418
                    query.setMaxResults(pageSize);
419
                    if(pageNumber != null) {
420
                        query.setFirstResult(pageNumber * pageSize);
421
                    } else {
422
                        query.setFirstResult(0);
423
                    }
424
                }
425

    
426
                List<TaxonDescription> results = query.getResultList();
427
                defaultBeanInitializer.initializeAll(results, propertyPaths);
428
                return results;
429
            } else {
430
                throw new OperationNotSupportedInPriorViewException("countTaxonDescriptions(Taxon taxon, Set<Scope> scopes,Set<NamedArea> geographicalScopes)");
431
            }
432
        }
433
    }
434

    
435
    @Override
436
    public List<TaxonNameDescription> getTaxonNameDescriptions(TaxonNameBase name, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
437
        AuditEvent auditEvent = getAuditEventFromContext();
438
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
439
            Criteria criteria = getSession().createCriteria(TaxonNameDescription.class);
440

    
441
          if(name != null) {
442
              criteria.add(Restrictions.eq("taxonName", name));
443
          }
444

    
445
          if(pageSize != null) {
446
              criteria.setMaxResults(pageSize);
447
              if(pageNumber != null) {
448
                  criteria.setFirstResult(pageNumber * pageSize);
449
              }
450
          }
451

    
452
          List<TaxonNameDescription> results = criteria.list();
453

    
454
          defaultBeanInitializer.initializeAll(results, propertyPaths);
455

    
456
          return results;
457
        } else {
458
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameDescription.class,auditEvent.getRevisionNumber());
459

    
460
            if(name != null) {
461
                query.add(AuditEntity.relatedId("taxonName").eq(name.getId()));
462
            }
463

    
464
            if(pageSize != null) {
465
                  query.setMaxResults(pageSize);
466
                  if(pageNumber != null) {
467
                      query.setFirstResult(pageNumber * pageSize);
468
                  }
469
            }
470

    
471
            List<TaxonNameDescription> results = query.getResultList();
472

    
473
            defaultBeanInitializer.initializeAll(results, propertyPaths);
474

    
475
            return results;
476
        }
477

    
478
    }
479

    
480
    @Override
481
    public int countTaxonNameDescriptions(TaxonNameBase name) {
482
        AuditEvent auditEvent = getAuditEventFromContext();
483
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
484
            Criteria criteria = getSession().createCriteria(TaxonNameDescription.class);
485

    
486
            if(name != null) {
487
                criteria.add(Restrictions.eq("taxonName", name));
488
            }
489

    
490
            criteria.setProjection(Projections.rowCount());
491

    
492
            return ((Number)criteria.uniqueResult()).intValue();
493
        } else {
494
            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameDescription.class,auditEvent.getRevisionNumber());
495

    
496
            if(name != null) {
497
                query.add(AuditEntity.relatedId("taxonName").eq(name.getId()));
498
            }
499

    
500
            query.addProjection(AuditEntity.id().count("id"));
501
            return ((Long)query.getSingleResult()).intValue();
502
        }
503
    }
504

    
505
    /**
506
     * Should use a DetachedCriteria & subquery, but HHH-158 prevents this, for now.
507
     *
508
     * e.g. DetachedCriteria inner = DestachedCriteria.forClass(type);
509
     *
510
     * outer.add(Subqueries.propertyIn("id", inner));
511
     */
512
    @Override
513
    public List<DescriptionBase> listDescriptions(Class<? extends DescriptionBase> clazz, Boolean hasImages, Boolean hasText,	Set<Feature> features, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
514
        checkNotInPriorView("DescriptionDaoImpl.listDescriptions(Class<TYPE> type, Boolean hasImages, Boolean hasText,	Set<Feature> features, Integer pageSize, Integer pageNumber)");
515
        Criteria inner = null;
516

    
517
        if(clazz == null) {
518
            inner = getSession().createCriteria(type);
519
        } else {
520
            inner = getSession().createCriteria(clazz);
521
        }
522

    
523
        Criteria elementsCriteria = inner.createCriteria("descriptionElements");
524
        if(hasText != null) {
525
            if(hasText) {
526
                elementsCriteria.add(Restrictions.isNotEmpty("multilanguageText"));
527
            } else {
528
                elementsCriteria.add(Restrictions.isEmpty("multilanguageText"));
529
            }
530
        }
531

    
532
        if(hasImages != null) {
533
            if(hasImages) {
534
                elementsCriteria.add(Restrictions.isNotEmpty("media"));
535
            } else {
536
                elementsCriteria.add(Restrictions.isEmpty("media"));
537
            }
538
        }
539

    
540
        if(features != null && !features.isEmpty()) {
541
            elementsCriteria.add(Restrictions.in("feature", features));
542
        }
543

    
544
        inner.setProjection(Projections.distinct(Projections.id()));
545

    
546
        List<Object> intermediateResult = inner.list();
547

    
548
        if(intermediateResult.isEmpty()) {
549
            return new ArrayList<DescriptionBase>();
550
        }
551

    
552
        Integer[] resultIds = new Integer[intermediateResult.size()];
553
        for(int i = 0; i < resultIds.length; i++) {
554
                resultIds[i] = ((Number)intermediateResult.get(i)).intValue();
555
        }
556

    
557
        Criteria outer = null;
558

    
559
        if(clazz == null) {
560
            outer = getSession().createCriteria(type);
561
        } else {
562
            outer = getSession().createCriteria(clazz);
563
        }
564

    
565
        outer.add(Restrictions.in("id", resultIds));
566
        addOrder(outer, orderHints);
567

    
568
        if(pageSize != null) {
569
            outer.setMaxResults(pageSize);
570
            if(pageNumber != null) {
571
                outer.setFirstResult(pageNumber * pageSize);
572
            }
573
        }
574

    
575
        List<DescriptionBase> results = outer.list();
576
        defaultBeanInitializer.initializeAll(results, propertyPaths);
577
        return results;
578
    }
579

    
580
    @Override
581
    public List<TaxonDescription> searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
582
        checkNotInPriorView("DescriptionDaoImpl.searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
583

    
584
        Criteria criteria = getSession().createCriteria(TaxonDescription.class);
585
        Criteria elements = criteria.createCriteria("descriptionElements", "descriptionElement", Criteria.LEFT_JOIN);
586
        elements.add(Restrictions.in("area", namedAreas.toArray()));
587

    
588
        if(status != null) {
589
            elements.add(Restrictions.eq("status", status));
590
        }
591

    
592
        ProjectionList projectionList = Projections.projectionList().add(Projections.id());
593

    
594
        if(orderHints != null && !orderHints.isEmpty()) {
595
            for(OrderHint orderHint : orderHints) {
596
                projectionList = projectionList.add(Projections.property(orderHint.getPropertyName()));
597
            }
598
        }
599

    
600
        criteria.setProjection(Projections.distinct(projectionList));
601

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

    
609
        addOrder(criteria,orderHints);
610

    
611
        List<Object> intermediateResult = criteria.list();
612

    
613
        if(intermediateResult.isEmpty()) {
614
            return new ArrayList<TaxonDescription>();
615
        }
616

    
617
        Integer[] resultIds = new Integer[intermediateResult.size()];
618
        for(int i = 0; i < resultIds.length; i++) {
619
            if(orderHints == null || orderHints.isEmpty()) {
620
                resultIds[i] = ((Number)intermediateResult.get(i)).intValue();
621
            } else {
622
              resultIds[i] = ((Number)((Object[])intermediateResult.get(i))[0]).intValue();
623
            }
624
        }
625

    
626
        criteria = getSession().createCriteria(TaxonDescription.class);
627
        criteria.add(Restrictions.in("id", resultIds));
628
        addOrder(criteria,orderHints);
629

    
630
        List<TaxonDescription> results = criteria.list();
631
        defaultBeanInitializer.initializeAll(results, propertyPaths);
632
        return results;
633
    }
634

    
635
    @Override
636
    public List<CommonTaxonName> searchDescriptionByCommonName(String queryString, MatchMode matchMode, Integer pageSize, Integer pageNumber) {
637

    
638
        Criteria crit = getSession().createCriteria(CommonTaxonName.class);
639
        if (matchMode == MatchMode.EXACT) {
640
            crit.add(Restrictions.eq("name", matchMode.queryStringFrom(queryString)));
641
        } else {
642
            crit.add(Restrictions.ilike("name", matchMode.queryStringFrom(queryString)));
643
        }
644

    
645
        if(pageSize != null) {
646
            crit.setMaxResults(pageSize);
647
            if(pageNumber != null) {
648
                crit.setFirstResult(pageNumber * pageSize);
649
            }
650
        }
651
        List<CommonTaxonName> results = crit.list();
652
        return results;
653
    }
654

    
655
    @Override
656
    public Integer countDescriptionByCommonName(String queryString, MatchMode matchMode) {
657
        //TODO inprove performance
658
        List<CommonTaxonName> results =  searchDescriptionByCommonName(queryString, matchMode, null, null);
659
        return results.size();
660
    }
661

    
662
    @Override
663
    public DescriptionBase find(LSID lsid) {
664
        DescriptionBase descriptionBase = super.find(lsid);
665
        if(descriptionBase != null) {
666
            List<String> propertyPaths = new ArrayList<String>();
667
            propertyPaths.add("createdBy");
668
            propertyPaths.add("updatedBy");
669
            propertyPaths.add("taxon");
670
            propertyPaths.add("taxonName");
671
            propertyPaths.add("descriptionElements");
672
            propertyPaths.add("descriptionElements.createdBy");
673
            propertyPaths.add("descriptionElements.updatedBy");
674
            propertyPaths.add("descriptionElements.feature");
675
            propertyPaths.add("descriptionElements.multilanguageText");
676
            propertyPaths.add("descriptionElements.multilanguageText.language");
677
            propertyPaths.add("descriptionElements.area");
678
            propertyPaths.add("descriptionElements.status");
679
            propertyPaths.add("descriptionElements.modifyingText");
680
            propertyPaths.add("descriptionElementsmodifyingText.language");
681
            propertyPaths.add("descriptionElements.modifiers");
682

    
683
            defaultBeanInitializer.initialize(descriptionBase, propertyPaths);
684
        }
685
        return descriptionBase;
686
    }
687

    
688

    
689
    @Override
690
    public <T extends DescriptionElementBase> List<T> getDescriptionElementForTaxon(
691
            UUID taxonUuid, Set<Feature> features,
692
            Class<T> type, Integer pageSize,
693
            Integer pageNumber, List<String> propertyPaths) {
694

    
695
        Query query = prepareGetDescriptionElementForTaxon(taxonUuid, features, type, pageSize, pageNumber, false);
696

    
697
        if (logger.isDebugEnabled()){logger.debug(" dao: get list ...");}
698
        List<T> results = query.list();
699
        if (logger.isDebugEnabled()){logger.debug(" dao: initialize ...");}
700
        defaultBeanInitializer.initializeAll(results, propertyPaths);
701
        if (logger.isDebugEnabled()){logger.debug(" dao: initialize - DONE");}
702
        return results;
703
    }
704

    
705
    @Override
706
    public <T extends DescriptionElementBase> long countDescriptionElementForTaxon(
707
            UUID taxonUuid, Set<Feature> features, Class<T> type) {
708

    
709
        Query query = prepareGetDescriptionElementForTaxon(taxonUuid, features, type, null, null, true);
710

    
711
        return (Long)query.uniqueResult();
712
    }
713

    
714
    /**
715
     * @param taxon
716
     * @param features
717
     * @param type
718
     * @param pageSize
719
     * @param pageNumber
720
     * @return
721
     */
722
    private <T extends DescriptionElementBase> Query prepareGetDescriptionElementForTaxon(UUID taxonUuid,
723
            Set<Feature> features, Class<T> type, Integer pageSize, Integer pageNumber, boolean asCountQuery) {
724

    
725
        String listOrCount;
726
        if(asCountQuery){
727
            listOrCount = "count(de)";
728
        } else {
729
            listOrCount = "de";
730
        }
731

    
732
        String queryString = "select " + listOrCount + " from DescriptionElementBase as de" +
733
                " left join de.inDescription as d" +
734
                " left join d.taxon as t" +
735
                " where d.class = 'TaxonDescription' AND t.uuid = :taxon_uuid ";
736

    
737
        if(type != null){
738
            queryString += " and de.class = :type";
739
        }
740
        if (features != null && features.size() > 0){
741
            queryString += " and de.feature in (:features) ";
742
        }
743
//		System.out.println(queryString);
744
        Query query = getSession().createQuery(queryString);
745

    
746
        query.setParameter("taxon_uuid", taxonUuid);
747
        if(type != null){
748
            query.setParameter("type", type.getSimpleName());
749
        }
750
        if(features != null && features.size() > 0){
751
            query.setParameterList("features", features) ;
752
        }
753

    
754
        if(pageSize != null) {
755
            query.setMaxResults(pageSize);
756
            if(pageNumber != null) {
757
                query.setFirstResult(pageNumber * pageSize);
758
            }
759
        }
760
        return query;
761
    }
762

    
763
    /* (non-Javadoc)
764
     * @see eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao#listTaxonDescriptionMedia(java.util.UUID, java.lang.Boolean, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)
765
     */
766
    @Override
767
    public List<Media> listTaxonDescriptionMedia(UUID taxonUuid,
768
            Boolean limitToGalleries, Set<MarkerType> markerTypes,
769
            Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
770

    
771
               AuditEvent auditEvent = getAuditEventFromContext();
772
            if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
773
                String queryString = " SELECT media " +
774
                    getTaxonDescriptionMediaQueryString(
775
                        taxonUuid, limitToGalleries,  markerTypes);
776
                queryString +=
777
                    " GROUP BY media "
778
//	    						" ORDER BY index(media) "  //not functional
779
                    ;
780

    
781
                Query query = getSession().createQuery(queryString);
782

    
783
                setTaxonDescriptionMediaParameters(query, taxonUuid, limitToGalleries, markerTypes);
784

    
785

    
786
//	            addMarkerTypesCriterion(markerTypes, hql);
787

    
788
                setPagingParameter(query, pageSize, pageNumber);
789

    
790
                List<Media> results = query.list();
791

    
792
                defaultBeanInitializer.initializeAll(results, propertyPaths);
793

    
794
                return results;
795
            } else {
796
                throw new OperationNotSupportedInPriorViewException("countTaxonDescriptionMedia(UUID taxonUuid, boolean restrictToGalleries)");
797
            }
798
    }
799

    
800

    
801
    /* (non-Javadoc)
802
     * @see eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao#countTaxonDescriptionMedia(java.util.UUID, java.lang.Boolean, java.util.Set)
803
     */
804
    @Override
805
    public int countTaxonDescriptionMedia(UUID taxonUuid,
806
            Boolean limitToGalleries, Set<MarkerType> markerTypes) {
807
        AuditEvent auditEvent = getAuditEventFromContext();
808
        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
809
            String queryString = " SELECT count(DISTINCT media) " +
810
                getTaxonDescriptionMediaQueryString(
811
                    taxonUuid, limitToGalleries, markerTypes);
812

    
813
            Query query = getSession().createQuery(queryString);
814
            setTaxonDescriptionMediaParameters(query, taxonUuid, limitToGalleries, markerTypes);
815
            return ((Long)query.uniqueResult()).intValue();
816
        }else{
817
            throw new OperationNotSupportedInPriorViewException("countTaxonDescriptionMedia(UUID taxonUuid)");
818
        }
819

    
820
    }
821

    
822
    private void setTaxonDescriptionMediaParameters(Query query, UUID taxonUuid, Boolean limitToGalleries, Set<MarkerType> markerTypes) {
823
        if(taxonUuid != null){
824
            query.setParameter("uuid", taxonUuid);
825
        }
826

    
827
    }
828

    
829
    /**
830
     * @param taxonUuid
831
     * @param restrictToGalleries
832
     * @param markerTypes
833
     * @return
834
     */
835
    private String getTaxonDescriptionMediaQueryString(UUID taxonUuid,
836
            Boolean restrictToGalleries, Set<MarkerType> markerTypes) {
837
        String fromQueryString =
838
            " FROM DescriptionElementBase as deb INNER JOIN " +
839
                " deb.inDescription as td "
840
                + " INNER JOIN td.taxon as t "
841
                + " JOIN deb.media as media "
842
                + " LEFT JOIN td.markers marker ";
843

    
844
        String whereQueryString = " WHERE (1=1) ";
845
        if (taxonUuid != null){
846
            whereQueryString += " AND t.uuid = :uuid ";
847
        }
848
        if (restrictToGalleries){
849
            whereQueryString += " AND td.imageGallery is true ";
850
        }
851
        if (markerTypes != null && !markerTypes.isEmpty()){
852
            whereQueryString += " AND (1=0";
853
            for (MarkerType markerType : markerTypes){
854
                whereQueryString += " OR ( marker.markerType.id = " + markerType.getId() + " AND marker.flag is true)";
855

    
856
            }
857
            whereQueryString += ") ";
858
        }
859

    
860
        return fromQueryString + whereQueryString;
861

    
862
    }
863

    
864
    /* (non-Javadoc)
865
     * @see eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao#listNamedAreasInUse(java.lang.Integer, java.lang.Integer, java.util.List)
866
     */
867
    @Override
868
    public List<NamedArea> listNamedAreasInUse(Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
869

    
870
        String queryString = "select distinct d.area from Distribution as d";
871
        Query query = getSession().createQuery(queryString);
872

    
873
        if(pageSize != null) {
874
            query.setMaxResults(pageSize);
875
            if(pageNumber != null) {
876
                query.setFirstResult(pageNumber * pageSize);
877
            }
878
        }
879

    
880
        List<NamedArea> results = query.list();
881

    
882
        defaultBeanInitializer.initializeAll(results, propertyPaths);
883

    
884
        return results;
885
    }
886

    
887

    
888

    
889
}
(1-1/10)