bugfix for countTaxonDescriptionMedia
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / description / DescriptionDaoImpl.java
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.LSID;
30 import eu.etaxonomy.cdm.model.common.MarkerType;
31 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
32 import eu.etaxonomy.cdm.model.description.DescriptionBase;
33 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
34 import eu.etaxonomy.cdm.model.description.Feature;
35 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
36 import eu.etaxonomy.cdm.model.description.Scope;
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 @SuppressWarnings("unused")
56 private static final Logger logger = Logger.getLogger(DescriptionDaoImpl.class);
57
58 public DescriptionDaoImpl() {
59 super(DescriptionBase.class);
60 indexedClasses = new Class[3];
61 indexedClasses[0] = TaxonDescription.class;
62 indexedClasses[1] = TaxonNameDescription.class;
63 indexedClasses[2] = SpecimenDescription.class;
64 }
65
66 public int countDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status) {
67 checkNotInPriorView("DescriptionDaoImpl.countDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status)");
68 Query query = null;
69
70 if(status == null) {
71 query = getSession().createQuery("select count(distinct description) from TaxonDescription description left join description.descriptionElements element join element.area area where area in (:namedAreas)");
72 } else {
73 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");
74 query.setParameter("status", status);
75 }
76 query.setParameterList("namedAreas", namedAreas);
77
78 return ((Long)query.uniqueResult()).intValue();
79 }
80
81 public int countDescriptionElements(DescriptionBase description, Set<Feature> features, Class<? extends DescriptionElementBase> clazz) {
82 AuditEvent auditEvent = getAuditEventFromContext();
83 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
84 Criteria criteria = null;
85 if(clazz == null) {
86 criteria = getSession().createCriteria(DescriptionElementBase.class);
87 } else {
88 criteria = getSession().createCriteria(clazz);
89 }
90
91 if(description != null) {
92 criteria.add(Restrictions.eq("inDescription", description));
93 }
94
95 if(features != null && !features.isEmpty()) {
96 criteria.add(Restrictions.in("feature", features));
97 }
98
99 criteria.setProjection(Projections.rowCount());
100
101 return (Integer)criteria.uniqueResult();
102 } else {
103 if(features != null && !features.isEmpty()) {
104 Integer count = 0;
105 for(Feature f : features) {
106 AuditQuery query = null;
107 if(clazz == null) {
108 query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
109 } else {
110 query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
111 }
112
113 if(description != null) {
114 query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
115 }
116
117 query.add(AuditEntity.relatedId("feature").eq(f.getId()));
118 query.addProjection(AuditEntity.id().count("id"));
119 count += ((Long)query.getSingleResult()).intValue();
120 }
121
122 return count;
123 } else {
124 AuditQuery query = null;
125 if(clazz == null) {
126 query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
127 } else {
128 query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
129 }
130
131 if(description != null) {
132 query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
133 }
134 query.addProjection(AuditEntity.id().count("id"));
135 return ((Long)query.getSingleResult()).intValue();
136 }
137 }
138 }
139
140 public int countDescriptions(Class<? extends DescriptionBase> clazz, Boolean hasImages, Boolean hasText, Set<Feature> features) {
141 checkNotInPriorView("DescriptionDaoImpl.countDescriptions(Class<TYPE> type, Boolean hasImages, Boolean hasText, Set<Feature> features)");
142 Criteria inner = null;
143
144 if(clazz == null) {
145 inner = getSession().createCriteria(type);
146 } else {
147 inner = getSession().createCriteria(clazz);
148 }
149
150 Criteria elementsCriteria = inner.createCriteria("descriptionElements");
151 if(hasText != null) {
152 if(hasText) {
153 elementsCriteria.add(Restrictions.isNotEmpty("multilanguageText"));
154 } else {
155 elementsCriteria.add(Restrictions.isEmpty("multilanguageText"));
156 }
157 }
158
159 if(hasImages != null) {
160 if(hasImages) {
161 elementsCriteria.add(Restrictions.isNotEmpty("media"));
162 } else {
163 elementsCriteria.add(Restrictions.isEmpty("media"));
164 }
165 }
166
167 if(features != null && !features.isEmpty()) {
168 elementsCriteria.add(Restrictions.in("feature", features));
169 }
170
171 inner.setProjection(Projections.countDistinct("id"));
172
173 return (Integer) inner.uniqueResult();
174 }
175
176 public int countTaxonDescriptions(Taxon taxon, Set<Scope> scopes,Set<NamedArea> geographicalScopes, Set<MarkerType> markerTypes) {
177 AuditEvent auditEvent = getAuditEventFromContext();
178 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
179 Criteria criteria = getSession().createCriteria(TaxonDescription.class);
180
181 if(taxon != null) {
182 criteria.add(Restrictions.eq("taxon", taxon));
183 }
184
185 if(scopes != null && !scopes.isEmpty()) {
186 Set<Integer> scopeIds = new HashSet<Integer>();
187 for(Scope s : scopes) {
188 scopeIds.add(s.getId());
189 }
190 criteria.createCriteria("scopes").add(Restrictions.in("id", scopeIds));
191 }
192
193 if(geographicalScopes != null && !geographicalScopes.isEmpty()) {
194 Set<Integer> geoScopeIds = new HashSet<Integer>();
195 for(NamedArea n : geographicalScopes) {
196 geoScopeIds.add(n.getId());
197 }
198 criteria.createCriteria("geoScopes").add(Restrictions.in("id", geoScopeIds));
199 }
200
201
202 addMarkerTypesCriterion(markerTypes, criteria);
203
204
205 criteria.setProjection(Projections.rowCount());
206
207 return (Integer)criteria.uniqueResult();
208 } else {
209 if((scopes == null || scopes.isEmpty())&& (geographicalScopes == null || geographicalScopes.isEmpty()) && (markerTypes == null || markerTypes.isEmpty())) {
210 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonDescription.class,auditEvent.getRevisionNumber());
211 if(taxon != null) {
212 query.add(AuditEntity.relatedId("taxon").eq(taxon.getId()));
213 }
214
215 query.addProjection(AuditEntity.id().count("id"));
216
217 return ((Long)query.getSingleResult()).intValue();
218 } else {
219 throw new OperationNotSupportedInPriorViewException("countTaxonDescriptions(Taxon taxon, Set<Scope> scopes,Set<NamedArea> geographicalScopes)");
220 }
221 }
222 }
223
224 /**
225 * @param markerTypes
226 * @param criteria
227 *
228 */
229 //TODO move to AnnotatableEntityDao(?)
230 private void addMarkerTypesCriterion(Set<MarkerType> markerTypes, Criteria criteria) {
231
232 if(markerTypes != null && !markerTypes.isEmpty()) {
233 Set<Integer> markerTypeIds = new HashSet<Integer>();
234 for(MarkerType markerType : markerTypes) {
235 markerTypeIds.add(markerType.getId());
236 }
237 criteria.createCriteria("markers").add(Restrictions.eq("flag", true))
238 .createAlias("markerType", "mt")
239 .add(Restrictions.in("mt.id", markerTypeIds));
240 } else if (markerTypes != null && markerTypes.isEmpty()){
241 //AT: added in case the projects requires an third state description, An empty Marker type set
242 }
243 }
244
245 public List<DescriptionElementBase> getDescriptionElements(DescriptionBase description, Set<Feature> features,Class<? extends DescriptionElementBase> clazz, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
246
247 AuditEvent auditEvent = getAuditEventFromContext();
248 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
249 Criteria criteria = null;
250 if(clazz == null) {
251 criteria = getSession().createCriteria(DescriptionElementBase.class);
252 } else {
253 criteria = getSession().createCriteria(clazz);
254 }
255
256 if(description != null) {
257 criteria.add(Restrictions.eq("inDescription", description));
258 }
259
260 if(features != null && !features.isEmpty()) {
261 criteria.add(Restrictions.in("feature", features));
262 }
263
264 if(pageSize != null) {
265 criteria.setMaxResults(pageSize);
266 if(pageNumber != null) {
267 criteria.setFirstResult(pageNumber * pageSize);
268 }
269 }
270
271 List<DescriptionElementBase> results = (List<DescriptionElementBase>)criteria.list();
272
273 defaultBeanInitializer.initializeAll(results, propertyPaths);
274
275 return results;
276 } else {
277 List<DescriptionElementBase> result = new ArrayList<DescriptionElementBase>();
278 if(features != null && !features.isEmpty()) {
279
280 for(Feature f : features) {
281 AuditQuery query = null;
282 if(clazz == null) {
283 query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
284 } else {
285 query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
286 }
287
288 if(description != null) {
289 query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
290 }
291
292 query.add(AuditEntity.relatedId("feature").eq(f.getId()));
293 result.addAll((List<DescriptionElementBase>)query.getResultList());
294 }
295 } else {
296 AuditQuery query = null;
297 if(clazz == null) {
298 query = getAuditReader().createQuery().forEntitiesAtRevision(DescriptionElementBase.class,auditEvent.getRevisionNumber());
299 } else {
300 query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());
301 }
302
303 if(description != null) {
304 query.add(AuditEntity.relatedId("inDescription").eq(description.getId()));
305 }
306
307 result = query.getResultList();
308 }
309
310 defaultBeanInitializer.initializeAll(result, propertyPaths);
311
312 return result;
313 }
314 }
315
316 public List<TaxonDescription> listTaxonDescriptions(Taxon taxon, Set<Scope> scopes, Set<NamedArea> geographicalScopes, Set<MarkerType> markerTypes, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
317 AuditEvent auditEvent = getAuditEventFromContext();
318 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
319 Criteria criteria = getSession().createCriteria(TaxonDescription.class);
320
321 if(taxon != null) {
322 criteria.add(Restrictions.eq("taxon", taxon));
323 }
324
325 if(scopes != null && !scopes.isEmpty()) {
326 Set<Integer> scopeIds = new HashSet<Integer>();
327 for(Scope s : scopes) {
328 scopeIds.add(s.getId());
329 }
330 criteria.createCriteria("scopes").add(Restrictions.in("id", scopeIds));
331 }
332
333 if(geographicalScopes != null && !geographicalScopes.isEmpty()) {
334 Set<Integer> geoScopeIds = new HashSet<Integer>();
335 for(NamedArea n : geographicalScopes) {
336 geoScopeIds.add(n.getId());
337 }
338 criteria.createCriteria("geoScopes").add(Restrictions.in("id", geoScopeIds));
339 }
340
341 addMarkerTypesCriterion(markerTypes, criteria);
342
343 if(pageSize != null) {
344 criteria.setMaxResults(pageSize);
345 if(pageNumber != null) {
346 criteria.setFirstResult(pageNumber * pageSize);
347 }
348 }
349
350 List<TaxonDescription> results = (List<TaxonDescription>)criteria.list();
351
352 defaultBeanInitializer.initializeAll(results, propertyPaths);
353
354 return results;
355 } else {
356 if((scopes == null || scopes.isEmpty())&& (geographicalScopes == null || geographicalScopes.isEmpty())&& (markerTypes == null || markerTypes.isEmpty())) {
357 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonDescription.class,auditEvent.getRevisionNumber());
358 if(taxon != null) {
359 query.add(AuditEntity.relatedId("taxon").eq(taxon.getId()));
360 }
361
362 if(pageSize != null) {
363 query.setMaxResults(pageSize);
364 if(pageNumber != null) {
365 query.setFirstResult(pageNumber * pageSize);
366 } else {
367 query.setFirstResult(0);
368 }
369 }
370
371 List<TaxonDescription> results = (List<TaxonDescription>)query.getResultList();
372 defaultBeanInitializer.initializeAll(results, propertyPaths);
373 return results;
374 } else {
375 throw new OperationNotSupportedInPriorViewException("countTaxonDescriptions(Taxon taxon, Set<Scope> scopes,Set<NamedArea> geographicalScopes)");
376 }
377 }
378 }
379
380 public List<TaxonNameDescription> getTaxonNameDescriptions(TaxonNameBase name, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
381 AuditEvent auditEvent = getAuditEventFromContext();
382 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
383 Criteria criteria = getSession().createCriteria(TaxonNameDescription.class);
384
385 if(name != null) {
386 criteria.add(Restrictions.eq("taxonName", name));
387 }
388
389 if(pageSize != null) {
390 criteria.setMaxResults(pageSize);
391 if(pageNumber != null) {
392 criteria.setFirstResult(pageNumber * pageSize);
393 }
394 }
395
396 List<TaxonNameDescription> results = (List<TaxonNameDescription>)criteria.list();
397
398 defaultBeanInitializer.initializeAll(results, propertyPaths);
399
400 return results;
401 } else {
402 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameDescription.class,auditEvent.getRevisionNumber());
403
404 if(name != null) {
405 query.add(AuditEntity.relatedId("taxonName").eq(name.getId()));
406 }
407
408 if(pageSize != null) {
409 query.setMaxResults(pageSize);
410 if(pageNumber != null) {
411 query.setFirstResult(pageNumber * pageSize);
412 }
413 }
414
415 List<TaxonNameDescription> results = (List<TaxonNameDescription>)query.getResultList();
416
417 defaultBeanInitializer.initializeAll(results, propertyPaths);
418
419 return results;
420 }
421
422 }
423
424 public int countTaxonNameDescriptions(TaxonNameBase name) {
425 AuditEvent auditEvent = getAuditEventFromContext();
426 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
427 Criteria criteria = getSession().createCriteria(TaxonNameDescription.class);
428
429 if(name != null) {
430 criteria.add(Restrictions.eq("taxonName", name));
431 }
432
433 criteria.setProjection(Projections.rowCount());
434
435 return (Integer)criteria.uniqueResult();
436 } else {
437 AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonNameDescription.class,auditEvent.getRevisionNumber());
438
439 if(name != null) {
440 query.add(AuditEntity.relatedId("taxonName").eq(name.getId()));
441 }
442
443 query.addProjection(AuditEntity.id().count("id"));
444 return ((Long)query.getSingleResult()).intValue();
445 }
446 }
447
448 /**
449 * Should use a DetachedCriteria & subquery, but HHH-158 prevents this, for now.
450 *
451 * e.g. DetachedCriteria inner = DestachedCriteria.forClass(type);
452 *
453 * outer.add(Subqueries.propertyIn("id", inner));
454 */
455 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) {
456 checkNotInPriorView("DescriptionDaoImpl.listDescriptions(Class<TYPE> type, Boolean hasImages, Boolean hasText, Set<Feature> features, Integer pageSize, Integer pageNumber)");
457 Criteria inner = null;
458
459 if(clazz == null) {
460 inner = getSession().createCriteria(type);
461 } else {
462 inner = getSession().createCriteria(clazz);
463 }
464
465 Criteria elementsCriteria = inner.createCriteria("descriptionElements");
466 if(hasText != null) {
467 if(hasText) {
468 elementsCriteria.add(Restrictions.isNotEmpty("multilanguageText"));
469 } else {
470 elementsCriteria.add(Restrictions.isEmpty("multilanguageText"));
471 }
472 }
473
474 if(hasImages != null) {
475 if(hasImages) {
476 elementsCriteria.add(Restrictions.isNotEmpty("media"));
477 } else {
478 elementsCriteria.add(Restrictions.isEmpty("media"));
479 }
480 }
481
482 if(features != null && !features.isEmpty()) {
483 elementsCriteria.add(Restrictions.in("feature", features));
484 }
485
486 inner.setProjection(Projections.distinct(Projections.id()));
487
488 List<Object> intermediateResult = (List<Object>)inner.list();
489
490 if(intermediateResult.isEmpty()) {
491 return new ArrayList<DescriptionBase>();
492 }
493
494 Integer[] resultIds = new Integer[intermediateResult.size()];
495 for(int i = 0; i < resultIds.length; i++) {
496 resultIds[i] = (Integer)intermediateResult.get(i);
497 }
498
499 Criteria outer = null;
500
501 if(clazz == null) {
502 outer = getSession().createCriteria(type);
503 } else {
504 outer = getSession().createCriteria(clazz);
505 }
506
507 outer.add(Restrictions.in("id", resultIds));
508 addOrder(outer, orderHints);
509
510 if(pageSize != null) {
511 outer.setMaxResults(pageSize);
512 if(pageNumber != null) {
513 outer.setFirstResult(pageNumber * pageSize);
514 }
515 }
516
517 List<DescriptionBase> results = (List<DescriptionBase>)outer.list();
518 defaultBeanInitializer.initializeAll(results, propertyPaths);
519 return results;
520 }
521
522 public List<TaxonDescription> searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
523 checkNotInPriorView("DescriptionDaoImpl.searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase status, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)");
524
525 Criteria criteria = getSession().createCriteria(TaxonDescription.class);
526 Criteria elements = criteria.createCriteria("descriptionElements", "descriptionElement", Criteria.LEFT_JOIN);
527 elements.add(Restrictions.in("area", namedAreas.toArray()));
528
529 if(status != null) {
530 elements.add(Restrictions.eq("status", status));
531 }
532
533 ProjectionList projectionList = Projections.projectionList().add(Projections.id());
534
535 if(orderHints != null && !orderHints.isEmpty()) {
536 for(OrderHint orderHint : orderHints) {
537 projectionList = projectionList.add(Projections.property(orderHint.getPropertyName()));
538 }
539 }
540
541 criteria.setProjection(Projections.distinct(projectionList));
542
543 if(pageSize != null) {
544 criteria.setMaxResults(pageSize);
545 if(pageNumber != null) {
546 criteria.setFirstResult(pageNumber * pageSize);
547 }
548 }
549
550 addOrder(criteria,orderHints);
551
552 List<Object> intermediateResult = (List<Object>)criteria.list();
553
554 if(intermediateResult.isEmpty())
555 return new ArrayList<TaxonDescription>();
556
557 Integer[] resultIds = new Integer[intermediateResult.size()];
558 for(int i = 0; i < resultIds.length; i++) {
559 if(orderHints == null || orderHints.isEmpty()) {
560 resultIds[i] = (Integer)intermediateResult.get(i);
561 } else {
562 resultIds[i] = (Integer)((Object[])intermediateResult.get(i))[0];
563 }
564 }
565
566 criteria = getSession().createCriteria(TaxonDescription.class);
567 criteria.add(Restrictions.in("id", resultIds));
568 addOrder(criteria,orderHints);
569
570 List<TaxonDescription> results = (List<TaxonDescription>)criteria.list();
571 defaultBeanInitializer.initializeAll(results, propertyPaths);
572 return results;
573 }
574
575 public List<CommonTaxonName> searchDescriptionByCommonName(String queryString, MatchMode matchMode, Integer pageSize, Integer pageNumber) {
576
577 Criteria crit = getSession().createCriteria(CommonTaxonName.class);
578 if (matchMode == MatchMode.EXACT) {
579 crit.add(Restrictions.eq("name", matchMode.queryStringFrom(queryString)));
580 } else {
581 crit.add(Restrictions.ilike("name", matchMode.queryStringFrom(queryString)));
582 }
583
584 if(pageSize != null) {
585 crit.setMaxResults(pageSize);
586 if(pageNumber != null) {
587 crit.setFirstResult(pageNumber * pageSize);
588 }
589 }
590 List<CommonTaxonName> results = (List<CommonTaxonName>)crit.list();
591 return results;
592 }
593
594 public Integer countDescriptionByCommonName(String queryString, MatchMode matchMode) {
595 //TODO inprove performance
596 List<CommonTaxonName> results = searchDescriptionByCommonName(queryString, matchMode, null, null);
597 return results.size();
598 }
599
600 @Override
601 public DescriptionBase find(LSID lsid) {
602 DescriptionBase descriptionBase = super.find(lsid);
603 if(descriptionBase != null) {
604 List<String> propertyPaths = new ArrayList<String>();
605 propertyPaths.add("createdBy");
606 propertyPaths.add("updatedBy");
607 propertyPaths.add("taxon");
608 propertyPaths.add("taxonName");
609 propertyPaths.add("descriptionElements");
610 propertyPaths.add("descriptionElements.createdBy");
611 propertyPaths.add("descriptionElements.updatedBy");
612 propertyPaths.add("descriptionElements.feature");
613 propertyPaths.add("descriptionElements.multilanguageText");
614 propertyPaths.add("descriptionElements.multilanguageText.language");
615 propertyPaths.add("descriptionElements.area");
616 propertyPaths.add("descriptionElements.status");
617 propertyPaths.add("descriptionElements.modifyingText");
618 propertyPaths.add("descriptionElementsmodifyingText.language");
619 propertyPaths.add("descriptionElements.modifiers");
620
621 defaultBeanInitializer.initialize(descriptionBase, propertyPaths);
622 }
623 return descriptionBase;
624 }
625
626
627 public <T extends DescriptionElementBase> List<T> getDescriptionElementForTaxon(
628 Taxon taxon, Set<Feature> features,
629 Class<T> type, Integer pageSize,
630 Integer pageNumber, List<String> propertyPaths) {
631
632 String queryString = "select de" +
633 " from TaxonDescription as td" +
634 " left join td.descriptionElements as de" +
635 " where td.taxon = :taxon ";
636
637 if(type != null){
638 queryString += " and de.class = :type";
639 }
640 if (features != null && features.size() > 0){
641 queryString += " and de.feature in (:features) ";
642 }
643 // System.out.println(queryString);
644 Query query = getSession().createQuery(queryString);
645
646 query.setParameter("taxon", taxon);
647 if(type != null){
648 query.setParameter("type", type.getSimpleName());
649 }
650 if(features != null && features.size() > 0){
651 query.setParameterList("features", features) ;
652 }
653
654 if(pageSize != null) {
655 query.setMaxResults(pageSize);
656 if(pageNumber != null) {
657 query.setFirstResult(pageNumber * pageSize);
658 }
659 }
660
661 List<T> results = (List<T>) query.list();
662 defaultBeanInitializer.initializeAll(results, propertyPaths);
663
664 return results;
665 }
666
667 /* (non-Javadoc)
668 * @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)
669 */
670 @Override
671 public List<Media> listTaxonDescriptionMedia(UUID taxonUuid,
672 Boolean limitToGalleries, Set<MarkerType> markerTypes,
673 Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
674
675 AuditEvent auditEvent = getAuditEventFromContext();
676 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
677 String queryString = " SELECT media " +
678 getTaxonDescriptionMediaQueryString(
679 taxonUuid, limitToGalleries, markerTypes);
680 queryString +=
681 " GROUP BY media "
682 // " ORDER BY index(media) " //not functional
683 ;
684
685 Query query = getSession().createQuery(queryString);
686
687 setTaxonDescriptionMediaParameters(query, taxonUuid, limitToGalleries, markerTypes);
688
689
690 // addMarkerTypesCriterion(markerTypes, hql);
691
692 if(pageSize != null) {
693 query.setMaxResults(pageSize);
694 if(pageNumber != null) {
695 query.setFirstResult(pageNumber * pageSize);
696 }
697 }
698
699 List<Media> results = (List<Media>)query.list();
700
701 defaultBeanInitializer.initializeAll(results, propertyPaths);
702
703 return results;
704 } else {
705 throw new OperationNotSupportedInPriorViewException("countTaxonDescriptionMedia(UUID taxonUuid, boolean restrictToGalleries)");
706 }
707 }
708
709
710 /* (non-Javadoc)
711 * @see eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao#countTaxonDescriptionMedia(java.util.UUID, java.lang.Boolean, java.util.Set)
712 */
713 @Override
714 public int countTaxonDescriptionMedia(UUID taxonUuid,
715 Boolean limitToGalleries, Set<MarkerType> markerTypes) {
716 AuditEvent auditEvent = getAuditEventFromContext();
717 if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {
718 String queryString = " SELECT count(DISTINCT media) " +
719 getTaxonDescriptionMediaQueryString(
720 taxonUuid, limitToGalleries, markerTypes);
721
722 Query query = getSession().createQuery(queryString);
723 setTaxonDescriptionMediaParameters(query, taxonUuid, limitToGalleries, markerTypes);
724 return ((Long)query.uniqueResult()).intValue();
725 }else{
726 throw new OperationNotSupportedInPriorViewException("countTaxonDescriptionMedia(UUID taxonUuid)");
727 }
728
729 }
730
731 private void setTaxonDescriptionMediaParameters(Query query, UUID taxonUuid, Boolean limitToGalleries, Set<MarkerType> markerTypes) {
732 if(taxonUuid != null){
733 query.setParameter("uuid", taxonUuid);
734 }
735
736 }
737
738 /**
739 * @param taxonUuid
740 * @param restrictToGalleries
741 * @param markerTypes
742 * @return
743 */
744 private String getTaxonDescriptionMediaQueryString(UUID taxonUuid,
745 Boolean restrictToGalleries, Set<MarkerType> markerTypes) {
746 String fromQueryString =
747 " FROM DescriptionElementBase as deb INNER JOIN " +
748 " deb.inDescription as td "
749 + " INNER JOIN td.taxon as t "
750 + " JOIN deb.media as media "
751 + " LEFT JOIN td.markers marker ";
752
753 String whereQueryString = " WHERE (1=1) ";
754 if (taxonUuid != null){
755 whereQueryString += " AND t.uuid = :uuid ";
756 }
757 if (restrictToGalleries){
758 whereQueryString += " AND td.imageGallery is true ";
759 }
760 if (markerTypes != null && !markerTypes.isEmpty()){
761 whereQueryString += " AND (1=0";
762 for (MarkerType markerType : markerTypes){
763 whereQueryString += " OR ( marker.markerType.id = " + markerType.getId() + " AND marker.flag is true)";
764
765 }
766 whereQueryString += ") ";
767 }
768
769 return fromQueryString + whereQueryString;
770
771 }
772
773
774
775 }